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

ERS

Offer Letter and Renewal System

Offer Letter and Renewal System is an internal offer-letter approval and renewal workflow system built with Next.js App Router + Prisma + Postgres.

README.md

Updated May 5, 2026, 9:14 AM

Offer Letter and Renewal System

Offer Letter and Renewal System is an internal offer-letter approval and renewal workflow system built with Next.js App Router + Prisma + Postgres.

Specs

  • docs/specs/ERS-v0.1-spec.md
  • docs/specs/ERS-v0.2-build-pack.md
  • docs/specs/ERS-v0.3-runnable-pack.md
  • docs/USER-MANUAL.md

Stack

  • Next.js (App Router, TypeScript)
  • Prisma + PostgreSQL
  • Local filesystem uploads (UPLOAD_BASE_DIR)
  • JWT cookie auth (email + password)
  • Resend-backed durable email outbox
  • PDF signature stamping with pdf-lib

Environment

Copy .env.example to .env and set values:

  • DATABASE_URL
  • AUTH_JWT_SECRET
  • AUTH_COOKIE_NAME
  • UPLOAD_BASE_DIR
  • UPLOAD_MAX_MB
  • NEXT_PUBLIC_APP_VERSION
  • RESEND_API_KEY
  • EMAIL_FROM
  • OPENAI_API_KEY (optional, for smarter offer-letter extraction)
  • OPENAI_MODEL (optional, default gpt-4.1-mini)
  • INTERNAL_API_SECRET

Install

npm install
npm run prisma:generate

Database Setup

npm run prisma:migrate
npm run db:seed

Run

npm run dev

Open http://localhost:3000.

Demo Users (from seed)

  • CEO: ceo@ers.local
  • HR: hr@ers.local
  • Manager: manager@ers.local
  • Password: Password123!

Core URLs

  • /login
  • /hr/renewals
  • /manager/requests
  • /ceo/renewals
  • /ceo/signature
  • /admin/settings
  • /admin/audit
  • /admin/users
  • /notifications

Supported Case Types

  • Renewal: requires offer letter, performance snapshot, and manager justification before CEO approval.
  • New Hire: requires offer letter only; manager justification and performance snapshot are not required.

Offer Letter Autofill

  • HR can upload an offer-letter PDF on /hr/renewals/new and click Extract & Prefill.
  • If OPENAI_API_KEY is configured, extraction uses OpenAI structured parsing with heuristic fallback.
  • Uploading OFFER_LETTER in a case detail also auto-maps extracted fields to RenewalCase.

Email Dispatch

Outbound emails are queued in EmailOutbox. Dispatch endpoint:

  • POST /api/internal/email/dispatch
  • Header: x-internal-secret: <INTERNAL_API_SECRET>

Recommended VPS cron (every minute):

* * * * * curl -X POST https://your-domain/api/internal/email/dispatch -H "x-internal-secret: your-secret"

Notes

  • HR/Manager cannot modify locked cases (locked_at set by CEO decision).
  • Renewal-case CEO approval requires latest offer letter, performance snapshot, and manager justification.
  • New-hire CEO approval requires latest offer letter only.
  • Signature stamping is enabled via /api/renewals/:id/sign-pdf with multi-placement payload.
  • Signing is allowed only when case status is APPROVED.
  • After signing, case status becomes SIGNED (closed/read-only) and HR users are notified via outbox email.