Handover workspace

ERS, Todo, OfferReview, and Docu in one view

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

Apr 3, 2026, 12:38 PM

OfferReview

W6 Setup & Deployment Guide

Before W6 can run, you must apply the Prisma migration:

W6-SETUP-GUIDE.md

Updated Feb 19, 2026, 6:59 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.

W6 Setup & Deployment Guide

Prerequisites

1. Database Migration

Before W6 can run, you must apply the Prisma migration:

cd /Users/rezafahmi/projectweb-nextjs

# Ensure PostgreSQL is running
# Then run:
export $(cat .env.local | xargs)
npx prisma migrate dev --name add_candidates_and_documents

# This creates:
# - candidate table
# - candidate_document table
# - Indexes on candidateCode, status, createdByUserId, etc.

2. Install AWS SDK (if not already installed)

cd /Users/rezafahmi/projectweb-nextjs
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner

3. Environment Variables

Add to .env.local:

# S3 Configuration
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
S3_BUCKET_NAME=offers-review

# Optional: For S3-compatible services (MinIO, LocalStack)
# S3_ENDPOINT=http://localhost:9000

For local development with MinIO:

# Install MinIO or use Docker:
docker run -p 9000:9000 minio/minio:latest

# Set in .env.local:
S3_ENDPOINT=http://localhost:9000

Files Created

API Endpoints

  • src/app/api/uploads/presign/route.ts – Presign upload URL
  • src/app/api/candidates/route.ts – Create candidate + resume

UI Components

  • src/app/(app)/upload-resume/page.tsx – Main form (380 lines)
  • src/app/(app)/upload-resume/_components/Dropzone.tsx – Drag-drop component
  • src/app/(app)/layout.tsx – Group layout wrapper

Libraries

  • src/lib/storage/s3.ts – S3 presign helper
  • src/lib/candidates/code.ts – Candidate code generator
  • src/lib/validation/schemas.ts – Updated with upload/candidate schemas

Database

  • prisma/schema.prisma – Added Candidate + CandidateDocument models
  • prisma/migrations/add_candidates_and_documents/migration.sql – Migration SQL

Documentation

  • docs/W6-UPLOAD-RESUME-IMPLEMENTATION.md – Full specification
  • docs/W6-IMPLEMENTATION-SUMMARY.md – Implementation overview

Testing

1. Check Database Migration

# Log into PostgreSQL
psql projectweb -U postgres

# Verify tables exist:
\dt candidate*

# Output should show:
# public | candidate             | table | postgres
# public | candidate_document    | table | postgres

2. Test in Browser

  1. Start dev server: npm run dev
  2. Login as HR user at http://localhost:3000/login
  3. Navigate to http://localhost:3000/upload-resume
  4. Test upload flow:
    • Select position (required dropdown)
    • Enter name (optional)
    • Drag-drop PDF resume
    • Click "Upload & Create Candidate"
    • Verify redirect to /candidates/{id} after success

3. Verify Database

# Connect to PostgreSQL
psql projectweb -U postgres

# Check candidate created
SELECT id, candidateCode, applyingFor, status FROM candidate ORDER BY createdAt DESC LIMIT 1;

# Check resume document
SELECT id, candidateId, category, filename FROM candidate_document ORDER BY createdAt DESC LIMIT 1;

# Check audit logs
SELECT eventType, details FROM audit_log WHERE eventType IN ('CANDIDATE_CREATED', 'RESUME_UPLOADED') ORDER BY createdAt DESC LIMIT 2;

4. Test RBAC

# As MANAGER user, try to access:
# GET /upload-resume → Should redirect (implement middleware)
# POST /api/uploads/presign → 403 Forbidden
# POST /api/candidates → 403 Forbidden

Integration Checklist

  • Database migration applied (prisma migrate dev)
  • AWS SDK installed (npm install @aws-sdk/...)
  • AWS credentials in .env.local
  • Dev server running (npm run dev)
  • Login as HR user
  • Upload PDF successfully
  • Redirect to candidate page
  • Check database for candidate + document records
  • Check audit logs for events
  • Test file validation (invalid type, size >10MB)
  • Test RBAC (403 as MANAGER/SMO)
  • Verify S3 upload (file exists in bucket)

Common Issues & Fixes

Issue: "DATABASE_URL not found"

Fix: Ensure .env.local exists with DATABASE_URL

cat .env.local | grep DATABASE_URL

Issue: "Cannot find module @aws-sdk/..."

Fix: Install AWS SDK

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner

Issue: S3 presign returns 403

Fix: Check AWS credentials in .env.local

echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY

Issue: Redirect not working (stuck on /upload-resume)

Fix: Check that /candidates/{id} page exists (W7 shell)

  • Create simple page at src/app/candidates/[id]/page.tsx if needed

Issue: "Candidate created but can't find on page"

Fix: Verify candidate record actually exists

SELECT * FROM candidate ORDER BY createdAt DESC LIMIT 1;

Deployment to Production

  1. Apply migrations:

    npx prisma migrate deploy
    
  2. Set production environment variables:

    AWS_REGION=us-east-1
    AWS_ACCESS_KEY_ID=prod-key
    AWS_SECRET_ACCESS_KEY=prod-secret
    S3_BUCKET_NAME=offers-review-prod
    
  3. Build and start:

    npm run build
    npm run start
    
  4. Test end-to-end:

    • HR uploads resume
    • Candidate created
    • Redirect works
    • Audit logged
    • File in S3

Related Wireframes

  • W5 (Dashboard) – Shows candidates (future integration)
  • W7 (Candidate Intake) – Where W6 redirects to
  • W3 (Access Requests) – Same RBAC pattern (HR/Admin only)

Support

For issues or questions:

  1. Check error messages in browser console
  2. Review server logs: npm run dev output
  3. Verify database connection: psql projectweb
  4. Test API directly: curl -X POST http://localhost:3000/api/candidates

W6 is ready for deployment!