Gamified Medical Terminology Learning App — Duolingo-Inspired, Published on iOS & Android
Designed and built a cross-platform Flutter app that teaches medical terminology through a gamified, spaced-repetition learning system — complete with structured learning paths, quiz modes, a global leaderboard, and a real-time daily review hub. Live on both the App Store and Google Play.
Problem Statement
Medical terminology is vast, highly technical, and notoriously hard to retain. Existing tools are either passive (PDFs, flashcards) or lack personalized repetition. The challenge was to build a system that combined structured curriculum delivery, active-recall quizzing, and a real SM-2 spaced repetition algorithm — all wrapped in a polished, Duolingo-style mobile experience, shipped to both platforms simultaneously.
Our Approach
Built MedLingo end-to-end in Flutter with Supabase as the backend. Implemented the SM-2 algorithm fully in Dart with server-side persistence (per-term ease factor and interval tracking in PostgreSQL). Designed a scrollable learning path with prerequisite locking, a flashcard system with three progressive definition levels (Layman → Clinical → Technical), a quiz mode with multiple-choice and drag-and-drop questions, and a daily review hub with a live countdown timer and XP goal tracking. All curriculum content lives in Supabase — zero app update required to add new terms.
SM-2 Spaced Repetition Engine (Custom Dart + PostgreSQL)
Challenges We Solved
SM-2 Spaced Repetition — Fully Implemented in Dart + Persisted Server-Side
Spaced repetition requires per-term state (ease factor, interval, mastery level) that must survive app restarts, device switches, and offline use — without any on-device dependency or data loss.
Designed a `user_progress` table in Supabase with columns for `ease_factor`, `interval_days`, `mastery_level`, `last_reviewed_at`, and `next_review_at`. The SM-2 logic runs entirely in Dart (progress_service.dart) after each quiz answer, and immediately upserts the updated state to Supabase. Row Level Security ensures users can only read/write their own records.
Two-Step Topic Progress Query Pattern
Supabase's PostgREST join-filter behavior made it impossible to correctly filter user_progress by topic in a single query — resulting in incorrect completion percentages on the learning path.
Implemented a deliberate two-query pattern: first fetch all term IDs for a given topic, then query user_progress filtered by that ID list. This ensures accurate term-level completion data without relying on brittle join filters.
Auth Trigger Auto-Provisioning (Zero Race Condition)
On sign-up, client-side profile creation created a race condition — the app could try to read the profile before the INSERT committed, causing crashes on the first session.
Replaced client-side profile creation with a PostgreSQL SECURITY DEFINER function triggered by `auth.users` INSERT. The profile row is always created within the same transaction as the auth user, eliminating the race condition entirely.
Leaderboard via PostgreSQL VIEW with ROW_NUMBER()
Computing real-time global rankings across all users by XP (with streak as tiebreaker) is expensive if done client-side, and Supabase doesn't natively support computed rankings.
Created a PostgreSQL VIEW (`leaderboard`) that uses `ROW_NUMBER() OVER (ORDER BY total_xp DESC, current_streak DESC)` to produce a pre-ranked result set. The Flutter app queries this view directly — rankings are always correct and database-computed.
Project Timeline
Discovery
Defined the full feature set: structured learning path with prerequisite locking, three-level flashcard system, quiz mode with multiple question types, SM-2 spaced repetition, daily review hub, leaderboard, achievements, and multi-method auth (Email / Google / Apple). Designed the Supabase schema with RLS policies, indexes on all hot foreign keys, and updated_at triggers on all mutable tables.
Build
Built all core screens and services end-to-end: scrollable learning path (learning_path_screen), flashcard viewer with progressive definition levels, Clinic Lesson quiz (multiple-choice + term-building question types), Daily Review with live countdown timer and XP tracking, MedDex searchable glossary, global leaderboard with PostgreSQL VIEW, achievements system, and user profile with avatar upload to Supabase Storage. Implemented local lesson resume via SharedPreferences (last-viewed term index saved on every navigation step). Authored bulk content tooling (generate_onboarding_sql.py, json_to_sql.dart) to import the 511 KB production curriculum.
Launch
Published to Google Play (v1.0.5, Build 8) and Apple App Store from a single Flutter codebase using flutter_native_splash and flutter_launcher_icons for native assets. Configured local push notifications (flutter_local_notifications + timezone) for streak reminders. App is live on both stores.
Screenshots & Visuals
Ready to Build Something Similar?
Let's discuss how we can help transform your business with AI.
Start Your Project