Voice-first mock interview platform powered by NestJS, React, TypeORM, and OpenAI (questions, evaluation, TTS + Whisper STT). The repo is an Nx monorepo with:
apps/api– NestJS REST APIapps/web– React/Vite clientlibs/shared-db– TypeORM entities + migrationslibs/shared-types– DTOs/interfaces shared across apps
| Dependency | Version |
|---|---|
| Node.js | 20.x |
| npm | 10.x |
| PostgreSQL | 14+ |
| OpenAI API key | access to gpt-4o-mini, gpt-4o-mini-tts, gpt-4o-mini-transcribe |
Copy the template and edit values:
cp config/env.example .envKey variables (all defined in .env):
| Variable | Purpose |
|---|---|
API_PORT |
NestJS port (default 4000) |
API_HOST |
API bind address (0.0.0.0 or LAN IP) |
DATABASE_URL |
Postgres connection string |
OPENAI_API_KEY |
OpenAI API token |
OPENAI_QUESTION_MODEL / OPENAI_EVAL_MODEL |
LLMs for question/evaluation |
OPENAI_TRANSCRIBE_MODEL |
Whisper/STT model |
WEB_ORIGIN |
Allowed CORS origin for the React app |
QUESTIONS_PER_TOPIC |
Interview length control |
VITE_API_URL |
Frontend base URL for API calls |
VITE_HOST / VITE_PORT |
Vite dev server bind address/port |
npm install| Command | Description | URL |
|---|---|---|
npm run dev:api |
Start NestJS server with hot reload | http://localhost:4000 |
npm run dev:web |
Start Vite dev server | http://localhost:4200 |
Backend endpoints:
POST /auth/register,POST /auth/loginGET /jobsPOST /interviews,GET /interviews,GET /interviews/:id,POST /interviews/:id/nextPOST /tts(OpenAI TTS proxy)POST /stt/chunk(Whisper transcription)
Tip: To demo on a LAN IP (e.g.
192.168.0.50), set:API_HOST=192.168.0.50 WEB_ORIGIN=http://192.168.0.50:4200 VITE_API_URL=http://192.168.0.50:4000 VITE_HOST=192.168.0.50Restart both dev servers afterward.
Frontend notes:
useSpeechRecognitionstreams mic audio, detects silence (5s), and auto-submits answers.- Progress UI shows per-topic status (2 questions/topic by default).
- Review page displays per-question summaries and per-topic averages (follow-up text hidden per request).
npx nx lint api
npx nx lint web
npx nx test web- Login / Register – basic JWT auth.
- Jobs dashboard – highlight seeded jobs and “Recent interviews”.
- Start interview – pick a job; showcase thank-you + TTS prompts.
- Voice loop – answer verbally:
- Transcript updates live (Whisper).
- Silence (5s) auto-submits and advances.
- Status badge shows Listening/Evaluating/Asking.
- Progress tracking – show topic chips + progress bar.
- Review – open
/interviews/:id/review:- Per-topic averages.
- Question-by-question summary (follow-up hidden).
- Demo data callout – mention preloaded interview for job
a34a80e5-f03d-462b-b2f2-9ed383a23f12if you need an immediate example.
- Speech-to-Text: MediaRecorder →
/stt/chunk→ Whisper. RMS-based silence detection ensures we only listen when the system is not speaking. - Text-to-Speech:
/ttsproxies OpenAI TTS; React autoplays the base64 MP3. - Prompt templates:
api/src/app/interview-engine/prompts.ts. - Data model:
users,jobs,interviews,interview_questions,interview_answers.
| Feature | File |
|---|---|
| Whisper STT | api/src/app/stt |
| Interview orchestration | api/src/app/interviews/interviews.service.ts |
| React hooks | web/src/app/hooks/* |
| Interview UI | web/src/app/pages/InterviewPage.tsx |
| Review UI | web/src/app/pages/InterviewReviewPage.tsx |