Node 20+, pnpm 10+, and a PostgreSQL database.
pnpm install # postinstall runs `prisma generate`
cp .env.exemple .env.local
# fill in DATABASE_URL and AUTH_SECRET (npx auth secret)
pnpm db:migrate
pnpm db:seed
pnpm dev # http://localhost:3000src/lib/env.ts validates everything with Zod at boot and derives a features object.
Only two variables are required; every integration is optional and its absence degrades to
a labelled "not configured" state rather than a crash.
| Variable | Required | Without it |
|---|---|---|
DATABASE_URL |
yes | The app cannot start |
DIRECT_URL |
no | Only needed for Prisma Migrate behind a connection pooler (e.g. Neon) |
AUTH_SECRET |
for real auth | Sessions cannot be signed |
AUTH_GITHUB_ID / AUTH_GITHUB_SECRET |
no | The GitHub button is not rendered |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET |
no | The Google button is not rendered |
SECRET_STRIPE_KEY |
no | Checkout surfaces say billing is not configured |
STRIPE_WEBHOOK_SECRET |
no | The webhook returns 503 |
UPLOADTHING_TOKEN |
no | Upload controls are disabled with an explanation |
ARCJET_KEY |
no | Rate limiting falls back to an in-process counter |
RESEND_API_KEY |
no | Emails are logged instead of sent |
CRON_SECRET |
in production | /api/cron/maintenance refuses to run |
DEV_AUTH_BYPASS |
never in production | See below |
This project's development database points at a hireek schema so the legacy MVP tables in
public were left untouched:
DATABASE_URL="postgresql://…/db?sslmode=require&schema=hireek"
DIRECT_URL="postgresql://…/db?sslmode=require&schema=hireek" # non-pooled host
Drop &schema=hireek to use public.
DEV_AUTH_BYPASS=1 makes getCurrentUser() resolve to a seeded persona so every page in
the product can be reached and reviewed without an OAuth round-trip. It exists for exactly
that, and it is fenced in three ways:
- It cannot turn itself on in production.
devAuthBypassEnabledinsrc/lib/env.tsis!isProduction && env.DEV_AUTH_BYPASS === "1".NODE_ENVis baked in at build time, so a production bundle cannot take the branch regardless of what is in the environment. - It is impossible to miss. While active, a persistent amber bar sits above every workspace screen saying the bypass is on and naming the persona.
- It is verified off by the test suite.
e2e/auth-protection.spec.tsasserts the bar is absent and that every protected route rejects a signed-out visitor. The Playwright config forcesDEV_AUTH_BYPASS=0for its server regardless of.env.local.
Switch personas with the dropdown in the amber bar, or set DEV_AUTH_USER_EMAIL.
To turn it off: delete the DEV_AUTH_BYPASS line from .env.local and restart.
| Script | Does |
|---|---|
pnpm dev |
Next dev server with Turbopack |
pnpm build / pnpm start |
Production build and server |
pnpm typecheck |
tsc --noEmit |
pnpm lint / pnpm lint:fix |
ESLint |
pnpm format / pnpm format:check |
Prettier |
pnpm test / pnpm test:watch / pnpm test:coverage |
Vitest |
pnpm test:e2e / pnpm test:e2e:ui |
Playwright |
pnpm verify |
typecheck → lint → design tokens → test → build |
pnpm db:migrate |
Create and apply a migration |
pnpm db:deploy |
Apply migrations (production) |
pnpm db:push |
Push the schema without a migration |
pnpm db:reset |
Drop, re-migrate and re-seed |
pnpm db:seed |
Seed demo data |
pnpm db:studio |
Prisma Studio |
The db:* scripts load .env.local through dotenv-cli, because the Prisma CLI reads
.env and Next reads .env.local.
Password for every account: hireek-demo-2026.
| Account | Role |
|---|---|
ada@hireek.dev |
Talent — applications, proposals, saved items, messages; also a member of one org |
mateo@hireek.dev |
Talent with a Talent Pro subscription |
marta@northwind.dev |
Organization OWNER |
dev@northwind.dev |
RECRUITER |
bella@northwind.dev |
HIRING_MANAGER |
amara@fathom.dev |
BILLING — useful for checking that role boundaries hold |
iris@meridian.dev |
OWNER of the org with the completed contract |
admin@hireek.dev |
Platform ADMIN |
moderator@hireek.dev |
Platform MODERATOR |
Organizations: northwind-labs, cadence-health, meridian-studio,
fathom-analytics-group, olga-and-co, baseline-robotics.
The seed is deterministic — a fixed PRNG seed means re-seeding produces an identical database, so screenshots and tests stay stable.
curl -X POST https://your-host/api/cron/maintenance \
-H "Authorization: Bearer $CRON_SECRET"Expires listings, lapses invitations and proposals, and grants monthly proposal credits. Run it hourly. It is idempotent.
- Server Components by default;
"use client"pushed as far down as possible. - Reads in
src/server/queries/<area>.ts, mutations insrc/server/actions/<area>.ts. - Never hand-write a label for a database enum — import it from
@/lib/enums. - Money is minor units everywhere; format with
formatMoney. - Tokens only in class names. No raw Tailwind palette colours.
paramsandsearchParamsare Promises in Next 15.