Daily habits,
measurable progress.
A multi-tenant gamified learning platform with streaks, XP, a role-gated admin panel, and HMAC-signed outbound webhooks. Built on Next.js 16, Prisma 6, and PostgreSQL.
Click either button to auto-fill the login form. Credentials also visible below.


Admin analytics: DAU line, completion funnel, top-10 learners, weekly retention.
What's actually in here
Every box a senior full-stack role checks, wrapped in one coherent product so a reviewer can trace a learner action through the whole system in under a minute.
Mobile-first gamification
Streaks, XP bars, and badges. Timezone-safe daily rollover with DST handling, fully unit-tested.
Admin panel with RBAC
Three roles, tenant-scoped queries, self-demote protection. Every admin mutation writes a typed audit row.
Multi-tenant data model
Every tenant table carries organizationId. Cross-tenant reads bounce to 403 through a three-layer guard.
Analytics dashboard
Daily active users, completion funnel, top learners by XP, weekly retention cohorts. Recharts, server rendered.
HMAC-signed webhooks
SHA-256 over timestamp, deliveryId, body. Exponential backoff with jitter, capped at 8 attempts.
CSV + PDF exports
Progress report as CSV via papaparse, per-learner report card as streamed PDF via @react-pdf/renderer.
Sign in as any role
Three seeded demo accounts. Click any card to land on the login page with credentials pre-filled.
Complete a lesson, watch it ripple
Marking a lesson complete fires a single transactional orchestrator that updates progress, activity, XP, streak, and badges in one Prisma transaction, then enqueues a signed webhook to every subscribed endpoint.
- โStreakcomputed in the user's local timezone, respecting DST.
- โXP event appended to a ledger. Level curve is
50ยทnยท(n+1). - โBadges checked via pure rule matcher over { xp | streak | lessons } thresholds.
- โWebhook delivery signed
sha256(secret, "ts.deliveryId.body"), retried with jittered backoff.
