Commit graph

9 commits

Author SHA1 Message Date
c82efa71af feat(crewing): Phase 3c — onboarding (flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 40s
PR checks / integration (pull_request) Successful in 28s
Final slice of Phase 3 (stacked on 3b pipeline). The onboarding transaction that
turns a SELECTED candidate into active crew, per Crewing-Implementation-Spec
§8.5/§9/§11. Behind NEXT_PUBLIC_CREWING_ENABLED; production unchanged.

What's in
- Schema (crewing_onboarding migration): CrewAssignment + AssignmentStatus
  (ACTIVE/ON_LEAVE/SIGNED_OFF — leave/sign-off are Phase 4); ContractLetter
  (salaryRestricted); SalaryStructure += assignmentId; CrewActionType +=
  CREW_ONBOARDED. Employee numbers CRW-xxxx via lib/employee-number.ts.
- Action (onboardCandidate, onboard_crew): one transaction off a SELECTED
  application — assign employeeId, create CrewAssignment(ACTIVE, signOnDate),
  bind the approved SalaryStructure (assignmentId + effectiveFrom), Application →
  ONBOARDED, Requisition → FILLED, CrewMember → EMPLOYEE (+ currentRank); contract
  letter stored after. Guards flag + permission + SELECTED state.
- Screen: the SELECTED action card's "Onboard to crew" modal (joining date,
  contract upload, starts-automatically chips); the CRW- number shows on the
  ONBOARDED card.

Tests & docs
- Integration: onboarding.test.ts (5) — full transaction, requisition FILLED +
  salary binding, joining-date + SELECTED-only guards, permission gating, sequential
  CRW- ids. type-check clean; full unit (234) + integration (168) green.
- CLAUDE.md updated with the Phase 3c surface.

Deferred: SITE_STAFF login creation for management ranks (grantsLogin) — a
follow-up; attendance/experience/PPE records begin in Phase 4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 19:12:53 +05:30
3ec3a2b4ef feat(crewing): Phase 3b — recruitment pipeline (flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 40s
PR checks / integration (pull_request) Successful in 30s
Second slice of Phase 3 (stacked on 3a candidates). The gated 7-stage
recruitment pipeline per Crewing-Implementation-Spec §5.1/§8.4–8.5/§8.13.
Behind NEXT_PUBLIC_CREWING_ENABLED; production unchanged.

What's in
- Schema (crewing_pipeline migration): Application (one per requisition+candidate)
  + 7-stage ApplicationStage; ApplicationGate (SALARY/SELECTION/WAIVER pending =
  Manager queue items); ReferenceCheck; effective-dated SalaryStructure (attached
  to the Application now, bound to the assignment in 3c); minimal BankDetail/EpfDetail
  captured at DOC_VERIFICATION (PII encryption deferred to Phase 4). CrewAction +=
  applicationId; pipeline CrewActionTypes.
- State machine: lib/application-pipeline.ts — sourcing advances MPO/Manager;
  approve_salary + select are Manager-only; orthogonal canReject; BOARD_STAGES.
- Actions: addApplication (first candidate → requisition SHORTLISTING), advanceStage,
  recordReferenceCheck, verifyDocuments (bank/EPF), agreeSalary→approveSalary/returnSalary,
  recordInterviewResult, requestInterviewWaiver→approve/decline, selectCandidate
  (→ requisition SELECTED)/returnSelection, rejectApplication. Waiver never automatic (R2).
  Notifications SALARY/SELECTION/WAIVER + CANDIDATE_PROPOSED.
- Screens: pipeline board per requisition (7 columns + Add candidate); application
  workhorse (7-step stepper + adaptive per-stage action card); "Open pipeline" on the
  requisition detail. Central /approvals gains a crewing section (inline Approve/Return)
  for one unified Manager queue (§8.13 R8).

Tests & docs
- Unit: application-pipeline.test.ts (9). Integration: applications.test.ts (10) —
  full happy path, salary/selection/waiver approvals + Manager-only gating, failed
  interview, reject, site-staff lockout. type-check clean; full unit (234) + integration
  (163) green.
- CLAUDE.md "Crewing" updated with the Phase 3b surface.

Deferred: onboarding (Epic D, Phase 3c) — SELECTED → ONBOARDED, CrewAssignment,
employeeId, requisition → FILLED, salary bound to the assignment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:49:12 +05:30
be6db075dc feat(crewing): Phase 3a — candidates / talent pool (flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 36s
PR checks / integration (pull_request) Successful in 27s
First slice of Phase 3 (Epics B/C/D shipped as stacked sub-PRs). Adds the
CrewMember talent-pool spine and the Candidates screens. Behind
NEXT_PUBLIC_CREWING_ENABLED; production unchanged. Stacks on the requisitions
branch (Phase 2).

What's in
- Schema (crewing_candidates migration): CrewMember (spine) + CrewStatus,
  CandidateType, CandidateSource enums; CrewAction gains a nullable crewMemberId;
  CrewActionType += CANDIDATE_ADDED/UPDATED. employeeId is assigned at onboarding
  (3c), so it's nullable here.
- Actions (crewing/candidates/actions.ts): addCandidate / updateCandidate —
  guard flag + manage_candidates, write a CrewAction, optional CV upload via
  buildStorageKey("cv", …) + uploadBuffer (no parsing — A2 deferred). EX_HAND
  source ⇒ type/status EX_HAND; edits never downgrade an EMPLOYEE.
- Screens: /crewing/candidates (master list with search/source/rank-applied/
  min-experience filters as removable chips + match count + Clear all; Add-candidate
  modal) and /crewing/candidates/[id] (profile; pipeline stepper is 3b). Candidates
  added to the flag-gated Crewing nav (Manager + MPO).

Tests & docs
- Integration: candidates.test.ts (7) — add/update, ex-hand derivation, employee
  no-downgrade, permission gating. type-check clean; full unit (225) + integration
  (153) suites green.
- CLAUDE.md "Crewing" section updated with the Phase 3a surface.

Deferred: public careers intake API (A2, §13 open question); CV parsing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:23:01 +05:30
0b2ed9ac07 feat(crewing): Phase 2 — requisitions + relief requests (flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 37s
PR checks / integration (pull_request) Successful in 28s
Second slice of the Crewing module per wiki Crewing-Implementation-Spec §12
(build order item 2). Everything stays behind NEXT_PUBLIC_CREWING_ENABLED;
production is unchanged. Schema is added incrementally — this lands the
requisition lifecycle layer.

What's in
- Schema: Requisition (OPEN→SHORTLISTING→PROPOSING→INTERVIEWING→SELECTED→FILLED,
  →CANCELLED), ReliefRequest, CrewAction (the POAction mirror) + their enums.
  Migration crewing_requisitions.
- State machine: lib/requisition-state-machine.ts mirrors po-state-machine
  (selection Manager-only; orthogonal cancel from OPEN/SHORTLISTING by
  cancel_requisition holders, §6). Codes REQ-9000… via lib/requisition-number.ts.
- Actions: raise/cancel/transition + requestReliefCover/convertReliefToRequisition,
  each guarding flag+permission+state, writing a CrewAction and notifying. Shared
  autoRaiseRequisition() (lib/requisition-service.ts) is the backfill entry point
  for sign-off / leave-clash (later phases).
- Notifier: notifyCrew() PO-independent path + CrewNotificationEvent.
- Screens: /crewing/requisitions (list + Raise modal + relief convert) and
  /crewing/requisitions/[id] (detail). Requisitions added to the flag-gated
  Crewing sidebar (Manager + MPO, §7).

Tests & docs
- Unit: requisition-state-machine.test.ts (11).
- Integration: requisitions.test.ts (15) — raise/cancel/transition, relief
  request + convert, auto-raise, permission gating.
- CLAUDE.md "Crewing" section updated with the Phase 2 surface.

Deferred: sign-off/experience (Epic K, §12 item 2) depends on the crew/assignment
models from Phase 3/4; autoRaiseRequisition() is ready for it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:22:59 +05:30
d0006a8fc7 feat(crewing): foundations — SITE_STAFF role, ranks reference data + admin (flagged)
All checks were successful
PR checks / checks (pull_request) Successful in 36s
PR checks / integration (pull_request) Successful in 28s
Phase 1 of the Crewing module per wiki Crewing-Implementation-Spec §12, all dark
behind NEXT_PUBLIC_CREWING_ENABLED (off by default — production unchanged).

- schema: add SITE_STAFF to Role; add Rank (self-referential org hierarchy, like
  Account) + RankDocRequirement, RankCategory & SeafarerDocType enums.
- permissions: full §6 crewing grant matrix (PO_ROLE_PERMISSIONS +
  CREWING_ROLE_PERMISSIONS merged); SITE_STAFF row; MPO has no attendance/leave,
  approvals are Manager-only, manage_ranks is Manager+Admin.
- feature flag: CREWING_ENABLED (opt-in "true").
- nav: flag-gated Crewing section scaffold + "Ranks & documents" under Admin.
- reference data: rank-data.ts + rank-doc-data.ts seeded via shared seed-ranks.ts
  in both dev and prod seeds (19 ranks, 118 doc requirements).
- screen: /admin/ranks — rank hierarchy card + per-rank required-documents card.
- role-label/prefix maps updated for the new role.

Tests: unit (permission matrix + flag), integration (ranks admin CRUD, parent
linking, cycle/children guards, doc-requirement upsert/remove, permission gating).
Docs: CLAUDE.md "Crewing (feature-flagged)" section + env var.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 13:26:04 +05:30
58a5a00594 docs: bring CLAUDE.md, README, Docs and CHANGELOG up to date with current product
Reflects this iteration's domain/feature changes across the docs set:
- Cost centre = Vessel only (labelled 'Cost Centre'); costCentreRef/Site removed
- Companies (multi-company invoicing) on POs and exports
- 3-level 6-digit accounting-code hierarchy; leaf-only PO selection
- Structured PO numbers COMPANY/VESSEL/ID/FY (ids from 9000)
- Compulsory payment date; editable poDate; export date = approval date
- Submitter vendor creation (unverified until proven); verifyVendor
- Import PO -> CLOSED with auto vendor/product creation
- Inventory flag; inventory added at approval; partial pay/receipt states
- Microsoft Entra SSO (nullable passwordHash); profile reachable by all roles
- README: roles, domain concepts, db:seed:prod, migrate-before-serve callout
- CHANGELOG: Added/Changed/Fixed for the above

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:43:24 +05:30
e31014d45c docs: document the issue-to-deploy pipeline, staging, and test DB
- App/README.md: add FORGEJO_*/NEXT_PUBLIC_ENV_LABEL env vars and an
  'Operations & Automation' section pointing to automation/README.md.
- App/CLAUDE.md: complete the env var list (AZURE_AD_*, FORGEJO_*, GST_SERVICE_URL,
  NEXT_PUBLIC_ENV_LABEL) and note the prod-mirror test DB used by autofix/staging.
- .env.example: document NEXT_PUBLIC_ENV_LABEL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:07:55 +05:30
cc7251e6b7 feat: Cost Centre covers vessels and sites, vessel codes, Accounting Code rename, vessel-site assignment
- Undo Vessel→Cost Centre rename in admin (admin shows "Vessel Management" again)
- Sidebar: "Cost Centres"→"Vessels", "Accounts"→"Accounting Codes"
- PO forms (new/edit/import/manager-edit) now show both Vessels (with code) and Sites in the
  Cost Centre dropdown, encoded as v:<id> / s:<id> via a costCentreRef field
- vesselId on PurchaseOrder is now nullable; siteId is set when a site is the cost centre
- History, approvals, dashboard, my-orders, payments display vessel.name ?? site.name as Cost Centre
- History and approvals cost centre filters use costCentreRef URL param supporting both types
- Admin vessel form: adds Site assignment dropdown
- Admin accounts: renamed to "Accounting Code" throughout (pages, forms, sidebar)
- PO detail and exports: "Account" label renamed to "Accounting Code"
- Site detail: "Assigned Vessels (Cost Centres)" heading; vessel detail breadcrumb fixed
- Create PO links from vessel/site detail use ?costCentreRef= param
- Export routes handle costCentreRef filter param (with legacy vesselId fallback)
- DB migration: ALTER TABLE PurchaseOrder ALTER COLUMN vesselId DROP NOT NULL
- CLAUDE.md updated with Cost Centre Model documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 03:04:29 +05:30
19029a5a77 chore: restructure repo — flatten App/pelagia-portal to App, rename Prototype→Wireframe and Spec→Design
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 23:18:58 +05:30
Renamed from App/pelagia-portal/CLAUDE.md (Browse further)