docs(crewing): add reconciled Implementation Spec; link under Planned
Reconcile the Crewing wiki design pages with the design handoff prototype,
using the Crewing CHANGELOG as tiebreaker, into one authoritative
Crewing-Implementation-Spec page: reconciliation decisions (R1-R11),
director Q&A folded in, how it slots into PPMS, codebase changes, the
final roles/permission + nav matrices, domain/state-machine deltas, a
detailed role-aware screen spec, modals, user-story reconciliations,
cross-cutting concerns, build order and open questions.
Key reconciled rulings: leave is Manager-approved (not MPO); interview
waiver is an explicit Manager-approved action (never auto for ex-hands);
only MPO/Manager raise requisitions (site staff request relief cover);
7-stage pipeline; MPO has no attendance access; effective-dated salary.
Add an authoritative-spec banner to each Crewing design page and link the
spec from the Module hub, Planned Features and the sidebar.
> **This page is the authoritative, reconciled build instruction set for the
> Crewing module.** It supersedes the other `Crewing-*` design pages wherever they
> differ. Those pages remain as design background; a banner on each points here.
>
> **Inputs reconciled:** the **design handoff** (`design_handoff_crewing/` — the
> hi-fi clickable prototype is the source of truth for UI, behaviour and copy),
> the **`Crewing-*` wiki design pages**, and the **Crewing CHANGELOG** (the
> tiebreaker). **Status:** design-complete proposal, not yet built; behind
> `NEXT_PUBLIC_CREWING_ENABLED`.
---
## 1. Reconciliation method
Where the wiki design pages and the handoff prototype disagree, the rule is:
1. Check the **Crewing CHANGELOG** (`design_handoff_crewing` change log).
2. If the point was an **intentional design change** recorded in the CHANGELOG →
**defer to the design** (prototype).
3. If it was **not** an intentional change (an oversight or omission in the
prototype) → **defer to the docs** (wiki).
4. Explicit **director answers** in [Design Doc § Open Questions](Crewing-Design-Document#7-open-questions) (Q1–Q7) are authoritative and folded in below.
### 1.1 Reconciliation decisions
| # | Point | Wiki said | Design said | CHANGELOG | **Ruling** |
|---|---|---|---|---|---|
| R1 | **Who approves leave** | MPO decides leave | **Manager** approves; MPO has no Leave nav at all | #8*Leave = manager-approved*, #15*Leave is site + manager only* | **Design** — leave is **Manager-approved**; MPO is removed from leave entirely. |
| R2 | **Interview waiver (ex-hands)** | Interview auto-waived / "optional" for ex-hands | Ex-hands go through Interview like everyone; waiver is an explicit **"Request waiver → Manager"** action | #18*stopped auto-waiving; waiver is explicit* | **Design** — waiver is an explicit **Manager-approved** action, never automatic. |
| R3 | **Who raises requisitions** | Site staff **or** MPO raise requisitions | Requisitions/Candidates **not** in site-staff nav; no Raise buttons for site staff | #11*Requisitions/Recruitment = MPO/Manager only* | **Design** — only **MPO/Manager** raise requisitions. Site staff instead **"Request relief cover"** (a relief request the office converts). |
| R4 | **Pipeline shape** | 8-stage enum, order competency → docs → reference → salary | **7-stage** board: Shortlisted → **Competency & references** → Docs → Salary → Proposed → Interview → Selected | #17*reworked the pipeline to these 7 stages* | **Design** — 7 visible stages; competency + reference **merged**; docs before salary. `ONBOARDED` stays a terminal system state, not a board column. |
| R5 | **MPO attendance access** | MPO has **no** attendance access; Manager reviews | Handoff nav table shows Attendance ✓ for MPO | *(no entry granting MPO attendance)* | **Docs** — the ✓ for MPO is an oversight. **MPO gets no Attendance**; nav = Manager + Site staff only. |
| R6 | **Clash → requisition** | **Automatic** on leave approval | Manual role-aware "Raise relief requisition" / "Request relief cover" + a relief-requests table | #6/#11/#13 added the relief affordances (did **not** say "make it manual") | **Both** — a detected hard clash (rank below required strength) **auto-raises** a `LEAVE` requisition (director-confirmed). The **relief-request** flow is a *complementary, proactive* site-staff channel for foreseen gaps. |
| R7 | **Wage reports surface** | Standalone wage flow | **No** wage-reports nav; a **Pay status** tab on the Crew Profile (status-only for site staff, net pay for office) + Wage approval in the Approvals queue | #12*replaced wage nav with Pay status tab* | **Design** — no standalone screen. Backend generation/approval/dispatch (wiki) is unchanged; surfaced via Pay-status tab, Approvals queue, and the Accounts export. |
| R8 | **Approvals** | Per-lifecycle approvals | One unified Manager **Approvals** queue across PO + crewing (7 kinds) | #20*expanded the central queue to all seven* | **Design** (additive) — one Manager Approvals queue. |
| R9 | **Candidates vs Crew** | `CrewMember` spine; ex-hands are a status | Top-level **Candidates** page; **ex-hands appear only in Candidates, not the Crew directory** | #16*added Candidates master; removed ex-hands from Crew* | **Design** — Crew directory lists active employees; ex-hands live in the Candidates pool. |
| R10 | **Salary basis** | `basic` + `victualingPerDay` | per-**month** / per-**day** rate toggle, each derived from the other | #3*salary per day/month toggle* | **Design** — capture both, derive. Aligns with **A4** (mid-assignment changes; prorate). |
| R11 | **Verification scope** | MPO verifies docs/PPE/**leave**/NoK | Leave is a **Manager approval**, not an MPO verification item | follows from R1 | **Reconciled** — MPO verifies **docs/PPE/NoK** (+ emergency); **leave → Manager**; **bank/EPF → Accounts**. |
### 1.2 Director answers folded in (Design Doc Q1–Q7)
- **A1** — single new **`SITE_STAFF`** role, held only by PM/APM/Site In-charge; MPO is `MANNING`.
- **A2** — the candidate self-apply form lives on the **public marketing site** (`pelagiamarine.com`) and posts to a portal API.
- **A3** — EPFO UAN/Aadhaar verification: **assisted-manual in v1** (record the result); a future **EPFO proxy microservice** (GstService pattern) is preferred.
- **A4** — salary **and the whole contract can change mid-assignment**; wage must prorate: `days×rate₁ + days×rate₂`. → **`SalaryStructure` is effective-dated** (many per assignment), not single.
- **A5** — **victualing is a separate accrual line**, shown distinctly from base pay.
- **A6** — **no crew self-service** in v1; only PM/APM/Site In-charge log in and act for crew.
- **A7** — attendance with shift/hours + overtime is desired but **tentative**; v1 ships the **daily** model the prototype built (Present/Absent/Half-day/Leave). Hours/overtime is a **deferred enhancement** (§13).
---
## 2. Corrections to apply to the existing design pages
These follow from §1.1 and are listed so the design pages can be brought in line
(each already carries a banner pointing here):
- **[Roles & Permissions](Crewing-Roles-and-Permissions):** `decide_leave` → **Manager** only (drop MAN); `apply_leave` → SITE + MGR (drop MAN); drop **leave** from `verify_site_records`; remove **SITE** from `raise_requisition`; add `request_relief_cover` (SITE) and `request/approve_interview_waiver`. Use the final matrix in **§6**.
- **[Workflows](Crewing-Workflows):** leave **decided by the Manager** (not MPO) in §3.1 and §9; remove the automatic ex-hand `PROPOSING→SELECTED` / `PROPOSED→SELECTED` waiver paths — ex-hands pass through `INTERVIEW`, satisfied either by an interview result or a **Manager-approved waiver**; re-order the Application diagram to the **7-stage** sequence (R4).
- **[Data Model](Crewing-Data-Model):** `ApplicationStage` → the 7 board stages + system states (R4, see §5.1); `LEAVE_REQUEST`**decided by Manager**; **`SalaryStructure` effective-dated** with `effectiveFrom` (R10/A4); add `RELIEF_REQUEST` model (R6).
`lib/appraisal-state-machine.ts`, `lib/wage-report.ts`, and routes under
`app/(portal)/crewing/…`.
---
## 4. Changes required to the current PPMS codebase
### 4.1 Schema (`App/prisma/schema.prisma`)
- **Add `SITE_STAFF` to `Role`.** Current enum: `TECHNICAL MANNING ACCOUNTS MANAGER SUPERUSER AUDITOR ADMIN` → append `SITE_STAFF`. (MPO = `MANNING`.)
- **Add all crewing models + enums** from [Data Model](Crewing-Data-Model), with the §1 reconciliations: 7-stage `ApplicationStage` (§5.1), effective-dated `SalaryStructure`, `RELIEF_REQUEST`, `Rank.grantsLogin` (true only for PM/APM/Site In-charge), `CrewAction` + `CrewActionType`.
- A `CrewMember` is promoted to a `User` (with a `SITE_STAFF` login) **only** when its rank `grantsLogin`; all other ranks are data subjects with no account.
### 4.2 Permissions (`App/lib/permissions.ts`)
Extend the `Permission` string union with the crewing permissions and add a
`ROLE_PERMISSIONS` row for `SITE_STAFF`; update `MANNING`/`MANAGER`/`ACCOUNTS`
the design handoff README (`design_handoff_crewing/README.md`) and match the PPMS
**[Design System](Design-System)** — build
with shadcn/ui, do **not** copy the prototype HTML.
### 8.1 Dashboard (role-aware)
KPI cards grouped by section + two action-queue list cards. Deep-links into each
screen. Per role:
- **Manager:** Purchasing KPIs (Open POs, Approvals pending, Payments due, Spend MTD) + Crewing KPIs (Open requisitions, In pipeline, Docs expiring, Crew on leave); lists *Approvals waiting* + *Recruitment at a glance*; header **Raise requisition**.
- **MPO:***my orders* PO KPIs + Crewing KPIs (Requisitions to source, In my pipeline, Verifications pending, Docs expiring); lists *My verification queue* + *Requisitions needing action*.
- **Site staff:** one *My site* KPI group (Crew on site, **Days to mark**, Leave to submit, Docs/PPE pending); lists *Today’s tasks* + *Expiring documents · my site*. No Raise button.
### 8.2 Requisitions (list) — MPO/Manager
Search + status + vessel filters; **Raise requisition** (modal). Columns:
Requisition (mono id + age), Vessel/site, Rank, Reason, Candidates (count), Status
- **Pay status (R7):** per-month rows, Month + Status badge (Paid→success, Processing→secondary); **Net pay column shown only to office roles**, hidden from site staff.
### 8.9 Leave — Manager & Site staff (R1)
Header **Apply for leave** (modal; site staff apply **on behalf of a crew
member**). **Leave planner** card: 6-month timeline, one row per crew member,
contract bars + approved-leave bars + same-rank **clash bars**. A red
**coverage-clash callout** names the two overlapping same-rank crew + dates;
- **Request relief cover** (site staff, R3/R6) — clash warning, Rank needed, note to office → creates a relief request.
---
## 10. User stories
The backlog in [Crewing User Stories](Crewing-User-Stories) (Epics A–M) stands,
with these reconciliations:
- **A2** — site staff **request relief cover**; only MPO/Manager raise requisitions (R3).
- **A5 / G3** — the **Manager** decides leave; an approved clash auto-raises a `LEAVE` requisition (R1/R6).
- **C7 / C8 / UC-08** — ex-hands are **interviewed**; waiver is an explicit **Manager-approved** action (R2).
- **C9** — the pipeline board has the **7 stages** of §5.1 (R4).
- **G3 / G4 / I1** — **MPO has no attendance**; Manager reviews it (R5).
- **J1** — wage prorates across **effective-dated** salary structures; **victualing is a separate line** (A4/A5).
---
## 11. Cross-cutting
- **Audit:** every transition + verification writes a `CrewAction` (actor, type, note, metadata) — "one transition, one row, declared side-effects", like PO approval. Onboarding is the side-effecting event (salary/victualing/attendance/experience/PF/PPE + employeeId + requisition→FILLED) in one transaction.
- **Attendance granularity (A7):** v1 ships daily Present/Absent/Half/Leave; shift/hours + **overtime** is a deferred enhancement — confirm before payroll work if hours must feed wages.
- **EPFO verification (A3):** assisted-manual in v1; schedule the EPFO proxy microservice (GstService pattern) for a later phase.
- **Careers intake (A2):** confirm the public `pelagiamarine.com` form → portal API contract and CV-parse service boundary.
- **Salary versioning (A4):** confirm the proration rule for mid-month contract changes feeds `WageLine` correctly (`days×rate₁ + days×rate₂`).