← Work
Product

Petica.app

A Croatian K-12 education platform, built solo end to end: a Next.js 16 + React 19 + Supabase + Payload CMS app powering AI grade summaries, exam prep, and auto-graded quizzes, built on a resilient authenticated integration client for the national e-Dnevnik gradebook, a provider-agnostic Gemini/Claude/OpenAI layer, AES-256-GCM credential vaulting, and an RLS-first multi-tenant model (170 policies across ~42 tables).

Role
Solo founder & engineer
Timeframe
2026 – Present
Stack
Next.js · React 19 · TypeScript · Gemini · OpenAI · Claude · Supabase · Payload CMS · Tailwind CSS v4 · Stripe · Vercel · pgvector
Petica app hero
Petica AI is a Croatian K-12 education platform, built solo end to end. Parents and students link their national e-Dnevnik grade book via AAI@EduHr SSO, then get AI-powered grade summaries, exam prep, auto-graded quizzes, and a social learning community.

Key Features Built

Grade management & e-Dnevnik sync

  • Authenticated integration client for Croatia's national ocjene.skole.hr gradebook, with cookie-jar sessions, an AAI@EduHr SSO login flow, retry/back-off, and region-appropriate routing
  • Multi-source parser (HTML + ICS) extracting grades, teacher notes, exam calendars, class schedules, and absences
  • Grade dashboards with timeline/distribution charts and a "what-if" grade calculator
  • Incremental sync: full history backfill on first run, current-year-only thereafter

AI-powered learning

  • AI student summaries covering strengths, weaknesses, and trends, reused in email digests
  • AI study guides and auto-quizzes generated from upcoming exam topics
  • Lektira module with AI "cliff notes" and literary-analysis quizzes for the Croatian required-reading curriculum
  • Interactive quiz engine with 8+ question types, from multiple choice to fill-in-the-dropdown
  • Vision auto-grading of handwritten or photo-submitted answers, including written math work
  • Document-to-quiz generation from uploaded notes or worksheets via OCR
  • Curriculum outcome matching against official Croatian kurikulum outcomes

Family, billing & tiers

  • Tiered feature-gating (free / starter / family / large_family) with per-tier student caps and full access while trialing
  • Stripe checkout, customer portal, and signature-verified webhook lifecycle handling
  • Family creation, member invites/roles, and a request/approve student-transfer flow between families

Community & messaging

  • Real-time 1:1 and group chat with threads, replies, reactions, edit/delete, read state, and link previews
  • Shared quizzes in chat: assign a quiz to a group, track per-member sessions, and post an AI performance analysis back into the thread
  • "Petko" AI assistant answering in-conversation questions using a group's linked student context
  • Polls, peer discovery with Croatian handles, study groups, and reporting with AI content moderation

Automation

  • A 3-stage nightly pipeline (grade sync, AI summaries, then email digests) chained and individually secured
  • Exam reminders: a 3-day-out check auto-generates a study-guide quiz, a 1-day-out check sends an email
  • A bilingual AI news digest and storage garbage-collection
  • Seasonal awareness: summer-break calendar logic (with admin override) pauses noisy AI/email crons while keeping grade sync running

Admin

  • Payload CMS collections for Users, Profiles, Students, Schools, Grades, Exams, Media, and Posts
  • An LLM configuration console to assign a model per feature area and manage encrypted per-provider API keys
  • User/family administration, manual sync trigger, lektira content management, a stats dashboard, and a seasonal-mode toggle

Engineering Highlights

A resilient authenticated integration client, production-grade The e-Dnevnik client manages its own cookie jar, handling an Expires-comma edge case, performs the AAI SSO CSRF-to-credential-to-redirect flow while carrying the session cookie across the redirect (a documented failure mode of naive clients), and applies abort timeouts with exponential-backoff retries that distinguish transient from permanent errors. It is region-pinned to Frankfurt to match the service's EU availability. Smart exam reconciliation auto-cancels vanished exams, restores reappearing ones, and transfers study guides to rescheduled replacements.

Provider-agnostic LLM router One callLLM(featureArea, ...) entry point reads a DB-driven config per feature area, resolves an API key, and routes to Gemini, Claude, or OpenAI behind a uniform interface, with vision normalized across providers via a shared images[] shape. A key-resolution cascade falls back from an encrypted DB key to an env var to a safe fallback model, with 60s in-process caches to avoid per-call DB round-trips, and graceful degradation so best-effort image or embedding calls return null rather than throw.

Authenticated encryption for sensitive credentials AES-256-GCM with scryptSync key derivation, a random per-encryption IV, and a packed iv + authTag + ciphertext with the GCM auth tag verified on decrypt, protecting two classes of sensitive credentials that are decrypted server-side only, at the moment of use.

RLS-first multi-tenant model with GDPR-conscious design 170 row-level-security policies model family access as a graph, with membership resolved through family_members and status/role checks. Partial unique indexes enforce invariants like one owner per family and no duplicate active memberships. Student deletion anonymizes rather than hard-deletes: foreign keys switch to ON DELETE SET NULL so pedagogical data survives, de-identified, for a shared question bank. A dedicated service-role client is walled off from the RLS-respecting SSR client with an explicit "never expose to client" guard.

pgvector semantic caching Generated-image dedup via 768-dimension embeddings, an HNSW cosine index, and a SQL RPC doing similarity matching above a threshold avoid regenerating near-identical AI images.

A 5-layer short-answer grader tuned for Croatian orthography Normalized exact match, then Croatian diacritic stripping (NFD plus an explicit đ→d rule), token-overlap/containment, length-scaled Levenshtein typo tolerance, and finally LLM semantic judgment at temperature 0, each layer emitting localized, pedagogically-worded feedback. Client-safe sync layers are split from the LLM layer, and polymorphic quiz grading dispatches over 10+ question types with partial credit and Croatian-decimal normalization.