Add governed PO approvals and ERP CSV exchange - #4
Conversation
Owner-bypass audit notePR #4 is being considered for repository-owner PR-mode bypass because the only unsatisfied ruleset condition is one approving review, and the PR author cannot provide an independent self-review. Evidence checked immediately before merge:
Independent pre-publication review summary: the atomic approval, idempotency, ERP CSV exchange, secret-handling, and demo-consistency changes received separate code and security-governance review; identified release blockers were corrected before the current head, with no unresolved critical or important finding recorded. This summary is supplemental evidence and does not represent a formal GitHub approval. The bypass is explicitly limited to this already-reviewed PR. The L1/L2/L3 entitlement and role-capability work will start from updated |
Scope
This PR establishes the SQLite correctness boundary for governed purchase-order writes and adds an L3 V1 ERP CSV batch-exchange prototype on top of it. It does not claim that all ERP writes are governed, that external delivery is exactly-once, that the audit chain is immutable, or that the system is production-ready.
L3 V1 is intentionally narrow: one CSV row represents one purchase order with one item. It is not a generic ETL system, a real-time ERP API connector, or a promise of compatibility with every ERP.
What changed
Governed PO execution
L3 ERP CSV exchange
Feature and deployment notes: docs/erp_csv_exchange.md
Safety properties covered
Verification
Trust boundary and known limitations
Follow-ups
Demo repair verification (2026-07-20)
Live L1/L2/L3 preview uncovered and fixed two reproducibility defects: fresh databases did not encode every schema field required by the bundled demo seeder, and Pandas null values could crash risk-map hover rendering. The ERP export caption now also matches the immutable approved-snapshot behavior.
Migration evidence: a regression test constructs the prior
purchase_ordersandcustomersschemas with existing rows, runsinit_db(), verifies the original data is unchanged, and confirms only the required columns/table are added.Verification:
146 passedgit diff --checkpassedFiles in this follow-up commit:
.gitignorebackend/database.pyfrontend/components/supply_map.pyfrontend/page_erp_csv_exchange.pyscripts/seed_e_day1_demo_data.pytests/test_erp_exchange_ui.pytests/test_demo_seed_schema.pytests/test_supply_map.py