HireSimTS is the realtime hiring backend that powers the AI interviewer experience. It authenticates talent with Clerk, ingests their resumes, synthesizes a tailored interview script with LangGraph + OpenAI, and streams the conversation over WebSockets/WebRTC while persisting the full outcome for review.
Express+wsserver exposes REST APIs for resume management and websockets for live interview control.- Authenticated endpoints use Clerk (
requireAuth,verifyUser) to ensure every resume, interview, and score is tied to a verified candidate. - Prisma models (
User,Resume,Interview,InterviewResponse) store long-lived state in PostgreSQL. - Resumes are parsed via
pdf-parse, text-indexed, and the source files are stored on ImageKit for later retrieval. - Scripts and interviewer personas are generated on-demand (
def_script,Entity) using LangChain, LangGraph, and GPT-4o mini. - The interviewer speaks through
@roamhq/wrtcby converting LLM replies into PCM audio (gpt-4o-mini-tts) and streaming them to the browser while waiting foruser_responseevents. - After each session, structured scoring feedback is produced (
Entity.results) and written back to theInterviewtables for dashboards.
- User bootstrap:
POST /api/createensures a Clerk user exists in PostgreSQL and captures profile metadata. - Resume upload:
POST /api/upload/resumeaccepts PDFs, extracts text, uploads the binary to ImageKit, and persists metadata plus parsed text for prompt grounding. - Resume access: candidates can list (
GET /api/get/resumes/list) and retrieve (GET /api/resumes/:id) their own files, enforced via Clerk auth checks. - Interview start:
- Frontend opens a WebSocket, sends
initwith{ userId, resumeId, role }. - Backend retrieves resume text, creates a bespoke script (
def_script), and acknowledges readiness. - Client shares WebRTC SDP (
offer) and ICE candidates; backend answers viaPeerConnection.
- Frontend opens a WebSocket, sends
- Conversation loop:
Entity.invoke_graphruns a LangGraph state machine that alternates interviewer turns withinterruptpoints that awaituser_responsefrom the socket.- Each AI message is synthesized to PCM audio (
stream_audio) and pushed into the WebRTC track so the candidate hears a natural voice.
- Completion:
- When the end-of-interview classifier fires, the backend compiles question/answer pairs, asks a reviewer model for scores/remarks, stores the result, and emits
{ type: "complete", data: interviewId }.
- When the end-of-interview classifier fires, the backend compiles question/answer pairs, asks a reviewer model for scores/remarks, stores the result, and emits
src/app.ts– Express app with CORS and JSON middleware.src/routes.ts– REST surface for user bootstrap, resume CRUD, and interview history fetches.src/main.ts– HTTP + WebSocket server bootstrap.src/user_services/– Prisma client, ImageKit integration, WebRTC peer connection wrapper, and theConnectionorchestration class.src/script.ts&src/prompts/– Prompt builders used to derive interviewer scripts, end-of-interview checks, and reviewer grading instructions.src/types/– Zod schemas for LangGraph state, interviewer termination checks, and review output typing.
- Runtime: Node.js + Express 5, ws, WebRTC (
@roamhq/wrtc) - AI orchestration: LangChain, LangGraph, OpenAI GPT-4o mini (chat + TTS)
- Auth: Clerk (JWT middleware for REST, future token-based WS upgrade)
- Persistence: PostgreSQL via Prisma Client
- File storage: ImageKit for resume binaries and thumbnails
- Utilities: Multer, pdf-parse, uuid, dotenv/cors
CLERK_*keys for REST authentication.OPENAI_API_KEYfor chat, reviewer, and TTS models.DATABASE_URLfor Prisma.IMAGEKIT_PUBLIC_KEY,IMAGEKIT_PRIVATE_KEY,IMAGEKIT_URL_ENDPOINTfor resume storage.