Skip to content

Phase 19 (F5a): IMDG dangerous-goods declarations + shore-pass/crew-change lifecycle - #54

Merged
munisp merged 9 commits into
mainfrom
f5a-phase19-dg-shorepass
Sep 16, 2026
Merged

munisp merged 9 commits into
mainfrom
f5a-phase19-dg-shorepass

Conversation

@munisp

@munisp munisp commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Phase 19 Wave B — F5a scenario-gap implementation (audit A5-scenario-matrix §B9/§C5, both rated feasible on existing schema).

A5-B9 — IMDG dangerous-goods declarations

  • server/_core/imdg.ts: local structural IMDG validation — UN number format/range (0004–3550), class/division membership (1.1–9, 20 codes), packing-group I–III applicability per class (allowed: 3, 4.x, 5.1, 6.1, 8, 9), class-3 flashpoint required/bounded, EmS fire/spillage schedule shapes. No substance database is shipped or fabricated.
  • server/routers/dangerousGoods.ts: addItem/removeItem (owner-only, frozen once declaration cleared, audited via logAuditEvent), listForDeclaration (owner or officer), officerBoard (officer view surfacing DG-flagged declarations with their items). DG flag is derived (existence of ≥1 DG item — never stored, never stale). lookup always fails closed with IMDG_CODE_LOOKUP_NOT_CONFIGURED — honest state since licensed IMDG Code data is not configured.
  • Migration 0071: declaration_dg_items (FK declarations/users, CHECK constraints), hand-written minimal delta + journal entry (0069/0070 precedent).

A5-C5 — Shore-pass / crew-change lifecycle

  • Builds on FAL5/FAL6 field patterns (server/data/imoMapping/v1/fal5.json) and the port-interop seafarer/STCW registry (blueeconomy-port-interoperability internal/registry/seafarer.go), consumed via new config-gated server/_core/seafarerRegistryClient.ts (GET /v1/registry/certificates/verify, typed classified errors, call-time config).
  • server/routers/shorePass.ts: submit → officer verifyCertificatedecide (approve/reject) → revoke / expiry (lazy at read + expireSweep). Approval is verification-gated fail-closed: cert-bearing applications require VERIFIED; FAILED/NOT_CONFIGURED can never be approved. Honest states when upstream crew data is not configured: CREW_REGISTRY_NOT_CONFIGURED / CREW_REGISTRY_UNAVAILABLE, recorded durably on the application. Append-only shore_pass_events audit trail on every transition.
  • Migration 0071: shore_pass_applications + shore_pass_events with CHECK constraints and indexes.

Notes

  • New drizzle tables live in drizzle/schemaDgShorePass.ts (NOT the central drizzle/schema.ts) to avoid conflicts with concurrent workstreams.
  • Registered dangerousGoods/shorePass in the PRA-109 permify coverage gate exempt list (owner-scoped writes, in-router officer enforcement — aeoFastLane/queuePolicy precedent).
  • Routers registered append-style at the tail of server/routers.ts.
  • submit (not apply) — apply is a tRPC reserved router key.

Tests

  • New suites: server/_core/imdg.test.ts (29), server/routers/dangerousGoods.test.ts (10), server/routers/shorePass.test.ts (18+5 table-driven) — 62 tests, all green; plus server/testutils/mockDrizzleDb.ts (condition-evaluating drizzle chain mock).
  • Full suite on this branch: 200 files, 5338 passed, 0 failed, 87 skipped (13 DB-gated files skip — no PostgreSQL in sandbox).
  • tsc --noEmit clean.

@munisp
munisp merged commit 2c26fff into main Sep 16, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant