Overview
This Next.js 14 app manages AI-driven interview workflows: create interviewers (Retell agents), create interviews with shareable call links, register and analyze calls, and store transcripts and insights in MongoDB with session-based access.This AI Recruiter is part of Weam. Configuration, usage, and access happen within Weam.
What It Does (Capabilities)
- Create Retell-backed interviewers and LLM agents
- Create interviews with questions/objectives and shareable call URLs
- Register calls and receive webhook events from Retell
- Fetch call details/transcripts and generate OpenAI analytics
- Manage interviews and responses via dashboard and APIs
- Session-based access control with
iron-sessionand middleware
User Flows
- Configure interviewer: Provision a Retell-backed agent.
- Create interview: Set name, objective, and questions; generate a shareable call URL.
- Conduct call: Candidate joins via the link; system registers and receives Retell events.
- Analyze & review: Transcript is processed, insights are generated via OpenAI, and data is stored for dashboard review.
Architecture
| Layer | Components |
|---|---|
| UI (Next.js App Router) | Client pages in src/app/(client) with React contexts (auth, interviews, interviewers, responses) |
| API/Services | Route handlers in src/app/api/*; business logic in src/services/* |
| Webhooks/Processing | api/response-webhook validates Retell signatures and triggers call retrieval and analysis |
| Data Store | MongoDB for interviews, interviewers, responses, users, and organizations |
| External Services | Retell (LLM agents + events) and OpenAI (analytics generation) |
Technical Design
- Interviewers: Create Retell LLM and agent, store
agent_idwith user and company context. - Interviews: Generate shareable call URL using
NEXT_PUBLIC_LIVE_URLand optional slug; store questions and metadata. - Responses: Register calls and persist transcript, analytics, duration, and status flags.
- Analytics: Build prompt from transcript and interview questions, generate structured insights with OpenAI.
- Session/State:
iron-sessionwith/api/auth/session; middleware checks public/protected routes viacheck-accessfor roleUSER. - Security/Validation: Retell webhook signature verification; API key validation; session-based access control; selective public routes for integration flows.
API Reference (High Level)
Auth / Session
GET /api/auth/session- Returns current session user andcompanyId(401 if none).POST /api/auth/logout- Ends session.POST /api/auth/check-access- Used by middleware for authorization decisions.
Interviewers
GET /api/interviewers- List interviewers.POST /api/interviewers- Create interviewer (provisions Retell agent).
Interviews
GET /api/interviews- List interviews (scoped by user/company).POST /api/interviews- Create new interview.POST /api/create-interview- Alternate creation path with call URL generation.POST /api/interviews/[id]/generate-token- Generates secure token.
Calls and Responses
- Public:
POST /api/public/register-callPOST /api/public/get-callPOST /api/public/responses
- Authenticated:
POST /api/register-callPOST /api/get-callGET /api/responses/call/[callId]- CRUD under
/api/responses
Webhooks
POST /api/response-webhook- Validates Retell signature and triggers call retrieval/analysis.
- Public endpoints are available for integrations (no session).
- Protected endpoints require
iron-session; middleware enforcesUSERrole access.
Data and Schemas (Conceptual)
| Entity | Key Fields |
|---|---|
| Interviewer | name, agent_id, user { id, email }, companyId |
| Interview | id, name, objective, questions[], url, readable_slug, user, companyId |
| Response | call_id, transcript, analytics { score, strengths, improvements, insights }, duration, is_analysed, candidate_status, timestamps |
| Organization | name, logo_url, companyId |
| User/Session | _id, email, roleCode, companyId |
TroubleShooting
- Interview Creation
- Calls & Analysis
- API & Auth
- App & Sessions
- Performance & Cost
Failed to create interview
Failed to create interview
Symptoms
- 500 errors; toast shows “Failed to create interview”
- Missing API keys; no new records
- Missing
OPENAI_API_KEY,RETELL_API_KEY,NEXT_PUBLIC_*, DB vars - No user session (401)
- Invalid payload types (e.g., BigInts)
- Set required env vars; retry
- Ensure valid session before calling API
- Sanitize payload on client
Tech Stack
| Layer | Technologies | Purpose |
|---|---|---|
| Frontend UI | Next.js 14 (App Router), React 18, Tailwind, Radix UI, shadcn/ui, framer-motion | Dashboard, modals, forms |
| State/Forms | React Context, React Hook Form | Client state and validation |
| API/Server | Next.js Route Handlers, iron-session | API endpoints and session management |
| Services | src/services/* | Business logic and data access |
| Database | MongoDB (native driver) | Data persistence |
| AI/ML | OpenAI SDK | Transcript analytics |
| Voice/Telephony | Retell SDK | LLM agent creation and event handling |
| Utilities | axios, zod, uuid/nanoid, lucide-react | HTTP, validation, IDs, icons |
| Styling | tailwindcss-animate, clsx, class-variance-authority | Styling helpers |
| Build/Tooling | TypeScript, ESLint, PostCSS, Tailwind | Developer tooling |
Best Practices
- Validate env vars before sensitive operations.
- Preserve HTTP status codes for clarity.
- Use authenticated endpoints wherever possible.
- Cache analytics results to avoid recomputation.
- Enforce tenant scoping via
companyId. - Clear cookies on inconsistent auth state.
- Log and handle Retell/OpenAI errors gracefully.
- Avoid re-analyzing the same transcript multiple times.
- Keep prompts deterministic and lightweight for stable OpenAI costs.

