A full-stack web app for scoring candidate speech using the ELSA Speech Analyzer API.
- Frontend: React 18 + Vite (port 5000, webview)
- Backend: Node.js + Express (port 3000, console workflow)
- Audio processing: FFmpeg (system dependency)
Start application— Vite dev server on port 5000 (webview)Backend API— Express API server on port 3000
- Candidates submit their own recording (audio or video) via a simple form
- Fields: Full Name, Email, Recording file, Upload status
- Submission is stored and visible to admins in the Recruiter Flow
- Scores are only visible to admins — applicants never see scores
- Create candidates manually; create meetings per candidate
- Upload transcript + recording per meeting
- FFmpeg extracts candidate speech segments from recording using transcript
- Send to ELSA scoring API; view detailed scores (EPS, CEFR, IELTS, etc.)
- Applicant submissions appear with an "Applicant" badge and can be scored too
- Login — Authenticate with ELSA credentials (Staging or Production)
- Candidates — Create/delete; filter by All / Recruiter Flow / Applicant Flow tabs
- Meetings — Multiple meetings per candidate; per-meeting upload + scoring
- File Upload — Transcript (SRT, VTT, JSON, DOCX, plain text) + recording (any audio/video)
- Audio Extraction — FFmpeg extracts candidate speech segments using transcript timestamps; applicant flow uses full audio
- ELSA Scoring — Sends extracted audio to ELSA
score_audio_plus_elsaAPI - Score Display — EPS, CEFR, IELTS, Pronunciation, Intonation, Fluency, Grammar, Vocabulary
server/
index.js — Express entry point (serves API + built client)
routes/
auth.js — POST /api/auth/login
candidates.js — CRUD /api/candidates (+ meetings sub-resource)
scoring.js — POST /api/scoring/upload/:cid/:mid, /score/:cid/:mid
apply.js — POST /api/apply (public applicant upload)
utils/
transcriptParser.js — Parses SRT/VTT/JSON/DOCX/plain text transcripts
audioExtract.js — FFmpeg audio segment extraction
client/src/
App.tsx — Router + session context
pages/
ApplyPage.tsx — Public applicant upload form (/apply)
LoginPage.tsx — Recruiter login form (/login)
CandidatesPage.tsx — Candidate list with flow filter tabs
CandidateDetailPage.tsx — Candidate info + meeting list
MeetingDetailPage.tsx — Per-meeting upload + scoring + score display
components/
Layout.tsx — App shell with header
ScoreCard.tsx — Score display with CEFR bars
data/candidates.json — Persistent candidate/meeting storage
uploads/ — Uploaded and extracted audio files (gitignored)
Candidate: { id, name, email, createdAt, source ('applicant'|undefined), meetings[] }
Meeting: { id, name, createdAt, source, transcriptPath, recordingPath, scores }
| Environment | Login | Scoring |
|---|---|---|
| Staging | https://staging.elsanow.co/user/api/v1/account/login |
https://silencer-stag.elsanow.co/api/v1/score_audio_plus_elsa |
| Production | https://pool.elsanow.io/user/api/v1/account/login |
https://pool.elsanow.io/api/v1/score_audio_plus_elsa |
- Target: VM (always-on; needed for FFmpeg + file persistence)
- Build:
npm run build(installs deps + compiles React) - Run:
npm start→node server/index.js