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>
48 lines
3.9 KiB
TypeScript
48 lines
3.9 KiB
TypeScript
// Crew rank hierarchy (org chart) — captured from Crewing.excalidraw and the
|
|
// tree in wiki Crewing-Data-Model §2. A self-referential tree like the Account
|
|
// accounting-code hierarchy: `parentCode = null` is the top of the org.
|
|
//
|
|
// grantsLogin = true → only PM, Assistant PM, Site In-charge (the three ranks
|
|
// that map to a SITE_STAFF portal login). Everyone else is
|
|
// a crew member / data subject with no account.
|
|
// isSeafarer = true → the dredging/engine/deck crew who hold seafarer documents
|
|
// (STCW/CDC/COC/medical). Management & shore-support do not.
|
|
// category → OPERATIONAL vs SUPPORT (the classDef "sup" nodes).
|
|
|
|
import type { RankCategory } from "@prisma/client";
|
|
|
|
export type RankEntry = {
|
|
code: string;
|
|
name: string;
|
|
parentCode: string | null;
|
|
category: RankCategory;
|
|
isSeafarer: boolean;
|
|
grantsLogin: boolean;
|
|
};
|
|
|
|
export const RANKS: RankEntry[] = [
|
|
// ── Management (portal logins) ──────────────────────────────────────────────
|
|
{ code: "PM", name: "PM", parentCode: null, category: "OPERATIONAL", isSeafarer: false, grantsLogin: true },
|
|
{ code: "APM", name: "Assistant PM", parentCode: "PM", category: "OPERATIONAL", isSeafarer: false, grantsLogin: true },
|
|
{ code: "SIC", name: "Site In-charge", parentCode: "APM", category: "OPERATIONAL", isSeafarer: false, grantsLogin: true },
|
|
|
|
// ── Shore support (no login, no seafarer docs) ──────────────────────────────
|
|
{ code: "ACC", name: "Accountant", parentCode: "APM", category: "SUPPORT", isSeafarer: false, grantsLogin: false },
|
|
{ code: "DRV", name: "Driver", parentCode: "APM", category: "SUPPORT", isSeafarer: false, grantsLogin: false },
|
|
{ code: "COOK", name: "Cook", parentCode: "APM", category: "SUPPORT", isSeafarer: false, grantsLogin: false },
|
|
{ code: "CKH", name: "Cook Helper", parentCode: "COOK", category: "SUPPORT", isSeafarer: false, grantsLogin: false },
|
|
|
|
// ── Operational crew (seafarers) ────────────────────────────────────────────
|
|
{ code: "DIC", name: "Dredger In-charge", parentCode: "SIC", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "SDO", name: "Sr. Dredge Operator", parentCode: "DIC", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "PLS", name: "Pipeline Supervisor", parentCode: "SDO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "PLA", name: "Pipeline Assistant", parentCode: "PLS", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "JDO", name: "Jr. Dredge Operator", parentCode: "SDO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "ERO", name: "Engine Room Operator", parentCode: "JDO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "DH", name: "Deck Hand", parentCode: "ERO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "TR", name: "Trainee", parentCode: "DH", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "MB", name: "Mess Boy", parentCode: "DH", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "ELE", name: "Electrician", parentCode: "SDO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "SFB", name: "Sr. Fabricator", parentCode: "SDO", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
{ code: "FW", name: "Fabricator / Welder", parentCode: "SFB", category: "OPERATIONAL", isSeafarer: true, grantsLogin: false },
|
|
];
|