fix: support bilingual Booking Excel headers

This commit is contained in:
Wyndham ARR
2026-08-11 15:29:42 +08:00
parent ca3e8e18fa
commit c947230471
15 changed files with 366 additions and 30 deletions

View File

@@ -47,7 +47,7 @@
| Step | Source | Destination | Gate |
|---|---|---|---|
| 1 | Authenticated Booking XLSX upload | Bounded parser 2.0 | Requires Tour Code + exact `โรงแรม`, latest-row/cancellation semantics and room-item extraction/review |
| 1 | Authenticated Booking XLSX upload | Bounded parser 2.1 | Requires one approved exact Tour Code/Group Code alias plus one approved exact hotel-detail alias on the same row; preserves latest-row/cancellation semantics and room-item extraction/review |
| 2 | Parsed raw items | Private artifact + extraction draft | Live migration 015 preserves source coordinates, confirmed/pending/deleted item state and extracted values |
| 3 | Human review | Draft item updates | Confirm/edit or atomically soft-delete 1-50 unique selected items while canonical current Booking source remains unchanged |
| 4 | Fully reviewed draft | Accepted canonical batch + `booking.current_source_batch` | Live 014/015 plus repository zero-pending/atomic activation; real PostgreSQL transaction-only vertical slice passes |
@@ -68,4 +68,4 @@ equals its persisted `as_of_date`. Every data-row `TOTAL PRICE` cell is `=R[row]
## Last Updated
2026-08-06
2026-08-11

View File

@@ -4,8 +4,8 @@
|---|---|---|
| `arr_web/auth.py` | Login credential verification and bounded attempt ledger | Environment-owned single-operator identity; dependency-free constant-time comparison; no secret logging |
| `arr_web/programmatic.py` | XML upload and manual-price finalization coordinator | Registers the validated browser basename separately from canonical `source.xml`; pure price misses create no Finance version, while a frozen manifest replays the original source for final commit |
| `arr_web/booking_uploads.py`, `booking_ingestion/excel.py` | Authenticated Booking source upload and bounded raw XLSX parsing | Parser 2.0 reads Tour Code plus exact `โรงแรม`, latest-row cancellations and extracted room items with review state; coordinator/backend route contracts target drafts |
| `booking_ingestion/excel_postgres.py` | Earlier direct Booking full-source import/activation path | Its one-item immediate-accept implementation does not represent parser 2.0 review and must not be treated as the completed review repository |
| `arr_web/booking_uploads.py`, `booking_ingestion/excel.py` | Authenticated Booking source upload and bounded raw XLSX parsing | Parser 2.1 uses approved full-cell exact aliases for Tour Code/Group Code and hotel detail (including legacy Thai and current bilingual forms), latest-row cancellations and extracted room items with review state; coordinator/backend route contracts target drafts |
| `booking_ingestion/excel_postgres.py` | Earlier direct Booking full-source import/activation path | Its one-item immediate-accept implementation does not represent parser 2.1 review and must not be treated as the completed review repository |
| `booking_ingestion/excel_review.py`, `booking_ingestion/excel_review_postgres.py` | Editable extraction drafts and atomic reviewed-source activation | Single-operator repository uses advisory locking and a zero-pending gate; real PostgreSQL transaction/rollback acceptance passes; actor/reason/revision history is not implemented |
| `arr_web/processing_runtime.py` | PostgreSQL + OSS + processor composition | Active production processing composition |
| `arr_processing/local.py` | Bounded subprocess and output manifest extraction | Never exposes stdout/stderr |
@@ -37,4 +37,4 @@ by the active ARR2.0 entrypoint.
## Last Updated
2026-08-06
2026-08-11

View File

@@ -2,7 +2,8 @@
## Current Architecture
ARR2.0 accepts Opera XML plus a separate Booking Tour Code/`โรงแรม` workbook and owns both deterministic processing
ARR2.0 accepts Opera XML plus a separate Booking workbook recognized through approved exact Tour Code/Group Code and
hotel-detail header aliases, and owns both deterministic processing
lifecycles. It writes immutable private
objects, runs the frozen processor locally, independently validates the complete artifacts, and atomically commits
accepted facts to PostgreSQL. A pure `PRICE_UNMATCHED` result instead enters an authenticated, auditable manual-price
@@ -21,7 +22,7 @@ from committed `ARRIVAL` facts, publishes a validated workbook, and records meta
| `arr_storage` | Immutable staged/committed OSS workflow; all object ACLs private |
| `arr_ingestion.validation` | Strict v3/v4 delivery/result/structured validation plus independent daily/review-manifest replay |
| `arr_ingestion.postgres` | Job/review lifecycle, artifact registration, atomic final Finance version commit and outbox |
| `booking_ingestion.excel` | Bounded Tour Code/`โรงแรม` extraction, latest-row/cancellation semantics and room-item normalization |
| `booking_ingestion.excel` | Bounded exact-header Booking extraction, latest-row/cancellation semantics and room-item normalization |
| `booking_ingestion.excel_review_postgres` | Durable editable draft state and zero-pending atomic current-source activation |
| `arr_web.booking_uploads` | Private Booking workbook upload, draft review orchestration and privacy-minimized source summaries |
| `arr_web.job_trace` | Read-only programmatic trace from persisted run/attempt/delivery/version/outbox facts |
@@ -57,4 +58,4 @@ from committed `ARRIVAL` facts, publishes a validated workbook, and records meta
## Last Updated
2026-08-06
2026-08-11