Final slice of Phase 5. The appraisal lifecycle raise → verify → approve across three role-gated surfaces, per Crewing-Implementation-Spec §5.4/§8.14. Stacks on 5a verification. Behind NEXT_PUBLIC_CREWING_ENABLED. Completes Phase 5. What's in - Schema: Appraisal (on CrewAssignment) + AppraisalStatus (DRAFT/SUBMITTED/MPO_VERIFIED/MANAGER_APPROVED/REJECTED); CrewActionType += APPRAISAL_SUBMITTED/VERIFIED/APPROVED/REJECTED. Migration crewing_appraisal. - State machine lib/appraisal-state-machine.ts: verify (SUBMITTED→MPO_VERIFIED, MPO/Manager), approve (MPO_VERIFIED→MANAGER_APPROVED, Manager); orthogonal reject. - Actions (crewing/appraisals/actions.ts): raiseAppraisal (raise_appraisal — PM/ site staff), verifyAppraisal (verify_appraisal — MPO), approveAppraisal (approve_appraisal — Manager); reject paths require remarks; notifications APPRAISAL_FOR_VERIFICATION / APPRAISAL_FOR_APPROVAL. - Three surfaces (§8.14): PM raises + tracks status on the crew-profile Appraisals tab; MPO verifies in the Verification queue (Appraisals section); Manager approves in the central /approvals queue (Appraisal kind). Tests & docs - Unit: appraisal-state-machine.test.ts (4). Integration: appraisal.test.ts (4) — raise→verify→approve happy path, MPO reject, permission gating (MPO can't raise, site staff can't verify, MPO can't approve). type-check clean; full unit (245) + integration (205) green (verified with RESEND_API_KEY unset). - CLAUDE.md updated — completes Phase 5 (I + H). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
1.3 KiB
SQL
36 lines
1.3 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "AppraisalStatus" AS ENUM ('DRAFT', 'SUBMITTED', 'MPO_VERIFIED', 'MANAGER_APPROVED', 'REJECTED');
|
|
|
|
-- AlterEnum
|
|
-- This migration adds more than one value to an enum.
|
|
-- With PostgreSQL versions 11 and earlier, this is not possible
|
|
-- in a single migration. This can be worked around by creating
|
|
-- multiple migrations, each migration adding only one value to
|
|
-- the enum.
|
|
|
|
|
|
ALTER TYPE "CrewActionType" ADD VALUE 'APPRAISAL_SUBMITTED';
|
|
ALTER TYPE "CrewActionType" ADD VALUE 'APPRAISAL_VERIFIED';
|
|
ALTER TYPE "CrewActionType" ADD VALUE 'APPRAISAL_APPROVED';
|
|
ALTER TYPE "CrewActionType" ADD VALUE 'APPRAISAL_REJECTED';
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Appraisal" (
|
|
"id" TEXT NOT NULL,
|
|
"assignmentId" TEXT NOT NULL,
|
|
"period" TEXT NOT NULL,
|
|
"ratings" JSONB,
|
|
"comments" TEXT,
|
|
"status" "AppraisalStatus" NOT NULL DEFAULT 'SUBMITTED',
|
|
"rejectedReason" TEXT,
|
|
"addedById" TEXT NOT NULL,
|
|
"verifiedById" TEXT,
|
|
"approvedById" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Appraisal_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Appraisal" ADD CONSTRAINT "Appraisal_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "CrewAssignment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|