# 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.
