Project: Preppr – AI-Powered Real-Time Voice Interview Trainer & Analytics Platform
Build a web application where a candidate can:
- Log in.
- Upload a resume.
- Select a company, role, difficulty, and duration.
- Have a real-time voice interview with an AI interviewer.
- Get resume-aware and company/role-aware follow-up questions.
- Track speaking metrics such as WPM, fillers, and pauses.
- Receive strict AI-based evaluation.
- View a dashboard and download a PDF improvement report.
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Next.js + TypeScript + Tailwind CSS | Web UI |
| Backend | Python + FastAPI | API and AI orchestration |
| Realtime | LiveKit / WebRTC | Live audio |
| VAD | Silero VAD | Speech/silence detection |
| STT | faster-whisper | Speech-to-text |
| LLM | Gemini API or Groq | Interview agent + evaluation |
| TTS | Kokoro-82M | Text-to-speech |
| Database | PostgreSQL | Application data |
| Vector DB | pgvector | RAG |
| Embeddings | BGE-small / Sentence Transformers | Local embeddings |
| Resume parsing | PyMuPDF + LLM JSON extraction | Resume processing |
| ReportLab | Final report | |
| Auth | Auth.js / Google OAuth | Login |
| Deployment | Vercel + backend host | Deployment |
| Containers | Docker | Development/deployment |
Next.js Frontend
|
v
LiveKit / WebRTC
|
v
FastAPI Backend
|
+--> Silero VAD
|
+--> faster-whisper STT
|
+--> RAG
| +--> Resume
| +--> Company
| +--> Role
| +--> PostgreSQL + pgvector
|
+--> LLM Interview Agent
|
+--> Kokoro TTS
|
+--> Analytics
| +--> WPM
| +--> Fillers
| +--> Pauses
| +--> Duration
|
+--> Evaluation Engine
|
+--> PDF Report
Build in this exact order:
- Authentication + dashboard
- PostgreSQL setup
- Resume upload
- Resume parsing
- Candidate profile
- pgvector + embeddings
- Company/role knowledge base
- RAG retrieval
- Text interview agent
- Adaptive follow-up logic
- LiveKit/WebRTC
- VAD + STT
- TTS + voice response
- WPM/filler/pause analytics
- LLM-as-a-judge evaluation
- Dashboard
- PDF report
- Testing
- Deployment
Do not start with voice. Build the text/RAG interview first.
- Node.js LTS
- npm
- Python 3.11+
- PostgreSQL
- pgvector
- Docker Desktop
- Git
- VS Code
preppr/
├── frontend/ # Next.js
├── backend/ # FastAPI
├── docker-compose.yml
├── .env.example
└── README.md
Working frontend + FastAPI backend + PostgreSQL + authentication.
Implement:
- Google OAuth / Auth.js
- User session
- Protected dashboard
- Logout
- User record in PostgreSQL
Login → Dashboard → Logout
Flow:
PDF Upload
↓
PyMuPDF
↓
Extract Text
↓
LLM Structured Extraction
↓
Candidate JSON
↓
PostgreSQL
Example profile:
{
"skills": ["Java", "Python", "React", "FastAPI"],
"projects": [],
"experience": [],
"education": [],
"certifications": []
}Store resume chunks for RAG.
Use:
- PostgreSQL
- pgvector
- Sentence Transformers
- BGE-small embeddings
Flow:
Resume / Company / Role Data
↓
Chunking
↓
Embeddings
↓
pgvector
↓
Similarity Search
↓
Relevant Context
↓
LLM
Start with a small company database instead of trying to support every company.
Before implementing voice, make a complete text interview.
The LLM receives:
- Company
- Role
- Difficulty
- Interview duration
- Resume profile
- Retrieved RAG context
- Conversation history
- Interview rules
Rules:
- Ask one question at a time.
- Avoid unnecessary praise.
- Ask relevant follow-ups.
- Challenge weak answers.
- Increase difficulty when appropriate.
- Reference resume projects when relevant.
- Stay within the selected interview duration.
A complete multi-turn text mock interview.
Implement:
Strong answer
↓
Harder follow-up
Weak answer
↓
Clarification / fundamentals
Incomplete STAR answer
↓
Ask for missing S/T/A/R
Repeated weakness
↓
Add competency to improvement areas
Flow:
Microphone
↓
LiveKit / WebRTC
↓
Silero VAD
↓
faster-whisper
↓
FastAPI
↓
RAG + Interview Agent
↓
LLM
↓
Kokoro TTS
↓
LiveKit
↓
Candidate hears response
Support:
- Microphone permissions
- Speech detection
- Silence detection
- Interruptions/barge-in
- Disconnect/reconnect handling
- Session state
Track:
- Speaking duration
- Word count
- WPM
- Filler-word count
- Filler rate
- Average pause
- Longest pause
- Answer duration
- Question-to-answer timing
Example:
WPM = total words / speaking minutes
Filler Rate = filler words / total words × 100
Do not claim emotion, stress, confidence, or cognitive-load detection unless it is actually implemented and validated.
Use an LLM-as-a-judge rubric.
Score:
- Technical correctness
- Relevance
- Clarity
- Depth
- Problem solving
- Answer structure
- Resume/project relevance
- STAR structure for behavioral questions
Combine these with deterministic audio metrics.
Store:
{
"technical": 78,
"communication": 64,
"problem_solving": 82,
"structure": 59,
"overall": 71
}Always store evidence and written feedback along with scores.
Show:
- Overall score
- Technical score
- Communication score
- Problem-solving score
- STAR/structure score
- Resume relevance
- WPM
- Filler count/rate
- Pause metrics
- Strengths
- Weaknesses
- Question-by-question review
- Interview history
- Recommended improvement areas
Generate using ReportLab.
Include:
- Candidate details
- Company and role
- Overall score
- Competency scores
- Acoustic metrics
- Question/answer evaluation
- Strengths
- Weaknesses
- Improved-answer examples
- Prioritized improvement areas
- Two-week improvement plan
- Optional transcript
Use PostgreSQL + pgvector.
users
resumes
candidate_profiles
companies
roles
knowledge_chunks
interview_sessions
interview_questions
interview_answers
audio_metrics
evaluations
reports
users
id, name, email, created_at
resumes
id, user_id, file_name, extracted_text
candidate_profiles
id, resume_id, skills, education, experience, projects
companies
id, name, description, values, interview_style
roles
id, company_id, role_name, difficulty, requirements
knowledge_chunks
id, source_type, source_id, content, embedding, metadata
interview_sessions
id, user_id, company_id, role_id, difficulty, duration, status
interview_answers
id, question_id, transcript, duration
audio_metrics
id, answer_id, word_count, wpm, filler_count, filler_rate,
longest_pause, average_pause
evaluations
id, session_id, scores, feedback_json
reports
id, session_id, file_path, created_at
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /auth/login |
Authentication |
| POST | /resume/upload |
Upload/parse resume |
| GET | /resume/profile |
Candidate profile |
| GET | /companies |
List companies |
| GET | /roles |
List roles |
| POST | /interviews |
Create session |
| GET | /interviews/{id} |
Session state |
| POST | /interviews/{id}/answer |
Process answer |
| POST | /interviews/{id}/end |
End interview |
| GET | /interviews/{id}/evaluation |
Evaluation |
| POST | /reports/{id}/generate |
Generate PDF |
| GET | /reports/{id} |
Report |
/
├── Landing page
/login
├── Authentication
/dashboard
├── Interview history
├── Quick start
/resume
├── Upload/manage resume
/interview/setup
├── Company
├── Role
├── Difficulty
└── Duration
/interview/[id]
├── Live interview
├── Timer
├── Voice status
└── Session controls
/interview/[id]/result
└── Immediate result
/reports/[id]
└── Detailed analytics
/settings
└── User settings
DATABASE_URL=
AUTH_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
LLM_API_KEY=
LIVEKIT_URL=
LIVEKIT_API_KEY=
LIVEKIT_API_SECRET=Never commit .env files or API keys.
- Login works
- Resume upload works
- Invalid PDFs fail gracefully
- Resume JSON is valid
- Resume RAG retrieves correct information
- Company context stays isolated
- Multi-turn interview works
- Microphone permissions work
- Disconnects are handled
- Interruptions do not break the interview
- STT works with test speakers
- WPM calculations are reproducible
- Filler calculations are reproducible
- Evaluation returns structured output
- PDF generation works
- Previous interviews are accessible
- API keys never reach the client
The MVP is complete when a user can:
- Log in
- Upload a resume
- Select a company and role
- Start a voice interview
- Have a multi-turn AI conversation
- Receive resume-aware follow-ups
- Finish the interview
- See speaking analytics
- Receive competency scores
- Download a PDF report
- View the interview later
Do not add these in the first version:
- Mobile application
- Kubernetes
- Microservices
- LLM fine-tuning
- Facial emotion detection
- Eye tracking
- Voice cloning
- Huge company database
- Complex recommendation engine
First make the core interview reliable.
Preppr should demonstrate this complete pipeline:
Resume + Company + Role
↓
RAG Context
↓
Real-Time Voice Interview
↓
Adaptive AI Follow-ups
↓
Acoustic Telemetry
↓
Strict AI Evaluation
↓
Analytics Dashboard
↓
PDF Report
↓
Two-Week Improvement Plan
Build text first, then voice.
The safest development path is:
Authentication
→ Resume
→ Database
→ RAG
→ Text Interview
→ Adaptive Logic
→ LiveKit
→ STT/VAD
→ TTS
→ Analytics
→ Evaluation
→ Dashboard
→ PDF
→ Testing
→ Deployment