diff --git a/Crewing-Architecture.md b/Crewing-Architecture.md index 872097c..6335023 100644 --- a/Crewing-Architecture.md +++ b/Crewing-Architecture.md @@ -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 diff --git a/Crewing-Data-Model.md b/Crewing-Data-Model.md index 952791a..a03942a 100644 --- a/Crewing-Data-Model.md +++ b/Crewing-Data-Model.md @@ -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). diff --git a/Crewing-Design-Document.md b/Crewing-Design-Document.md index c0bd869..284e662 100644 --- a/Crewing-Design-Document.md +++ b/Crewing-Design-Document.md @@ -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 diff --git a/Crewing-Module.md b/Crewing-Module.md index 3e85f5e..1ec751f 100644 --- a/Crewing-Module.md +++ b/Crewing-Module.md @@ -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). | diff --git a/Crewing-Roles-and-Permissions.md b/Crewing-Roles-and-Permissions.md index 9b8dae3..71aca67 100644 --- a/Crewing-Roles-and-Permissions.md +++ b/Crewing-Roles-and-Permissions.md @@ -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 diff --git a/Crewing-Use-Cases.md b/Crewing-Use-Cases.md index e2f91b1..72c0a43 100644 --- a/Crewing-Use-Cases.md +++ b/Crewing-Use-Cases.md @@ -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). diff --git a/Crewing-User-Stories.md b/Crewing-User-Stories.md index 3192fc3..fbd5273 100644 --- a/Crewing-User-Stories.md +++ b/Crewing-User-Stories.md @@ -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 ``, I want ``, so that ``* + 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**. diff --git a/Crewing-Workflows.md b/Crewing-Workflows.md index 6b7d30b..0214bfe 100644 --- a/Crewing-Workflows.md +++ b/Crewing-Workflows.md @@ -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