# Evidence Topic: Booking manual-review schema audit ## Metadata - Date: 2026-07-31 - Status: Superseded implementation snapshot; audit-grade history gap remains active - Scope: Live `booking_test`, Booking parser 2.0, migrations 008/014/015 and Web review composition - Confidence: Fact - Source: repeatable-read live metadata, DDL/contract/source inspection, focused tests, process timestamps and HTTP probes - Last verified: 2026-07-31 11:21 +08:00 - Stale trigger: port-8766 restart, HTTP method-adapter change, first real draft/activation, or review-policy decision ## Question Can the current Booking database model and running program support parser 2.0's unrecognized-room items and a human confirmation loop? ## Evidence - Migration 008 already supplied a coarse row gate: `parse_versions.parse_status` permits `needs_review`, while `current_row_parses` and downstream views permit only accepted parses in accepted batches. The existing 867 parses are all accepted; all 867 canonical room items have non-null room codes. - At 11:12 +08:00 the live database still lacked migrations 014/015. At 11:19 +08:00 a new read-only snapshot found `booking.current_source_batch`, `booking.extraction_drafts` and `booking.extraction_draft_items`. This audit did not perform those concurrent migrations. - The live singleton now points to accepted source batch 1. Both draft tables are empty, so no real upload/review/activate transaction has yet been evidenced by their data. - The live draft schema supports a basic latest-state operator loop: draft `reviewing/activated/superseded`; item `confirmed/pending/deleted`; source sheet/row/item, Group Code, raw hotel/room text, canonical room type, quantity, automatic flag, source fragment and timestamps. A pending item must have a null canonical room type; a confirmed item must have one. All new constraints are validated. - The schema is not an approval ledger. It has no assignee/reviewer/actor, reason/note, explicit decision timestamp, before/after values, immutable item revision or append-only review event. No trigger makes closed drafts immutable or enforces zero pending items at activation; these rules currently depend on application transactions. - The new PostgreSQL repository uses serializable transactions plus a shared advisory lock, edits only reviewing drafts, rejects pending/empty activation, writes confirmed items to accepted canonical facts, switches the current source and closes the draft atomically. Re-extracting the same non-activated artifact deletes its earlier draft/items, so prior manual edits are not durable history. - The browser and business router model upload, list, edit, delete, discard and activate. However the browser sends `PATCH` for confirmation and `DELETE` for item/draft removal, while `arr_web/server.py` implements only `do_GET` and `do_POST`. Read-only loopback probes returned HTTP 501 for both `PATCH` and `DELETE`. The application-route unit tests call the router directly and therefore do not catch this transport gap. - The active port-8766 process started at 2026-07-30 23:19. The new Python composition files were modified at 2026-07-31 11:07-11:13, and the server has no hot-reload mechanism, so the running process has not loaded the new repository/routes even though the database structure is now present. - Twenty-seven focused parser/migration/review-contract/fake-repository/Web-route tests pass and a fresh source import succeeds. No test executes draft CRUD/activation against a real PostgreSQL transaction, and no server-adapter test covers `PATCH`/`DELETE`. ## Follow-up Resolution Later on 2026-07-31, `arr_web/server.py` gained bounded PATCH/DELETE dispatch and real loopback socket coverage. The supplied workbook then passed parser replay, the live review schema passed a read-only repository probe and the complete source implementation was recorded in [Booking Excel extraction program](2026-07-31-booking-extraction-program.md). The original audit remains evidence of the before-state and of the still-open actor/reason/revision-history decision; its claim that PATCH/DELETE are currently unimplemented is no longer authoritative. ## Original Point-In-Time Finding The problem is not relational normalization itself. Canonical `booking.room_items` should remain accepted facts; pending extraction belongs in a separate draft/workflow layer. The now-live 015 tables implement that separation and are enough to represent a simple single-operator correction state. At the 11:21 snapshot, the complete workflow was not runnable: the active service predated the new composition and the HTTP adapter could not transport manual-confirm/delete calls. The later extraction-program work repaired and loaded those implementation gaps. The audit-depth finding remains: if “人工确认” must be attributable and auditable, the schema stores only the latest edited state, not who decided what, why, and how it changed. ## Original Point-In-Time Capability Classification | Capability | Live database | Current program/runtime | |---|---|---| | Keep pending extraction out of canonical reports | Yes, through separate draft tables and accepted current-source gate | Repository models it; real PostgreSQL flow untested | | Item pending/confirmed/deleted | Yes | UI/router/repository model it | | Edit room type and quantity | Schema supports latest state | At 11:21, blocked because `PATCH` returned 501; later resolved | | Delete item / discard draft | Schema supports status changes | At 11:21, blocked because `DELETE` returned 501; later resolved | | Zero-pending atomic activation | Not declaratively enforced | Repository enforces it; real DB transaction untested | | Reviewer/reason/history | No | No | | Currently loaded on port 8766 | N/A | No; process predates new Python source | ## Original Open Items And Resolution - PATCH/DELETE handling, server-level tests, controlled restart and Booking-source readiness are resolved in the later extraction-program evidence. - Add real-PostgreSQL draft CRUD, atomic activation and rollback tests before the first business workbook import. - If audit-grade review is required, add actor/reviewer, action/reason, event time, old/new values or immutable item revisions, optimistic concurrency and database transition guards. - Run one controlled raw workbook through upload -> pending review -> confirmation/deletion -> activation -> company report. No such business mutation was performed by this audit.