# PragatiVeer v2 — Pagewise UI & API Specification Map
> **Document Type:** Comprehensive Pagewise Architecture, Button-to-API Interaction, and UI Specification Map
> **Target Audience:** Frontend Engineers, Full-Stack Developers, Product Managers, QA & DevOps
> **Last Verified:** September 2026
> **Frontend Engine:** Next.js 16 (App Router, React 19, TypeScript, TailwindCSS, Zustand)
> **Backend Engine:** FastAPI (Python 3.11) + PostgreSQL 15 (PgBouncer) + Redis 7 + MinIO S3
---
## 1. Architectural & Network Request Flow
### 1.1 Client-to-Backend Network Pipeline
PragatiVeer v2 operates two primary communication paths between the Next.js frontend and the FastAPI backend:
```mermaid
graph LR
Browser["Client Browser"] -->|1. Page Navigation| NextServer["Next.js 16 App Router (:3000)"]
NextServer -->|2. Route Guard proxy.ts| Edge["Edge Cookie Evaluation"]
Browser -->|3. /api/* Internal Calls| Rewrites["next.config.ts Rewrites"]
Rewrites -->|http://backend:8000/api/*| FastAPI["FastAPI Backend (:8000)"]
Browser -->|4. Direct NEXT_PUBLIC_API_URL| FastAPI
FastAPI -->|Queries| PgBouncer["PgBouncer :5432"]
PgBouncer --> DB[("PostgreSQL 15")]
FastAPI -->|Cache & Tasks| Redis[("Redis 7")]
FastAPI -->|S3 Uploads| MinIO[("MinIO S3 :9000")]
```
1. **Proxy Middleware (`src/proxy.ts`):** Evaluates `auth_token` cookie on all `/dashboard/*` and `/admin/*` routes.
- Non-authenticated visitors heading to `/dashboard` are redirected to `/login`.
- Non-admin visitors (`token !== 'admin'`) heading to `/admin` are redirected to `/login`.
2. **Reverse Proxy Rewrites (`next.config.ts`):** Inside Docker, `/api/:path*` is automatically rewritten to `http://backend:8000/api/:path*`.
3. **Direct Client Fetching:** Certain client stores (e.g. `cbtStore.ts` and `src/app/cbt/[examId]/page.tsx`) use `NEXT_PUBLIC_API_URL` (default `http://localhost:8000`) for high-throughput examination requests.
4. **Session Token Enforcement:** `localStorage.getItem("active_session_token")` provides single-device session validation against `/api/users/{id}/session`.
---
## 2. Master Page Directory
| Route URL | Component File Location | Access Level | Primary Backend APIs Called |
| :--- | :--- | :---: | :--- |
| `/` | `src/app/page.tsx` | Public | None (Static / Marketing) |
| `/about` | `src/app/about/page.tsx` | Public | None (Informational) |
| `/contact` | `src/app/contact/page.tsx` | Public | None (Static Form / Mailto) |
| `/login` | `src/app/login/page.tsx` | Public | `POST /api/auth/login`, `POST /api/users/{id}/session` |
| `/signup` | `src/app/signup/page.tsx` | Public | `POST /api/auth/register`, `POST /api/auth/login`, `POST /api/users/{id}/session` |
| `/forgot-password` | `src/app/forgot-password/page.tsx` | Public | `POST /api/auth/forgot-password` |
| `/upgrade` | `src/app/upgrade/page.tsx` | Public / Auth | None (Routing to `/checkout?tier=...`) |
| `/checkout` | `src/app/checkout/page.tsx` | Authenticated | `POST /api/billing/create-order`, `POST /api/billing/verify-payment` |
| `/cbt/[examId]` | `src/app/cbt/[examId]/page.tsx` | Authenticated | `GET /api/tests/{examId}`, `GET /api/tests/{examId}/questions`, `POST /api/attempts/submit` |
| `/dashboard` | `src/app/dashboard/page.tsx` | Student (`Free`+) | `GET /api/users/{id}`, `GET /api/ai-coach/study-plan/today`, `GET /api/growth/referral/{id}` |
| `/dashboard/cbt` | `src/app/dashboard/cbt/page.tsx` | Student (`Free`+) | `GET /api/users/{id}`, `GET /api/tests`, `GET /api/users/{id}/attempts` |
| `/dashboard/cbt/history/[attemptId]` | `src/app/dashboard/cbt/history/[attemptId]/page.tsx` | Student (`Free`+) | `GET /api/users/{id}/attempts`, `GET /api/tests/{id}`, `GET /api/questions/{id}` |
| `/dashboard/dpp` | `src/app/dashboard/dpp/page.tsx` | Student (`Free`+) | `GET /api/tests?type=DPS`, `GET /api/users/{id}/attempts` |
| `/dpp/review/[dppId]` | `src/app/dpp/review/[dppId]/page.tsx` | Student (`Free`+) | Local DPP attempt state & question review |
| `/dashboard/analytics` | `src/app/dashboard/analytics/page.tsx` | Student (`Free`+) | `GET /api/users/{id}` (Performance graphs & accuracies) |
| `/dashboard/progress` | `src/app/dashboard/progress/page.tsx` | Student (`Free`+) | `GET /api/og/progress` (Progress card export) |
| `/dashboard/streaks` | `src/app/dashboard/streaks/page.tsx` | Student (`Free`+) | `GET /api/users/{id}` (Streak count & freeze tokens) |
| `/dashboard/leaderboard` | `src/app/dashboard/leaderboard/page.tsx` | Student (`Free`+) | Client ranking engine & state filtering |
| `/dashboard/materials` | `src/app/dashboard/materials/page.tsx` | Student (`Free`+) | Formula sheets repository & PDF downloads |
| `/dashboard/rank-predictor` | `src/app/dashboard/rank-predictor/page.tsx` | Student (`Free`+) | Percentile-to-AIR calculation engine |
| `/dashboard/community` | `src/app/dashboard/community/page.tsx` | Student (`Free`+) | Student doubt forum & study channels |
| `/dashboard/settings` | `src/app/dashboard/settings/page.tsx` | Student (`Free`+) | `GET /api/users/{id}`, `PUT /api/users/{id}`, `POST /api/users/{id}/avatar` |
| `/dashboard/ai-coach` | `src/app/dashboard/ai-coach/page.tsx` | Student (`AI_COACH`) | `GET /api/ai-coach/readiness/{id}`, `GET /api/growth/referral/{id}` |
| `/dashboard/ai-coach/tutor` | `src/app/dashboard/ai-coach/tutor/page.tsx` | Student (`AI_COACH`) | `POST /api/ai-coach/chat/stream` (SSE stream) |
| `/dashboard/ai-coach/study-plan` | `src/app/dashboard/ai-coach/study-plan/page.tsx` | Student (`AI_COACH`) | `GET /api/ai-coach/study-plan/today?user_id={id}` |
| `/dashboard/ai-coach/readiness` | `src/app/dashboard/ai-coach/readiness/page.tsx` | Student (`AI_COACH`) | `GET /api/ai-coach/readiness/{id}` |
| `/dashboard/ai-coach/mistakes` | `src/app/dashboard/ai-coach/mistakes/page.tsx` | Student (`AI_COACH`) | `GET /api/mistakes/today?user_id={id}`, `POST /api/mistakes/review` |
| `/dashboard/ai-coach/cbt-dpp` | `src/app/dashboard/ai-coach/cbt-dpp/page.tsx` | Student (`AI_COACH`) | `GET /api/tests?type=DPS`, `GET /api/users/{id}/attempts` |
| `/dashboard/ai-coach/cbt-dpp/[id]` | `src/app/dashboard/ai-coach/cbt-dpp/[id]/page.tsx` | Student (`AI_COACH`) | Submits to `/cbt/[examId]` |
| `/dashboard/ai-coach/cbt-dpp/history/[attemptId]` | `src/app/dashboard/ai-coach/cbt-dpp/history/[attemptId]/page.tsx` | Student (`AI_COACH`) | `GET /api/users/{id}/attempts`, `GET /api/tests/{id}` |
| `/dashboard/ai-coach/heatmap` | `src/app/dashboard/ai-coach/heatmap/page.tsx` | Student (`AI_COACH`) | Mistake frequency matrix by topic & difficulty |
| `/dashboard/ai-coach/college-predictor` | `src/app/dashboard/ai-coach/college-predictor/page.tsx` | Student (`AI_COACH`) | `GET /api/ai-coach/readiness/{id}` + College cutoff mapping |
| `/dashboard/ai-coach/time-optimization` | `src/app/dashboard/ai-coach/time-optimization/page.tsx` | Student (`AI_COACH`) | Time-per-question analysis & speed pace guide |
| `/dashboard/ai-coach/strategy` | `src/app/dashboard/ai-coach/strategy/page.tsx` | Student (`AI_COACH`) | Exam temperament & question selection strategy |
| `/dashboard/ai-coach/weekly-progress` | `src/app/dashboard/ai-coach/weekly-progress/page.tsx` | Student (`AI_COACH`) | Weekly AI mastery trajectory |
| `/admin` | `src/app/admin/page.tsx` | Admin | Real-time system monitoring & KPI metrics |
| `/admin/students` | `src/app/admin/students/page.tsx` | Admin | `GET /api/admin/students` |
| `/admin/students/[studentId]` | `src/app/admin/students/[studentId]/page.tsx` | Admin | `GET /api/admin/students/{id}`, `PATCH /api/admin/students/{id}` |
| `/admin/tests` | `src/app/admin/tests/page.tsx` | Admin | `GET /api/admin/tests`, `PUT /api/admin/tests/{id}/toggle`, `DELETE /api/admin/tests/{id}`, `POST /api/admin/tests/create_manual` |
| `/admin/questions` | `src/app/admin/questions/page.tsx` | Admin | Global question search & question bank table |
| `/admin/coupons` | `src/app/admin/coupons/page.tsx` | Admin | `GET /api/admin/coupons`, `POST /api/admin/coupons`, `DELETE /api/admin/coupons/{id}` |
| `/admin/settings` | `src/app/admin/settings/page.tsx` | Admin | `GET /api/admin/settings`, `POST /api/admin/settings` |
| `/admin/agents` | `src/app/admin/agents/page.tsx` | Admin | AI Agent orchestration & heartbeat monitor |
| Policy Pages | `/privacy`, `/terms`, `/refund`, `/cancellation`, `/disclaimer` | Public | Static legal disclosures |
---
## 3. Exhaustive Pagewise UI & API Breakdowns
---
### 3.1 Authentication & Onboarding Pages
#### A. Login Page (`/login`)
- **File Location:** `src/app/login/page.tsx`
- **Access Guard:** Public (Redirects authenticated users to `/dashboard` or `/admin`)
- **UI Components:**
- Brand Logo linking to `/`
- Email ``
- Password `` with show/hide password toggle button
- "Forgot password?" link to `/forgot-password`
- "Sign In" submit button
- "Sign up" link to `/signup`
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Show/Hide Password` | Toggles password visibility | `setShowPassword(!showPassword)` |
| `Sign In Button` | Submits form, authenticates user | `handleLogin(e)` |
| `Forgot password?` | Navigates to password reset | `/forgot-password` |
| `Sign up` | Navigates to registration | `/signup` |
- **APIs Invoked:**
1. `POST /api/auth/login`
- **Trigger:** On form submit (`handleLogin`)
- **Request Body:** `{ "email": "...", "password": "..." }`
- **Response:** `{ "success": true, "role": "user" | "admin", "token": "UUID" | "admin" }`
- **Side Effects:**
- Sets `document.cookie = "auth_token=...; path=/; max-age=2592000; SameSite=Lax"`
- Writes `localStorage.setItem("activeUserId", data.token)`
- Generates `crypto.randomUUID()` session token and writes `localStorage.setItem("active_session_token", sessionToken)`
2. `POST /api/users/{userId}/session`
- **Trigger:** Immediately following successful student login
- **Request Body:** `{ "session_token": "" }`
- **Response:** `{ "status": "session_registered", ... }`
- **Redirect:** `window.location.href = "/admin"` (if admin) or `"/dashboard"` (if student)
---
#### B. Signup Page (`/signup`)
- **File Location:** `src/app/signup/page.tsx`
- **Access Guard:** Public
- **UI Components:**
- Name ``
- Email ``
- Password ``
- "Create Account" submit button
- "Sign In" link to `/login`
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Create Account Button` | Submits registration | `handleSignup(e)` |
| `Sign in Link` | Navigates to login | `/login` |
- **APIs Invoked:**
1. `POST /api/auth/register`
- **Trigger:** On form submit
- **Request Body:** `{ "name": "...", "email": "...", "password": "..." }`
- **Response:** `{ "success": true, "message": "User registered successfully" }`
2. `POST /api/auth/login` (Auto-login chaining)
- **Trigger:** Immediately upon successful registration
- **Request Body:** `{ "email": "...", "password": "..." }`
- **Response:** `{ "success": true, "token": "", "role": "user" }`
3. `POST /api/users/{userId}/session`
- Registers active session token and redirects to `/dashboard`.
---
#### C. Forgot Password Page (`/forgot-password`)
- **File Location:** `src/app/forgot-password/page.tsx`
- **Access Guard:** Public
- **UI Components:**
- Email ``
- "Send Reset Link" button
- Success message banner
- "Back to login" link
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Send Reset Link` | Dispatches password reset email | `handleReset(e)` |
| `Back to login` | Navigates to `/login` | `/login` |
- **APIs Invoked:**
1. `POST /api/auth/forgot-password`
- **Trigger:** On form submit
- **Request Body:** `{ "email": "student@example.com" }`
- **Response:** `{ "message": "If this email is registered, a password reset link has been sent." }`
---
### 3.2 Subscription & Checkout Subsystem
#### A. Pricing & Upgrade Page (`/upgrade`)
- **File Location:** `src/app/upgrade/page.tsx`
- **Access Guard:** Public / Authenticated
- **UI Components:**
- Plan selection cards:
- **Free Plan:** Basic mocks, limited practice sheets (Default)
- **Pro Plan (₹3,499/yr):** Unlimited Full-Syllabus CBT Mocks, Detailed Analytics, Daily DPS
- **AI Coach Plan (₹11,999/yr):** Real-time AI Tutor, College Predictor, Spaced Repetition Notebook, Adaptive Daily Study Plans
- Feature comparison matrix
- FAQ accordion
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Choose Pro` | Navigates to checkout for Pro | `router.push('/checkout?tier=Pro')` |
| `Upgrade to AI Coach` | Navigates to checkout for AI Coach | `router.push('/checkout?tier=Al_Coach')` |
---
#### B. Checkout & Payment Page (`/checkout`)
- **File Location:** `src/app/checkout/page.tsx`
- **Access Guard:** Authenticated (Redirects to `/login?redirect=/checkout?tier=...` if guest)
- **UI Components:**
- Order summary sidebar (Plan name, subtotal, GST 18%, grand total)
- Delivery/Student Address inputs (`Address`, `City`, `Pincode`, `Phone`)
- Payment method selector: Razorpay / Cashfree / Stripe
- "Proceed to Payment" button with active loader
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Proceed to Payment` | Initiates backend order & triggers Razorpay Modal | `handlePayment()` |
- **APIs Invoked:**
1. `POST /api/billing/create-order?user_id={userId}&plan_tier={tier}`
- **Trigger:** On `Proceed to Payment` click
- **Request Body:** `{ "gateway": "razorpay" }`
- **Response:**
```json
{
"id": "order_XXXXXXXXXXXXXX",
"amount": 1199900,
"currency": "INR",
"status": "created"
}
```
2. **Client-Side SDK:** Opens `window.Razorpay(options).open()`
3. `POST /api/billing/verify-payment`
- **Trigger:** Razorpay `handler(response)` callback upon payment approval
- **Request Body:**
```json
{
"gateway": "razorpay",
"razorpay_order_id": "order_XXXXXX",
"razorpay_payment_id": "pay_XXXXXX",
"razorpay_signature": "signature_hash",
"user_id": "",
"tier": "Al_Coach"
}
```
- **Response:** `{ "status": "success", "tier": "Al_Coach" }`
- **Action on Success:** Updates local user tier and redirects to `/dashboard?payment=success`.
---
### 3.3 Computer-Based Testing (CBT) Examination Engine
#### A. Full-Screen CBT Examination Room (`/cbt/[examId]`)
- **File Location:** `src/app/cbt/[examId]/page.tsx`
- **Access Guard:** Authenticated (`Free`, `Pro`, or `AI_COACH` depending on test gating)
- **UI Components:**
- Header: Candidate Name, Photo, Roll Number, Exam Title, Section Switcher (`Physics`, `Chemistry`, `Mathematics` or `Biology`)
- Floating Exam Timer (Hours : Minutes : Seconds) with visual alert when under 5 minutes
- Question Palette Matrix (Grid 1 to N with NTA standard colors: Green=Answered, Purple=Marked for Review, Red=Unanswered, Grey=Not Visited)
- Question Panel: Question Text (KaTeX LaTeX rendering), Image Diagram from MinIO, Multiple Choice Options (`A`, `B`, `C`, `D`) or Numerical Input box
- Action Bar:
- "Save & Next" button
- "Clear Response" button
- "Mark for Review & Next" button
- "Submit Test" button
- Submit Confirmation Modal: Summary table of Answered, Unanswered, Marked for Review questions
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | State / Store Handler |
| :--- | :--- | :--- |
| `Option Selection (A/B/C/D)` | Selects radio answer | `saveAnswer(questionId, optionKey)` |
| `Numerical Input Change` | Enters integer/decimal answer | `saveAnswer(questionId, value)` |
| `Save & Next` | Commits answer and advances index | `handleNextQuestion()` |
| `Clear Response` | Resets current question answer | `clearAnswer(questionId)` |
| `Mark for Review & Next` | Sets flagged review state and advances | `markForReview(questionId)` |
| `Question Palette Button [i]` | Direct jump to question index `i` | `setCurrentIndex(i)` |
| `Section Tab Switcher` | Filters question palette by Subject | `setActiveSection(sectionName)` |
| `Submit Test Button` | Opens final confirmation dialog | `setIsSubmitModalOpen(true)` |
| `Confirm Final Submission` | Dispatches submission payload | `submitAttemptToServer(userId)` |
- **APIs Invoked:**
1. `GET /api/tests/{examId}?user_id={userId}`
- **Trigger:** On mount (`useEffect`)
- **Response:** Test metadata, sections mapping, total duration, question ID sequence.
2. `GET /api/tests/{examId}/questions`
- **Trigger:** On mount immediately following test metadata
- **Response:** Array of full question objects (LaTeX text, options, subject, topic).
3. `POST /api/attempts/submit`
- **Trigger:** On manual submission confirm OR auto-submit on countdown timeout
- **Request Body (`src/store/cbtStore.ts`):**
```json
{
"test_id": "",
"user_id": "",
"time_spent": 10420,
"answers": [
{
"question_id": "",
"selected_option": "B",
"time_spent": 115,
"is_marked_for_review": false
}
],
"status": "Submitted"
}
```
- **Response:**
```json
{
"id": "",
"score": 240,
"total_questions": 75,
"accuracy": 82.5,
"rank": 412
}
```
- **Redirect:** Navigates directly to `/dashboard/cbt/history/{attemptId}`.
---
#### B. CBT Mock Directory Hub (`/dashboard/cbt`)
- **File Location:** `src/app/dashboard/cbt/page.tsx`
- **Access Guard:** Authenticated (`Free`+)
- **UI Components:**
- Exam Filter Tabs: `All`, `JEE Main`, `JEE Advanced`, `NEET`
- Active Full Mocks Grid (Test Card: Title, Pattern badge, Total Questions, Time limit, Attempts count, "Start Test" or "Review" button)
- Recent Attempts History Table (Exam Title, Score, Accuracy, Date, "View Solution" button)
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Exam Filter Tabs` | Filters active tests by pattern | `setSelectedPattern(pattern)` |
| `Start Test Button` | Navigates into full-screen exam room | `router.push('/cbt/' + test.id)` |
| `View Solution Button` | Navigates to detailed attempt analysis | `router.push('/dashboard/cbt/history/' + attempt.id)` |
- **APIs Invoked:**
1. `GET /api/users/{userId}` (Fetches user's targeted exam e.g. `JEE_MAIN`)
2. `GET /api/tests?user_id={userId}&exam_pattern={pattern}` (Lists available mock tests)
3. `GET /api/users/{userId}/attempts` (Fetches historical attempt records)
---
#### C. Test Attempt Analysis & Solution Review (`/dashboard/cbt/history/[attemptId]`)
- **File Location:** `src/app/dashboard/cbt/history/[attemptId]/page.tsx`
- **Access Guard:** Authenticated
- **UI Components:**
- Score summary card: Final Score, Total Marks, Accuracy %, Positive Marks, Negative Marks, Percentile
- Question-by-question breakdown list:
- Status badge: Correct (+4), Incorrect (-1), Unattempted (0)
- Full LaTeX question rendering
- Student's chosen answer vs Official Correct Answer
- Step-by-step text solution
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Filter by Subject (All/Phys/Chem/Math)` | Filters questions | `setSelectedSubject(sub)` |
| `Filter by Status (Incorrect/Correct)` | Isolates student errors | `setStatusFilter(filter)` |
| `Back to Test Directory` | Navigates back | `/dashboard/cbt` |
- **APIs Invoked:**
1. `GET /api/users/{userId}/attempts` (Locates `attemptId`)
2. `GET /api/tests/{source_id}?user_id={userId}` (Fetches test structure)
3. `GET /api/questions/{questionId}` (Fetches detailed solutions per question)
---
#### D. Daily Practice Sheets (DPS / DPP) Test Center (`/dashboard/dpp`)
- **File Location:** `src/app/dashboard/dpp/page.tsx`
- **Access Guard:** Authenticated (`Free`+ with tiered limits)
- **UI Components:**
- Daily Sheets Calendar / Carousel:
- Biology Ch4 DPS
- Chemistry Ch4 DPS
- Mathematics Ch4 DPS
- Physics Ch4 DPS
- Sheet Status: `Pending` | `Completed` (with Score & Accuracy)
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Solve DPS Button` | Launches CBT engine for that practice sheet | `router.push('/cbt/' + sheet.id)` |
| `Review Solution Button` | Opens attempt breakdown | `router.push('/dashboard/cbt/history/' + attempt.id)` |
- **APIs Invoked:**
1. `GET /api/tests?type=DPS&exam_pattern={pattern}` (Fetches seeded DPS tests)
2. `GET /api/users/{userId}/attempts` (Checks which DPS sheets have been completed)
---
### 3.4 Student Dashboard & Core Learning Hub
#### A. Main Student Dashboard (`/dashboard`)
- **File Location:** `src/app/dashboard/page.tsx`
- **Access Guard:** Authenticated (`Free`+)
- **UI Components:**
- Header: Welcome message, Active Target Exam (`JEE Main` / `NEET`), Streak Badge
- Performance Overview Grid: Tests Taken, Average Accuracy %, Study Streak, Target Score
- Embedded Adaptive Study Plan Card (`AdaptiveStudyPlan.tsx`)
- Embedded Mistake Heatmap Card (`MistakeHeatmap.tsx`)
- Embedded Viral Referral Card (`ReferralCard.tsx`)
- "Share Card" Button (Generates and downloads high-res progress PNG via `html-to-image`)
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Share Card Button` | Exports dashboard card as PNG | `handleExport()` (`html-to-image`) |
| `Start Today's DPS` | Launches daily practice | `/dashboard/dpp` |
| `Explore AI Coach` | Navigates to AI features | `/dashboard/ai-coach` |
- **APIs Invoked:**
1. `GET /api/users/{userId}` via `useActiveUser()`
2. `GET /api/ai-coach/study-plan/today?user_id={userId}` (via `AdaptiveStudyPlan`)
3. `GET /api/growth/referral/{userId}` (via `ReferralCard`)
---
#### B. Student Profile & Settings Page (`/dashboard/settings`)
- **File Location:** `src/app/dashboard/settings/page.tsx`
- **Access Guard:** Authenticated
- **UI Components:**
- Avatar Profile Picture with MinIO upload button
- Personal Information Form: First Name, Last Name, Email (read-only), Target Exam selector (`JEE Main`, `JEE Advanced`, `NEET`), School, State
- "Save Changes" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Avatar File Upload Input` | Uploads image directly to MinIO | `handleAvatarUpload(e)` |
| `Save Changes Button` | Updates student profile | `handleSave()` |
- **APIs Invoked:**
1. `POST /api/users/{userId}/avatar`
- **Trigger:** On file input change
- **Request Form-Data:** `file: `
- **Response:** `{ "url": "http://localhost:9000/avatars/user_avatar_....png" }`
2. `PUT /api/users/{userId}`
- **Trigger:** On `Save Changes` click
- **Request Body:**
```json
{
"name": "Rahul Sharma",
"target_exam": "JEE_MAIN",
"school": "Delhi Public School",
"state": "Delhi"
}
```
- **Response:** Updated user record.
---
### 3.5 AI Coach Suite (`/dashboard/ai-coach/*`)
> **Access Restriction:** All pages in this section are gated to `tier == "Al_Coach"`. Users on `Free` or `Pro` tiers see an upgrade paywall with a direct link to `/checkout?tier=Al_Coach`.
#### A. AI Doubt Solver & Tutor Chat (`/dashboard/ai-coach/tutor`)
- **File Location:** `src/app/dashboard/ai-coach/tutor/page.tsx` & `src/components/AI/TutorChat.tsx`
- **Access Guard:** `AI_COACH` Tier
- **UI Components:**
- Real-time chat message history (User messages in brand cyan, AI Tutor responses formatted in Markdown + KaTeX LaTeX equations)
- Chat `` with send button and typing indicator
- Quick Suggestion Chips: *"Explain Photoelectric Effect"*, *"Solve JEE 2024 Math Integration"*, *"Give me a 3-step revision plan"*
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Send Message Button` | Submits doubt to streaming API | `sendMessage(text)` |
| `Suggestion Chips` | Populates input with prompt | `setInput(chipText)` |
- **APIs Invoked:**
1. `POST /api/ai-coach/chat/stream`
- **Trigger:** On sending a message
- **Request Headers:** `Content-Type: application/json`, `Accept: text/event-stream`
- **Request Body:** `{ "user_id": "", "message": "Explain Lenz's Law" }`
- **Response Stream:** `text/event-stream; charset=utf-8` (Server-Sent Events)
- **Phase 2 Status:** Intentionally stubbed with friendly coming-soon notice to decouple from external LLM providers during initial launch.
---
#### B. Spaced Repetition Mistake Notebook (`/dashboard/ai-coach/mistakes`)
- **File Location:** `src/app/dashboard/ai-coach/mistakes/page.tsx`
- **Access Guard:** `AI_COACH` Tier
- **UI Components:**
- Daily Mistake Card Queue: Displays questions that the student answered incorrectly in previous CBT exams, scheduled for revision today using the SuperMemo-2 (SM-2) algorithm.
- Interactive Answer Selector (`A`, `B`, `C`, `D`)
- "Submit Answer" button
- Post-submission Feedback Panel: Immediate correctness status, explanation, and new scheduled review interval (e.g. *"Reviewed! Next review in 6 days"*).
- "Next Question" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Select Answer (A/B/C/D)` | Selects answer option | `setSelectedOption(opt)` |
| `Submit Answer Button` | Submits review and updates SM-2 interval | `submitReview(mistakeId, option)` |
| `Next Question Button` | Advances to next queued mistake | `handleNext()` |
- **APIs Invoked:**
1. `GET /api/mistakes/today?user_id={userId}`
- **Trigger:** On page mount
- **Response:** Array of pending mistake objects where `next_review <= NOW()`.
2. `POST /api/mistakes/review`
- **Trigger:** On `Submit Answer` click
- **Request Body:** `{ "mistake_id": "", "selected_answer": "B" }`
- **Response:**
```json
{
"status": "reviewed",
"is_correct": true,
"interval": 6,
"next_review": "2026-09-15T00:00:00Z"
}
```
---
#### C. Exam Readiness & College Predictor (`/dashboard/ai-coach/readiness` & `/college-predictor`)
- **File Location:** `src/app/dashboard/ai-coach/readiness/page.tsx`, `college-predictor/page.tsx`, `ReadinessGauge.tsx`, `CollegePredictorCard.tsx`
- **Access Guard:** `AI_COACH` Tier
- **UI Components:**
- Circular SVG Exam Readiness Gauge (0–100%)
- Readiness Breakdown: Accuracy Score, Time Management Score, Consistency Score, Topic Coverage
- AI College Predictor Card: Predicted Rank, Eligible IIT/NIT/AIIMS colleges based on historical cutoffs (Safe, Probable, Reach)
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Recalculate Score Button` | Refetches latest readiness calculation | `fetchReadiness()` |
| `Explore College Cutoffs` | Expands category details | `setCategoryFilter(...)` |
- **APIs Invoked:**
1. `GET /api/ai-coach/readiness/{userId}`
- **Trigger:** On mount
- **Response:**
```json
{
"readiness_score": 78,
"predicted_rank": 3420,
"confidence_interval": "± 400",
"subject_breakdown": {
"Physics": 82,
"Chemistry": 85,
"Mathematics": 67
}
}
```
---
#### D. Adaptive Daily Study Plan (`/dashboard/ai-coach/study-plan`)
- **File Location:** `src/app/dashboard/ai-coach/study-plan/page.tsx` & `src/components/AI/StudyPlanCard.tsx`
- **Access Guard:** `AI_COACH` Tier
- **UI Components:**
- Daily Study Plan Task List: Revision Target, Practice Target, Test Recommendation
- Task checkboxes to mark tasks as completed
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Task Checkbox` | Marks daily task complete | Local task state |
| `Start Recommended Task` | Deep-links to relevant test or DPS | `/dashboard/dpp` |
- **APIs Invoked:**
1. `GET /api/ai-coach/study-plan/today?user_id={userId}`
- **Trigger:** On mount
- **Response:** Daily plan JSON generated by Celery Beat at 5:00 AM IST.
---
### 3.6 Admin Management Console (`/admin/*`)
> **Access Restriction:** Protected by `proxy.ts` (Requires `auth_token=admin` cookie). Non-admin users are immediately redirected to `/login`.
#### A. Command Center Overview (`/admin`)
- **File Location:** `src/app/admin/page.tsx`
- **Access Guard:** Admin Only
- **UI Components:**
- KPI Stat Cards: Total Revenue, Active Students, AI Agent Accuracy %, Total Questions
- System Health & Accuracy Area Chart (`recharts`)
- Quick Action Buttons: "Refresh Data", "Create Test", "Manage Students"
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Refresh Data Button` | Triggers refetch of dashboard metrics | `fetchDashboardData()` |
| `Create Test Quick Link` | Navigates to Test Management | `/admin/tests` |
---
#### B. Student Directory & Profile Control (`/admin/students` & `[studentId]`)
- **File Location:** `src/app/admin/students/page.tsx` and `src/app/admin/students/[studentId]/page.tsx`
- **Access Guard:** Admin Only
- **UI Components:**
- Students Directory Table: Name, Email, Target Exam, Class, Tier Badge (`Free`/`Pro`/`AI Coach`), Streak, Actions
- Search & Filter Bar: Filter by Exam (`JEE Main` / `NEET`) or Tier
- Detail Page (`[studentId]`):
- Full Profile Card
- Tier Override Selector (`Free` -> `Pro` -> `Al_Coach`)
- "Update Tier" button
- "Reset Streak" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `View Student Row` | Navigates to individual student control | `router.push('/admin/students/' + student.id)` |
| `Update Tier Button` | Changes student subscription tier | `handleTierUpdate(newTier)` |
| `Reset Streak Button` | Resets student streak counter to 0 | `handleResetStreak()` |
- **APIs Invoked:**
1. `GET /api/admin/students` (Lists all student accounts)
2. `GET /api/admin/students/{studentId}` (Fetches single student record)
3. `PATCH /api/admin/students/{studentId}`
- **Trigger:** On tier change or profile update
- **Request Body:** `{ "tier": "Al_Coach" }`
- **Response:** Updated student record.
---
#### C. Test & DPS Management Center (`/admin/tests`)
- **File Location:** `src/app/admin/tests/page.tsx`
- **Access Guard:** Admin Only
- **UI Components:**
- Active Tests Table: Title, Exam Pattern, Total Time, Scheduled Date, Active Switch toggle, Delete button
- Manual Test Creation Form / JSON Drag-and-Drop Uploader:
- Test Title ``
- Exam Pattern selector (`JEE_MAIN`, `JEE_ADVANCED`, `NEET`)
- Test Type selector (`Mock`, `DPS`)
- Time Limit `` (minutes)
- JSON Question File Uploader (Validates question schema: `question_text`, `options`, `correct_answer`, `subject`, `topic`)
- "Create Test" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Active Toggle Switch` | Toggles test visibility to students | `handleToggle(testId)` |
| `Delete Test Button` | Permanently deletes test and its questions | `handleDelete(testId)` |
| `JSON File Drop Zone` | Parses and validates questions JSON | `processFile(file)` |
| `Create Test Button` | Dispatches manual test creation | `handleCreateTest()` |
- **APIs Invoked:**
1. `GET /api/admin/tests`
- **Trigger:** On mount
- **Response:** Array of all existing tests.
2. `PUT /api/admin/tests/{testId}/toggle`
- **Trigger:** On switch toggle
- **Response:** `{ "status": "toggled", "is_active": true|false }`
3. `DELETE /api/admin/tests/{testId}`
- **Trigger:** On delete confirm
- **Response:** `{ "status": "deleted" }`
4. `POST /api/admin/tests/create_manual`
- **Trigger:** On `Create Test` submit
- **Request Body:**
```json
{
"title": "JEE Main Physics Final Mock",
"type": "Mock",
"exam_pattern": "JEE_MAIN",
"time_limit": 180,
"admin_id": "",
"questions_json": [ ... ]
}
```
- **Response:** `{ "status": "created", "test_id": "", "questions_count": 75 }`
---
#### D. Coupon Management (`/admin/coupons`)
- **File Location:** `src/app/admin/coupons/page.tsx`
- **Access Guard:** Admin Only
- **UI Components:**
- Active Coupons Table: Code, Discount %, Max Discount Amount, Status, Delete button
- New Coupon Creation Card: Code input, Discount percentage input, Max discount input, "Create Coupon" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Create Coupon Button` | Submits new coupon | `handleCreate()` |
| `Delete Coupon Button` | Deletes discount coupon | `handleDelete(couponId)` |
- **APIs Invoked:**
1. `GET /api/admin/coupons` (Fetches active coupons list)
2. `POST /api/admin/coupons`
- **Request Body:** `{ "code": "PRAGATI50", "discount_percent": 50, "max_discount_amount": 2000 }`
3. `DELETE /api/admin/coupons/{id}` (Deletes coupon)
---
#### E. Global Platform Settings (`/admin/settings`)
- **File Location:** `src/app/admin/settings/page.tsx`
- **Access Guard:** Admin Only
- **UI Components:**
- Maintenance Mode Switch
- Free Test Quota `` (Number of free mock tests allowed before paywall)
- Allow Registrations Switch
- "Save Settings" button
- **Buttons & Interactive Elements:**
| Button / Trigger | Action | Target / Handler |
| :--- | :--- | :--- |
| `Save Settings Button` | Persists global configuration | `handleSaveSettings()` |
- **APIs Invoked:**
1. `GET /api/admin/settings` (Fetches current settings)
2. `POST /api/admin/settings`
- **Request Body:** `{ "maintenance_mode": false, "free_test_limit": 2, "allow_registrations": true }`
---
## 4. Master Button-to-API Cross Reference Matrix
| Button / UI Element | Page Location | Trigger Type | HTTP Method & Endpoint | Payload / Parameters |
| :--- | :--- | :--- | :--- | :--- |
| **Sign In** | `/login` | Form Submit | `POST /api/auth/login` | `{ email, password }` |
| **Register & Login** | `/signup` | Form Submit | `POST /api/auth/register` | `{ name, email, password }` |
| **Reset Password** | `/forgot-password` | Form Submit | `POST /api/auth/forgot-password` | `{ email }` |
| **Proceed to Payment** | `/checkout` | User Click | `POST /api/billing/create-order` | Query: `?user_id=...&plan_tier=...` |
| **Razorpay Verification** | `/checkout` | SDK Callback | `POST /api/billing/verify-payment` | `{ razorpay_order_id, razorpay_payment_id, ... }` |
| **Start CBT Exam** | `/dashboard/cbt` | Navigation | `GET /api/tests/{examId}` | Query: `?user_id=...` |
| **Fetch Questions** | `/cbt/[examId]` | Page Mount | `GET /api/tests/{examId}/questions` | Path: `{examId}` |
| **Final Submit Exam** | `/cbt/[examId]` | Modal Confirm | `POST /api/attempts/submit` | `{ test_id, user_id, answers, ... }` |
| **Submit Mistake Review** | `/dashboard/ai-coach/mistakes` | User Click | `POST /api/mistakes/review` | `{ mistake_id, selected_answer }` |
| **Send AI Doubt** | `/dashboard/ai-coach/tutor` | Form Submit | `POST /api/ai-coach/chat/stream` | `{ user_id, message }` |
| **Upload Avatar** | `/dashboard/settings` | File Input | `POST /api/users/{id}/avatar` | Form-Data: `file: ` |
| **Save Profile** | `/dashboard/settings` | User Click | `PUT /api/users/{id}` | `{ name, target_exam, school, state }` |
| **Toggle Test Status** | `/admin/tests` | Switch Toggle | `PUT /api/admin/tests/{id}/toggle` | Path: `{id}` |
| **Delete Test** | `/admin/tests` | Button Click | `DELETE /api/admin/tests/{id}` | Path: `{id}` |
| **Create Manual Test** | `/admin/tests` | Form Submit | `POST /api/admin/tests/create_manual` | `{ title, exam_pattern, questions_json, ... }` |
| **Update Student Tier** | `/admin/students/[id]` | Dropdown Change | `PATCH /api/admin/students/{id}` | `{ tier: "Al_Coach" }` |
| **Create Coupon** | `/admin/coupons` | Form Submit | `POST /api/admin/coupons` | `{ code, discount_percent, ... }` |
| **Delete Coupon** | `/admin/coupons` | Button Click | `DELETE /api/admin/coupons/{id}` | Path: `{id}` |
| **Save Admin Settings** | `/admin/settings` | User Click | `POST /api/admin/settings` | `{ maintenance_mode, free_test_limit, ... }` |
---
## 5. Codebase Cleanup Audit & Phase 2 Roadmap
### 5.1 Cleaned & Removed Legacy Files
In accordance with production standards, the following 10 dead/legacy files and temporary development artifacts have been hard-deleted:
- `backend/fix.py`: One-time script for manual LaTeX question corrections.
- `backend/fix_from_source.py`: One-time PDF extraction script.
- `backend/fix_ions.py`: One-time chemical formula fixer.
- `backend/seed_dpps.py`: Legacy DPS script using PyMuPDF and OpenAI.
- `backend/seed_dpps_mock.py`: Obsolete mock DPS generator.
- `backend/seed_dpps_real.py`: Obsolete duplicate DPS script.
- `backend/seed_from_dpps.py`: Redundant seeder variant.
- `backend/pragativeer-prd.pdf`: Product Requirements Document binary removed from backend.
- `backend/pragativeer.db`: Abandoned SQLite file (PragatiVeer exclusively uses PostgreSQL).
- `backend/test.pdf` & `backend/test2.pdf`: Temporary test PDFs.
### 5.2 Decoupled Dependencies (`requirements.txt`)
The following heavy external packages were removed from `backend/requirements.txt`:
- `openai==1.14.0`: Decoupled to eliminate reliance on external LLM keys during initial rollout.
- `PyMuPDF==1.23.26`: Decoupled to prevent native C-library compile overhead in production.
### 5.3 Stubbed Modules for Phase 2 AI Integration
- `backend/llm.py`: Cleanly stubbed with an async generator returning a friendly coming-soon notice.
- `backend/pdf_parser.py`: Cleanly stubbed with an empty list return.
- `backend/worker.py`: Cleaned to retain exclusively the active 5:00 AM IST Celery Beat daily study plan scheduler.
- `POST /api/admin/tests/upload`: Returns a structured message directing administrators to use `/api/admin/tests/create_manual` until Phase 2 is provisioned.
---
*Document compiled and verified for PragatiVeer v2 — Production Release*