CodeQuestWeb is a gamified coding-learning platform built with Next.js App Router, React, and Supabase. It provides language learning paths, interactive question-based lessons, daily quests, profile customization, and a global leaderboard.
- Technical Overview
- Architecture
- Project Structure
- Routing and Feature Modules
- Data and State Flow
- Database Design (Supabase)
- Libraries and Tooling
- Environment Variables
- Local Development
- Build, Lint, and Runtime Commands
- Security and Operational Notes
- Framework: Next.js 16 (App Router)
- UI Runtime: React 19
- Language: TypeScript (strict mode)
- Styling: Tailwind CSS v4 + custom global theme variables
- Animation: Framer Motion
- Backend as a Service: Supabase (Auth + Postgres + RLS)
- Client Data Fetching: SWR
- Client State: Zustand + persist middleware
The application follows a client-heavy model for interactive gameplay while still using App Router structure and server-side Supabase support for auth cookie/session handling.
graph TD
U[Browser] --> N[Next.js App Router]
N --> C[Client Feature Pages]
C --> S[SWR Fetch Layer]
S --> SB[(Supabase Postgres + Auth)]
C --> Z[Zustand User Store]
Z --> L[Local Storage Persist]
Z --> SB
N --> P[Proxy Middleware]
P --> SB
- Presentation Layer
- Implemented in route pages under
src/app/* - Rich UI interactions, motion transitions, and responsive dashboard shell
- Lesson runtime supports three question types: multiple choice, code assembly, and fill blank
- Application Layer
- Data API functions in
src/lib/dataApi.tsconvert raw DB responses into typed domain models - User progression logic in
src/store/userStore.tshandles XP, coins, streaks, claiming quests, unlock logic, and persistence
- Infrastructure Layer
- Supabase browser client in
src/lib/supabaseClient.ts - Supabase server client in
src/lib/supabaseServer.ts - Session-refresh proxy in
src/proxy.ts - SQL schema and data bootstrapping in
supabase/migrations/*.sql
- Connected mode
- If
NEXT_PUBLIC_SUPABASE_URLand anon key are configured, auth and data are live against Supabase.
- Demo mode
- If Supabase env vars are missing, auth falls back to local/demo behavior and the app remains usable for UI flows.
src/
app/
layout.tsx
page.tsx
login/page.tsx
signup/page.tsx
dashboard/
layout.tsx
page.tsx
leaderboard/page.tsx
quests/page.tsx
profile/page.tsx
learn/[language]/page.tsx
components/
AuthSync.tsx
Sidebar.tsx
Topbar.tsx
MobileNav.tsx
ThemeSync.tsx
lib/
dataApi.ts
languageUi.ts
supabaseClient.ts
supabaseServer.ts
types.ts
store/
userStore.ts
proxy.ts
supabase/
migrations/
0000_initial_schema.sql
0001_seed_data.sql
0002_expanded_features.sql
0003_profile_trigger.sql
0004_leaderboard_policy.sql
/: marketing/landing experience with animated call-to-actions/login: email/password sign-in (Supabase or demo fallback)/signup: account creation and initial profile setup
/dashboard: overview (stats, language paths, recommendations)/dashboard/learn/[language]: lesson runner and progression flow/dashboard/quests: daily quest progression and reward claim/dashboard/leaderboard: global XP/streak ranking/dashboard/profile: profile, theme/avatar unlocks, session sign-out
src/app/layout.tsx: global shell, fonts, metadata, theme syncsrc/app/dashboard/layout.tsx: dashboard shell usingSidebar,Topbar,MobileNav, andAuthSync
- SWR is used for cache-aware fetches in dashboard and feature pages
- Each query key maps to a function in
src/lib/dataApi.ts - Supabase queries are normalized to app domain types from
src/lib/types.ts
src/store/userStore.ts is the central domain store for:
- auth flags and identity profile
- XP, level, coins, streak
- completed lessons and best scores
- owned themes/avatars and selected cosmetics
- daily stats and claimed quests
Persistence strategy:
- Local persistence via Zustand
persist - Cloud synchronization via
saveToSupabaseandsyncWithSupabase AuthSyncsubscribes to auth state changes and syncs after sign-in
Lesson completion and unlock model:
- Lessons scored at or above 60% are counted as completed
- Repeating a lesson grants reduced rewards
- Module progression is controlled by prior module completion/scores
src/proxy.tscreates a server-side Supabase client and refreshes auth tokens by callingsupabase.auth.getUser()- Cookie propagation is handled through the proxy response
languagesmodules(belongs to language)lessons(belongs to module + language)questions(belongs to lesson, question payload in JSONB)
user_profiles(linked toauth.users)user_progress(unique by user + lesson)
themesavatarsdaily_questsuser_themes(join)user_avatars(join)
Row-level security is enabled broadly, with policies that:
- allow public read for learning/catalog entities
- allow user-scoped read/write for profile/progress/ownership entities
- allow public read of
user_profilesfor leaderboard display (migration0004)
0003_profile_trigger.sql adds a trigger on auth.users that automatically creates:
- default
user_profilesrow - default ownership rows for theme and avatar
next: React framework and App Router runtimereact,react-dom: UI runtime@supabase/ssr: SSR-aware client construction and cookie plumbing@supabase/supabase-js: Supabase data/auth clientswr: client-side data fetching, cache, and revalidationzustand: lightweight app state managementframer-motion: page and component animationslucide-react: icon systemclsx: conditional className construction helpertailwind-merge: Tailwind class conflict resolution helper
typescript: static typing and strict compile-time checkseslint,eslint-config-next: linting and Next.js rulestailwindcss,@tailwindcss/postcss: styling engine and PostCSS integration@types/node,@types/react,@types/react-dom: TypeScript type packages
Create .env.local with:
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
# optional alias supported by code:
# NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=...Notes:
- If variables are missing or URL is placeholder-like, the app operates in demo mode.
NEXT_PUBLIC_DEV_SERVER_START_TIMEis set automatically bynext.config.tsfor dev reset behavior.
- Install dependencies
npm install-
Configure environment variables in
.env.local -
Ensure Supabase schema/data are applied
- Execute migration SQL files in order from
supabase/migrations/against your Supabase project - Or use your Supabase CLI workflow if already configured for this repo
- Start dev server
npm run dev- Open app
- Default local URL:
http://localhost:3000
npm run dev # start development server
npm run build # production build
npm run start # serve production build
npm run lint # run ESLint- RLS is enabled across major tables; policy changes should be versioned via migrations.
- Leaderboard requires public profile read policy by design.
- User store writes can happen frequently (
saveToSupabaseon progression/currency updates); consider request batching/debouncing for scale optimization. - Development-only
ThemeSyncbehavior clears local/session storage when the dev server start timestamp changes, then signs out and reloads. This avoids stale persisted state across restarts.