Spaces:
Sleeping
Sleeping
File size: 4,954 Bytes
6a8e2e2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # AI InterviewMentor β Architecture Overview
## System Architecture
```
Browser (React SPA)
β
βΌ
HF Spaces Docker Container (port 7860)
βββ FastAPI (Python 3.11)
β βββ /api/auth/* β Custom JWT auth (jose + bcrypt)
β βββ /api/batches/* β Batch/class management
β βββ /api/topics/* β Topic CRUD + unlock control
β βββ /api/upload β CSV question bank ingestion
β βββ /api/sessions/* β Session detail + reports
β βββ /api/instructor/* β Dashboard + student analytics
β βββ /api/student/* β Student dashboard
β βββ /interview/* β LangGraph interview engine
β βββ / (catch-all) β React static files (Vite build)
β
βββ LangGraph Engine
β βββ ask_question β Picks next question from bank
β βββ evaluate_answer β Scores: strong | shallow | wrong
β βββ counter_question β Probing follow-up for shallow answers
β βββ summarize β Compresses conversation every 4 turns
β βββ generate_report β Final scored feedback JSON
β
βββ External Services
βββ NeonDB (PostgreSQL)
β βββ public schema β App data (users, batches, topics, questions, sessions)
β βββ checkpointer β LangGraph state (auto-managed)
βββ OpenRouter API β MiniMax 2.7 model
```
## Tech Stack
| Layer | Technology |
|-------|-----------|
| Frontend | React 18 + Vite + TypeScript + Tailwind CSS v3 (dark theme only) |
| Backend | FastAPI (Python 3.11) |
| AI Orchestration | LangGraph (state machine with checkpointing) |
| Database | NeonDB (PostgreSQL) β app data + LangGraph checkpoints |
| AI Gateway | OpenRouter β MiniMax 2.7 |
| Auth | Custom JWT (jose + bcrypt) β no third-party auth |
| Deployment | Single Docker container on Hugging Face Spaces (port 7860) |
## Key Design Decisions
1. **Single container deployment** β React static build served by FastAPI, no split deployment
2. **Same-origin API calls** β No CORS needed, browser hits FastAPI directly
3. **Two DB schemas** β `public` for app data, `checkpointer` for LangGraph state
4. **Token budget control** β Summarize every 4 turns, ~700 token ceiling per LLM call
5. **session_id = thread_id** β Natural scoping between DB sessions and LangGraph state
6. **CSV-to-DB question ingestion** β No file storage needed (no S3/R2)
7. **Custom JWT only** β Supabase/Firebase explicitly banned (hackathon rules)
## Database Schema
### Tables
- **users** β id, full_name, email, password_hash, role (student|instructor), batch_id
- **refresh_tokens** β id, user_id, token_hash, expires_at
- **batches** β id, name, instructor_id, class_code (auto-generated)
- **topics** β id, batch_id, name, is_unlocked, order_index
- **questions** β id, topic_id, question_text, difficulty (easy|medium|hard)
- **interview_sessions** β id, student_id, topic_id, status, score, feedback (JSONB)
### Relationships
```
instructor (user) β creates batches β has topics β has questions
student (user) β joins batch via class_code β takes interview_sessions on topics
```
## Auth Flow
- **Access token**: HS256 JWT, 15min expiry, sent in `Authorization: Bearer` header
- **Refresh token**: 7-day expiry, bcrypt-hashed in DB, sent as httpOnly cookie
- **Route protection**: `get_current_user` dependency extracts JWT β `require_instructor` / `require_student` role guards
## LangGraph Interview Flow
```
START β ask_question β [wait for student answer] β evaluate_answer
β
ββββββββββββββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
counter_question ask_question generate_report β END
β (or summarize
βΌ every 4 turns)
evaluate_answer
```
- **8 turns max** or question bank exhausted β generate_report
- **Counter-questions** fire once per shallow answer (no double-countering)
- **Summarize node** compresses messages every 4 turns to keep token usage flat
## Frontend Architecture
- **Routing**: React Router with `ProtectedRoute` wrapper
- **State**: Zustand stores β `authStore` (JWT + user), `interviewStore` (session state)
- **API layer**: Single `apiFetch` wrapper with auto-refresh on 401
- **Pages**: Login, Signup, StudentDashboard, Interview, Report, InstructorDashboard, Upload, StudentDetail
## Scope Boundary (Not In V1)
Voice input, email notifications, leaderboard, certificates, question bank editor UI, light theme, multi-instructor batches.
|