Monorepo for a recruiter-style candidate flow: browse jobs, apply (with résumé and contact details), complete an AI phone screening (via Bolna), and—after passing a configurable score—book a technical interview from recruiter-configured time slots. The stack is Next.js (apps/web) and NestJS (apps/api), with PostgreSQL and optional AWS S3 for file storage.
| Package | Role |
|---|---|
apps/web |
Next.js 16 / React 19 UI, talks to the API via NEXT_PUBLIC_API_URL. |
apps/api |
NestJS 11 REST API, TypeORM, JWT auth, Bolna + optional LLM scoring. |
Documentation
- Backend architecture — modules, data model, integrations, security, and API conventions (detailed).
-
Node.js LTS (v20+ recommended)
-
pnpm — the repo pins
packageManagerin the rootpackage.json; enable with:corepack enable -
Docker (optional but recommended) — for local PostgreSQL via
docker-compose.yml
From the repository root:
pnpm installEither use your own Postgres instance or start the bundled one (maps host 5433 → container 5432 to avoid clashing with a local Postgres on 5432):
docker compose up -d postgresConnection defaults match apps/api/.env.example (DATABASE_URL uses port 5433).
cp apps/web/.env.example apps/web/.env.local
cp apps/api/.env.example apps/api/.envEdit as needed:
- Web —
NEXT_PUBLIC_API_URLmust include the API global prefix, e.g.http://localhost:8080/api. - API — At minimum set
DATABASE_URL,JWT_SECRET, and—if you use uploads—AWS_*/S3_BUCKETper.env.example. For screening calls, configure Bolna variables (BOLNA_API_KEY,BOLNA_SCREENING_AGENT_ID, etc.).
Env load order (API) — @nestjs/config loads (later wins for each key): apps/api/.env.local → apps/api/.env → monorepo root .env. Plain Node does not load .env automatically; the API explicitly merges these files.
pnpm dev| App | Directory | Default URL |
|---|---|---|
| Web | apps/web |
http://localhost:3000 |
| API | apps/api |
http://localhost:8080/api |
- Swagger UI: http://localhost:8080/api/docs
- Health: http://localhost:8080/api/health
The API enables CORS for CORS_ORIGIN (default http://localhost:3000).
On API startup, SeedService runs JobsSeeder.seedIfEmpty() so you get sample jobs if the jobs table is empty. If the DB was down on first boot, fix connectivity and restart the API to retry seeding.
You can also run the seed script after a build (see apps/api/package.json seed script) if you use that workflow.
| Command | Description |
|---|---|
pnpm dev |
Turborepo: dev in all apps (web + API in parallel). |
pnpm build |
Production build for all apps. |
pnpm lint |
ESLint in each app. |
pnpm format |
Prettier for common file types. |
API-only (from apps/api):
pnpm dev—nest start --watchpnpm build/pnpm start:prod— production
Web-only (from apps/web):
pnpm dev/pnpm build/pnpm start
- Auth — Register/login; JWT returned to the client; profile update can attach résumé metadata after upload.
- Jobs — Public listing; authenticated users apply to a job (snapshots skills, résumé pointers, phone for dialing).
- Uploads — Authenticated multipart upload to S3 (public-read objects; bucket/policy requirements are documented in
apps/api/.env.example). - Screening — For each application, a screening session tracks Bolna outbound calls, transcripts, optional LLM-derived scoring, and pipeline transitions (pass / reject thresholds from env).
- Webhooks — Bolna calls
POST /api/screening/webhook(unauthenticated; restrict at the edge by IP or network policy—see env comments). - Technical interviews — After screening pass, candidates can confirm a slot from
TECH_INTERVIEW_AVAILABLE_SLOTS_JSON(and related Bolna scheduling options).
For module-level detail, request/response shape, and diagrams, see docs/BACKEND_ARCHITECTURE.md.
- Web cannot reach API — Check
NEXT_PUBLIC_API_URLincludes/apiand matches the API port; checkCORS_ORIGINon the API. - DB connection errors — Confirm Postgres is up,
DATABASE_URLhost/port match (5433 for the compose file), and credentials matchdocker-compose.yml. - S3 errors — Ensure both
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYare set together if you use static keys; see.env.examplefor MinIO-styleS3_ENDPOINT. - Screening / Bolna — Verify
BOLNA_*keys and agent IDs; register the public webhook URL in the Bolna dashboard as documented in.env.example.
apps/
web/ # Next.js frontend
api/ # NestJS backend
docs/ # Engineering docs (e.g. backend architecture)
docker-compose.yml
package.json # pnpm workspace root
pnpm-workspace.yaml
turbo.json
Private / UNLICENSED unless otherwise stated in subpackages.