Skip to content

feat(executive): port performance report endpoints (Phase 16 Wave P2) - #50

Merged
munisp merged 1 commit into
mainfrom
p2/phase16-port-performance-api
Sep 7, 2026
Merged

feat(executive): port performance report endpoints (Phase 16 Wave P2)#50
munisp merged 1 commit into
mainfrom
p2/phase16-port-performance-api

Conversation

@munisp

@munisp munisp commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Backend for the ministry-portal Port Performance page (A4 contract).

  • GET /v1/port-performance/report?period= — real SQL aggregates against manifests/bills_of_lading/transshipment_links/declarations; honest value:null where a source has no rows; period-over-period delta_pct.
  • GET /v1/port-performance/report.pdf?period= — JWS-EdDSA signed PDF, same envelope + singlewindow-<epoch> kid convention as /v1/briefings/weekly.
  • Fail-closed: DB outage or missing signing key -> 503; teu_out null with the missing port-interoperability gate-move aggregate named in source.
  • Tests: server/portPerformance.test.ts (10 tests) — aggregation, null honesty, deltas, route registration, signed-PDF round-trip. tsc --noEmit clean.

GET /v1/port-performance/report?period=weekly|monthly|quarterly returns
fail-closed real aggregates (cargo throughput, vessel calls, TEU in,
transshipment, export/import tonnage) shaped PortPerformanceMetric
{source,value|null,delta_pct|null,unit} with period-over-period deltas;
teu_out is served null with the missing upstream named (no gate-move
aggregate exists on port-interoperability). GET /v1/port-performance/report.pdf
issues a JWS-EdDSA signed PDF via the weekly-briefing envelope/kid
convention (server/lib/envelopeSign). DB outage -> 503; unconfigured
signing key -> 503, no unsigned output.
@munisp
munisp merged commit 7f7cc13 into main Sep 7, 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