Coastal Shipping 08 — Port Costs & Disbursement Manager (coast_08_portcosts)

Order the port service, keep the evidence, check the supplier's invoice, approve one immutable cost per line, and allocate it internally — port supplier rates, service orders and evidence, supplier invoices, approved costs and cost allocation.

Its central question:

What did the port services for this call really cost, who is responsible for paying it, and is it supported by evidence that the service happened?

coast_08_portcosts is application SHP-08 of the Coastal Shipping series (coast_NN_<name>, Stage 2; each able to run stand-alone or as a member of a network). It shares no tables and no foreign keys with its siblings (for example coast_06_voyage and coast_07_accounts) — they link by canonical_ref strings only. All data is fictional.

The spine

PortServiceOrder → PortServicePerformance → PortCostEstimate → PortSupplierInvoice(Line) → PortApprovedCost → PortCostAllocation, with PortCostAudit recording history and PortCostException raising what assurance must see.

The documents

Page What's in it
00 — Overview What the app is, the rules it is built around, the 17 models by area, the demo scenario
01 — Quick Reference Menu map, every model, status vocabularies, the messages, how to run, seed and regenerate
02 — System Diagram The data model as diagrams (+ interactive viewer) and how the app links to its siblings

Status

Built (rules and handlers, tested): the order workflow (approve with a valid call, an active provider and an assigned payer whose agent appointment is current; perform on a verified service fact; close when every invoice line is reconciled; cancel before any performance); the rate estimate (approved rate scope, increment, minimum, cent rounding, immutable, never payable); the supplier invoice workflow (record with a normalised key that stops a duplicate, match with evidence and exact line totals, dispute an unresolved variance, resolve, approve independently and create one immutable cost per line, credit notes as exact signed reversals); one responsible payer per cost; exact net and tax allocation and its approval; immutable approved costs; append-only audit; control exceptions with resolution. Messages: the projections from coast_06_voyage and coast_07_accounts (stale and conflicting versions rejected), the verified activity facts (matched to an approved order, pending until one exists), the assurance action request, and the sweep portcost.detect_unmatched_facts (matches pending facts to orders approved since, and raises UNMATCHED_SERVICE_FACT for the rest after a day).

Not built yet: screen buttons for estimate, match, dispute and allocate (the transitions are made by the status field, guarded; the estimate and the allocation split are functions in rules.py); the sweep is not yet on the network's timetable; the manifest-line weights are entered, not read from coast_02_manifest. The rules are in integration/ (rules.py, engine.py), with their tests under server/tests/integration_apps/.

Prototype system; draft. All names and amounts in the demo data are fictional.