Handover workspace

ERS, Todo, OfferReview, and Docu in one view

Imported from live server docs, code structure, and deployment notes.

May 31, 2026, 11:17 AM

OfferReview

Project Context (OfferReview)

Last updated: 2026-04-26

docs/PROJECT_CONTEXT.md

Updated Apr 26, 2026, 9:22 AM

Codex 5.3 Refactor Note: Canonical refactor plan: docs/CODEX-5.3-REFACTOR-PLAN.md. This document is retained for historical and implementation context during the refactor.

Project Context (OfferReview)

Last updated: 2026-04-26

This file summarizes the current state, decisions, and operational notes so future Codex sessions can act quickly and safely. It now tracks both the committed baseline and the current local worktree state in prod.

What this project is

  • Next.js 16.1.4 app (App Router) called OfferReview (HR/manager workflow system).
  • Prisma ORM used for DB access.
  • App runs locally via npm run dev and in production via npm run build + next start (PM2 on VPS).

Key tech stack

  • Next.js 16.1.4
  • Prisma (6.x expected; avoid Prisma 7 unless config updated)
  • Node 20.x
  • DB: Postgres on VPS (current target). Local DB also Postgres.
  • Resend for email sending.

Repo layout on this machine

  • Primary working tree: /srv/apps/offerreview/prod
  • Sibling trees: /srv/apps/offerreview/prod_hotfix_manager, /srv/apps/offerreview/prod_deploy_smo_hotfix
  • Production deployment path: /var/www/offerreview
  • Default branch: main

Repo status / recent changes

  • Current prod HEAD on main: 4b9615c (feat: ground resume extraction and add evidence-based skills).
  • Recent history:
    • 0f793ba feat: expand SMO analytics and interview workflow
    • b70b127 feat: enrich employer context with web search
    • 951b112 feat: expand review workflow and resume insights
  • prod currently has local uncommitted changes across Prisma schema, candidate detail tabs, dashboard/settings, job-description analysis, candidate deep-dive flows, and manager-review access links.
  • prod_hotfix_manager also has local changes; prod_deploy_smo_hotfix is currently clean.
  • Future sessions should run git status --short before editing and treat this doc as the source of truth for the local workstream.

Active local workstream (2026-04-26)

  • Shipped recently:
    • resume extraction is now grounded to direct resume evidence and exposes evidence-based skills via src/lib/resumeSkills.ts and src/components/ResumeSkillsGrid.tsx
    • SMO compare analytics is live through src/app/api/analytics/smo-compare/route.ts and src/lib/analytics/smoCompare.ts
    • SMO interview questions are generated/cached through src/app/api/candidates/[id]/smo-questions/route.ts
  • Active local slice:
    • candidate deep-dive questionnaire flow with new Prisma models, public questionnaire token routes, an SMO-only review tab, and an SMO-owned deep-dive question bank
    • manager-review magic-link access with long-lived tokens sent on manager assignment
    • position/job-description analysis and a requirement that new candidate uploads target positions with an active job description
    • candidate detail expansion (Radar, Deep Dive, richer overview/header/tabs) plus supporting dashboard/settings/API cleanup
  • Candidate workflow currently represented in schema and code:
    • NEW -> HR_SCREENED -> MANAGER_EVAL_PENDING -> MANAGER_REVIEWED or CANDIDATE_DEEP_DIVE_PENDING -> TO_SMO -> APPROVED/REJECTED/KIV
  • AI evaluation prefill remains disabled end-to-end:
    • GET /api/candidates/[id]/evaluation-prefill returns a disabled status message
    • POST /api/candidates/[id]/evaluation-prefill returns 410
    • src/app/api/candidates/[id]/documents/route.ts no longer triggers evaluation analysis on upload
  • Role-flow audit is stored in docs/ROLE-FLOW-CHECK-2026-04-26.md.

Environment variables (critical)

Local .env.local (dev):

  • DATABASE_URL=postgresql://... (local Postgres)
  • JWT_SECRET=...
  • RESEND_API_KEY=...
  • RESEND_FROM_EMAIL=...
  • OPENAI_API_KEY=...
  • OPENAI_MODEL=... (optional, defaults to gpt-4o-mini)
  • APP_NAME=OfferReview (optional)

VPS .env (prod):

  • DATABASE_URL=postgresql://offerreview_user:***@localhost:5432/offerreview
  • JWT_SECRET=...
  • RESEND_API_KEY=...
  • RESEND_FROM_EMAIL=...

Notes:

  • Do NOT point local env to Hostinger MySQL. That caused login 500s.
  • On VPS, ensure .env exists and is loaded by PM2/systemd.

Database + Prisma

  • Provider should be postgresql in prisma/schema.prisma.
  • Migration folder exists: prisma/migrations/20250205_init/migration.sql.
  • If migrations missing on VPS, run: npx prisma migrate deploy.
  • If Prisma fails with missing DATABASE_URL, .env isn't loaded.

Postgres permissions on VPS

  • If you see permission denied for schema public, fix as postgres user:
    • ALTER DATABASE offerreview OWNER TO offerreview_user;
    • ALTER SCHEMA public OWNER TO offerreview_user;
    • GRANT ALL ON SCHEMA public TO offerreview_user;
    • ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO offerreview_user;

Deployment on VPS (current path)

  • VPS OS: Ubuntu (plain OS)
  • App folder: /var/www/offerreview
  • PM2 process name: offerreview

Typical flow:

  1. cd /var/www/offerreview
  2. git pull origin main
  3. Ensure .env is present
  4. npm install
  5. npx prisma generate
  6. npx prisma migrate deploy
  7. npm run build
  8. Restart PM2:
    • pm2 delete offerreview
    • export $(grep -v '^#' .env | xargs)
    • pm2 start npm --name offerreview -- start
    • pm2 save

PM2 logs (VPS)

  • pm2 logs offerreview --lines 50 --nostream
  • Files: /root/.pm2/logs/offerreview-out.log and ...-error.log

Common errors previously seen:

  • Environment variable not found: DATABASE_URL (PM2 not loading env)
  • Cannot find module @prisma/client-... (Prisma client not generated after build)

Nginx / Adminer (VPS)

  • Nginx reverse proxy to Node (port 3000).
  • Adminer installed for DB inspection.
  • If Adminer 404, ensure Nginx config includes:
    • location /adminer/ { alias /usr/share/adminer/; ... }
    • fastcgi_pass unix:/run/php/php8.3-fpm.sock; (note php8.3)
  • Access: http://<server-ip>/adminer/

Authentication + audit log

  • Audit log writes can fail if userId doesn't exist.
  • Recent fix: writeAuditEvent now allows null userId when it doesn't exist.

Resend (email)

  • API key and from email required.
  • Helper functions are in src/lib/notifications/email.ts.

OpenAI / document analysis

  • Resume analysis is active and updates CandidateDocument AI fields plus candidate snapshot fields.
  • SMO interview analysis is active.
  • Candidate deep-dive answer analysis is present in the worktree via src/lib/ai/deepDiveAnalysis.ts.
  • Evaluation document AI parsing code exists, but the user-facing prefill workflow is currently disabled. Do not assume evaluation uploads will auto-populate HR or manager review forms.

Known pitfalls

  • Prisma v7 errors about datasource url: stick to Prisma 6.x unless you migrate config.
  • Avoid Turbopack on low-resource servers (set NEXT_DISABLE_TURBOPACK=1).
  • If login returns 500 locally, check .env.local points to local Postgres.
  • Older docs may still mention AI evaluation prefill as if it is live. Current local truth is manual HR/Manager form completion plus a disabled prefill endpoint.
  • Current local manager access logic is assignment-based, not department-wide, in the actively edited candidate flows.
  • src/app/page.tsx is still the default starter page; actual product entry flows are /login and /dashboard.
  • Settings is linked in the global nav for all roles, but /api/settings and /api/settings/notification-rules are currently admin-only.
  • The manager dashboard currently includes unassigned HR_SCREENED cases even though candidate detail access remains assignment-locked.
  • HR can list users from /admin/users, but GET /api/users/[id] is currently restricted to Admin/SMO.
  • For reasoning-model OpenAI variants, use src/lib/ai/openaiTokenLimits.ts helpers instead of hardcoding temperature, max_tokens, or max_completion_tokens.

Quick local commands

  • Start dev: npm run dev
  • Build: npm run build
  • Prisma generate: npx prisma generate
  • Migrate deploy: npx prisma migrate deploy
  • DB health check (Postgres): psql "$DATABASE_URL" -c "select 1;"