# 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*