docs(crewing): rewrite design-page bodies to the reconciled model

Bring the Crewing design pages in line with Crewing-Implementation-Spec
(no longer just banners): leave is Manager-approved (MPO removed from
leave and the planner); interview waiver is an explicit Manager-approved
action with no auto path; only MPO/Manager raise requisitions (site staff
request relief cover, new RELIEF_REQUEST model + ReliefRequestStatus); the
Application pipeline is the 7-stage board (competency & references merged,
docs before salary, JOINING folded into onboard); SalaryStructure is
effective-dated (mid-assignment changes prorate); victualing is a separate
wage line; verify_site_records drops leave.

Updates state/sequence diagrams, the ER model + enums, the permission
matrix, the use-case diagram/catalogue, and the user-story backlog. Each
page's banner is reduced to a plain pointer to the spec.
Hardik 2026-06-22 11:59:08 +05:30
parent b9e5118693
commit bafb12cede
8 changed files with 207 additions and 145 deletions

@ -1,5 +1,9 @@
# Crewing Architecture
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase changes, roles/nav matrices,
> screen spec). This page is the module/layer layout, aligned with that spec.
The Crewing Module is **not a new application** — it is a feature area inside the
existing Pelagia Portal. It adopts the same stack and the same patterns
documented in [Architecture](Architecture); this page only describes what

@ -1,10 +1,8 @@
# Crewing Data Model
> **Reconciled:** [Crewing Implementation Spec](Crewing-Implementation-Spec) is the
> authoritative build instruction set. Where this page differs, follow the spec —
> notably the **7-stage `ApplicationStage`**, **effective-dated `SalaryStructure`**
> (mid-assignment changes), the new **`RELIEF_REQUEST`** model, and **leave decided
> by the Manager**.
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase changes, roles/nav matrices,
> screen spec). This page is the detailed schema, aligned with that spec.
**Proposed source of truth:** `App/prisma/schema.prisma` (new models). Mirrors
the conventions on [Data Model](Data-Model): monetary values are `Decimal`,
@ -20,9 +18,12 @@ enum RequisitionStatus { OPEN SHORTLISTING PROPOSING INTERVIEWING SELECTED
// candidate progress against a requisition (the gated pipeline)
enum CandidateType { EX_HAND NEW }
enum ApplicationStage {
SHORTLISTED COMPETENCY_CHECK DOC_VERIFICATION REFERENCE_CHECK
SALARY_AGREEMENT PROPOSED INTERVIEW SELECTED REJECTED JOINING ONBOARDED
SHORTLISTED COMPETENCY_AND_REFERENCES DOC_VERIFICATION SALARY_AGREEMENT
PROPOSED INTERVIEW SELECTED REJECTED ONBOARDED
}
// the 7 board stages are SHORTLISTED → COMPETENCY_AND_REFERENCES → DOC_VERIFICATION
// → SALARY_AGREEMENT → PROPOSED → INTERVIEW → SELECTED; ONBOARDED is the terminal
// system state, REJECTED the branch. Joining formalities fold into the onboard action.
// the person's overall status
enum CrewStatus { PROSPECT CANDIDATE EMPLOYEE EX_HAND BLACKLISTED }
@ -33,7 +34,8 @@ enum AssignmentStatus { ACTIVE ON_LEAVE SIGNED_OFF }
// site HR
enum AttendanceStatus { PRESENT ABSENT HALF_DAY ON_LEAVE SIGN_OFF }
enum LeaveType { ANNUAL MEDICAL EMERGENCY UNPAID OTHER }
enum LeaveStatus { APPLIED APPROVED REJECTED CANCELLED }
enum LeaveStatus { APPLIED APPROVED REJECTED CANCELLED } // decided by the Manager
enum ReliefRequestStatus { OPEN CONVERTED DISMISSED } // site-staff gap flag → office converts
// PPE kit
enum PpeItem {
@ -142,7 +144,7 @@ erDiagram
APPLICATION ||--o{ APPLICATION_GATE : evaluated_by
APPLICATION ||--o{ REFERENCE_CHECK : has
CREW_ASSIGNMENT ||--o| SALARY_STRUCTURE : paid_by
CREW_ASSIGNMENT ||--o{ SALARY_STRUCTURE : paid_by
CREW_ASSIGNMENT ||--o| CONTRACT_LETTER : documented_by
CREW_ASSIGNMENT ||--o{ ATTENDANCE : records
CREW_ASSIGNMENT ||--o{ LEAVE_REQUEST : has
@ -190,7 +192,7 @@ erDiagram
APPLICATION_GATE {
string id PK
string applicationId FK
string gate "competency|document|experience|reference|salary|interview"
string gate "competency_reference|document|experience|salary|interview"
enum result "PENDING|VERIFIED|REJECTED"
string note
string decidedById FK
@ -208,10 +210,13 @@ erDiagram
SALARY_STRUCTURE {
string id PK
string assignmentId FK
enum rateBasis "MONTHLY|DAILY (the other is derived)"
decimal basic
decimal victualingPerDay
json allowances
string currency
date effectiveFrom "effective-dated: many per assignment"
date effectiveTo "null = current"
string approvedById FK "Manager"
}
CONTRACT_LETTER {
@ -235,6 +240,16 @@ erDiagram
date toDate
enum status "LeaveStatus"
string appliedById FK "Site in-charge (applies for crew)"
string decidedById FK "Manager (approves/rejects)"
}
RELIEF_REQUEST {
string id PK
string vesselId FK
string rankId FK
string reason
enum status "ReliefRequestStatus"
string requestedById FK "site staff (flags a foreseen gap)"
string requisitionId FK "set when the office converts it"
}
PPE_ISSUE {
string id PK
@ -334,9 +349,10 @@ erDiagram
what makes "ex-hand preferred" cheap — their experience and documents are
already on file. `employeeId` is assigned at onboarding.
- **`Application` vs `Requisition`** — one requisition, many applications;
`APPLICATION_GATE` rows are the audit of each vetting gate (the columns in
notebook page 2: competency, document, experience, reference, salary,
interview). `interviewWaived` is set true for ex-hands.
`APPLICATION_GATE` rows are the audit of each vetting gate (competency &
references, document, experience, salary, interview — competency and reference
are one gate). `interviewWaived` is set true **only after a Manager-approved
waiver** for a returning ex-hand — never automatically.
- **`CrewAssignment`** is a single tour of duty. Onboarding creates it and
flips the requisition to `FILLED`. Sign-off sets `signOffDate`/`SIGNED_OFF`,
appends an `EXPERIENCE_RECORD`, and triggers a backfill requisition.
@ -347,16 +363,23 @@ erDiagram
attendance access** (the Manager reviews it for the wage report).
- **Leave** (`LEAVE_REQUEST`) is **applied by the Site in-charge for a crew
member** (`appliedById` = site staff, `assignmentId` = the crew member) and
**decided by the MPO**. An approved leave that **clashes** — overlaps others for
the same rank below its required strength — auto-raises a `Requisition`
(`reason = LEAVE`, `autoRaised`, system-raised), mirroring the sign-off backfill
on `CrewAssignment`.
- **`SalaryStructure`** holds `basic`, `victualingPerDay`, and a JSON
`allowances`; approved by a Manager. Salary is the restricted field on the
contract letter for site staff.
- **`WageReport` / `WageLine`** are the generated monthly artefact:
`lineTotal = daysAttended × dailyRate + victualing`; the report
`totalAmount` is the sum. Exportable to XLSX/PDF like a PO.
**decided by the Manager** (`decidedById`) — the **MPO has no leave role**. An
approved leave that **clashes** — overlaps others for the same rank below its
required strength — auto-raises a `Requisition` (`reason = LEAVE`, `autoRaised`,
system-raised), mirroring the sign-off backfill on `CrewAssignment`.
- **`RELIEF_REQUEST`** is the site-staff channel for flagging a foreseen cover gap
(site staff do **not** raise requisitions). The office reviews it and **converts**
it into a `Requisition` (`requisitionId` set, status `CONVERTED`).
- **`SalaryStructure`** holds a `rateBasis` (MONTHLY or DAILY, the other derived),
`basic`, `victualingPerDay`, and a JSON `allowances`; approved by a Manager. It
is **effective-dated** (`effectiveFrom`/`effectiveTo`) so the salary or contract
can change mid-assignment — many structures per assignment. Salary is the
restricted field on the contract letter for site staff.
- **`WageReport` / `WageLine`** are the generated monthly artefact. A line
**prorates across the effective-dated structures** that overlap the month
(`days×rate₁ + days×rate₂`); **victualing is a separate accrual line**, not
rolled into base pay. The report `totalAmount` is the sum. Exportable to
XLSX/PDF like a PO.
- **PPE as inventory** — when the inventory flag is on, a `PPE_ISSUE` can also
decrement `ItemInventory` at the site (optional integration).

@ -1,11 +1,8 @@
# Crewing Design Document
> **Reconciled:** [Crewing Implementation Spec](Crewing-Implementation-Spec) is the
> authoritative build instruction set. Where this page differs, follow the spec —
> notably: **leave is Manager-approved** (not MPO); the **interview waiver is an
> explicit Manager-approved action** (never automatic); **only MPO/Manager raise
> requisitions** (site staff *request relief cover*); the recruitment board has
> **7 stages**; the **MPO has no attendance access**.
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase changes, final roles/nav
> matrices, screen spec). This page is the design rationale, aligned with that spec.
> Companion pages: [Architecture](Crewing-Architecture) ·
> [Data Model](Crewing-Data-Model) · [Workflows](Crewing-Workflows) ·
@ -61,7 +58,8 @@ A crew member goes on leave, finishes a contract (EOC), is terminated, is
signed off on medical grounds, or leaves for another reason. Any of these
creates a **gap** for a specific **rank** on a specific **vessel/site**. On a
*scheduled sign-off* the gap (and its **Requisition**) is raised automatically;
otherwise site staff or the MPO raise it manually. A **leave clash** — when
otherwise the **MPO or Manager** raise it manually (site staff instead **request
relief cover**, which the office converts into a requisition). A **leave clash** — when
approved leaves overlap so a rank drops below its required strength on a
vessel/site — likewise **auto-raises a Requisition** (reason `LEAVE`).
@ -73,17 +71,23 @@ New candidates either **apply on the Pelagia site** (uploading a CV, which is
entry as fallback) or are **uploaded manually** by the MPO.
### 3.3 Vetting (gated)
Each shortlisted candidate is evaluated against the rank's **minimum criteria**:
Each shortlisted candidate moves through a **7-stage** gated pipeline, evaluated
against the rank's **minimum criteria**:
- **Competency** — qualifications for the rank.
- **Document verification** — seafarer documents present and valid.
- **Experience***type of vessel*, *time in rank*, *total duration*.
- **Reference check** — previous-employer confirmation.
- **Salary agreement** — proposed structure accepted in principle.
1. **Competency & references** — qualifications for the rank plus previous-employer
confirmation (one stage).
2. **Document verification** — seafarer documents present and valid.
3. **Salary agreement** — proposed structure accepted in principle (Manager
approves the structure).
4. **Proposal** — terms put to the candidate.
5. **Interview****everyone is interviewed**; for a returning ex-hand the
interview may be **waived only with explicit Manager approval** (never
automatic).
6. **Selection** — all gates cleared and Manager-approved.
The candidate is then **proposed** and (except for ex-hands, where it's
**optional**) **interviewed**. The outcome is **Selection** or **Rejection with
remarks**. Every gate is recorded.
Experience (*type of vessel*, *time in rank*, *total duration*) is checked as part
of competency/document review. The outcome of any gate is **pass** or **Rejection
with remarks**; every gate is recorded.
### 3.4 Onboarding
On selection: **joining formalities** run — salary is confirmed and a
@ -103,9 +107,9 @@ Site staff record **attendance** daily, **issue PPE** (with boiler-suit and shoe
sizes), maintain **documents/bank/EPF/next-of-kin/emergency contact**, and apply
for **leave on behalf of crew members** through the site **leave planner** (which
shows every crew member's contract span and leaves on one timeline; crew are data
subjects, not portal users, so the **Site in-charge applies leave for them**). If
an approved leave **clashes** with another for the same rank, the planner
auto-raises a backfill **Requisition**. The PM raises **appraisals**; the **MPO
subjects, not portal users, so the **Site in-charge applies leave for them** and
the **Manager approves** it). If an approved leave **clashes** with another for the
same rank, the planner auto-raises a backfill **Requisition**. The PM raises **appraisals**; the **MPO
verifies**, the **Manager approves**.
### 3.6 Office verification

@ -1,12 +1,9 @@
# Crewing Module
> **Reconciled:** [Crewing Implementation Spec](Crewing-Implementation-Spec) is the
> authoritative build instruction set (it reconciles this design page with the
> design handoff). Where they differ, follow the spec — notably: **leave is
> Manager-approved** (not MPO); the **interview waiver is an explicit
> Manager-approved action** (never automatic); **only MPO/Manager raise
> requisitions** (site staff *request relief cover*); the recruitment board has
> **7 stages**; the **MPO has no attendance access**.
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions — codebase changes, the final
> roles/permission and navigation matrices, and the detailed screen spec. This
> page is the design overview, aligned with that spec.
The **Crewing Module** (a.k.a. *Manning*) extends Pelagia Portal (PPMS) from a
purchasing system into a crew lifecycle system. It manages the people who run
@ -41,7 +38,7 @@ for this design were literally two notebook pages). The pain points it removes:
| Area | Capability |
|---|---|
| **Requisitions** | Auto-raised (on sign-off / end-of-contract, or when a **leave clash** leaves a rank short) or manually-raised vacancy for a rank on a vessel/site; reason (leave / end-of-contract / termination / medical / other). |
| **Candidate pipeline** | Shortlist (ex-hand preferred) → competency → document verification → reference check → salary agreement → proposal → interview (optional for ex-hands) → selection / rejection with remarks. |
| **Candidate pipeline** | A 7-stage gated board: shortlist (ex-hand preferred) → competency & references → document verification → salary agreement → proposal → interview → selection / rejection with remarks. Everyone is interviewed; for returning ex-hands the interview can be **waived only with Manager approval**. |
| **CV intake** | Self-apply on the Pelagia site or MPO upload; CV parsed for age, vessel type, rank and experience, with manual fallback. |
| **Onboarding** | One selection event starts salary, victualing, attendance, experience accrual, PF tracking and the PPE issue checklist. |
| **Crew records** | Bank details, EPF/UAN, next of kin, emergency contact, contract letter, and role-based seafarer documents (STCW, Aadhaar, PAN, Passport, CDC, COC, photo, licence, medical fitness). |

@ -1,11 +1,9 @@
# Crewing Roles and Permissions
> **Reconciled:** the authoritative permission matrix is in
> [Crewing Implementation Spec § 6](Crewing-Implementation-Spec#6-roles--permissions-final-matrix).
> It corrects this page: **`decide_leave` → Manager only** (not MPO); `apply_leave`
> → Site staff + Manager; **leave removed** from `verify_site_records`;
> `raise_requisition` is **MPO/Manager only** (site staff get `request_relief_cover`);
> and new `request/approve_interview_waiver` + `record_interview_result` permissions.
> **Authoritative build spec:** the same matrix appears in
> [Crewing Implementation Spec § 6](Crewing-Implementation-Spec#6-roles--permissions-final-matrix),
> alongside the codebase wiring. This page is the detailed rationale, aligned with
> that spec.
Crewing extends the existing `lib/permissions.ts` map (see
[Roles and Permissions](Roles-and-Permissions)) with crewing permissions. Every
@ -16,10 +14,10 @@ relevant state machine adds the status+role gate on top.
| Crewing actor | PPMS role | Notes |
|---|---|---|
| PM / APM / Site In-charge **(the only on-site logins)** | **`SITE_STAFF`** (new, proposed) | apply-only leave **(on behalf of crew)**, attendance, PPE issue, doc upload, view-only contract (except salary) & bank |
| MPO | **`MANNING`** (existing — "crew-management staff") | recruitment + verifies all site data except bank/EPF; **no attendance access** |
| PM / APM / Site In-charge **(the only on-site logins)** | **`SITE_STAFF`** (new, proposed) | apply-only leave **(on behalf of crew)**, attendance, PPE issue, doc upload, view-only contract (except salary) & bank; **requests relief cover** (does not raise requisitions) |
| MPO | **`MANNING`** (existing — "crew-management staff") | recruitment + verifies site data (docs/PPE/NoK), **except** bank/EPF (Accounts) and leave (Manager); **no leave and no attendance access** |
| Accounts | **`ACCOUNTS`** | verifies bank + EPF; consumes wage report |
| Manager | **`MANAGER`** | approves salary structures, candidate list, appraisals, wage reports; **reviews attendance** |
| Manager | **`MANAGER`** | approves salary structures, candidate selection, interview waivers, **leave**, appraisals, wage reports; **reviews attendance** |
| Superuser | **`SUPERUSER`** | combined authority across crewing actions |
| Auditor | **`AUDITOR`** | read-only across crewing |
| Admin | **`ADMIN`** | manages ranks & doc requirements |
@ -44,25 +42,29 @@ relevant state machine adds the status+role gate on top.
| Permission | SITE | MAN | ACC | MGR | SU | AUD | ADM |
|---|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| `raise_requisition` | ✓ | ✓ | | ✓ | ✓ | | |
| `raise_requisition` ⁵ | | ✓ | | ✓ | ✓ | | |
| `request_relief_cover` ⁵ | ✓ | | | | ✓ | | |
| `convert_relief_to_requisition` | | ✓ | | ✓ | ✓ | | |
| `cancel_requisition` | | ✓ | | ✓ | ✓ | | |
| `view_requisitions` | ✓ | ✓ | | ✓ | ✓ | ✓ | ✓ |
| `view_requisitions` | | ✓ | | ✓ | ✓ | ✓ | ✓ |
| `manage_candidates` (shortlist/vetting) | | ✓ | | ✓ | ✓ | | |
| `record_reference_check` | | ✓ | | ✓ | ✓ | | |
| `propose_interview` | | ✓ | | ✓ | ✓ | | |
| `record_interview_result` | | ✓ | | ✓ | ✓ | | |
| `request_interview_waiver` ⁶ | | ✓ | | | ✓ | | |
| `approve_interview_waiver` ⁶ | | | | ✓ | ✓ | | |
| `approve_salary_structure` | | | | ✓ | ✓ | | |
| `select_candidate` | | ✓ | | ✓ | ✓ | | |
| `select_candidate` (final approval) | | | | ✓ | ✓ | | |
| `onboard_crew` | | ✓ | | ✓ | ✓ | | |
| `sign_off_crew` | ✓ | ✓ | | ✓ | ✓ | | |
| `view_crew_records` | ✓¹ | ✓ | ✓² | ✓ | ✓ | ✓ | ✓ |
| `upload_crew_records` (docs/NoK/emergency/EPF) | ✓ | ✓ | | ✓ | ✓ | | |
| `issue_ppe` | ✓ | ✓ | | ✓ | ✓ | | |
| `apply_leave` | ✓ | | | ✓ | ✓ | | |
| `decide_leave` | | | | ✓ | ✓ | | |
| `apply_leave` | ✓ | | | ✓ | ✓ | | |
| `decide_leave` | | | | ✓ | ✓ | | |
| `record_attendance` | ✓ | | | | ✓ | | |
| `view_attendance` ³ | ✓ | | | ✓ | ✓ | ✓ | |
| `verify_site_records` (docs/PPE/leave/NoK) | | ✓ | | ✓ | ✓ | | |
| `verify_bank_epf` | | | ✓ | | ✓ | | |
| `verify_site_records` (docs/PPE/NoK) | | ✓ | | ✓ | ✓ | | |
| `verify_bank_epf` | | | ✓ | | ✓ | | |
| `raise_appraisal` | ✓ | | | ✓ | ✓ | | |
| `verify_appraisal` | | ✓ | | ✓ | ✓ | | |
| `approve_appraisal` | | | | ✓ | ✓ | | |
@ -78,6 +80,14 @@ relevant state machine adds the status+role gate on top.
record it; the **Manager** reviews it (it feeds the wage report).
⁴ The wage report reads attendance, so it is generated by the **Manager** (or the
month-end job) — **not** the MPO, who has no attendance access.
**Site staff do not raise requisitions.** They flag a gap with
`request_relief_cover`; the office (MPO/Manager) reviews it and converts it into a
requisition.
⁶ Everyone is interviewed. For a returning ex-hand the MPO may
`request_interview_waiver`; only a **Manager** can `approve_interview_waiver`
(never automatic).
**Leave is decided by the Manager**, not the MPO. Site staff apply on behalf of
crew; the MPO has no role in leave.
## 3. Field-level restrictions (PII)
@ -100,10 +110,16 @@ Enforced in Server Components/Actions on top of the permission map:
site staff and visible only to site staff and the Manager** — the **MPO cannot
see attendance**; the Manager reviews it (it feeds the wage report).
- **Leave is applied by the Site in-charge on behalf of crew** (crew are not portal
users); the **MPO decides** (approves/rejects) leave. An **approved leave that
clashes** — overlaps another for the same rank below its required strength —
**auto-raises a `LEAVE`-reason requisition** (system-raised, same backfill path
as sign-off).
users); the **Manager decides** (approves/rejects) leave — the **MPO has no leave
role**. An **approved leave that clashes** — overlaps another for the same rank
below its required strength — **auto-raises a `LEAVE`-reason requisition**
(system-raised, same backfill path as sign-off).
- **Site staff do not raise requisitions.** A foreseen gap is flagged with
`request_relief_cover`; the office converts the relief request into a
requisition.
- **Everyone is interviewed**; an ex-hand interview is **waived only with Manager
approval** (`request_interview_waiver` by MPO → `approve_interview_waiver` by
Manager).
- An **appraisal** must be `MPO_VERIFIED` before a Manager can approve it.
- A **wage report** must be `MANAGER_APPROVED` before it is `SENT_TO_ACCOUNTS`.
- Only **one ACTIVE assignment** per crew member; sign-off is required before a

@ -1,10 +1,8 @@
# Crewing Use Cases
> **Reconciled:** [Crewing Implementation Spec](Crewing-Implementation-Spec) is the
> authoritative build instruction set. Where this page differs, follow the spec —
> notably: **leave is decided by the Manager** (UC-12); the **interview waiver is an
> explicit Manager-approved action** (UC-08); and **only MPO/Manager raise
> requisitions** (site staff *request relief cover*, UC-01).
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase changes, roles/nav matrices,
> screen spec). This page is the actor/use-case catalogue, aligned with that spec.
Actors and the use cases each can perform. The diagram uses a flowchart to
approximate UML use-case notation (Mermaid has no native use-case diagram);
@ -23,6 +21,7 @@ flowchart LR
subgraph Requisition
U1(["Raise requisition"])
U1b(["Request relief cover"])
U2(["Sign off crew → auto-requisition"])
U2b(["Leave clash → auto-requisition (system)"])
U3(["Cancel requisition"])
@ -39,13 +38,14 @@ flowchart LR
end
subgraph SiteHR["Site HR"]
U12(["Apply for leave"])
U12b(["Approve leave (Manager)"])
U13(["View leave planner"])
U14(["Record attendance"])
U15(["Issue PPE (sizes)"])
U16(["Upload documents / EPF / NoK"])
end
subgraph Verify["Office verification"]
U17(["Verify docs / PPE / leave"])
U17(["Verify docs / PPE / NoK"])
U18(["Verify bank & EPF"])
end
subgraph Appraisal
@ -62,10 +62,10 @@ flowchart LR
U25(["Manage ranks & doc requirements"])
end
SS --- U1 & U2 & U12 & U13 & U14 & U15 & U16 & U19
SS --- U1b & U2 & U12 & U13 & U14 & U15 & U16 & U19
CAND --- U4
MPO --- U5 & U6 & U7 & U8 & U9 & U11 & U17 & U20 & U2b
MGR --- U3 & U9 & U10 & U11 & U21 & U22 & U23 & U24
MPO --- U1 & U5 & U6 & U7 & U8 & U9 & U11 & U17 & U20 & U2b
MGR --- U1 & U3 & U9 & U10 & U11 & U12b & U13 & U21 & U22 & U23 & U24
ACC --- U18 & U24
ADM --- U25
```
@ -78,23 +78,25 @@ flowchart LR
| ID | Use case | Primary actor | Pre-condition | Main success outcome |
|---|---|---|---|---|
| UC-01 | Raise requisition | Site staff / MPO | a rank is or will be vacant | `Requisition(OPEN)` created, MPO notified |
| UC-01 | Raise requisition | MPO / Manager | a rank is or will be vacant | `Requisition(OPEN)` created, MPO notified |
| UC-01b | Request relief cover | Site staff | a foreseen cover gap | `ReliefRequest(OPEN)`; office converts it into a requisition |
| UC-02 | Auto-requisition on sign-off | System | crew member signed off | requisition raised automatically; experience updated |
| UC-03 | Cancel requisition | Manager | requisition not yet filled | `CANCELLED` with reason |
| UC-04 | Apply with CV | Candidate | careers form reachable | `CrewMember(PROSPECT)` + application; CV parsed or manual |
| UC-05 | Shortlist candidates | MPO | requisition `OPEN` | applications `SHORTLISTED`; ex-hands preferred |
| UC-06 | Run vetting gates | MPO | candidate shortlisted | competency/document/experience gates recorded |
| UC-07 | Reference check | MPO | candidate in vetting | reference result recorded |
| UC-08 | Propose & interview | MPO | gates cleared | proposal sent; interview recorded (waived for ex-hands) |
| UC-09 | Select / reject with remarks | MPO / Manager | interview done / waived | `SELECTED` or `REJECTED` + remarks |
| UC-08 | Propose & interview | MPO | gates cleared | proposal sent; interview result recorded — ex-hand interview waivable **only with Manager approval** |
| UC-09 | Select / reject with remarks | MPO records, **Manager approves** | interview done or Manager-approved waiver | `SELECTED` (Manager-approved) or `REJECTED` + remarks |
| UC-10 | Approve salary structure & candidate list | Manager | candidate proposed | salary structure approved |
| UC-11 | Onboard candidate | MPO / Manager | candidate selected | `CrewAssignment(ACTIVE)`; salary/victualing/attendance/experience/PF/PPE started; employeeId issued; requisition `FILLED` |
| UC-12 | Apply for leave (for a crew member) | Site in-charge | crew has active assignment | `LeaveRequest(APPLIED)` on the crew member's assignment |
| UC-13 | View leave planner | Site staff / MPO / Manager | — | timeline of contracts + leaves per site |
| UC-12b | Approve / reject leave | Manager | leave applied | `APPROVED` → assignment `ON_LEAVE` (clash auto-raises a requisition); or `REJECTED` |
| UC-13 | View leave planner | Site staff / Manager | — | timeline of contracts + leaves per site (the MPO has no leave access) |
| UC-14 | Record attendance | Site staff | active assignment | daily `Attendance` rows (visible to site staff + Manager; **not** the MPO) |
| UC-15 | Issue PPE | Site staff | active assignment | `PpeIssue` with size (boiler suit/shoes) |
| UC-16 | Upload documents / EPF / next-of-kin / emergency | Site staff | crew exists | records created `PENDING` verification |
| UC-17 | Verify docs / PPE / leave | MPO | pending records exist | `VERIFIED` (everything except attendance) |
| UC-17 | Verify docs / PPE / NoK | MPO | pending records exist | `VERIFIED` (everything except attendance and leave) |
| UC-18 | Verify bank & EPF | Accounts | pending bank/EPF | `VERIFIED`; UAN/Aadhaar checked vs EPFO |
| UC-19 | Raise appraisal | Site staff (PM) | active assignment | `Appraisal(SUBMITTED)` |
| UC-20 | Verify appraisal | MPO | appraisal submitted | `MPO_VERIFIED` |
@ -110,7 +112,8 @@ flowchart LR
- **UC-04 alt** — CV not parseable → manual field entry (never blocks intake).
- **UC-06/07/09 alt** — any gate fails → `REJECTED` with remarks; application
ends, requisition stays open for other candidates.
- **UC-08 alt** — ex-hand → interview waived (`interviewWaived = true`).
- **UC-08 alt** — returning ex-hand → MPO requests an interview waiver; on
**Manager approval** `interviewWaived = true` (never automatic).
- **UC-11 alt** — joining formalities incomplete (no signed contract / unapproved
salary) → onboarding blocked.
- **UC-16/17 alt** — verifier rejects a record → back to `PENDING` with remarks
@ -118,7 +121,8 @@ flowchart LR
- **UC-22 alt** — attendance gaps flagged before generation; report can be
regenerated until approved.
- **UC-12 note** — crew are data subjects, not portal users, so the **Site
in-charge applies leave on their behalf** (apply-only; the MPO decides it).
in-charge applies leave on their behalf** (apply-only; the **Manager decides it**
— the MPO has no leave role).
- **UC-14 note** — attendance is recorded by site staff and **reviewed by the
Manager**; the **MPO has no attendance access** (so the wage report, UC-22, is
generated by the Manager / month-end job, not the MPO).

@ -1,10 +1,8 @@
# Crewing User Stories
> **Reconciled:** [Crewing Implementation Spec § 10](Crewing-Implementation-Spec#10-user-stories)
> carries the authoritative reconciliations to this backlog — notably **A2**
> (site staff *request relief cover*; only MPO/Manager raise requisitions),
> **G3** (the **Manager** decides leave), **C7/C8** (interview waiver is an explicit
> Manager-approved action), and **G4/I1** (the **MPO has no attendance access**).
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase changes, roles/nav matrices,
> screen spec). This page is the requirement backlog, aligned with that spec.
Backlog for the Crewing Module, grouped into epics. Format:
*As a `<role>`, I want `<capability>`, so that `<value>`* + acceptance criteria
@ -24,11 +22,18 @@ signs off, so that no vacancy goes untracked.
- AC4: a `CrewAction(REQUISITION_RAISED)` is written.
**A2 — Manual requisition**
As **site staff / MPO**, I want to raise a requisition manually (e.g. planned
As an **MPO / Manager**, I want to raise a requisition manually (e.g. planned
leave), so that I can pre-empt a gap.
- AC1: I select vessel, rank, reason, needed-by date, and min-experience criteria.
- AC2: the requisition appears in the MPO shortlist queue.
**A2b — Request relief cover (site staff)**
As **site staff**, I want to flag a foreseen cover gap (I cannot raise
requisitions myself), so that the office can act on it.
- AC1: I submit a relief request (vessel, rank, reason, note) → `ReliefRequest(OPEN)`.
- AC2: it appears in the office "Relief requests from sites" list; the MPO/Manager
**convert** it into a requisition (status `CONVERTED`).
**A3 — Requisition list & detail**
As an **MPO/Manager**, I want a filterable list of requisitions by
vessel/rank/status, so that I can prioritise sourcing.
@ -114,16 +119,21 @@ allowances), so that the proposal has terms.
- AC1: structure captured; visible only to office roles (not site staff).
**C7 — Proposal & interview**
As an **MPO**, I want to propose to the candidate and record an interview, so
that selection is informed.
- AC1: new candidates require an interview record.
- AC2: ex-hands can have the interview **waived** (`interviewWaived`).
As an **MPO**, I want to propose to the candidate and record an interview result,
so that selection is informed.
- AC1: **everyone is interviewed** by default; the MPO records the result.
- AC2: for a returning ex-hand the interview is **waived only with Manager
approval** — the MPO requests the waiver (`request_interview_waiver`), a
**Manager** approves it (`approve_interview_waiver`), then `interviewWaived` is
set. There is no automatic waiver.
**C8 — Selection / rejection with remarks**
As an **MPO/Manager**, I want to select or reject with remarks, so that the
decision and its reason are on record.
As an **MPO** (records) and **Manager** (approves), I want to select or reject
with remarks, so that the decision and its reason are on record.
- AC1: rejection requires remarks.
- AC2: selection requires all prior gates cleared.
- AC3: **selection is Manager-approved** — the MPO records the interview result;
the Manager approves the salary structure and the selection.
**C9 — Pipeline board**
As an **MPO**, I want a board showing each candidate's stage per requisition, so
@ -207,8 +217,9 @@ As **site staff**, I want to record PPE returns, so that the register is current
## Epic G — Leave & attendance
**G1 — Site leave planner**
As **site staff / MPO / Manager**, I want a planner showing every crew member's
contract span and leaves on one timeline, so that I can plan cover.
As **site staff / Manager**, I want a planner showing every crew member's
contract span and leaves on one timeline, so that I can plan cover. (The MPO has
no leave access.)
- AC1: timeline per site with contract bars + leave bars.
- AC2: overlapping absences for the same rank are highlighted (a clash below
required strength auto-raises a requisition — see **A5**).
@ -220,8 +231,8 @@ As the **Site in-charge**, I want to apply for leave **on behalf of a crew membe
- AC2: site staff cannot self-approve (no `decide_leave`).
**G3 — Decide leave**
As an **MPO**, I want to approve/reject leave with a note, so that the planner
stays accurate.
As a **Manager**, I want to approve/reject leave with a note, so that the planner
stays accurate (the **MPO has no leave role**).
- AC1: approval moves the assignment to `ON_LEAVE` for the period.
- AC2: if the approval creates a clash (the rank falls below required strength for
the overlap), a backfill requisition is auto-raised — see **A5**.

@ -1,10 +1,9 @@
# Crewing Workflows
> **Reconciled:** [Crewing Implementation Spec](Crewing-Implementation-Spec) is the
> authoritative build instruction set. Where this page differs, follow the spec —
> notably: **leave is decided by the Manager** (not MPO); ex-hands pass through
> **Interview** unless a **Manager-approved waiver** is granted (no automatic
> waiver path); and the Application pipeline has the reconciled **7 stages**.
> **Authoritative build spec:** [Crewing Implementation Spec](Crewing-Implementation-Spec)
> carries the full reconciled instructions (codebase wiring, roles/nav matrices,
> screen spec). This page holds the detailed state/sequence diagrams, aligned with
> that spec.
Every crewing lifecycle is enforced by a single state-machine module (the
`po-state-machine.ts` pattern) and recorded as `CrewAction` audit rows. This
@ -24,8 +23,7 @@ stateDiagram-v2
OPEN --> SHORTLISTING : add candidates
SHORTLISTING --> PROPOSING : a candidate clears vetting
PROPOSING --> INTERVIEWING : interview scheduled
PROPOSING --> SELECTED : ex-hand, interview waived
INTERVIEWING --> SELECTED : candidate selected
INTERVIEWING --> SELECTED : candidate selected (or Manager-approved waiver)
INTERVIEWING --> SHORTLISTING : all rejected, re-source
SELECTED --> FILLED : onboarded (assignment created)
OPEN --> CANCELLED : vacancy withdrawn
@ -36,40 +34,43 @@ stateDiagram-v2
| From | Action | To | Roles | Side-effect |
|---|---|---|---|---|
| — | `raise` | OPEN | system (sign-off **or leave clash**) / SITE_STAFF / MANNING | email MPO |
| — | `raise` | OPEN | system (sign-off **or leave clash**) / MANNING / MANAGER | email MPO |
| OPEN | `start_shortlist` | SHORTLISTING | MANNING | — |
| SHORTLISTING | `propose` | PROPOSING | MANNING | email Manager |
| PROPOSING | `schedule_interview` | INTERVIEWING | MANNING | email candidate |
| PROPOSING | `select` (ex-hand) | SELECTED | MANNING, MANAGER | email candidate |
| INTERVIEWING | `select` | SELECTED | MANNING, MANAGER | email candidate |
| INTERVIEWING | `select` | SELECTED | MANAGER | email candidate |
| INTERVIEWING | `reject_all` | SHORTLISTING | MANNING | — |
| SELECTED | `onboard` | FILLED | MANNING, MANAGER | **onboarding side-effects** |
| OPEN/SHORTLISTING | `cancel` | CANCELLED | MANAGER | — |
| OPEN/SHORTLISTING | `cancel` | CANCELLED | MANNING, MANAGER | — |
Site staff do **not** raise requisitions — they **request relief cover**, which
the office converts into a requisition. Selection is **Manager-approved** (the MPO
records the interview result; the Manager approves the salary structure and the
selection). For a returning ex-hand the interview may be **waived only with Manager
approval** — there is no automatic waiver path.
---
## 2. Candidate pipeline (Application)
The per-candidate gated vetting from notebook page 2. Many applications run per
requisition; one ends in `ONBOARDED`. **Ex-hands skip the interview** (optional).
Any gate can end in **rejection with remarks**.
The per-candidate gated vetting from notebook page 2, as a **7-stage board**.
Many applications run per requisition; one ends in `ONBOARDED`. **Everyone is
interviewed**; for a returning ex-hand the interview is **waived only with Manager
approval** (`interviewWaived` is set after approval). Any gate can end in
**rejection with remarks**.
```mermaid
stateDiagram-v2
[*] --> SHORTLISTED
SHORTLISTED --> COMPETENCY_CHECK
COMPETENCY_CHECK --> DOC_VERIFICATION : pass
DOC_VERIFICATION --> REFERENCE_CHECK : pass
REFERENCE_CHECK --> SALARY_AGREEMENT : pass
SALARY_AGREEMENT --> PROPOSED : agreed
PROPOSED --> INTERVIEW : new candidate
PROPOSED --> SELECTED : ex-hand (interview waived)
INTERVIEW --> SELECTED : pass
SELECTED --> JOINING : joining formalities
JOINING --> ONBOARDED : contract + salary confirmed
COMPETENCY_CHECK --> REJECTED : fail (remarks)
SHORTLISTED --> COMPETENCY_AND_REFERENCES
COMPETENCY_AND_REFERENCES --> DOC_VERIFICATION : pass
DOC_VERIFICATION --> SALARY_AGREEMENT : pass
SALARY_AGREEMENT --> PROPOSED : agreed (Manager approves structure)
PROPOSED --> INTERVIEW : proposal accepted
INTERVIEW --> SELECTED : pass / Manager-approved waiver
SELECTED --> ONBOARDED : onboard (joining formalities, Manager-approved)
COMPETENCY_AND_REFERENCES --> REJECTED : fail (remarks)
DOC_VERIFICATION --> REJECTED : fail (remarks)
REFERENCE_CHECK --> REJECTED : fail (remarks)
SALARY_AGREEMENT --> REJECTED : not agreed
INTERVIEW --> REJECTED : fail (remarks)
ONBOARDED --> [*]
@ -103,8 +104,9 @@ backfill Requisition** for the same rank/vessel.
### 3.1 Leave & the clash backfill
Leave is **applied by the Site in-charge on behalf of a crew member**
(`LeaveRequest(APPLIED)`) and **decided by the MPO** (`APPROVED` / `REJECTED`).
An approval moves the assignment to `ON_LEAVE` for the period. On approval the
(`LeaveRequest(APPLIED)`) and **decided by the Manager** (`APPROVED` / `REJECTED`)
— the **MPO has no role in leave**. An approval moves the assignment to `ON_LEAVE`
for the period. On approval the
state machine checks the rank's cover on that vessel/site over the leave window:
if the approved leaves would drop the rank **below its required strength**, it
**auto-raises a backfill `Requisition`** (reason `LEAVE`, `autoRaised`) — the same
@ -116,13 +118,14 @@ highlighted. (Attendance, by contrast, is recorded on site and reviewed by the
sequenceDiagram
actor SIC as Site in-charge
participant SYS as App / state machines
actor MPO
actor MGR as Manager
participant DB as PostgreSQL
participant N as Notifier
actor MPO
SIC->>SYS: apply leave for crew member (dates)
SYS->>DB: LeaveRequest (APPLIED)
MPO->>SYS: approve leave
MGR->>SYS: approve leave
SYS->>DB: LeaveRequest APPROVED; assignment ON_LEAVE
SYS->>SYS: check rank cover over the leave window
alt clash — rank below required strength
@ -234,20 +237,20 @@ sequenceDiagram
actor C as Candidate
participant DB as PostgreSQL
MPO->>SYS: competency check
SYS->>DB: gate(competency)=VERIFIED
MPO->>SYS: competency & references check
SYS->>DB: gate(competency_reference)=VERIFIED
MPO->>SYS: document verification
SYS->>DB: gate(document)=VERIFIED
MPO->>SYS: reference check
SYS->>DB: gate(reference)=VERIFIED
MPO->>SYS: salary agreement (propose structure)
SYS->>DB: gate(salary)=VERIFIED, proposedSalary
SYS->>DB: gate(salary)=PROPOSED, proposedSalary
MPO->>C: proposal
alt new candidate
MPO->>SYS: schedule + record interview
alt interview held (everyone by default)
MPO->>SYS: schedule + record interview result
SYS->>DB: gate(interview)=VERIFIED
else ex-hand
Note over MPO,SYS: interview waived
else returning ex-hand, waiver requested
MPO->>MGR: request interview waiver
MGR->>SYS: approve waiver
SYS->>DB: gate(interview)=WAIVED (Manager-approved)
end
MGR->>SYS: approve salary structure + select
SYS->>DB: application SELECTED
@ -271,10 +274,10 @@ sequenceDiagram
actor MPO
actor ACC as Accounts
SS->>SYS: upload documents / PPE issue / leave / next-of-kin / EPF
SS->>SYS: upload documents / PPE issue / next-of-kin / EPF
SYS->>DB: records (verificationStatus=PENDING)
par MPO verifies (all except attendance)
MPO->>SYS: verify document / PPE / leave / NoK
par MPO verifies (all except attendance and leave)
MPO->>SYS: verify document / PPE / NoK
SYS->>DB: VERIFIED (verifiedById=MPO)
and Accounts verifies bank + EPF
ACC->>SYS: verify bank detail