Update Crewing Design Document
parent
24dc4c62c1
commit
9bcc43f460
1 changed files with 171 additions and 164 deletions
|
|
@ -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).
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue