# Ranked EQAO — Claude Code Guide ## Project Overview A ranked quiz app based on EQAO (Ontario standardized tests). Users sign in with Google, answer questions by grade and subject, and compete on leaderboards. ## Tech Stack - **Runtime:** Node.js + Express - **Database:** PostgreSQL via Prisma ORM - **Auth:** Google OAuth 2.0 (Passport.js) + JWT - **AI:** Gemini API (passage + question generation for English; answer checking) - **Frontend:** React (Vite) — `frontend/` directory ## Grades Only three grades are supported: **3, 6, 9** - In the schema these are the `Grade` enum: `G3`, `G6`, `G9` - Never use raw integers for grade — always use the enum ## Subjects Two sections per quiz: `MATH` and `ENGLISH` (reading + writing combined) - The Prisma `Subject` enum currently has `MATH`, `READING`, `WRITING` — these remain as-is for DB storage - In the UI and game logic, treat READING + WRITING as a single **English** section ## Project Structure ``` / ├── prisma/ │ └── schema.prisma # All DB models ├── src/ │ ├── db.js # Prisma singleton │ ├── auth/ │ │ └── google.js # Google OAuth + JWT issuing │ ├── middleware/ │ │ └── auth.js # JWT verification middleware │ └── services/ │ └── leaderboard.js # Leaderboard upsert + query logic ├── frontend/ │ └── src/ │ ├── pages/ │ │ ├── Login.jsx # Pre-login landing page │ │ ├── Dashboard.jsx # Post-login dashboard (to be built) │ │ └── MathGame.jsx # SCRAPPED — delete this file │ ├── App.jsx │ ├── index.css │ └── main.jsx ├── .env # Never commit this ├── CLAUDE.md └── package.json ``` ## Environment Variables | Variable | Purpose | |---|---| | `DATABASE_URL` | PostgreSQL connection string | | `GOOGLE_CLIENT_ID` | Google OAuth app client ID | | `GOOGLE_CLIENT_SECRET` | Google OAuth app client secret | | `GOOGLE_CALLBACK_URL` | OAuth redirect URI | | `JWT_SECRET` | Secret for signing JWTs | | `GEMINI_API_KEY` | Gemini API key for English question/passage generation and answer checking | | `PORT` | Express server port (default 3000) | | `FRONTEND_URL` | Frontend origin for CORS | ## Key Conventions - Always use `Grade` enum (`G3`, `G6`, `G9`) — never raw numbers - Always use `Subject` enum (`MATH`, `READING`, `WRITING`) - All routes that touch user data require the `auth.js` JWT middleware - Leaderboard is scoped per `[userId, grade, subject]` — unique constraint enforced in DB - Sessions track full answer history via `UserAnswer` for future analytics ## Database Commands ```bash npx prisma migrate dev --name # new migration npx prisma generate # regenerate client after schema change npx prisma studio # visual DB browser ``` --- ## Frontend Pages ### Login.jsx (Pre-login Landing Page) — KEEP, DO NOT ADD DEBUG BUTTON - The current pre-login landing page and Google sign-in button are good — preserve this design - The page will eventually be a longer scrollable page with a top navigation bar linking to info sections and other useful tabs (TBD before release) - **DO NOT add any debug/bypass button that skips Google login** — all such buttons must be removed if found anywhere in the codebase - For now, leave the landing page as-is; extended layout/nav is a pre-release task ### MathGame.jsx — SCRAPPED, DELETE THIS FILE - `frontend/src/pages/MathGame.jsx` is fully scrapped — delete it - Remove all routes, imports, and links pointing to MathGame anywhere in the codebase - The actual EQAO quiz experience will be built fresh (see Quiz UI section below) ### Dashboard.jsx (Post-login) — TO BE BUILT - Replaces the current "Coming Soon" placeholder - Should be a rich, well-designed dashboard with multiple sections/widgets, for example: - User greeting with avatar - Stats summary (games played, best scores, rank per grade) - Leaderboard preview - Recent activity - A **"Start Game"** button (prominent CTA) — the button exists in the UI but does NOT wire up to the quiz yet; the quiz flow is not being programmed at this stage - The exact set of dashboard widgets/tabs is TBD — design it to look complete and polished even if most data is placeholder --- ## Quiz UI (To Be Built — Design Reference) ### General Flow The quiz covers **two sections**: Math and English. The user completes them in order. After finishing a section, the app checks answers and shows one of two outcomes: - **100% correct** → proceed to the next section (or end the quiz if both are done) - **At least 1 wrong** → must redo the section; keep retrying until 100% correct before advancing There is no partial credit / moving on with mistakes — the player must get a perfect section to continue. ### Math Section - Questions are **pre-generated** (not from Gemini) but with **randomised values each time** so the same question template produces different numbers on each attempt - Questions should be creative and contextual — avoid trivial `a + b` style arithmetic; think word problems, patterns, multi-step reasoning appropriate to the grade level - Multiple choice format (matching the original EQAO UI style — see design reference below) ### English Section - **Gemini API** generates a reading passage appropriate for the grade - Gemini also generates comprehension questions based on that passage - Gemini checks free-response and paragraph writing answers (not just multiple choice) - The section combines reading comprehension and a short writing component ### Quiz UI Design - The actual in-quiz UI (question display, answer choices, progress) should stay **visually identical or very close to the original MathGame design** — same layout, card style, fonts, colour scheme - Reference the existing `index.css` (`.math-game`, `.choice-btn`, `.grade-btn`, etc.) and replicate that look for the new quiz component - Upload of reference screenshots is pending — when provided, match them closely --- ## What's Not Built Yet - [ ] API routes (auth, sessions, leaderboard, questions) - [ ] Gemini service for English passage + question generation and answer checking - [BUILT] Math question templates with randomised values - [BUILT] Quiz game component (replaces scrapped MathGame.jsx) - [HALF-BUILT] Post-login Dashboard (rich version, not "Coming Soon" placeholder) - [HALF-BUILT] Pre-login landing page extended layout + top nav (pre-release) - [ ] Question seeding/storage strategy - [ ] Frontend wiring for "Start Game" button