European event procurement · build status

Procurevent

From a request, through quotes and a comparison, to an award and somebody turning up. The ledger is the authority; this page is generated from it and from nothing else.

generated 2026-08-03 23:11 UTC tree 54cc7f3 (uncommitted changes present) 36 slices from docs/BUILD-LEDGER.md

Overall

78%complete
28 complete2 verified, awaiting production1 in progress5 not started 36 total

Phases

Slices

P1 – P36 · 36 slices

28 complete · 2 verified, awaiting production · 1 in progress · 5 not started

Every module

SliceNameStatusThe ledger’s note
Slices
P1Schema foundation and enumscomplete0001. Types, uuidv7, the forbid_mutation trigger that makes five tables append-only.
P2Identity and tenancycomplete0002. Organisations, workspaces, users, memberships, roles. db/test/isolation-test.sh, 18 assertions.
P3Federation and taxonomycomplete0003. Every federated table carries its own uuid plus a (source_id, external_id) natural key — the shape event.clinic's R6 later required, built five days earlier. D-112.
P4Suppliers and compliancecomplete0004.
P5Events and requestscomplete0005.
P6Clarifications and submissionscomplete0006.
P7Evaluation, approval, award tablescomplete0007. awards, award_snapshots, award_line_items, award_notifications.
P8Handoff, catalog, notifications, auditcomplete0008. Tables only; the handoff feature is P24.
P9Row-level securitycomplete0009, 0010. Every table forced. Never tested as the database owner — BYPASSRLS would make the suite pass against no security at all.
P10The privilege modelcomplete0021. Both databases fail closed: a table with no grant produces permission denied naming it, loudly, on the developer's machine. ./db/privilege-audit.sh.
P11Migration governancecompletemigration-ledger.sh, apply-migrations.sh. Migration state is measured, never recorded.
P12Sign-up and provisioningcompleteClerk, db/test/provisioning-test.sh and api/test/provisioning-api-test.sh, 50 assertions between them.
P13The request buildercompleteTen chapters, lots, criteria. api/test/workspace-api-test.sh, 141 assertions — the largest suite in the repository.
P14Budget, scope and timelinecomplete0017. db/test/budget-timeline-test.sh, 18.
P15Issuing a requestcomplete0022, and 0042 which moved the per-lot budget out of the snapshot after measuring that an invited supplier could read it. db/test/issue-request-test.sh, 42.
P16Inviting supplierscompletedb/test/invitation-target-test.sh, 17.
P17The supplier answerscompleteInterested or declined, with a reason the buyer reads. api/test/supplier-api-test.sh, 50.
P18Clarifications and notescomplete0016. db/test/note-visibility-test.sh, 12.
P19Bid feescomplete0031. db/test/bid-fee-test.sh, 29.
P20The supplier's quotecomplete25 fields, two-press send, everything locks on submit. api/test/quote-api-test.sh, 63.
P21Submission deadlinescomplete0036. db/test/submission-deadline-test.sh, 16.
P22ComparisoncompleteLot by lot, with exclusions. api/test/compare-api-test.sh and db/test/exclusion-verdict-test.sh, 46.
P23Awarding and issuingverified, not deployedStages 9 and 10. Split awards, two-press confirm, email notices. 00430047 are local only; production is at 0044. award-api-test.sh 33, issue-api-test.sh 39, award-reference-test.sh 12.
P24The handoffverified, not deployedStage 11. Scope, build-up and strike windows, site address, the person each side phones, a checklist. 0049 closed a defect that let a supplier rewrite the buyer's terms and delete the record. handoff-api-test.sh 51, handoff-ownership-test.sh 20.
P25Supplier discoverabilitycomplete0038, 0039. Being findable by a signed-in buyer and being readable by anyone are different permissions. db/test/supplier-discoverability-test.sh, 27.
P26The public supplier directorycompleteapi/test/public-directory-api-test.sh, 23. Q-047: a supplier opts in through its own control, and the copy states the consequence beside it.
P27Directory sync from event.clinicin progressCategories sync cleanly, 3 167 rows. Venues cannot: upstream now holds 31 135 and the sync makes one detail request per venue. Q-054. api/test/sync-test.sh, 155.
P28Billing and subscriptionscompleteStripe, 0040 and 0041. The webhook re-fetches the event from Stripe rather than trusting the posted body. api/test/billing-api-test.sh, 35.
P29The marketing sitecompleteAstro, static, nightly rebuild. Never renders fabricated records as real.
P30The platform consolecompleteapi/test/platform-api-test.sh, 19.
P31Immutable personal datacompleteD-016. IDs in append-only records, never names. db/test/immutable-personal-data-test.sh discovers the tables from the catalogue on every run, 11 assertions with 4 controls.
P32Approvalsnot started0007 has the full design — policies, instances, steps, actions — and no screens.
P33Orders and purchase ordersnot started0008 has orders. Nothing reads it.
P34Supplier performance reviewnot startedsupplier_evaluations exists. Q-045 touches the shape of the verdict.
P35Documents and reportsnot startedSidebar shows both as "soon".
P36Events as a first-class screennot startedThe table drives the handoff's seeded windows; there is no screen.

What “done” means here

Done means a verification script exited zero on the committed tree. Not that somebody opened the screen and it looked right, and not that an agent reported success. Every slice marked complete above has a script in scripts/ that exits 0 against the code as committed; a slice whose script has not exited 0 in a single run is not complete here, whatever else was built. Exit 2 means BLOCKED — nothing was measured, which is not a pass. The same is true of a suite that prints BLOCKED: no assertion ran.

Run every gate at once:
./db/migration-ledger.sh local

Run it locally

# 1 · seed a tender you can award and hand off
cd ~/Documents/procuvent && ./api/test/fixtures/stage10-browser.sh
# 2 · the API, against local Postgres
cd ~/Documents/procuvent && PROCUVENT_API_DATABASE_URL=postgresql://procuvent_app_rw@localhost:5432/procuvent_dev PORT=8802 PROCUVENT_DEV_AUTH=1 PROCUVENT_DEV_MAIL=1 node api/scripts/serve-api.mjs
# 3 · the app, signed in as the buyer
cd ~/Documents/procuvent/app && VITE_DEV_AUTH=1 VITE_DEV_AUTH_SUBJECT=stage10-buyer VITE_API_BASE=http://localhost:8802 npm run dev -- --port 5186

Screens with data

Screen
Open at
What is on it