First slice of Phase 4 (stacked on 3c onboarding). The Crew directory and tabbed
crew profile with documents, bank/EPF (role-masked), next of kin, PPE and
experience, per Crewing-Implementation-Spec §8.7–8.8. Behind
NEXT_PUBLIC_CREWING_ENABLED; production unchanged.
What's in
- Schema (crewing_crew_records migration): SeafarerDocument, NextOfKin
(isEmergency), ExperienceRecord, PpeIssue (PpeItem enum) — all on CrewMember;
CrewActionType += DOCUMENT_UPLOADED/RECORD_UPDATED/PPE_ISSUED/PPE_RETURNED/
EXPERIENCE_ADDED.
- PII masking (lib/crew-pii.ts, §6/§8.8): bank account + Aadhaar full only for
Accounts/SuperUser, masked otherwise; salary hidden from site staff. Applied
server-side before crossing to the client.
- Actions (crewing/crew/actions.ts): uploadDocument/deleteDocument, saveBankEpf,
addNextOfKin/deleteNextOfKin, issuePpe/returnPpe, addExperience — guarded by
upload_crew_records / issue_ppe, each writes a CrewAction.
- Screens: /crewing/crew (directory, search + vessel filter, ex-hands excluded)
and /crewing/crew/[id] (tabbed profile: Documents · Bank & EPF · Next of kin ·
PPE · Experience · Pay status). Crew added to the flag-gated nav (MGR/MPO/Site/
Accounts).
Tests & docs
- Unit: crew-pii.test.ts (6). Integration: crew-records.test.ts (7) — documents,
bank/EPF upsert, NoK, PPE issue/return, experience + permission gating.
type-check clean; full unit (240) + integration (175) green.
- CLAUDE.md updated with the Phase 4a surface.
Deferred: site-staff own-site scoping (needs a User↔Site link); the records verify
queue (§8.11, Phase 5); Pay-status shows the salary structure only until payroll
(Phase 6).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First slice of Phase 3 (Epics B/C/D shipped as stacked sub-PRs). Adds the
CrewMember talent-pool spine and the Candidates screens. Behind
NEXT_PUBLIC_CREWING_ENABLED; production unchanged. Stacks on the requisitions
branch (Phase 2).
What's in
- Schema (crewing_candidates migration): CrewMember (spine) + CrewStatus,
CandidateType, CandidateSource enums; CrewAction gains a nullable crewMemberId;
CrewActionType += CANDIDATE_ADDED/UPDATED. employeeId is assigned at onboarding
(3c), so it's nullable here.
- Actions (crewing/candidates/actions.ts): addCandidate / updateCandidate —
guard flag + manage_candidates, write a CrewAction, optional CV upload via
buildStorageKey("cv", …) + uploadBuffer (no parsing — A2 deferred). EX_HAND
source ⇒ type/status EX_HAND; edits never downgrade an EMPLOYEE.
- Screens: /crewing/candidates (master list with search/source/rank-applied/
min-experience filters as removable chips + match count + Clear all; Add-candidate
modal) and /crewing/candidates/[id] (profile; pipeline stepper is 3b). Candidates
added to the flag-gated Crewing nav (Manager + MPO).
Tests & docs
- Integration: candidates.test.ts (7) — add/update, ex-hand derivation, employee
no-downgrade, permission gating. type-check clean; full unit (225) + integration
(153) suites green.
- CLAUDE.md "Crewing" section updated with the Phase 3a surface.
Deferred: public careers intake API (A2, §13 open question); CV parsing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Second slice of the Crewing module per wiki Crewing-Implementation-Spec §12
(build order item 2). Everything stays behind NEXT_PUBLIC_CREWING_ENABLED;
production is unchanged. Schema is added incrementally — this lands the
requisition lifecycle layer.
What's in
- Schema: Requisition (OPEN→SHORTLISTING→PROPOSING→INTERVIEWING→SELECTED→FILLED,
→CANCELLED), ReliefRequest, CrewAction (the POAction mirror) + their enums.
Migration crewing_requisitions.
- State machine: lib/requisition-state-machine.ts mirrors po-state-machine
(selection Manager-only; orthogonal cancel from OPEN/SHORTLISTING by
cancel_requisition holders, §6). Codes REQ-9000… via lib/requisition-number.ts.
- Actions: raise/cancel/transition + requestReliefCover/convertReliefToRequisition,
each guarding flag+permission+state, writing a CrewAction and notifying. Shared
autoRaiseRequisition() (lib/requisition-service.ts) is the backfill entry point
for sign-off / leave-clash (later phases).
- Notifier: notifyCrew() PO-independent path + CrewNotificationEvent.
- Screens: /crewing/requisitions (list + Raise modal + relief convert) and
/crewing/requisitions/[id] (detail). Requisitions added to the flag-gated
Crewing sidebar (Manager + MPO, §7).
Tests & docs
- Unit: requisition-state-machine.test.ts (11).
- Integration: requisitions.test.ts (15) — raise/cancel/transition, relief
request + convert, auto-raise, permission gating.
- CLAUDE.md "Crewing" section updated with the Phase 2 surface.
Deferred: sign-off/experience (Epic K, §12 item 2) depends on the crew/assignment
models from Phase 3/4; autoRaiseRequisition() is ready for it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>