pelagia-portal/App/prisma/rank-doc-data.ts
Hardik d0006a8fc7
All checks were successful
PR checks / checks (pull_request) Successful in 36s
PR checks / integration (pull_request) Successful in 28s
feat(crewing): foundations — SITE_STAFF role, ranks reference data + admin (flagged)
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>
2026-06-22 13:26:04 +05:30

42 lines
1.6 KiB
TypeScript

// Default required-document set per rank, derived from the rank flags in
// rank-data.ts. Drives candidate vetting and crew uploads (RankDocRequirement).
// - Every crew member: Aadhaar, PAN, photograph.
// - Seafarers additionally: STCW, CDC, passport, medical fitness (mandatory);
// COC is conditional (officer/senior ranks only).
// - Driver: driving licence (mandatory).
// Editable afterwards at /admin/ranks; this is just the seeded baseline.
import type { SeafarerDocType } from "@prisma/client";
import { RANKS } from "./rank-data";
export type RankDocReq = {
rankCode: string;
docType: SeafarerDocType;
isMandatory: boolean;
note?: string;
};
const COMMON: { docType: SeafarerDocType; isMandatory: boolean }[] = [
{ docType: "AADHAAR", isMandatory: true },
{ docType: "PAN", isMandatory: true },
{ docType: "PHOTOGRAPH", isMandatory: true },
];
const SEAFARER: { docType: SeafarerDocType; isMandatory: boolean; note?: string }[] = [
{ docType: "STCW", isMandatory: true },
{ docType: "CDC", isMandatory: true },
{ docType: "PASSPORT", isMandatory: true },
{ docType: "MEDICAL_FITNESS", isMandatory: true },
{ docType: "COC", isMandatory: false, note: "Officer / senior ranks only" },
];
export const RANK_DOC_REQUIREMENTS: RankDocReq[] = RANKS.flatMap((rank) => {
const reqs: RankDocReq[] = COMMON.map((c) => ({ rankCode: rank.code, ...c }));
if (rank.isSeafarer) {
reqs.push(...SEAFARER.map((s) => ({ rankCode: rank.code, ...s })));
}
if (rank.code === "DRV") {
reqs.push({ rankCode: "DRV", docType: "DRIVING_LICENSE", isMandatory: true });
}
return reqs;
});