Gamified adaptive learning platform that helps children (ages 6–10) master multiplication and division fluency through spaced repetition, streaks, quests, and XP — inspired by Duolingo's proven habit mechanics.
- Overview
- Key Features
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Environment Variables
- API Reference
- Testing
- Roadmap
- Contributing
- License
MathMagic transforms rote multiplication/division memorization into a daily practice journey. Children progress through an 8×8 mastery matrix (facts 2×2 through 9×9), with an adaptive engine that intelligently selects which facts to practice based on accuracy, speed, recency, and mastery state.
Two user personas:
| Persona | Needs |
|---|---|
| Child (6–10) | Fast, game-like sessions with instant feedback, visible progress, streaks, and rewards |
| Parent | Clear progress visibility, weak-fact identification, assignment control, and AI-assisted weekly planning |
North Star Metric: Mastered facts per active child per week.
| Mode | Description |
|---|---|
| Multiplication Dash | 10 adaptive questions (2×2 to 9×9) with timed response |
| Division Dash | 10 inverse-fact questions for balanced fluency |
| Table Mastery | Sequential deep-dive into a specific number family |
| Study Tricks | Visual mnemonics for the most difficult facts |
- XP Engine — +10 per correct answer, +5 speed bonus, combo multipliers, quest/assignment completion bonuses
- Level Progression — Formula:
LevelXP(n) = 50 × n² - Daily Quests — Complete all 4 learning modes with ≥80% accuracy
- Streak System — Maintain daily practice (15 solved + ≥70% accuracy); earn streak shields every 7 days
- Mastery Matrix — 8×8 heat map with 6 states:
New → Attempted → Learning → Practiced → Mastered → At-Risk
The fact selection algorithm uses weighted scoring:
weight = base_state_weight × error_boost × recency_factor × assignment_boost × novelty_boost
Mastery criteria: ≥20 attempts, ≥95% rolling accuracy (last 20), ≤4s median latency, active ≥3 days.
- Mastery map visualization with weak-fact highlighting
- Streak health and weekly trend charts
- Manual assignment creation (target questions, due dates, status tracking)
- AI-assisted weekly planning (planned — requires parent approval before activation)
| Component | Technology |
|---|---|
| Framework | Flutter (Dart SDK ≥3.10.8) |
| Platforms | iOS, Android, Web (Chrome) |
| Local Database | SQLite via sqflite / sqflite_common_ffi_web |
| State Management | ChangeNotifier (Riverpod migration planned) |
| Notifications | awesome_notifications + flutter_timezone |
| Home Widget | home_widget (iOS + Android) |
| Component | Technology |
|---|---|
| Runtime | Node.js 22 LTS + TypeScript 5.x |
| Framework | Fastify 4.x |
| Database | PostgreSQL 16 |
| ORM | Prisma 6.x |
| Validation | Zod |
| Auth | jose (JWT) + openid-client (OAuth OIDC) |
| Security | @fastify/helmet, @fastify/cors, @fastify/rate-limit |
| Testing | Vitest 2.x |
| Package Manager | pnpm 9.x |
┌─────────────────────────────────────────────────┐
│ Flutter App │
│ ┌───────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Child Loop│ │ Parent │ │ Sync Layer │ │
│ │ (Adaptive │ │Dashboard │ │ (Outbox) │ │
│ │ Engine) │ │ │ │ │ │
│ └─────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│ └──────────────┼───────────────┘ │
│ ┌─────┴─────┐ │
│ │ SQLite │ │
│ │ (Local) │ │
│ └───────────┘ │
└─────────────────────┬───────────────────────────┘
│ HTTP (REST)
┌─────────────────────┴───────────────────────────┐
│ Fastify API Server │
│ ┌──────────┐ ┌──────────┐ ┌─────────────────┐ │
│ │ Identity │ │ Family & │ │ Learning │ │
│ │ (OAuth) │ │ Roles │ │ (Sessions, │ │
│ │ │ │ │ │ Assignments) │ │
│ └────┬─────┘ └────┬─────┘ └───────┬─────────┘ │
│ └─────────────┼───────────────┘ │
│ ┌─────┴─────┐ │
│ │ Prisma │ │
│ │ ORM │ │
│ └─────┬─────┘ │
│ ┌──────────────────┴────────────────────────┐ │
│ │ Outbox Worker (Background) │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────┬───────────────────────────┘
│
┌───────┴───────┐
│ PostgreSQL 16 │
└───────────────┘
Pattern: Modular monolith with transactional outbox + background worker for reliable async processing.
xronocode-mathmagic/
├── apps/
│ └── mobile_flutter/ # Flutter app (iOS, Android, Web)
│ ├── lib/
│ │ ├── main.dart # App entry point
│ │ ├── core/
│ │ │ ├── api/ # HTTP client
│ │ │ ├── app/ # DI bootstrap, AppShell, root widget
│ │ │ ├── clock/ # Testable clock abstraction
│ │ │ ├── data/local/ # SQLite database layer
│ │ │ ├── env/ # Environment configuration
│ │ │ ├── routing/ # App router
│ │ │ └── theme/ # Material theme
│ │ └── features/
│ │ ├── assignments/ # Parent assignment CRUD
│ │ ├── child_loop/ # Core learning engine (Dash, mastery)
│ │ ├── instrumentation/ # Analytics events
│ │ ├── parent_loop/ # Parent dashboard
│ │ ├── profile/ # Profile management
│ │ ├── progress/ # Progress & mastery matrix
│ │ ├── reminders/ # Notification scheduling
│ │ ├── streak/ # Streak evaluation
│ │ ├── sync/ # Outbox sync (offline-first)
│ │ └── widget/ # iOS/Android home screen widget
│ ├── test/ # Unit & widget tests
│ ├── assets/ # Fonts, icons
│ └── pubspec.yaml
├── backend/
│ ├── src/
│ │ ├── main.ts # API server entry point
│ │ ├── worker-main.ts # Outbox worker entry point
│ │ ├── app.ts # Fastify app construction
│ │ ├── config/ # Zod-validated env config
│ │ ├── modules/
│ │ │ ├── identity/ # OAuth, accounts, sessions
│ │ │ ├── account-linking/ # Provider link/unlink
│ │ │ ├── family-roles-relationships/ # Parent/child/teacher roles
│ │ │ ├── invitations-approval/ # Invitation lifecycle
│ │ │ ├── authorization-policy/ # Policy service
│ │ │ ├── learning/ # Learning domain
│ │ │ ├── assignments/ # Assignment module
│ │ │ ├── parent-insights/ # Dashboard aggregates
│ │ │ ├── sync/ # Push/pull sync endpoints
│ │ │ ├── outbox/ # Transactional outbox + worker
│ │ │ └── audit/ # Audit logging
│ │ ├── routes/v1/ # Route registration
│ │ └── shared/ # DB, errors, HTTP, security
│ ├── prisma/
│ │ ├── schema.prisma # Database schema
│ │ └── migrations/ # Migration history
│ ├── test/ # Integration tests
│ ├── package.json
│ ├── docker-compose.yml
│ └── vitest.config.ts
└── docs/
├── prd/ # Product requirements
└── refactoring/ # Technical reviews & gap analysis
| Tool | Version | Install |
|---|---|---|
| Node.js | ≥22 LTS | nodejs.org |
| pnpm | ≥9.x | npm install -g pnpm |
| Docker | Latest | docker.com |
| Flutter SDK | ≥3.10 | flutter.dev/docs/get-started |
| Dart SDK | ≥3.10.8 | Bundled with Flutter |
# 1. Navigate to backend
cd backend
# 2. Install dependencies
pnpm install
# 3. Start PostgreSQL (Docker)
pnpm db:up
# → PostgreSQL at localhost:5432 (user: postgres / password: postgres / db: mathmagic)
# 4. Run database migrations
pnpm prisma:migrate
# 5. Start API server (dev mode with hot-reload)
pnpm dev
# → http://localhost:3000
# 6. Start outbox worker (separate terminal)
pnpm dev:workerVerify the server is running:
curl http://localhost:3000/health# 1. Navigate to Flutter app
cd apps/mobile_flutter
# 2. Install dependencies
flutter pub get
# 3. Run on your target platform
# Web (Chrome):
dart run sqflite_common_ffi_web:setup # one-time SQLite setup for web
flutter run -d chrome
# iOS:
cd ios && pod install && cd ..
flutter run -d ios
# Android:
flutter run -d androidCreate a .env file in the backend/ directory:
# Server
NODE_ENV=development
PORT=3000
LOG_LEVEL=info
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/mathmagic?schema=public
# Auth
JWT_SECRET=your-secret-key-minimum-16-chars
# Idempotency
IDEMPOTENCY_TTL_HOURS=24
# Outbox Worker
OUTBOX_BATCH_SIZE=20
OUTBOX_POLL_INTERVAL_MS=2000
OUTBOX_MAX_ATTEMPTS=10
# OAuth (optional — disabled by default)
OAUTH_CODE_EXCHANGE_ENABLED=false
# OAUTH_GOOGLE_CLIENT_ID=...
# OAUTH_GOOGLE_CLIENT_SECRET=...
# OAUTH_GOOGLE_REDIRECT_URI=...
# OAUTH_APPLE_CLIENT_ID=...
# OAUTH_APPLE_CLIENT_SECRET=...
# OAUTH_APPLE_REDIRECT_URI=...
# OAUTH_MICROSOFT_CLIENT_ID=...
# OAUTH_MICROSOFT_CLIENT_SECRET=...
# OAUTH_MICROSOFT_REDIRECT_URI=...All endpoints are versioned under /v1. Mutating endpoints require an Idempotency-Key header.
| Method | Endpoint | Description |
|---|---|---|
POST |
/v1/auth/oauth/:provider/exchange |
OAuth login (Google/Apple/Microsoft) |
POST |
/v1/auth/providers/link |
Link additional OAuth provider |
POST |
/v1/auth/providers/unlink |
Unlink OAuth provider |
GET |
/v1/accounts/me |
Get current account details |
| Method | Endpoint | Description |
|---|---|---|
POST |
/v1/invitations |
Create invitation |
GET |
/v1/invitations/:id |
Get invitation details |
POST |
/v1/invitations/:id/approve |
Approve invitation |
POST |
/v1/invitations/:id/reject |
Reject invitation |
POST |
/v1/roles/fallback-teacher/assign |
Assign fallback teacher |
DELETE |
/v1/roles/fallback-teacher/:id |
Remove fallback teacher |
| Method | Endpoint | Description |
|---|---|---|
POST |
/v1/sync/push |
Push local changes to server |
POST |
/v1/sync/pull |
Pull server changes to client |
| Method | Endpoint | Description |
|---|---|---|
GET |
/v1/audit/events |
Query audit log |
GET |
/health |
Health check |
Error Response Format:
{
"code": "VALIDATION_ERROR",
"message": "Human-readable description",
"details": { ... },
"request_id": "uuid"
}cd backend
# Run all tests
pnpm test
# Watch mode
pnpm test:watch
# Type checking
pnpm typecheck
# Lint
pnpm lint
# Run all checks (typecheck + lint + test)
pnpm checkcd apps/mobile_flutter
# Run all tests
flutter test
# Run specific test file
flutter test test/domain/mastery_test.dart
# Run with coverage
flutter test --coverage- Core learning engine (adaptive fact selection, mastery tracking)
- All 4 learning modes (Multiplication Dash, Division Dash, Table Mastery, Study Tricks)
- Gamification (XP, levels, streaks, daily quests)
- Parent dashboard with mastery visualization
- Assignment system
- Home screen widget (iOS/Android)
- Notification reminders
- Backend identity & OAuth (Google, Apple, Microsoft)
- Family role model & invitation lifecycle
- Transactional outbox with background worker
- Idempotency middleware & audit logging
- Phase 6: State management migration (ChangeNotifier → Riverpod)
- Backend learning domain API endpoints
- Authentication flow in Flutter (OAuth SDK + token storage)
- Real sync implementation (replace mock client with HTTP)
- Data model alignment (frontend ↔ backend enum parity)
- Backend hardening (policy enforcement, refresh token rotation)
- OpenAPI spec generation
- AI-assisted weekly planning for parents
- CI/CD pipeline
See CONTRIBUTING.md for development guidelines, branching strategy, and code standards.
This project is licensed under the MIT License — see the LICENSE file for details.
MathMagic — Making math facts stick, one streak at a time.