A full-stack AI voice interview practice platform. Practice technical and behavioral interviews with an AI interviewer that asks real questions out loud, listens to your spoken answers, asks intelligent follow-ups, and gives you a scored report with a concrete improvement plan.
Built across 7 phases — see each phase's section in backend/README.md and frontend/README.md for what was built, why, and exactly what was tested at each step.
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ React Frontend │ ──────▶ │ Express Backend │ ──────▶ │ MongoDB Atlas │
│ (Vite, TS, │ HTTPS │ (TypeScript, │ │ (Mongoose) │
│ Tailwind v4) │ cookies │ REST API) │ └─────────────────┘
└─────────────────┘ └──────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ OpenAI │ │ Cloudinary │ │ Nodemailer │
│ (Whisper, │ │ (resumes, │ │ (SMTP) │
│ GPT, TTS) │ │ audio, │ │ │
│ — optional │ │ PDFs) │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
Key design decision, applied consistently across every AI feature: OpenAI integration is additive, not load-bearing. Question generation, follow-up questions, and report scoring all have real, working non-AI fallback paths (a curated static question bank, and heuristic scoring derived from objective speech metrics). The app is fully functional — signup through scored PDF report — with zero API keys beyond MongoDB, email, and Cloudinary. Adding OPENAI_API_KEY upgrades the experience; it never gates it.
- Create (
POST /interviews) — questions generated immediately (AI or static bank) - Start (
PATCH /interviews/:id/start) — status →in_progress - Session loop (
GET /interviews/:id/session→ answer via voice or text → repeat) — voice answers go through Whisper transcription; either path computes word count / filler-word ratio / speech rate - Complete (
PATCH /interviews/:id/complete) — triggers report generation automatically (AI content-scoring if configured, heuristic fallback otherwise; communication/confidence scores are always computed from real speech metrics regardless) - Report (
GET /interviews/:id/report,GET /interviews/:id/report/pdf) — 5-dimension scores, strengths/weaknesses/improvement plan, PDF export
interviewai/
├── backend/ # Express + TypeScript API
│ ├── src/
│ │ ├── config/ # env validation, DB connection, Cloudinary, OpenAI client
│ │ ├── models/ # 8 Mongoose models (User, Interview, Question, Answer,
│ │ │ # Report, Notification, Session, Resume)
│ │ ├── middleware/ # auth, validation, rate limiting, CSRF, error handling, uploads
│ │ ├── controllers/ # HTTP req/res layer — thin, delegates to services
│ │ ├── services/ # business logic — auth, interviews, questions, answers,
│ │ │ # resumes, reports, scoring, AI, PDF generation
│ │ ├── routes/ # Express routers, one per resource
│ │ ├── validations/ # Zod schemas per resource
│ │ ├── data/ # static question bank + skills taxonomy (AI fallback data)
│ │ └── utils/ # ApiError/ApiResponse, tokens, email, sanitization, pagination
│ └── README.md # phase-by-phase backend build log + what was tested
├── frontend/ # React 19 + Vite + TypeScript + Tailwind v4
│ ├── src/
│ │ ├── components/ # ui/ (design-system primitives), layout/, dashboard/,
│ │ │ # interview/ (voice recorder, audio player), reports/ (charts)
│ │ ├── contexts/ # AuthContext
│ │ ├── hooks/ # useAuth, useAudioRecorder
│ │ ├── lib/ # axios client, validation schemas, utils
│ │ ├── services/ # one file per backend resource
│ │ ├── types/ # TypeScript types matching backend models
│ │ └── pages/ # auth/, dashboard/, interviews/, reports/, settings/, admin/
│ └── README.md # phase-by-phase frontend build log + what was tested
├── SECURITY.md # security audit — what's implemented and why
├── DEPLOYMENT.md # Atlas + Railway + Vercel deployment guide
└── API_DOCUMENTATION.md # full endpoint reference
# 1. Backend
cd backend
npm install
cp .env.example .env
# fill in MONGODB_URI, JWT secrets, SMTP creds (see backend/.env.example for details)
npm run dev # runs on :5000
# 2. Frontend (new terminal)
cd frontend
npm install
cp .env.example .env
# VITE_API_URL=http://localhost:5000/api/v1
npm run dev # runs on :5173Visit http://localhost:5173, sign up, and check your email (or SMTP sandbox) for the verification link.
Minimum to run the full flow: MongoDB Atlas connection string + SMTP credentials + Cloudinary credentials. OPENAI_API_KEY is optional — everything works without it, just with static questions and heuristic scoring instead of AI-generated ones.
Every phase's README documents exactly what was run and confirmed working in this build environment (typechecks, production builds, live server boot tests, direct unit tests of scoring/PDF logic, auth-guard verification) versus what requires credentials or a browser that aren't available here (live OpenAI calls, a real MongoDB instance, visual/pixel rendering, actual microphone hardware). Each README section is explicit about which is which — nothing is claimed as "tested" that wasn't actually run.
backend/README.md— backend build log, phase by phasefrontend/README.md— frontend build log, phase by phaseSECURITY.md— security hardening auditDEPLOYMENT.md— deployment guideAPI_DOCUMENTATION.md— full API reference