diff --git a/Crewing-Design-Document.md b/Crewing-Design-Document.md index 8600ba6..be3d889 100644 --- a/Crewing-Design-Document.md +++ b/Crewing-Design-Document.md @@ -1,164 +1,171 @@ -# Crewing Design Document - -> Companion pages: [Architecture](Crewing-Architecture) · -> [Data Model](Crewing-Data-Model) · [Workflows](Crewing-Workflows) · -> [Use Cases](Crewing-Use-Cases) · [Roles & Permissions](Crewing-Roles-and-Permissions) · -> [User Stories](Crewing-User-Stories) - -## 1. Purpose & scope - -The Crewing Module digitises Pelagia's **manning process**: keeping every -dredger and site crewed with competent, documented, paid people, and recording -the full lifecycle of each crew member. - -**In scope** - -1. Vacancy detection & **requisitions**. -2. **Recruitment pipeline** (shortlist → vetting → proposal → interview → - selection) for ex-hands and new candidates. -3. **Onboarding** and the automatic processes it kicks off. -4. **Crew records**: documents, bank, EPF, next-of-kin, emergency contact, - contract, PPE. -5. **Site HR**: leave planner, attendance. -6. **Appraisal** (PM → MPO → Manager). -7. **Sign-off** and experience accrual. -8. **Wage report** generation for Accounts. - -**Out of scope (v1)** — actual salary disbursement / banking integration (we -produce the report; Accounts pays), payslip generation, statutory return filing, -training-course delivery, and seafarer-document issuance (we store and verify, -we don't issue). - -## 2. Actors - -| Actor | Real-world role | Maps to PPMS role | -|---|---|---| -| **Site staff** | PM / Assistant PM / Site In-charge on the dredger | new `SITE_STAFF` role (proposed) | -| **MPO** | Manning / Personnel Officer in the office | existing `MANNING` role | -| **Accounts** | Finance team | existing `ACCOUNTS` role | -| **Manager** | Department / crewing manager | existing `MANAGER` role | -| **Candidate** | External applicant (ex-hand or new) | unauthenticated public form / lightweight `CANDIDATE` identity | -| **Crew member** | Onboarded employee | data subject; not necessarily a portal login in v1 | -| Admin / Superuser / Auditor | as in PO module | existing roles | - -See the on-vessel **rank hierarchy** (PM → … → Mess Boy) in -[Data Model § Rank](Crewing-Data-Model#rank-the-org-hierarchy). - -## 3. Domain narrative - -### 3.1 A vacancy opens -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. - -### 3.2 Sourcing candidates -The MPO shortlists candidates for the rank. **Ex-hands are preferred** (people -who have sailed with Pelagia before — their record is already in the system). -New candidates either **apply on the Pelagia site** (uploading a CV, which is -**parsed** for age, vessel type, current/past rank and experience — with manual -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**: - -- **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. - -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. - -### 3.4 Onboarding -On selection: **joining formalities** run — salary is confirmed and a -**contract letter** issued. Creating the **CrewAssignment** automatically starts: - -- **salary** (the agreed structure becomes active), -- **victualing** (food/messing allowance accrual), -- **attendance** capture, -- **experience** accrual on this vessel/rank, -- **PF** tracking (UAN/EPF), and -- the **PPE issue** checklist. - -The crew member receives an **Employee ID**. - -### 3.5 Life on site -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** through the site **leave planner** (which shows every crew -member's contract span and leaves on one timeline). The PM raises **appraisals**; -the **MPO verifies**, the **Manager approves**. - -### 3.6 Office verification -The office is the source of truth for verified data. **The MPO verifies -everything site staff enter, except attendance**; **bank details and EPF are -verified by Accounts** (UAN/Aadhaar checked against EPFO). - -### 3.7 Sign-off & backfill -When a crew member signs off, the assignment closes, their **experience record -is updated** with the completed tour, and a **backfill Requisition** is raised -automatically — closing the loop back to §3.1. - -### 3.8 Payroll feed -At month end a **Wage Report** is generated per site: -`crew × salary × days-attended (+ victualing)`. It is reviewed, **approved by the -Manager**, and **sent to Accounts** for disbursement. - -## 4. Salient features & design decisions - -| # | Decision | Rationale | -|---|---|---| -| D1 | **Two coupled state machines** — `Requisition` (the vacancy) and `Application` (a candidate's progress against a requisition). | The requisition is "is this seat filled?"; the application is the per-candidate gated pipeline. Many applications per requisition; exactly one ends in onboarding. | -| D2 | **Unified `CrewMember`** record with a `status` (PROSPECT → CANDIDATE → EMPLOYEE → EX_HAND). | "Ex-hand preferred" only works if a candidate and an ex-employee are the same record; experience carries forward automatically. | -| D3 | **Onboarding is a side-effecting transition**, exactly like PO approval increments inventory. | Single source of truth: salary/victualing/attendance/experience/PF/PPE all start from one event, recorded as one `CrewAction`. | -| D4 | **Verification is a field-level state**, not a separate workflow. Each verifiable record carries `verificationStatus + verifiedBy`. Routing: site-entered → MPO; bank/EPF → Accounts. | Mirrors "view-only / upload / verify" split from the notebook; keeps the office as the trust boundary. | -| D5 | **Sensitive fields are masked & gated.** Salary on the contract letter, full bank account number, and Aadhaar/PAN are restricted; site staff get *view-only-except-salary* on contracts and *view-only* bank. | Matches the explicit notebook rules and basic PII hygiene. | -| D6 | **Rank is reference data with a self-hierarchy** (3+ levels), mirroring the `Account` accounting-code hierarchy. | Drives requisition criteria, document requirements (e.g. licence for drivers), and the org chart. | -| D7 | **Document requirements are rank-driven.** A `RankDocRequirement` defines which seafarer docs a rank must hold. | "Seafarer docs (based on role)"; driving licence only for drivers. | -| D8 | **Wage report is a generated artefact**, not live-computed on the Accounts screen. | Auditable monthly snapshot; mirrors PO export/report pattern. | -| D9 | **Reuse `Vessel`/`Site` as the cost centre** so crew cost is attributable on the same axis as PO spend. | Single cost-centre vocabulary across the portal. | -| D10 | **CV parsing is best-effort with manual fallback.** Extraction populates a draft; a human confirms. | Never block intake on a parser; keep the office in control. | - -## 5. Non-functional requirements - -- **Auditability** — every lifecycle transition and verification writes a - `CrewAction` row (actor, type, note, metadata), like `POAction`. -- **Privacy** — bank/EPF/identity documents are PII: stored via the same - signed-URL [file storage](File-Storage); account numbers and identity numbers - stored masked/encrypted; access gated by permission. -- **Consistency** — all mutations are Server Actions calling `requirePermission` - then the relevant state-machine guard; **no mutation REST endpoints**. -- **Notifications** — declarative per-transition email/in-app side-effects via - `lib/notifier.ts` (e.g. requisition raised → MPO; proposal → Manager; - appraisal verified → Manager; wage report ready → Accounts). -- **Document expiry** — documents with `expiryDate` surface upcoming-expiry - warnings (medical fitness, passport, CDC, STCW). - -## 6. Assumptions - -1. PM/APM/Site In-charge get a dedicated `SITE_STAFF` role rather than reusing - `TECHNICAL`. (Confirm in review — see Open Questions.) -2. Crew members are **data subjects**, not portal logins, in v1. A future phase - may give crew a self-service login. -3. **EPFO** UAN/Aadhaar verification is a manual/assisted step in v1 (record the - result); a programmatic check can follow the GstService precedent. -4. "Victualing" is a per-day messing allowance, configurable per rank/vessel. -5. One **active** assignment per crew member at a time. - -## 7. Open questions - -| # | Question | -|---|---| -| Q1 | New role `SITE_STAFF`, or extend `TECHNICAL`/`MANNING`? | -| Q2 | Does the candidate self-apply form live inside the portal (public route) or on the marketing site posting to an API? | -| Q3 | EPFO verification — assisted-manual now, or build an EPFO proxy microservice like GstService? | -| Q4 | Should salary structures be versioned per assignment (raises mid-contract) in v1, or single-structure-per-assignment? | -| Q5 | Is victualing part of the wage report total, or a separate accrual line? | -| Q6 | Do we need crew self-service (view own docs/payslip) in v1 or v2? | -| Q7 | Attendance granularity — daily present/absent only, or shift/hours? | - -See the requirement backlog in [Crewing User Stories](Crewing-User-Stories). +# Crewing Design Document + +> Companion pages: [Architecture](Crewing-Architecture) · +> [Data Model](Crewing-Data-Model) · [Workflows](Crewing-Workflows) · +> [Use Cases](Crewing-Use-Cases) · [Roles & Permissions](Crewing-Roles-and-Permissions) · +> [User Stories](Crewing-User-Stories) + +## 1. Purpose & scope + +The Crewing Module digitises Pelagia's **manning process**: keeping every +dredger and site crewed with competent, documented, paid people, and recording +the full lifecycle of each crew member. + +**In scope** + +1. Vacancy detection & **requisitions**. +2. **Recruitment pipeline** (shortlist → vetting → proposal → interview → + selection) for ex-hands and new candidates. +3. **Onboarding** and the automatic processes it kicks off. +4. **Crew records**: documents, bank, EPF, next-of-kin, emergency contact, + contract, PPE. +5. **Site HR**: leave planner, attendance. +6. **Appraisal** (PM → MPO → Manager). +7. **Sign-off** and experience accrual. +8. **Wage report** generation for Accounts. + +**Out of scope (v1)** — actual salary disbursement / banking integration (we +produce the report; Accounts pays), payslip generation, statutory return filing, +training-course delivery, and seafarer-document issuance (we store and verify, +we don't issue). + +## 2. Actors + +| Actor | Real-world role | Maps to PPMS role | +|---|---|---| +| **Site staff** | PM / Assistant PM / Site In-charge on the dredger | new `SITE_STAFF` role (proposed) | +| **MPO** | Manning / Personnel Officer in the office | existing `MANNING` role | +| **Accounts** | Finance team | existing `ACCOUNTS` role | +| **Manager** | Department / crewing manager | existing `MANAGER` role | +| **Candidate** | External applicant (ex-hand or new) | unauthenticated public form | +| **Crew member** | Onboarded employee | data subject; not necessarily a portal login in v1 | +| Admin / Superuser / Auditor | as in PO module | existing roles | + +See the on-vessel **rank hierarchy** (PM → … → Mess Boy) in +[Data Model § Rank](Crewing-Data-Model#rank-the-org-hierarchy). + +## 3. Domain narrative + +### 3.1 A vacancy opens +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. + +### 3.2 Sourcing candidates +The MPO shortlists candidates for the rank. **Ex-hands are preferred** (people +who have sailed with Pelagia before — their record is already in the system). +New candidates either **apply on the Pelagia site** (uploading a CV, which is +**parsed** for age, vessel type, current/past rank and experience — with manual +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**: + +- **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. + +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. + +### 3.4 Onboarding +On selection: **joining formalities** run — salary is confirmed and a +**contract letter** issued. Creating the **CrewAssignment** automatically starts: + +- **salary** (the agreed structure becomes active), +- **victualing** (food/messing allowance accrual), +- **attendance** capture, +- **experience** accrual on this vessel/rank, +- **PF** tracking (UAN/EPF), and +- the **PPE issue** checklist. + +The crew member receives an **Employee ID**. + +### 3.5 Life on site +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** through the site **leave planner** (which shows every crew +member's contract span and leaves on one timeline). The PM raises **appraisals**; +the **MPO verifies**, the **Manager approves**. + +### 3.6 Office verification +The office is the source of truth for verified data. **The MPO verifies +everything site staff enter, except attendance**; **bank details and EPF are +verified by Accounts** (UAN/Aadhaar checked against EPFO). + +### 3.7 Sign-off & backfill +When a crew member signs off, the assignment closes, their **experience record +is updated** with the completed tour, and a **backfill Requisition** is raised +automatically — closing the loop back to §3.1. + +### 3.8 Payroll feed +At month end a **Wage Report** is generated per site: +`crew × salary × days-attended (+ victualing)`. It is reviewed, **approved by the +Manager**, and **sent to Accounts** for disbursement. + +## 4. Salient features & design decisions + +| # | Decision | Rationale | +|---|---|---| +| D1 | **Two coupled state machines** — `Requisition` (the vacancy) and `Application` (a candidate's progress against a requisition). | The requisition is "is this seat filled?"; the application is the per-candidate gated pipeline. Many applications per requisition; exactly one ends in onboarding. | +| D2 | **Unified `CrewMember`** record with a `status` (PROSPECT → CANDIDATE → EMPLOYEE → EX_HAND). | "Ex-hand preferred" only works if a candidate and an ex-employee are the same record; experience carries forward automatically. | +| D3 | **Onboarding is a side-effecting transition**, exactly like PO approval increments inventory. | Single source of truth: salary/victualing/attendance/experience/PF/PPE all start from one event, recorded as one `CrewAction`. | +| D4 | **Verification is a field-level state**, not a separate workflow. Each verifiable record carries `verificationStatus + verifiedBy`. Routing: site-entered → MPO; bank/EPF → Accounts. | Mirrors "view-only / upload / verify" split from the notebook; keeps the office as the trust boundary. | +| D5 | **Sensitive fields are masked & gated.** Salary on the contract letter, full bank account number, and Aadhaar/PAN are restricted; site staff get *view-only-except-salary* on contracts and *view-only* bank. | Matches the explicit notebook rules and basic PII hygiene. | +| D6 | **Rank is reference data with a self-hierarchy** (3+ levels), mirroring the `Account` accounting-code hierarchy. | Drives requisition criteria, document requirements (e.g. licence for drivers), and the org chart. | +| D7 | **Document requirements are rank-driven.** A `RankDocRequirement` defines which seafarer docs a rank must hold. | "Seafarer docs (based on role)"; driving licence only for drivers. | +| D8 | **Wage report is a generated artefact**, not live-computed on the Accounts screen. | Auditable monthly snapshot; mirrors PO export/report pattern. | +| D9 | **Reuse `Vessel`/`Site` as the cost centre** so crew cost is attributable on the same axis as PO spend. | Single cost-centre vocabulary across the portal. | +| D10 | **CV parsing is best-effort with manual fallback.** Extraction populates a draft; a human confirms. | Never block intake on a parser; keep the office in control. | + +## 5. Non-functional requirements + +- **Auditability** — every lifecycle transition and verification writes a + `CrewAction` row (actor, type, note, metadata), like `POAction`. +- **Privacy** — bank/EPF/identity documents are PII: stored via the same + signed-URL [file storage](File-Storage); account numbers and identity numbers + stored masked/encrypted; access gated by permission. +- **Consistency** — all mutations are Server Actions calling `requirePermission` + then the relevant state-machine guard; **no mutation REST endpoints**. +- **Notifications** — declarative per-transition email/in-app side-effects via + `lib/notifier.ts` (e.g. requisition raised → MPO; proposal → Manager; + appraisal verified → Manager; wage report ready → Accounts). +- **Document expiry** — documents with `expiryDate` surface upcoming-expiry + warnings (medical fitness, passport, CDC, STCW). + +## 6. Assumptions + +1. PM/APM/Site In-charge get a dedicated `SITE_STAFF` role rather than reusing + `TECHNICAL`. (Confirm in review — see Open Questions.) +2. Crew members are **data subjects**, not portal logins, in v1. A future phase + may give crew a self-service login. +3. **EPFO** UAN/Aadhaar verification is a manual/assisted step in v1 (record the + result); a programmatic check can follow the GstService precedent. +4. "Victualing" is a per-day messing allowance, configurable per rank/vessel. +5. One **active** assignment per crew member at a time. + +## 7. Open questions + +| # | Question | +|---|---| +| Q1 | New role `SITE_STAFF`, or extend `TECHNICAL`/`MANNING`? | +| A1 | New role `SITE_STAFF_*` for the site heirarchy, MPO is "MANNING" | +| Q2 | Does the candidate self-apply form live inside the portal (public route) or on the marketing site posting to an API? | +| A2 | Lives at the static site pelagiamarine.com | +| Q3 | EPFO verification — assisted-manual now, or build an EPFO proxy microservice like GstService? | +| A3 | EPFO proxy microservice like GstService would be better | +| Q4 | Should salary structures be versioned per assignment (raises mid-contract) in v1, or single-structure-per-assignment? | +| A4 | It is possible for the salary and entire contract to be changed mid assignment and salary must be calculated accordingly (days x amt 1 + days x amt 2) | +| Q5 | Is victualing part of the wage report total, or a separate accrual line? | +| A5 | separate accrual line? | +| Q6 | Do we need crew self-service (view own docs/payslip) in v1 or v2? | +| A6 | No, only PM APM Site-incharge users needed from site, they will generate slips for other site crew members | +| Q7 | Attendance granularity — daily present/absent only, or shift/hours? | +| A7 | Shift/hours + overtime? | + +See the requirement backlog in [Crewing User Stories](Crewing-User-Stories).