Phase 1 of the Crewing module per wiki Crewing-Implementation-Spec §12, all dark behind NEXT_PUBLIC_CREWING_ENABLED (off by default — production unchanged). - schema: add SITE_STAFF to Role; add Rank (self-referential org hierarchy, like Account) + RankDocRequirement, RankCategory & SeafarerDocType enums. - permissions: full §6 crewing grant matrix (PO_ROLE_PERMISSIONS + CREWING_ROLE_PERMISSIONS merged); SITE_STAFF row; MPO has no attendance/leave, approvals are Manager-only, manage_ranks is Manager+Admin. - feature flag: CREWING_ENABLED (opt-in "true"). - nav: flag-gated Crewing section scaffold + "Ranks & documents" under Admin. - reference data: rank-data.ts + rank-doc-data.ts seeded via shared seed-ranks.ts in both dev and prod seeds (19 ranks, 118 doc requirements). - screen: /admin/ranks — rank hierarchy card + per-rank required-documents card. - role-label/prefix maps updated for the new role. Tests: unit (permission matrix + flag), integration (ranks admin CRUD, parent linking, cycle/children guards, doc-requirement upsert/remove, permission gating). Docs: CLAUDE.md "Crewing (feature-flagged)" section + env var. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
49 lines
1.7 KiB
SQL
49 lines
1.7 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "RankCategory" AS ENUM ('OPERATIONAL', 'SUPPORT');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "SeafarerDocType" AS ENUM ('STCW', 'AADHAAR', 'PAN', 'PASSPORT', 'CDC', 'COC', 'PHOTOGRAPH', 'DRIVING_LICENSE', 'MEDICAL_FITNESS', 'CONTRACT_LETTER');
|
|
|
|
-- AlterEnum
|
|
ALTER TYPE "Role" ADD VALUE 'SITE_STAFF';
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Rank" (
|
|
"id" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"category" "RankCategory" NOT NULL DEFAULT 'OPERATIONAL',
|
|
"isSeafarer" BOOLEAN NOT NULL DEFAULT false,
|
|
"grantsLogin" BOOLEAN NOT NULL DEFAULT false,
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
"parentId" TEXT,
|
|
|
|
CONSTRAINT "Rank_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "RankDocRequirement" (
|
|
"id" TEXT NOT NULL,
|
|
"rankId" TEXT NOT NULL,
|
|
"docType" "SeafarerDocType" NOT NULL,
|
|
"isMandatory" BOOLEAN NOT NULL DEFAULT true,
|
|
"note" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "RankDocRequirement_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Rank_code_key" ON "Rank"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "RankDocRequirement_rankId_docType_key" ON "RankDocRequirement"("rankId", "docType");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Rank" ADD CONSTRAINT "Rank_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Rank"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RankDocRequirement" ADD CONSTRAINT "RankDocRequirement_rankId_fkey" FOREIGN KEY ("rankId") REFERENCES "Rank"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|