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

W9 Quick Reference Card

npx prisma migrate dev --name add_evaluation_templates

W9-REFERENCE.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.

W9 Quick Reference Card

πŸš€ Deploy in 3 Steps

# 1. Migrate database
npx prisma migrate dev --name add_evaluation_templates

# 2. Start server
npm run dev

# 3. Open browser
http://localhost:3000/admin/templates

πŸ“‹ All Files Created/Modified

FileTypeLinesPurpose
prisma/schema.prismaSchema50EvaluationTemplate + fields
src/lib/validation/templates.tsValidation15011 Zod schemas
src/app/api/templates/route.tsAPI118GET, POST
src/app/api/templates/[id]/route.tsAPI142GET, PUT
src/app/api/templates/[id]/publish/route.tsAPI147POST publish
src/app/api/templates/[id]/archive/route.tsAPI99POST archive
src/app/api/templates/[id]/duplicate/route.tsAPI128POST duplicate
src/app/(app)/admin/templates/page.tsxUI400Main page
src/app/(app)/admin/templates/_components/TemplatesTable.tsxUI350List view
src/app/(app)/admin/templates/_components/TemplateBuilder.tsxUI600Editor
docs/W9-IMPLEMENTATION.mdDoc950Full spec + tests
docs/W9-FILES.mdDoc-File summary

Total: 11 files, ~3,100 lines


🎯 Core Concepts

Status Machine

DRAFT ──publish──> PUBLISHED ──archive──> ARCHIVED
 ↑                     ↑
 └─── edit via PUT ─────┴─── copy via duplicate ───────┐
                                                        ↓
                                                   DRAFT (new v)

Versioning

  • v1: Original template
  • v2: Result of publishing edited published template
  • v3+: Continues incrementing

Immutability

  • DRAFT: Editable (PUT allowed)
  • PUBLISHED: Read-only (no PUT, must duplicate)
  • ARCHIVED: No operations

πŸ”Œ API Endpoints (7 Total)

GET    /api/templates              List all (filters: q, status, position)
POST   /api/templates              Create draft v1
GET    /api/templates/:id          Fetch one
PUT    /api/templates/:id          Update draft (DRAFT only)
POST   /api/templates/:id/publish  Publish (DRAFT→PUBLISHED or create new version)
POST   /api/templates/:id/archive  Archive (PUBLISHED→ARCHIVED only)
POST   /api/templates/:id/duplicate Duplicate as draft v1

πŸ“Š Request/Response Examples

Create Template

curl -X POST http://localhost:3000/api/templates \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Senior Engineer - HR",
    "appliesToPosition": "Senior Software Engineer",
    "enableQuickScreen": false,
    "schemaJson": {
      "stages": [{
        "stage": "HR_SCREENING",
        "enabled": true,
        "categories": [{
          "id": "cat-1",
          "name": "Technical Fit",
          "questions": [{
            "id": "q-1",
            "text": "Does candidate have relevant background?",
            "type": "rating_1_5",
            "required": true,
            "order": 0
          }],
          "order": 0
        }]
      }],
      "scoringScale": {"min": 1, "max": 5}
    },
    "quickQuestionIds": []
  }'

List with Filters

curl 'http://localhost:3000/api/templates?q=senior&status=PUBLISHED&position=Engineer'

Publish

curl -X POST http://localhost:3000/api/templates/{id}/publish

Archive

curl -X POST http://localhost:3000/api/templates/{id}/archive

Duplicate

curl -X POST http://localhost:3000/api/templates/{id}/duplicate \
  -H "Content-Type: application/json" \
  -d '{"name": "Senior Engineer - HR (Copy)"}'

βœ… Validation Rules

Template Creation

  • βœ“ Name: 3-200 characters
  • βœ“ Position: Required, 1-200 characters
  • βœ“ At least 1 stage enabled
  • βœ“ Each enabled stage has β‰₯3 questions total
  • βœ“ All categories have β‰₯1 question

Before Publishing

  • βœ“ All validation rules above
  • βœ“ schemaJson valid structure
  • βœ“ No empty categories

πŸ§ͺ Quick Test (5 min)

  1. Login as ADMIN
  2. Navigate to /admin/templates
  3. Click "New Template"
  4. Enter name: "Test"
  5. Enter position: "Engineer"
  6. Click "+ Add Category" (on HR_SCREENING)
  7. Enter category name: "Technical"
  8. Click "+ Add Question" (3 times)
  9. Fill each question with dummy text
  10. Click "Save Draft"
  11. Verify success message
  12. Return to list, verify DRAFT badge

πŸ” RBAC

Admin Only: All operations

  • βœ… List, Create, Read, Update, Publish, Archive, Duplicate

HR: (Future - not in W9)

  • ❌ Cannot access template management

SMO: (Future - not in W9)

  • ❌ Cannot access template management

πŸ“ Audit Events

EventWhenMetadata
TEMPLATE_CREATEDPOST createtemplateId, name, version, status
TEMPLATE_DRAFT_UPDATEDPUT updatetemplateId, name, version
TEMPLATE_PUBLISHEDPOST publishtemplateId, name, version, status
TEMPLATE_ARCHIVEDPOST archivetemplateId, name, version, status
TEMPLATE_DUPLICATEDPOST duplicatetemplateId, name, sourceName, version

πŸ› οΈ Question Types

TypeChoicesCommentUse Case
rating_1_51-5 buttonsIf ≀2Scoring
yes_noYes/NoNoPass/fail
short_textText inputNoQuick notes
long_textTextareaNoFeedback

πŸ—‚οΈ File Locations

Database: prisma/schema.prisma
Validation: src/lib/validation/templates.ts
API: src/app/api/templates/**
UI: src/app/(app)/admin/templates/**
Docs: docs/W9-*.md + W9-*.md


πŸ“– Documentation Map

DocumentRead TimeBest For
W9-DELIVERY.md5 minOverview (you are here)
W9-QUICK-START.md10 minGetting started + API ref
W9-VISUAL-SUMMARY.md15 minDiagrams + examples
W9-IMPLEMENTATION.md30 minFull spec + 13 tests
W9-FILES.md20 minCode walkthrough
W9-INDEX.md5 minNavigation

🚨 Common Issues & Fixes

Issue: 403 Forbidden on API

Fix: Ensure logged in as ADMIN user

Issue: Validation always fails

Fix: Each enabled stage must have β‰₯3 questions TOTAL (not per category)

Issue: Cannot edit published template

Fix: This is expected! Duplicate it instead, then edit the draft copy.

Issue: Database migration fails

Fix: Ensure PostgreSQL running and DATABASE_URL set correctly


⚑ Keyboard Shortcuts (UI)

ActionKey
Focus name inputAlt+N
Focus position inputAlt+P
Expand categoryClick chevron
Delete questionHover + click trash
Save draftCtrl+S

(Most browser defaults work)


πŸ“Š Database Schema Snippet

enum TemplateStatus {
  DRAFT
  PUBLISHED
  ARCHIVED
}

model EvaluationTemplate {
  id                  String          @id @default(cuid())
  name                String
  appliesToPosition   String
  version             Int             @default(1)
  status              TemplateStatus  @default(DRAFT)
  schemaJson          String          @db.Text
  enableQuickScreen   Boolean         @default(false)
  quickQuestionIds    String          @default("[]") @db.Text
  createdByUserId     String
  createdByUser       User?           @relation("TemplateCreatedBy", ...)
  publishedAt         DateTime?
  archivedAt          DateTime?
  createdAt           DateTime        @default(now())
  updatedAt           DateTime        @updatedAt
  
  @@index([status])
  @@index([appliesToPosition])
  @@index([publishedAt])
  @@index([createdByUserId])
  @@index([createdAt])
}

πŸŽ“ Design Principles

  1. Immutability: Published templates cannot be edited (prevents accidents)
  2. Versioning: Each publish increments version; all versions preserved
  3. Separation of Concerns: Validation separated from persistence
  4. RBAC First: Admin-only, checked at API level
  5. Audit Everything: All changes logged with metadata
  6. Backward Compatible: W7/W8 work with null templateId

✨ Next Steps

  1. βœ… Review this card
  2. βœ… Run migration: npx prisma migrate dev --name add_evaluation_templates
  3. βœ… Start server: npm run dev
  4. βœ… Visit: http://localhost:3000/admin/templates
  5. βœ… Create sample template (5 min)
  6. βœ… Run test checklist (2 hours)
  7. βœ… Deploy to staging/prod

πŸ“ž Support


Status: βœ… Complete | Date: Jan 23, 2026 | Lines: ~3,100 | Files: 11 | Tests: 13