feat: add daily manual price review workflow
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
- 未登录用户只能看到 ARR 登录页或无详情 readiness;页面、API、上传、日志和下载均由服务端会话保护,退出后立即失效。
|
||||
- XML 上传、确定性处理、完整结果验证和 Finance 提交不依赖 Agent/MCP,并得到终态任务回执。
|
||||
- 纯 `PRICE_UNMATCHED` 上传得到 `needs_review` 而非失败:初始阶段没有日报、Finance 版本、失败事件或月报事件;填写全部键后原 XML + 冻结清单的独立重放才可产生一次最终成功。
|
||||
- 用户上传 XML 后无需再提交月报参数;结构化结果成功入库会自动触发相应月报处理。
|
||||
- 生成的月报包含 `TOTAL PRICE` 字段,并在每个数据行使用 `REAL PRICE × NIGHTS × NO_OF_ROOMS` 的 Excel 公式。
|
||||
- 月报发布完成后,打开的月报页面自动出现新版本,不要求用户点击刷新。
|
||||
@@ -17,10 +18,14 @@
|
||||
|
||||
- 测试必须覆盖错误/正确登录、尝试限流、安全回跳、CSRF 退出、会话撤销、桌面/H5 会话过期处理,以及 375/768/1024/1440 响应式无横向溢出。
|
||||
- 测试必须证明月报触发发生在数据库成功提交之后,且失败提交不会触发。
|
||||
- 测试必须覆盖合并重复价格键、候选价、整数格式、显式 `0`(冻结清单规范化为 `0.00`)、未完成禁止确认、revision 冲突、重复最终化、技术重试、取消留痕、认证/CSRF和隐私字段隔离。
|
||||
- `待人工处理` 状态与复核进度必须作为同一个操作入口,点击或键盘激活后定位并聚焦人工价格面板,不能误开任务日志;复核面板、动态消息、确认弹窗和安全 API 错误必须完整支持中文、英文和泰文。
|
||||
- 人工确认请求在途时,上传卡片必须显示本地化的“日报生成中”;请求结束后按成功、仍在生成或可重试复核状态收敛,不能继续显示过期的“等待人工定价”。
|
||||
- 最终人工成功必须证明日报行序/数值可重放、Finance 只有一个 active 版本、`manual_review` 行数和冻结清单 SHA-256 可追踪、月报事件仅一次。
|
||||
- 重新打开生成的 XLSX,确认 `TOTAL PRICE` 为公式单元格并逐行引用同一行的 `REAL PRICE`、`NIGHTS`、`NO_OF_ROOMS`。
|
||||
- 用户入口不得要求提交月报年份、月份或截止日期。
|
||||
- 页面自动同步必须避免重叠请求;页面隐藏或离开月报页时停止轮询,恢复可见时立即重新读取。
|
||||
|
||||
## Last Reviewed
|
||||
|
||||
2026-07-30
|
||||
2026-08-06
|
||||
|
||||
49
.project-docs/10-decisions/ADR-006-daily-price-review.md
Normal file
49
.project-docs/10-decisions/ADR-006-daily-price-review.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# ADR-006: PRICE_UNMATCHED uses a frozen, source-replayed manual review
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Date
|
||||
|
||||
2026-08-06
|
||||
|
||||
## Context
|
||||
|
||||
The fixed price table can legitimately lack an exact normalized price key. Treating every such result as a permanent
|
||||
failure makes staff re-upload unchanged XML after a separate price decision, while accepting edited spreadsheets or
|
||||
mutable price-table changes would create a second intake path and weaken provenance.
|
||||
|
||||
## Decision
|
||||
|
||||
Only a non-empty error set entirely composed of `PRICE_UNMATCHED` becomes `review_required`. ARR stores one
|
||||
privacy-minimized review case per run, grouped missing keys, revisioned actor/price history and candidate comparisons.
|
||||
It creates no Finance version, daily download, rejected Finance version, `arr.processing_failed`, or monthly event.
|
||||
|
||||
After every key has a non-negative integer value, ARR freezes canonical JSON bound to the job, case, original XML
|
||||
SHA-256, business date, processor version, rule hash and complete issue set. The operator/API surface uses integer text
|
||||
(including explicit `0`); ARR normalizes that value to exact `numeric(18,2)` and canonical `.00` manifest text before
|
||||
replay. Finalization re-materializes the registered source XML and replays it with the fixed price table plus that
|
||||
manifest. Independent validation must accept the same manifest before one atomic Finance-version activation, case
|
||||
completion and `arr.daily_version_committed` event.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `POST /api/jobs` remains XML-only; there is no Excel draft/download/upload-back workflow.
|
||||
- Staff can change only a reviewed missing key's non-negative integer price, including explicit `0`; fixed pricing rules and XML fields
|
||||
remain immutable.
|
||||
- Review mutations require session authentication, CSRF and optimistic revision checks. Frozen item/manifest facts are
|
||||
immutable and permanently audited without free-form notes or guest detail.
|
||||
- Infrastructure failures after freeze become `generation_failed` and may retry with the identical manifest. A
|
||||
deterministic final replay failure closes the review and run as failed. Processor/rule identity drift requires cancel
|
||||
then fresh upload.
|
||||
- The legacy `direct_mcp` path uses an isolated v3 success/failure projection: it rejects manual overrides and maps
|
||||
price misses to normal v3 failures, so it cannot gain review behavior from the active v4 processor.
|
||||
|
||||
## Related
|
||||
|
||||
- `database/017_daily_price_review.sql`
|
||||
- `database/018_daily_review_manual_override_artifact.sql`
|
||||
- `arr_web/programmatic.py`
|
||||
- `arr_ingestion/postgres.py`
|
||||
- `arr-opera-daily-ingest/scripts/process_daily.py`
|
||||
@@ -5,6 +5,7 @@
|
||||
| ID | Decision | Status | Date | Applies To | Detail |
|
||||
|---|---|---|---|---|---|
|
||||
| ADR-005 | 手机 H5 看板通过专用只读聚合接口公开访问;桌面及运营接口继续认证 | Accepted | 2026-08-03 | Web access boundary, H5, Channel BI | [ADR-005](ADR-005-public-read-only-h5-dashboard.md) |
|
||||
| ADR-006 | 仅纯 `PRICE_UNMATCHED` 进入冻结人工价格复核;最终原 XML 重放才可提交 Finance | Accepted | 2026-08-06 | Daily XML, review lifecycle, Finance/outbox, Web | [ADR-006](ADR-006-daily-price-review.md) |
|
||||
| ADR-004 | ARR2.0 owns deterministic processing, artifact validation and terminal ingestion; no Agent/MCP in production XML flow | Accepted | 2026-07-30 | Upload, processing runtime, OSS ACL, validation, deployment | [ADR-004](ADR-004-arr-owned-programmatic-processing.md) |
|
||||
| ADR-001 | 月报由独立 worker 自动触发;“更新至”取最新纳入的 `ARRIVAL`;发布后页面自动新增;`TOTAL PRICE` 为公式字段 | Implemented | 2026-07-29 | 月报触发、持久化、页面同步、XLSX 输出 | [ADR-001](ADR-001-automatic-monthly-trigger-and-total-price-formula.md) |
|
||||
|
||||
|
||||
@@ -18,15 +18,17 @@
|
||||
|---|---|---|---|
|
||||
| 1 | Browser XML upload | Uploaded-basename task provenance + private canonical source object + queued DB job | Filename/content/size and immutable object identity |
|
||||
| 2 | Committed source object | Isolated processor input | Materialization rechecks stored bytes |
|
||||
| 3 | Fixed `process_daily.py` | Daily/result/structured or failure artifacts | Timeout, confined paths, exit/JSON agreement |
|
||||
| 3 | Fixed `process_daily.py` | Final daily/result/structured, pure-price review JSON, or failure artifacts | Timeout, confined paths, exit/JSON agreement |
|
||||
| 4 | Validated processor/report artifacts | Private committed OSS objects | Role, MIME, size and SHA-256 |
|
||||
| 5 | Canonical `DeliveryEnvelope` | `DeliveryValidator` | Strict Schema, reconciliation, source/artifact hashes and independent validation |
|
||||
| 6 | Verified delivery | PostgreSQL Finance facts | Serializable atomic commit/version activation |
|
||||
| 7 | Accepted/failed run | Task trace and outbox | Persisted state is authoritative |
|
||||
| 8 | `arr.daily_version_committed` | Dedicated monthly worker | Lease, `SKIP LOCKED`, bounded retry/dead-letter |
|
||||
| 9 | Retained Finance `ARRIVAL` facts | Monthly snapshot request | Affected month from event version; “更新至” is max included `ARRIVAL` |
|
||||
| 10 | Monthly snapshot | XLSX/result + `reporting` metadata | Formula reopen-validation, current-pin recheck, atomic activation |
|
||||
| 11 | Registered active report | Web list/download + outbox acknowledgement | Real report ID; visible monthly tab polls automatically; path/size/SHA-256 recheck before download |
|
||||
| 5 | Canonical `DeliveryEnvelope` | `DeliveryValidator` | Strict v4 Schema, reconciliation, source/artifact hashes and independent final/review replay |
|
||||
| 6 | Pure `PRICE_UNMATCHED` delivery | PostgreSQL review case/items/events | No daily XLSX, Finance version, failure event or monthly event; task remains active as `awaiting_review` |
|
||||
| 7 | Frozen complete review manifest + registered original source | Same processor and independent validator | UI/API accepts only a non-negative integer for a missing key; storage and the manifest normalize it to exact `.00`, and the manifest binds job/case/source/date/processor/rules/full key set |
|
||||
| 8 | Final verified delivery | PostgreSQL Finance facts | Serializable atomic version activation, review completion and one commit outbox event |
|
||||
| 9 | Accepted/failed run | Task trace and outbox | Persisted state is authoritative; retryable final infrastructure failure returns to `generation_failed` with manifest retained |
|
||||
| 10 | `arr.daily_version_committed` | Dedicated monthly worker | Lease, `SKIP LOCKED`, bounded retry/dead-letter |
|
||||
| 11 | Retained Finance `ARRIVAL` facts | Monthly snapshot request | Affected month from event version; “更新至” is max included `ARRIVAL` |
|
||||
| 12 | Monthly snapshot | XLSX/result + `reporting` metadata | Formula reopen-validation, current-pin recheck, atomic activation |
|
||||
| 13 | Registered active report | Web list/download + outbox acknowledgement | Real report ID; visible monthly tab polls automatically; path/size/SHA-256 recheck before download |
|
||||
|
||||
## State Ownership
|
||||
|
||||
@@ -36,6 +38,7 @@
|
||||
- `processing_runs.uploaded_filename` owns the user-facing browser basename; the source artifact remains canonically
|
||||
named `source.xml` for processing and validation.
|
||||
- Temporary processor/validator paths are deleted after each request.
|
||||
- `daily_review_cases`/items/events retain only normalized price keys, aggregate impact, actor/revision and before/after price; they deliberately contain no guest names, comments or raw traces. Frozen manifests and items are immutable.
|
||||
- New monthly/company XLSX and `result.json` bytes live in immutable private OSS objects; the database stores provider,
|
||||
bucket alias, object key and identity. The controlled local reader remains available for historical local records,
|
||||
while `/app/outputs` is only staging/cache and local `.web-jobs` state.
|
||||
@@ -65,4 +68,4 @@ equals its persisted `as_of_date`. Every data-row `TOTAL PRICE` cell is `=R[row]
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-07-31
|
||||
2026-08-06
|
||||
|
||||
@@ -3,28 +3,30 @@
|
||||
| Path | Responsibility | Notes |
|
||||
|---|---|---|
|
||||
| `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` | Upload-to-terminal coordinator | Registers the validated browser basename separately from canonical `source.xml`; no remote/model transport |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `arr_processing/policy.py` | Frozen processor/rule identity | Neutral, reusable loader |
|
||||
| `arr_ingestion/validation.py` | Strict artifact/result validation | Runs `validate_daily.py` on success |
|
||||
| `arr_ingestion/postgres.py` | Atomic Finance commit and lifecycle state | Four retries only for transient SQLSTATEs |
|
||||
| `arr_processing/policy.py` | Frozen processor/rule identity | Active v4 loader plus isolated legacy direct-MCP v3 compatibility projection |
|
||||
| `arr_ingestion/validation.py` | Strict artifact/result validation | Dispatches v3/v4; independently replays review and frozen-manifest final results |
|
||||
| `arr_ingestion/postgres.py` | Job/review lifecycle and atomic Finance commit | `recorded_review` has no Finance/outbox write; final success is the only activation boundary; four retries only for transient SQLSTATEs |
|
||||
| `arr_storage/aliyun_oss_v2.py` | Encrypted/unversioned OSS adapter | Writes all objects private |
|
||||
| `arr_web/downloads.py` | OSS daily/report + controlled local legacy download routing | Rechecks provider metadata, size and SHA-256 |
|
||||
| `arr_web/job_trace.py` | Programmatic persisted-fact trace | No external trace store |
|
||||
| `arr_web/app.py`, `arr_web/repository.py`, `arr_web/company_jobs.py` | Authenticated portal routes plus public H5 aggregate routes, paged history reads and read-only history-month discovery | Default-deny login gate protects the desktop/API/download surface; purpose-built `/api/public/h5/*` exposes only sanitized aggregate metrics; daily/monthly counts and rows share a repeatable-read snapshot; `/api/history-months` merges daily/monthly database counts with company job-state counts; company totals/slices share one lock |
|
||||
| `arr_web/server.py` | Standard-library HTTP transport | Dispatches GET/POST/PATCH/DELETE with one bounded body reader; real socket tests cover review update/delete and missing/oversized lengths |
|
||||
| `arr_web/static/login.html`, `login.css`, `login.js` | Responsive ARR login gateway | Labeled form, password visibility, generic inline failures, safe desktop/H5 return target and reduced-motion support |
|
||||
| `arr_web/static/app.js`, `arr_web/static/h5.js` | Authenticated desktop and anonymous-capable H5 client state, rendering and polling | Desktop daily/monthly/company histories own independent viewing-month state and default to the latest non-empty month; company generation month remains separate. H5 reads only public aggregate endpoints and may retain optional logout for an authenticated session. Desktop also includes 50-row Booking draft review/edit, the draft's validated uploaded filename below the review title, individual/all-visible selection, count-aware in-page delete confirmation and activation; company generation keeps the fixed five-company context beside the page title, a four-card upload/period setup row, cumulative CO display labels, short centered period actions and an in-page generation confirmation dialog; session-expiry redirect and CSRF logout remain shared; monthly versions auto-refresh the selected viewing month every four seconds |
|
||||
| `arr_web/static/app.js`, `arr_web/static/i18n.js`, `arr_web/static/h5.js` | Authenticated desktop and anonymous-capable H5 client state, rendering, localization and polling | Desktop daily/monthly/company histories own independent viewing-month state and default to the latest non-empty month; needs-review status opens/focuses the paged privacy-safe price panel, finalization projects a generating upload state, and review controls/errors follow the shared Chinese/English/Thai catalog. H5 reads only public aggregate endpoints; session-expiry redirect and CSRF logout remain shared |
|
||||
| `monthly_reports/worker.py` | Dedicated outbox consumer | Lease/reclaim, retry/dead-letter, success acknowledgement after activation |
|
||||
| `monthly_reports/repository.py` | Monthly snapshot and publication repository | Derives scope from `ARRIVAL`; persists metadata/lineage/artifact identities |
|
||||
| `monthly_reports/publishing.py` | Python/openpyxl monthly builder and atomic/OSS publisher | Reopens sheets, headers, row counts, semantic hash and exact row-relative `TOTAL PRICE` formulas |
|
||||
| `monthly_reports/`, `company_reports/`, `channel_analytics/` | Downstream reports/BI | Consume accepted Finance facts |
|
||||
| `database/012_monthly_report_publication.sql` | Additive metadata-only publication schema | Applied after immutable 008–011 baseline |
|
||||
| `database/016_monthly_report_oss_artifacts.sql` | Monthly publication provider compatibility | Allows new OSS/S3 identities while retaining legacy local records |
|
||||
| `database/017_daily_price_review.sql` | Daily missing-price review lifecycle | Applied to controlled `booking_test` on 2026-08-06 after exact 016 semantic verification and corrected up/down probe; adds protected case/item/event audit, `awaiting_review`, manual lineage and guarded rollback |
|
||||
| `database/018_daily_review_manual_override_artifact.sql` | Frozen manual-manifest artifact compatibility | Applied as a forward-only correction after rollback probing; permits only `manual_override_json` in the existing artifact-kind constraint and refuses destructive rollback once such an immutable artifact exists |
|
||||
| `database/014_booking_current_source_batch.sql` | Booking full-workbook current-source pointer and view scoping | Formally applied on 2026-07-31; batch 1 remains selected |
|
||||
| `database/015_booking_excel_review_drafts.sql` | Item-level Booking extraction draft state | Formally applied and empty; basic latest-state review only, with no actor/reason/revision history and no DB-enforced zero-pending activation |
|
||||
| `compose.yaml`, `deploy/` | Web-login + Caddy-HTTPS template and worker deployment boundary | Requires Web credentials for the desktop/operational surface; public H5 aggregate routes and `/healthz` remain anonymously reachable; no MCP port/domain/service |
|
||||
@@ -35,4 +37,4 @@ by the active ARR2.0 entrypoint.
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-02
|
||||
2026-08-06
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
ARR2.0 accepts Opera XML plus a separate Booking Tour Code/`โรงแรม` workbook 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. Downstream analytics and report programs read committed facts.
|
||||
accepted facts to PostgreSQL. A pure `PRICE_UNMATCHED` result instead enters an authenticated, auditable manual-price
|
||||
review state and cannot create Finance facts until the original XML is replayed with a frozen canonical manifest.
|
||||
Downstream analytics and report programs read committed facts.
|
||||
Successful daily commits also create a durable outbox event. A separate worker derives the affected month and watermark
|
||||
from committed `ARRIVAL` facts, publishes a validated workbook, and records metadata-only report state in PostgreSQL.
|
||||
|
||||
@@ -14,11 +16,11 @@ from committed `ARRIVAL` facts, publishes a validated workbook, and records meta
|
||||
| Component | Responsibility |
|
||||
|---|---|
|
||||
| `arr_web.auth` / authenticated `SessionLedger` | Environment-owned operator credentials, bounded login attempts, random server-side sessions, CSRF and logout revocation |
|
||||
| `arr_web.programmatic` | Terminal upload orchestration and safe public error mapping |
|
||||
| `arr_web.programmatic` | XML upload plus synchronous frozen-review final replay orchestration and safe public error mapping |
|
||||
| `arr_processing.local` / `arr_processing.policy` | Isolated frozen processor execution and approved version/rule identity |
|
||||
| `arr_storage` | Immutable staged/committed OSS workflow; all object ACLs private |
|
||||
| `arr_ingestion.validation` | Strict delivery/result/structured validation plus independent daily validation |
|
||||
| `arr_ingestion.postgres` | Job lifecycle, artifact registration, atomic Finance version commit and outbox |
|
||||
| `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_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 |
|
||||
@@ -37,6 +39,8 @@ from committed `ARRIVAL` facts, publishes a validated workbook, and records meta
|
||||
- Operator credentials come only from runtime `ARR_WEB_USERNAME` / `ARR_WEB_PASSWORD`; the application fails closed when either is absent. Authenticated mutations also require the per-session CSRF token.
|
||||
- Processor exit code and JSON status must agree; output paths are confined to an isolated temporary directory.
|
||||
- Validation completes before the database transaction; any transaction failure leaves no partial active version.
|
||||
- `review_required` is valid only for a non-empty error set entirely composed of `PRICE_UNMATCHED`. It records neither a Finance version nor an `arr.processing_failed`/monthly event; a final manual value is limited to the verified missing key and is entered as a non-negative integer (including `0`) before exact `.00` storage/manifest normalization.
|
||||
- All review mutations use the authenticated session plus CSRF protection and optimistic revision checks. Finalization is idempotent; infrastructure failures retain the frozen manifest for retry, while deterministic replay failures close the case and job as failed.
|
||||
- Booking uploads create review drafts first. Only an explicit activation with no retained pending items can atomically
|
||||
create immutable Booking facts and switch `booking.current_source_batch`; an open draft blocks company-report creation.
|
||||
- Only recognized transient PostgreSQL concurrency errors receive bounded transaction retries.
|
||||
@@ -53,4 +57,4 @@ from committed `ARRIVAL` facts, publishes a validated workbook, and records meta
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-03
|
||||
2026-08-06
|
||||
|
||||
@@ -19,6 +19,84 @@ preserves its no-formula contract. Both publishers upload new workbook and `resu
|
||||
immutable OSS adapter, while download routing retains controlled-local compatibility for historical records and keeps
|
||||
`.web-jobs` queue state local.
|
||||
|
||||
## Runtime Recovery On 2026-08-06
|
||||
|
||||
- Restored the local ARR login page after a reported opening failure. No Web process was listening and the retained
|
||||
Keychain-backed 8766 launcher still passed two removed Node/artifact-tool flags. Removed only those obsolete flags,
|
||||
then started one detached `arr2-web-8766` Screen session. `/healthz` returns 200 and root redirects to login with no
|
||||
browser console error. No login, upload, database, Finance or object-store mutation was performed. The existing
|
||||
reboot-persistent supervision follow-up remains open.
|
||||
|
||||
## Deployed And Accepted On 2026-08-06
|
||||
|
||||
- Reconciled the live migration-016 function/comment semantics without rerunning 016, created a privacy-minimized
|
||||
pre-017 checkpoint, and ran a transaction-only up/down probe. The first probe exposed a real legacy
|
||||
`artifact_callback`/`direct_mcp` run-constraint drift and rolled back cleanly; corrected 017 preserves that contract.
|
||||
Formally applied migration 017 SHA-256 `22a0578e…67b5b` under an advisory lock with all original business table counts
|
||||
unchanged. The guarded down migration SHA-256 is `9e85af0c…29101`.
|
||||
- Closed incomplete runs 61–63 through the normal repository failure transition as
|
||||
`REVIEW_SCHEMA_MIGRATION_MISSING`, retaining all three source artifacts and adding only failure-audit events. The
|
||||
first post-migration upload, run 64, then exposed a 16-value/15-placeholder delivery INSERT bug and closed safely as
|
||||
`DATABASE_WRITE_FAILED`; the placeholder and a focused regression were corrected.
|
||||
- Restarted Web as PID 24225 with all six authenticated readiness flags true. A subsequent exact-hash `0805.XML`
|
||||
upload is now run 65 / open review case `dailyreview-878e45ae132b73c131560299b3b2dcb3`: the live page shows the two
|
||||
expected Lian Tai keys and candidate prices at `0 / 2`, while confirmation remains disabled. PostgreSQL has one open
|
||||
revision-0 case, two unset items and one required event, with no daily XLSX, manual manifest, Finance version, run
|
||||
outbox or new monthly event. Historical daily version 28 remains rejected and unchanged. Finance-priced finalization
|
||||
is the remaining authorized business step.
|
||||
- Subsequent employee interactions created two independent frozen cases: run 66 stores GRP1/LBLT as `2300/0`, and
|
||||
latest run 67 stores `200/0`. Both stopped safely as retryable `generation_failed` with no Finance version or run
|
||||
outbox event. Diagnosis found two finalization defects: the live artifact-kind constraint omitted
|
||||
`manual_override_json`, and the Finance-version INSERT had 21 placeholders for 20 values. Migration 018
|
||||
(`5600d825…cd00`) was rollback-probed and formally applied as the additive artifact-kind correction; the surplus SQL
|
||||
placeholder was removed. A real PostgreSQL outer-transaction review-to-Finance slice now reaches one active version,
|
||||
one manual row and one commit event before rolling back to zero residue.
|
||||
- Web is now PID 26286 with all six readiness flags true. The review UI/API displays and accepts only non-negative
|
||||
integers while preserving exact `.00` database/manifest normalization. At the finalization-repair handoff, run 67
|
||||
was revision 2 `generation_failed`, read back as `200` and `0`, and had not been retried by that repair; run 66 held a
|
||||
different frozen GRP1 value. That checkpoint is historical and the later browser-visible state is recorded below.
|
||||
Historical version 28 remained rejected and unchanged at the repair checkpoint.
|
||||
- The manual-review UI follow-up is runtime-active without a Web restart because static files are read on each request.
|
||||
`待人工处理` plus progress are one operation button that focuses/scrolls the price panel without opening the task
|
||||
log; retryable cases omit the removed frozen-list sentence; finalization projects `日报生成中`; and the complete
|
||||
review panel/dialog/error surface follows the Chinese/English/Thai selector. Authenticated read-only browser QA
|
||||
verified both a retryable and an editable case. During that QA, history had advanced outside this task: jobs
|
||||
`arrjob-e36d8c4c133b48dbb81a57a002e41d76` and `arrjob-cce736734c5e4731b733f03c4a9a3b76` displayed succeeded, while
|
||||
`arrjob-d3bbbb435cae4559b5f69cb7ea331cee` and `arrjob-dddc27119bea43b19588c78eac087763` still displayed needs-review.
|
||||
This UI task issued no price save, finalize/retry/cancel submission or upload, so it does not attribute those external
|
||||
lifecycle changes to itself.
|
||||
|
||||
## Diagnosed On 2026-08-06
|
||||
|
||||
- Diagnosed the user's fresh post-v4 `0805.XML` upload read-only. The page shows `请求未完成`, while PostgreSQL has
|
||||
three new v4 run/attempt shells (61–63 / 53–55) stuck `running`, three exact 948,683-byte source artifacts, no
|
||||
delivery, Finance version or outbox event. Live database effects match 016 but migration 017 is absent: review tables
|
||||
do not exist and lifecycle checks permit only success/failed. An isolated same-hash v4 replay plus independent
|
||||
validation succeeds as `review_required` with exactly `LIAN TAI / LBLT / 0` and `LIAN TAI / GRP1 / 1150`. The Web
|
||||
transaction therefore fails on the missing review table and its best-effort closure fails at the same dependency.
|
||||
No live migration, cleanup, re-upload, review edit or business write was performed.
|
||||
- Diagnosed deployed daily job `arrjob-f1cd01f5fddd458cbdafada0ec7dd14d` read-only. A local XML with the exact logged
|
||||
948,683-byte/SHA-256 identity reproduces the processor-3.0.0 failure: Lian Tai `LBLT + 0` and `GRP1 + 1150` are absent
|
||||
from the frozen price reference. All 151 `validation_failed` outcomes are `BATCH_NOT_VALIDATED` fallout; they are not
|
||||
separate source-field errors. Finance version 28 remains rejected, and no price, code, server, database or job state
|
||||
was changed. Finance must approve the missing totals or an explicit zero-night rule before rebuild, exact replay and a
|
||||
fresh upload.
|
||||
|
||||
## Implemented Locally On 2026-08-06
|
||||
|
||||
- Added the v4 `PRICE_UNMATCHED`-only manual-price-review path for the active fixed-processor/artifact-callback flow.
|
||||
A pure missing-price result records an audited, privacy-minimized `awaiting_review` case and returns `needs_review`
|
||||
without a daily XLSX, Finance version, rejected version, failure outbox or monthly event. Mixed errors remain failures.
|
||||
- Authenticated/CSRF review APIs and the Daily Report panel page grouped keys, candidate fixed prices, aggregate impact
|
||||
and revision-locked non-negative integer prices (including `0`), then normalize exact `.00` storage/manifest values. Finalization freezes canonical provenance, rematerializes
|
||||
the registered source XML and independently replays before its one atomic Finance/outbox commit. Infrastructure
|
||||
retries retain the manifest; deterministic final errors close the review/run.
|
||||
- Migrations 017/018 and their guarded down migrations, v4 processor package/schema, trace v4 and package checksum parity were
|
||||
locally verified. After the navigation/progress/localization follow-up, the dependency-complete `.venv` suite passes
|
||||
393 tests with three intentional private-fixture skips; direct-MCP remains an explicit v3 no-review compatibility
|
||||
projection. The controlled rollout and later browser-visible user activity supply live review/success state, while
|
||||
this follow-up itself remains UI-only and produced no Finance or monthly mutation.
|
||||
|
||||
## Completed On 2026-08-04
|
||||
|
||||
- Repaired deployment availability for monthly and company report artifacts. Removed the monthly Node/private-package
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
|
||||
| Date | Task | Outcome | Docs Updated |
|
||||
|---|---|---|---|
|
||||
| 2026-08-06 | Repair manual-review navigation/progress and add English/Thai | Merged the status chip and progress into one review action that focuses the operation panel while row clicks still own logs; removed the frozen-case sentence; set upload status to `日报生成中` before finalization; localized the complete review UI and review API errors. Live browser QA covered zh/en/th and dialog copy without submitting a business action. Full suite: 393 passed, 3 intentional skips | Current state, success criteria, module map, [UI evidence](../50-evidence/topics/2026-08-06-daily-review-ui-navigation-i18n.md), scoped planning record |
|
||||
| 2026-08-06 | Use integer review prices and repair `请求未完成` finalization | Changed review display/PATCH input to non-negative integer text while retaining canonical `.00` storage and replay. Bound the visible failure to runs 66/67, repaired a 21-placeholder/20-value Finance INSERT and the missing `manual_override_json` artifact kind through additive migration 018, then proved the full PostgreSQL finalization path in an outer rollback. Web PID 26286 is healthy; latest run 67 remains explicitly retryable with frozen `200/0` and no Finance/outbox mutation. Full suite: 387 passed, 3 intentional skips | ADR/domain/architecture/current state, migration/deployment ledgers, [repair evidence](../50-evidence/topics/2026-08-06-integer-review-finalize-repair.md), scoped planning record |
|
||||
| 2026-08-06 | Deploy migration 017 and restore live `0805.XML` manual review | Reconciled already-live 016 semantics, corrected a legacy run-constraint drift found by rollback probe, formally applied 017 with unchanged business counts, closed runs 61–63 as infrastructure failures, then fixed a 16-value/15-placeholder delivery INSERT exposed by the first acceptance upload. Restarted Web and proved run 65 opens the exact two-key review panel at revision 0 with no prices, daily XLSX, Finance version or daily-commit/monthly event. Historical version 28 remains rejected | Migration ledger, current state, [live rollout evidence](../50-evidence/topics/2026-08-06-live-daily-price-review-rollout.md), SHA-protected runtime checkpoints, scoped planning record |
|
||||
| 2026-08-06 | Diagnose fresh `0805.XML` v4 upload not entering review | Proved the exact file correctly yields independently valid v4 `review_required` with two keys, but live `booking_test` lacks migration 017 tables/states. Three new runs remain `running` after source registration because review commit and best-effort closure both depend on the missing table; no delivery, Finance or outbox fact exists. Live 016 effects are present despite the checked-in ledger saying pending. No database/runtime/business mutation was performed; 017 deployment and explicit shell cleanup require operator authorization | Current state, [live mismatch evidence](../50-evidence/topics/2026-08-06-live-0805-review-migration-mismatch.md), evidence index, stale item, scoped planning record |
|
||||
| 2026-08-06 | Restore local ARR page opening | Found no listener or Screen session and traced startup failure to the owner-local Keychain launcher passing retired Node/artifact-tool arguments. Removed only those flags, started one detached 8766 Web session, verified `/healthz` 200 and the login redirect with no browser console errors. No login, upload, database, Finance or object-store mutation occurred; reboot-persistent supervision remains open | Current state, evidence/index, scoped planning record |
|
||||
| 2026-08-06 | Implement Daily `PRICE_UNMATCHED` manual-price review | Added active processor/result v4, canonical frozen override replay, independent review/manual validation, migration 017/down, review lifecycle/repository/API/trace/UI, package parity and focused browser QA. Pure price-only output is `needs_review` without Finance/outbox; final source replay is the first Finance/monthly event boundary. The complete `.venv` suite passes 384 tests with three intentional private-fixture skips; the retired direct-MCP path is an explicit v3 no-review projection. No live database, OSS or job was mutated; deployment requires 016 → 017 backup/disposable rollback probe | ADR-006, data-flow/business rules/success criteria, deployment runbook, migration ledger, [implementation evidence](../50-evidence/topics/2026-08-06-daily-price-review-implementation.md), stale deployment item |
|
||||
| 2026-08-06 | Diagnose deployed 2026-08-05 Daily `PRICE_UNMATCHED` | Verified the Desktop XML exactly matches the logged 948,683-byte/SHA-256 identity and reproduced the failure with processor 3.0.0. The only actionable misses are Lian Tai `LBLT + 0` and `GRP1 + 1150`; all 151 validation-failed rows are atomic `BATCH_NOT_VALIDATED` fallout. Both checked-in price references are identical and lack the keys. No price, code, runtime, database or job state changed; Finance approval is required before rebuild and fresh upload | Current state, price-unmatched evidence/index, stale item, scoped planning record |
|
||||
| 2026-08-04 | Fix false monthly XLSX output-validation failure on 440-row reports | Replaced read-only workbook random-cell validation with sequential `iter_rows` scanning and changed Excel-decimal readback checks to an explicit `0.000001` tolerance. Sheet/header/dimension checks, semantic SHA-256, formula count and exact `=R[row]*C[row]*G[row]` formulas remain strict. Added a 440-row, three-date, five-sheet decimal regression; the XLSX test and 18-case monthly builder/publishing/worker/service/repository suite pass. No outbox, database or live runtime state was changed | Current state, report-artifact evidence, scoped planning record |
|
||||
| 2026-08-04 | Remove private monthly XLSX runtime and make report artifacts deployment-safe | Replaced monthly and company report builders' production path with Python/openpyxl; preserved the exact monthly `TOTAL PRICE` formula and workbook semantic checks; published new monthly/company XLSX and `result.json` artifacts through the existing OSS adapter while retaining legacy local reads; added migration 016 for OSS monthly artifacts, removed Node builders/flags, and added OSS/local download routing tests. Targeted report/deployment tests pass; the full local suite has 307 passes, 3 skips and 8 environment-only errors (`httpx`/Aliyun test setup). Docker and live OSS were intentionally not run in this development environment | Current state, architecture, deployment runbook, migration ledger, evidence/index, stale item |
|
||||
| 2026-08-03 | Make company-report XLSX generation deploy without private npm | Replaced the company-report builder's Node/private `@oai/artifact-tool` runtime dependency with Python/openpyxl workbook generation and self-validation, removed the private package dependency, enabled `--enable-company-reports` in Compose Web, and documented that only the monthly worker still needs Node/artifact-tool packaging. Focused company-report and deployment-entrypoint tests pass 19/19; no migration or live deployment was performed | Current state/history, architecture, deployment evidence/index, stale item, runbooks |
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
recent month containing that record type. Viewing-month state is read-only: it resets list paging but never changes
|
||||
monthly derivation or a company generation request. Company `生成月份` and history `查看月份` are separate inputs.
|
||||
- ARR's frozen processor generates complete structured data, which must be independently validated and successfully committed to the database before downstream monthly processing starts.
|
||||
- A non-empty set of errors made entirely of `PRICE_UNMATCHED` is the sole exception to immediate failure: it becomes a pending manual-price review and remains active without a Finance version, daily download, failure event or monthly trigger.
|
||||
- The review key is normalized company + Rate Code + Opera price. Staff may set only its non-negative integer price
|
||||
(including explicit `0`); they may not change XML/company/rate/Opera fields or the fixed reference table. ARR stores
|
||||
the accepted integer as exact `numeric(18,2)` and freezes canonical `.00` manifest text for deterministic replay.
|
||||
- Finalization freezes one canonical manifest bound to job, case, source SHA, business date, processor/rule identity and the complete key set, then replays original XML plus the fixed table. Only independently accepted final replay creates `manual_review` retained facts and one daily-commit event.
|
||||
- If the processor/rule identity changes while a case is open, staff must cancel and re-upload. Retryable infrastructure errors preserve the frozen manifest; deterministic final errors formally fail the case/run.
|
||||
- The production XML path must not require Agent, MCP, prompts, model-generated JSON, fetch grants, or a public source URL.
|
||||
- A successful database commit automatically triggers the monthly-report processing program through the business system.
|
||||
- Automatic monthly processing runs in a dedicated worker process, not inside the Web request process.
|
||||
@@ -73,4 +79,4 @@
|
||||
|
||||
## Last Reviewed
|
||||
|
||||
2026-07-31
|
||||
2026-08-06
|
||||
|
||||
@@ -4,6 +4,13 @@ Use this index for searchable, traceable evidence records.
|
||||
|
||||
| Date | Topic | Status | Source | Detail |
|
||||
|---|---|---|---|---|
|
||||
| 2026-08-06 | Daily review navigation, progress and three-language UI | Implemented and runtime-active | [Evidence topic](topics/2026-08-06-daily-review-ui-navigation-i18n.md) | The whole needs-review status now opens/focuses the operation panel without opening logs; the unwanted retry sentence is removed; finalization sets `日报生成中` before its request; review UI/API errors are localized in Chinese, English and Thai. Live read-only browser QA and 393 tests pass; no price/finalize/cancel/upload mutation was invoked. |
|
||||
| 2026-08-06 | Integer review prices and finalization repair | Deployed repair; run-67 checkpoint is historical | [Evidence topic](topics/2026-08-06-integer-review-finalize-repair.md) | Review amounts now display/accept integers and normalize to canonical `.00`. Migration 018 fixes the omitted manual-manifest artifact kind and the Finance INSERT now has 20 binds; rollback probes, live readiness and the then-current 387-test suite passed. Run 67 was still frozen at `200/0` when that repair ended; later browser-visible lifecycle state is recorded in the UI follow-up topic. |
|
||||
| 2026-08-06 | Live Daily price-review rollout and `0805.XML` acceptance | Historical initial-review snapshot; superseded by repair topic | [Evidence topic](topics/2026-08-06-live-daily-price-review-rollout.md) | Reconciled live 016 semantics without rerunning it, corrected and applied 017 after an exact up/down rollback probe, closed runs 61–63, fixed a delivery-placeholder runtime bug, and proved run 65 reached the two-key live panel with no Finance/report/outbox effect. Later runs and current retry instructions are in the integer/finalization repair topic. |
|
||||
| 2026-08-06 | Fresh `0805.XML` did not enter v4 manual review | Historical diagnosis; resolved by live rollout | [Evidence topic](topics/2026-08-06-live-0805-review-migration-mismatch.md) | Exact-source v4 replay isolated the absent-017 failure. The authorized follow-up applied corrected 017, closed the three shells, fixed the delivery INSERT and proved a fresh run enters the two-key review; see the live rollout topic above. |
|
||||
| 2026-08-06 | Local ARR page-opening recovery | Restored locally; supervision follow-up unchanged | [Evidence topic](topics/2026-08-06-web-launcher-compatibility-recovery.md) | No ARR Web listener was present. The owner-local Keychain launcher still supplied two removed Node/artifact-tool flags; deleting only those flags restored 8766, `/healthz` 200 and the login page with no console error. No business write occurred. |
|
||||
| 2026-08-06 | Daily `PRICE_UNMATCHED` manual-price review implementation | Implemented; repair and UI follow-ups active | [Evidence topic](topics/2026-08-06-daily-price-review-implementation.md) | v4 creates a no-Finance `needs_review` receipt only for pure missing fixed-price keys, freezes a manifest, replays original XML for final success, and preserves retry/audit/privacy boundaries. Integer/finalization and navigation/i18n behavior are covered by the two newer evidence topics. |
|
||||
| 2026-08-06 | 2026-08-05 Daily `PRICE_UNMATCHED` | Historical diagnosis and frozen-case checkpoint | [Evidence topic](topics/2026-08-06-daily-price-unmatched.md) | The original v3 diagnosis isolated the two missing Lian Tai keys. Its later run-67 `200/0` generation-failed statement is a historical pre-retry snapshot; current browser-visible lifecycle changes are recorded in the UI follow-up, while rejected version 28 remains immutable in the last authoritative database audit. |
|
||||
| 2026-08-04 | Report artifact deployability repair | Implemented locally; CentOS/Docker acceptance pending operator execution | [Evidence topic](topics/2026-08-04-report-artifact-deployability.md) | Monthly XLSX now uses Python/openpyxl with exact row-relative formulas and semantic validation. New monthly/company workbook and result artifacts use the existing immutable OSS adapter; download routing supports OSS plus legacy local records, and migration 016 permits OSS monthly identities. Focused report/storage/Web/migration tests pass; Docker/real OSS were intentionally not run locally. |
|
||||
| 2026-08-04 | Deployed monthly-report download diagnosis | Superseded for implementation; optional authenticated remote capture pending | [Evidence topic](topics/2026-08-04-deployed-monthly-download-diagnosis.md) | The pre-repair Node/local-output diagnosis remains useful as historical cause evidence. The implementation now uses Python/openpyxl plus OSS-backed report identities and legacy local fallback; remote acceptance still belongs on the CentOS deployment. |
|
||||
| 2026-08-03 | Company-report openpyxl builder for deployment | Implemented; focused deployment checks pass | [Evidence topic](topics/2026-08-03-company-report-openpyxl-builder.md) | CentOS Docker build failed because public npm cannot install private `@oai/artifact-tool`. Company-report XLSX generation now runs through Python/openpyxl in Web, while monthly worker packaging remains the only Node/artifact-tool concern. Focused company-report/deployment tests pass 19/19. |
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
# Daily PRICE_UNMATCHED manual-price review implementation
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Implemented; integer-input/finalization repair deployed, explicit employee retry pending
|
||||
- Scope: `artifact_callback/fixed_processor` daily XML path only; legacy `direct_mcp` remains an explicit v3,
|
||||
no-review compatibility projection
|
||||
- Confidence: High; local regression plus the later controlled migration/runtime and exact-XML initial-review acceptance agree
|
||||
- Last verified: 2026-08-06
|
||||
- Stale trigger: a later migration, processor/rule change, successful run-67 retry, or new 0805 re-upload
|
||||
|
||||
## Implemented boundary
|
||||
|
||||
- Active processor/result schemas are v4. A result becomes `review_required` only when its non-empty actionable error
|
||||
set is entirely `PRICE_UNMATCHED`; it exits technically successfully with `result.json` and
|
||||
`structured-result.json` only, no daily/exception XLSX.
|
||||
- The review result includes candidate auto-priced rows, grouped normalized `(company, Rate Code, Opera price)` issues,
|
||||
existing fixed-price comparisons and aggregate room/room-night impact. It contains no guest name, comment or raw
|
||||
trace in the review API/read model.
|
||||
- Staff PATCH only a verified missing key using a non-negative integer string, including `0`. ARR normalizes it to
|
||||
exact `numeric(18,2)` and canonical `.00` manifest text. Case revision, session username, old/new price and timestamps
|
||||
are permanently recorded without a free-form note field.
|
||||
- Finalization freezes canonical JSON bound to job/case/source SHA/business date/processor/rules/full issue key set and
|
||||
re-materializes the registered original XML. Processor and independent validator both replay that exact manifest;
|
||||
final retained manual rows use `pricing_method=manual_review` and `MANUAL_PRICE_APPLIED`.
|
||||
- Initial `recorded_review` creates no Finance/rejected version, download, `arr.processing_failed` or monthly event.
|
||||
One final atomic success creates/activates Finance lineage and emits `arr.daily_version_committed`. Infrastructure
|
||||
errors retain the frozen manifest as `generation_failed`; deterministic final errors fail the case/run.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `.venv/bin/python -m unittest discover -s tests -p 'test_*.py' -v`: 387 passed, with three intentional skips for a
|
||||
private acceptance fixture not bundled in the repository. This includes active v4 behavior and direct-MCP v3
|
||||
no-review compatibility.
|
||||
- `python3 -m unittest tests.test_arr_opera_daily_ingest -v`: 14 passed, including pure-review grouping, mixed-error
|
||||
failure, zero-price final replay and package source/archive parity.
|
||||
- `python3 -m unittest tests.test_arr_ingestion_validation -v`: 7 passed for outer review/manual independent replay.
|
||||
- `python3 -m unittest tests.test_arr_ingestion_postgres -v`: 16 passed, including source-artifact reload plan, no-Finance
|
||||
review receipt and deterministic-final-failure audit path.
|
||||
- `python3 -m unittest tests.test_arr_programmatic -v`: 5 passed, including original-source `0.00` final replay and
|
||||
deterministic finalization failure closure.
|
||||
- `python3 -m unittest tests.test_arr_web -v`: covers authenticated/CSRF review routes, strict integer grammar and
|
||||
privacy-safe response shape. `tests.test_arr_web_job_trace`, `tests.test_arr_web_repository_schema` and migration
|
||||
static tests also passed during the implementation run.
|
||||
- `shasum -a 256 -c CHECKSUMS.sha256` passes after rebuilding byte-identical `.zip`/`.skill`; archive filenames are
|
||||
UTF-8-preserved, including `价格对照.xlsx`.
|
||||
- Browser QA used a temporary localhost fake service: logged in with test-only credentials, opened the review panel,
|
||||
rendered candidate/impact fields, saved `0`, finalized to a successful state, and observed no browser console
|
||||
errors. No production service, private XML, database or object storage was used.
|
||||
|
||||
## Live follow-up
|
||||
|
||||
- The authorized follow-up reconciled already-live 016 semantics, corrected and applied 017 after an exact up/down
|
||||
rollback probe, fixed a delivery-placeholder defect exposed by the first real attempt, and proved run 65 reaches the
|
||||
expected two-key initial-review state with no Finance/event change. See
|
||||
`2026-08-06-live-daily-price-review-rollout.md`.
|
||||
- A later repair changed the operator surface to integer prices, applied additive migration 018 for the omitted
|
||||
`manual_override_json` artifact kind, and corrected the Finance INSERT bind count. Latest run 67 remains frozen at
|
||||
`200/0` and awaits an explicit employee retry; see `2026-08-06-integer-review-finalize-repair.md`.
|
||||
- Remaining evidence is Finance-owned finalization: verify run 67's frozen values, retry once, require 153 retained lines
|
||||
with two `manual_review` rows and one final daily-commit/monthly event, and leave rejected version 28 unchanged.
|
||||
@@ -0,0 +1,48 @@
|
||||
# 2026-08-05 Daily PRICE_UNMATCHED diagnosis
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Latest frozen review awaits explicit employee retry after deployed technical repair
|
||||
- Scope: Daily job `arrjob-f1cd01f5fddd458cbdafada0ec7dd14d`, rejected Finance version 28
|
||||
- Confidence: Fact for the hash-matched local replay and checked-in reference; production rule-set binary identity remains unproven because the supplied trace omits `rule_set_sha256`
|
||||
- Source: operator-supplied ARR trace, hash-matched `0805.XML`, deterministic processor 3.0.0 replay, structured failure result, fixed price-reference workbook
|
||||
- Last verified: 2026-08-06
|
||||
- Stale trigger: a successful run-67 retry, a price/rule deployment, or a fresh processing job for business date 2026-08-05
|
||||
|
||||
## Question
|
||||
|
||||
Why did the deployed 2026-08-05 Opera XML daily job fail with `PRICE_UNMATCHED`, and do the reported 151 validation-failed rows represent separate bad source records?
|
||||
|
||||
## Evidence
|
||||
|
||||
- The server trace reports source size 948,683 bytes, rejected version 28 and outcomes `199 source = 46 excluded + 151 validation_failed + 2 price_unmatched`, with no duplicates or retained output.
|
||||
- The read-only Desktop XML has the exact logged size and SHA-256. An isolated replay with checked-in processor 3.0.0 exits 2 and creates only `result.json`, `structured-result.json` and `异常清单.xlsx`.
|
||||
- The two actionable errors are:
|
||||
- `reservation[2]`: Lian Tai + `LBLT` + Opera amount `0`; zero-night stay.
|
||||
- `reservation[64]`: Lian Tai + `GRP1` + Opera amount `1150`; one-night stay.
|
||||
- Every one of the 151 `validation_failed` records carries `BATCH_NOT_VALIDATED`; 150 also carry `PRICE_REFERENCE_MATCHED`, and one carries the approved `ZERO_PRICE_EXCEPTION`. They are atomic batch fallout, not 151 independent field/date errors.
|
||||
- Read-only artifact-tool inspection of `arr-opera-daily-ingest/references/价格对照.xlsx` shows Lian Tai `GRP1` mappings only at Sheet1 rows 23–28 for Opera amounts `900/1200/1300/1400/1800/2400`, and Lian Tai `LBLT` mappings at rows 40/42/43 for `900/1400/2400`. Neither exact target exists.
|
||||
- Both checked-in price-reference workbooks are byte-identical at SHA-256 `123d1d1ea0e28ce481a63dfdbe4bd22b5e6069c585a8cbde4194376ed18fb0d6` and have not changed since commit `a701de9` (2026-07-29).
|
||||
- The local replay rule-set SHA is `c41257208324a43e711de13ec9776a5e6486db334757f152531bf8292a2018eb`. The server trace exposes only processor version 3.0.0, so exact production rule-set hash comparison is not available from that trace alone.
|
||||
|
||||
## Finding
|
||||
|
||||
The deterministic processor correctly failed under the current frozen rules because two exact normalized price keys are absent. Numeric formatting and trailing rate-code spaces are not the cause. The `总价` values cannot be inferred safely from neighboring mappings, and zero nights do not bypass price-key validation under the current approved rule.
|
||||
|
||||
## Impact
|
||||
|
||||
- The deployed v4 workflow created review cases instead of another rejected Finance version. Latest run 67 has a frozen
|
||||
GRP1/LBLT manifest of `200/0` and remains retryable `generation_failed` after two repaired infrastructure defects;
|
||||
it still has no Finance version or run outbox event. Run 66 separately retains `2300/0`, and run 65 remains unset.
|
||||
- The values apply only to their own task and do not change the fixed reference table. No automatic retry or re-upload
|
||||
is safe because a successful final replay is the Finance/monthly commit boundary.
|
||||
- Keep rejected version 28 as immutable failure history. Only an explicitly authorized successful final replay may
|
||||
activate Finance facts and trigger monthly processing.
|
||||
|
||||
## Open Items
|
||||
|
||||
- Refresh/login, open latest run 67, confirm its frozen `LBLT=0` and `GRP1=200` values are intended, then invoke its
|
||||
retry once. Do not select run 66 accidentally because its frozen GRP1 value differs.
|
||||
- After success, verify 153 retained rows, two `manual_review` rows, one active Finance version and exactly one new
|
||||
daily-commit/monthly event.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Daily Review UI Navigation, Progress And I18n
|
||||
|
||||
Date: 2026-08-06
|
||||
Status: implemented and runtime-active
|
||||
Scope: authenticated desktop Daily Report UI only
|
||||
|
||||
## Reported Problems
|
||||
|
||||
- Clicking `待人工处理` opened the task log instead of the manual-price operation panel.
|
||||
- A retryable frozen case displayed an unwanted frozen-manifest explanation.
|
||||
- Final confirmation did not change the upload-card status from `等待人工定价` to `日报生成中` while the synchronous
|
||||
request was running.
|
||||
- The added manual-price module was not localized with the existing Chinese/English/Thai selector.
|
||||
|
||||
## Root Cause And Change
|
||||
|
||||
- The history row owned the log-opening click/keyboard behavior, while only the small `复核 x / y` child button owned
|
||||
`data-open-price-review`. The status chip therefore fell through to the row action. Status plus progress are now one
|
||||
semantic review button; nested controls are excluded from the row keyboard handler. A successful read focuses and
|
||||
scrolls the dedicated `daily-price-review-panel`.
|
||||
- `generation_failed` now hides the instruction node. The removed sentence is absent from HTML, JavaScript and the
|
||||
language catalog.
|
||||
- `finalizeDailyPriceReview()` sets the upload progress component to the localized running label before awaiting the
|
||||
finalize API. Success resolves to complete, an active server-side generation remains generating, and a returned
|
||||
editable/retryable review resolves back to waiting for manual pricing.
|
||||
- Static and dynamic review copy, responsive `data-label` values, row states, pagination, validation/toasts, cancel
|
||||
dialog and review API errors now have explicit Chinese, English and Thai catalog entries. Review prices use the
|
||||
current locale's integer formatter.
|
||||
|
||||
## Verification
|
||||
|
||||
- `node --check arr_web/static/i18n.js` and `node --check arr_web/static/app.js` passed.
|
||||
- Focused Web/static regression passed 31/31 tests.
|
||||
- Full discovery passed 393 tests in 247.709 seconds, with three intentional skips for private Booking fixtures.
|
||||
- Authenticated browser verification on the live 8766 page proved:
|
||||
- the needs-review status is exposed as one button with an explicit open-review accessible name;
|
||||
- clicking it made `daily-price-review-panel` the active element, scrolled to the panel and left the task-log dialog
|
||||
closed;
|
||||
- the retryable instruction node was hidden and the removed sentence was not rendered;
|
||||
- Chinese, English and Thai rendered localized title, progress, table labels, instructions, row state, save/finalize
|
||||
controls and status-action names;
|
||||
- both English and Thai cancellation dialogs rendered localized title, description, audit note and buttons, then
|
||||
closed through the non-mutating return action.
|
||||
|
||||
## Safety Boundary
|
||||
|
||||
Browser verification issued only review-detail reads, client-side locale changes and open/close dialog actions. It did
|
||||
not edit or save a price, submit finalize/retry/cancel, upload XML, create a Finance version or trigger monthly work.
|
||||
The finalization-progress transition is covered by the source-order regression because clicking it would be a real
|
||||
business mutation. The Web process was not restarted: authenticated page reload proved the running server reads and
|
||||
serves the current static files.
|
||||
@@ -0,0 +1,71 @@
|
||||
# Integer Review Prices And Finalization Repair
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Deployed and technically verified; latest employee case awaits explicit retry
|
||||
- Scope: Daily `PRICE_UNMATCHED` review UI/API, PostgreSQL finalization and local Web runtime on port 8766
|
||||
- Confidence: High; browser/database correlation, exact SQL planning, protected migration probes, a real PostgreSQL
|
||||
rollback-only vertical slice and the full repository suite agree
|
||||
- Last verified: 2026-08-06
|
||||
- Stale trigger: a successful retry of run 67, a new `0805.XML` upload, or a later migration/runtime deployment
|
||||
|
||||
## User-visible contract
|
||||
|
||||
- Review prices display without trailing `.00`. The PATCH contract accepts a non-negative integer string of at most 16
|
||||
digits, including explicit `0`; decimal input such as `0.00` is rejected.
|
||||
- The repository still stores exact `numeric(18,2)` values and the immutable manifest retains canonical two-decimal
|
||||
text such as `0.00`. Processor arithmetic, result schemas and independent replay therefore remain unchanged.
|
||||
- `DATABASE_WRITE_FAILED` now has a specific retryable message instead of the unhelpful generic `请求未完成` copy.
|
||||
|
||||
## Root causes and corrections
|
||||
|
||||
- Runs 66 and 67 reached final validation but rolled back before Finance activation. The Finance-version INSERT declared
|
||||
21 placeholders for 20 supplied dynamic values. The statement now has exactly 20 placeholders, with a regression
|
||||
assertion and a live read-only PostgreSQL `EXPLAIN INSERT` plan.
|
||||
- A full outer-transaction probe then found an earlier live constraint failure: migration 017 referenced a manual
|
||||
manifest artifact but omitted `manual_override_json` from `ingestion.artifacts`' allowed kinds. Migration 018 is an
|
||||
additive, target-guarded correction that changes only this check and refuses destructive rollback after an immutable
|
||||
manual manifest exists.
|
||||
- Migration 018 up SHA-256 is
|
||||
`5600d82597304d66ffb4933df4b375406080484dfbc7717c360b48a9e28ccd00`; down SHA-256 is
|
||||
`514ba908059bd8eadedd9a38da6efae85efb378ccfca0395028eae1fed22b92f`.
|
||||
|
||||
## Protected live evidence
|
||||
|
||||
- Pre-018 privacy-minimized checkpoint:
|
||||
`runtime/backups/booking_test_pre_018_20260806T210250+0800/manifest.json`, SHA-256
|
||||
`fcc24362d43c5982590a6566276e6ac7d1d172da2f2f040e8e54a063ca7e2b16`.
|
||||
- Up/down outer-transaction probe:
|
||||
`runtime/backups/booking_test_pre_018_20260806T210250+0800/rollback-probe.json`, SHA-256
|
||||
`6d7f6b29a2e2a9ac528d18159d5ee1c046e786437c3d096e0fad42e85d779190`. It restored the exact pre-state fingerprint
|
||||
and left no committed row or schema residue.
|
||||
- Formal application evidence:
|
||||
`runtime/backups/booking_test_pre_018_20260806T210250+0800/formal-application.json`, SHA-256
|
||||
`651dc998d471734ebfc1ebd5ba81f5a5da57942879676aa1747fe5bcb2d24d84`. Pre-existing review cases, business counts
|
||||
and rejected Finance version 28 stayed unchanged; zero manual-manifest artifacts existed at apply time.
|
||||
- Post-018 finalization probe:
|
||||
`runtime/backups/booking_test_pre_018_20260806T210250+0800/finalization-rollback-probe.json`, SHA-256
|
||||
`857cee393fa232ea4cbd85913f5069948246acdace6add39c019bd91787711dd`. A synthetic review was recorded, integer `0`
|
||||
read back correctly, its manifest froze `0.00`, finalization created an active two-row version with one
|
||||
`manual_review` row and one commit event, and the outer rollback left zero probe residue.
|
||||
|
||||
## Runtime and remaining business boundary
|
||||
|
||||
- Web restarted as PID 26286; anonymous `/healthz` and all six authenticated readiness checks pass. A temporary API
|
||||
session was revoked after confirming integer read-model output.
|
||||
- Run 65 remains an unset `0/2` case. Run 66 is separately frozen at GRP1/LBLT `2300/0`. Latest run 67 is revision 2,
|
||||
frozen at `200/0`, and remains `generation_failed`; none of these runs has a Finance version or run outbox event.
|
||||
- No finalize, cancel, upload or automatic retry was performed during the repair. After refresh/login, an employee must
|
||||
open latest run 67, verify `200/0` are intended, and explicitly retry it once. Run 66 must not be selected by mistake.
|
||||
Successful acceptance must then prove 153 retained rows, two `manual_review` rows, one active Finance version, a
|
||||
matching manifest SHA and exactly one new daily-commit/monthly event while version 28 remains rejected.
|
||||
- A final explicit read-only transaction confirms the live artifact constraint includes `manual_override_json`, runs
|
||||
65/66/67 each still have zero Finance versions and zero run outbox events, run 67 remains revision 2 at `200.00/0.00`,
|
||||
and version 28 is rejected with no manual lineage. `/healthz` remains `ready` under listener PID 26286.
|
||||
|
||||
## Verification
|
||||
|
||||
- Full repository discovery: 387 tests passed; three private Booking fixture tests were intentionally skipped.
|
||||
- Focused Web/PostgreSQL/service/programmatic coverage: 52 passed. Focused migration/PostgreSQL coverage: 21 passed.
|
||||
- JavaScript/Python syntax, package checksum parity, whitespace checks and both project-document gates pass.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Fresh 0805.XML v4 review blocked by live migration mismatch
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Historical root-cause record; resolved by the authorized live rollout
|
||||
- Scope: local authenticated 8766 Web runtime and controlled `booking_test`
|
||||
- Confidence: High; UI, PostgreSQL catalog/lifecycle, source identity, isolated processor replay and independent validator agree
|
||||
- Last verified: 2026-08-06
|
||||
|
||||
## Observed behavior
|
||||
|
||||
- The authenticated upload UI retained `0805.XML`, displayed `处理失败` / `请求未完成`, and showed zero August history
|
||||
rows with no browser console error.
|
||||
- PostgreSQL contains three fresh v4 runs (61–63) and attempts (53–55), all still `running`. Each has one committed
|
||||
private OSS source artifact but no delivery row, result identity, business date or finish timestamp.
|
||||
- All three source artifacts are 948,683 bytes and share SHA-256
|
||||
`40a40f09dd110cc9814df3da9c747d5b08c9f8357e703fe1ea96ebf8daaeede3` with historical run 58.
|
||||
- No Finance version and no outbox event references these new runs.
|
||||
|
||||
## Root cause
|
||||
|
||||
- Live `booking_test` has no `ingestion.daily_review_cases`, `daily_review_items` or `daily_review_events` relations.
|
||||
Its lifecycle checks also lack `awaiting_review`, `review_required` and delivery result `review_required`, proving 017
|
||||
is not applied.
|
||||
- The live monthly publication validator body/comment matches migration 016's OSS-enabled definition, despite the
|
||||
checked-in applied-migration ledger still marking 016 pending. This is a migration-ledger conflict, not proof that
|
||||
016 must be rerun.
|
||||
- The exact local XML under active processor 4.0.0 returns technical success `review_required`, 151 candidate rows and
|
||||
exactly two grouped keys: `LIAN TAI / LBLT / 0` and `LIAN TAI / GRP1 / 1150`. It creates only result/structured JSON.
|
||||
The independent validator accepts this review output.
|
||||
- During live ingestion, the atomic review receipt attempts to insert the missing review case and is wrapped as
|
||||
`DATABASE_WRITE_FAILED`; the delivery transaction rolls back. Best-effort terminalization then queries the same
|
||||
missing review table, fails and is swallowed, leaving the registered run/attempt shells `running`. The frontend has
|
||||
no specific translation for this code and displays generic `请求未完成`.
|
||||
|
||||
## Safe correction boundary
|
||||
|
||||
Do not convert or reopen runs 61–63. After operator authorization, reconcile the live 016 signature with migration
|
||||
history, back up and probe/apply 017, explicitly terminalize the three infrastructure-failed shells with audit, reload
|
||||
and verify schema-aware readiness, then perform one fresh upload for the two-key review. No migration, shell cleanup,
|
||||
re-upload, review edit/finalization, Finance change, object-store write or runtime restart was performed in this
|
||||
diagnosis.
|
||||
|
||||
## Resolution
|
||||
|
||||
The operator subsequently authorized the bounded correction. Migration-016 semantics were verified live and not
|
||||
rerun. A privacy-minimized checkpoint and corrected 017 up/down probe passed, then migration 017 was formally applied.
|
||||
Runs 61–63 were closed as audited `REVIEW_SCHEMA_MIGRATION_MISSING` failures. The first post-migration acceptance
|
||||
identified and safely closed a separate delivery-placeholder defect; after that one-line SQL binding fix and restart,
|
||||
run 65 entered an open two-key review case with no Finance/report/outbox effect. See
|
||||
`2026-08-06-live-daily-price-review-rollout.md` for authoritative rollout and acceptance evidence.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Live Daily Price Review Rollout And `0805.XML` Acceptance
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Historical initial-review rollout; superseded for latest runtime state by the integer/finalization repair topic
|
||||
- Scope: controlled `booking_test`, local authenticated Web on port 8766, exact desktop `0805.XML`
|
||||
- Acceptance job: `arrjob-dddc27119bea43b19588c78eac087763` (run 65)
|
||||
- Review case: `dailyreview-878e45ae132b73c131560299b3b2dcb3`
|
||||
|
||||
## Rollout evidence
|
||||
|
||||
- The privacy-minimized pre-017 checkpoint is
|
||||
`runtime/backups/booking_test_pre_017_20260806T192026+0800/manifest.json`, SHA-256
|
||||
`d66cc4341db42420b9382fa78c90214f5ecb3c200062c0ac4bb8d275a7123b17`. It excludes credentials, XML bytes,
|
||||
guest rows and raw delivery/outbox payloads.
|
||||
- The first up/down probe failed closed and rolled back because 017 had simplified the migration-010
|
||||
`artifact_callback`/`direct_mcp` terminal constraint. Corrected up/down preserve that legacy split and add only the
|
||||
`awaiting_review` branch. The corrected probe restores the exact pre-migration fingerprint and leaves no row/schema
|
||||
residue; its evidence SHA-256 is `c62e07f60b4f2b481fb6fcb72a6aeaeccc3e73b87f36f87af1478f63027eb971`.
|
||||
- Live migration-016 function/comment semantics were already exact before the rollout; 016 was not rerun. Corrected
|
||||
migration 017 SHA-256 `22a0578e8748573d29ff2c15dbc687aaea14d7dc0c34cf8fe1faa2ef56067b5b` was formally applied under an advisory lock.
|
||||
All new relations, columns, indexes, triggers and lifecycle/pricing values passed post-commit checks while original
|
||||
business table counts stayed unchanged. Formal evidence SHA-256 is
|
||||
`9837fce88d5bd18ff58b5575375af9f31fec89252123b7cf44d3a3fb991bd83a`.
|
||||
- Runs 61–63 were closed through the normal repository transition as
|
||||
`REVIEW_SCHEMA_MIGRATION_MISSING`. Their three private source artifacts remain intact; only three
|
||||
`arr.processing_failed` audit events were added. No delivery, review case, Finance version or daily-commit event was
|
||||
created for those shells. Cleanup evidence SHA-256 is
|
||||
`ad0d4ce01644d6adc5e58fc0c5182240398568ed4b6546be1a3b15a4dbb273a1`.
|
||||
|
||||
## Runtime correction and real acceptance
|
||||
|
||||
- The first post-migration upload became run 64 and failed safely as `DATABASE_WRITE_FAILED`. Source artifact 173 and
|
||||
failure event 45 were retained, with no delivery/review/Finance fact. Diagnosis found a 16-value/15-placeholder
|
||||
mismatch in the newly extended `processing_deliveries` INSERT. The missing placeholder and a regression assertion
|
||||
were added; 18 focused migration/PostgreSQL tests, compilation and whitespace checks pass, and PostgreSQL plans the
|
||||
exact 16-parameter INSERT.
|
||||
- Final repository discovery passes all 384 tests with three intentional skips for private booking fixtures. Package
|
||||
checksums, Python/JavaScript syntax, diff whitespace and project-document gates also pass.
|
||||
- Web was restarted as PID 24225. Authenticated health reports database, processing, monthly, download, company report
|
||||
and company source upload readiness all true.
|
||||
- One subsequent exact-hash upload reached run 65 and automatically opened the live review panel. PostgreSQL records
|
||||
`awaiting_review` / `review_required` / `recorded_review`, one open revision-0 case, one
|
||||
`PRICE_REVIEW_REQUIRED` event and exactly two unset items:
|
||||
- `LIAN TAI / GRP1 / 1150.00`, impact 1 record / 1 room / 1 room-night;
|
||||
- `LIAN TAI / LBLT / 0.00`, impact 1 record / 1 room / 0 room-nights.
|
||||
- The page shows both fixed-price candidate lists, `复核 0 / 2`, and a disabled `确认并生成日报` button. No employee
|
||||
price was entered and the case was not finalized or cancelled.
|
||||
- Only source XML, result JSON and structured-result JSON are registered. The run has no daily XLSX, exception XLSX,
|
||||
manual manifest, Finance version or outbox event. Total `arr.daily_version_committed` remains 20, monthly-run count
|
||||
remains 14, and historical daily version 28 remains rejected with no review lineage.
|
||||
- The complete acceptance snapshot is
|
||||
`runtime/backups/booking_test_pre_017_20260806T192026+0800/live-0805-review-acceptance.json`, SHA-256
|
||||
`a8994ada1644e039dac7ea888cdba5143bca72cbc6d47c5bf7c4e09d5d6fa315`.
|
||||
|
||||
## Remaining boundary
|
||||
|
||||
Finance must supply the two approved prices in the open panel. Only after both revision-locked saves should an
|
||||
authorized employee invoke finalization and verify the expected final 153 retained rows, two `manual_review` rows,
|
||||
one active Finance version and exactly one new daily-commit/monthly event. Historical version 28 must remain unchanged.
|
||||
|
||||
This was the exact run-65 state at rollout time. Subsequent employee interactions created runs 66/67 and exposed two
|
||||
finalization defects now repaired by migration 018 plus an SQL-bind correction. Use
|
||||
`2026-08-06-integer-review-finalize-repair.md` for the current retry boundary; do not act on this historical run-65
|
||||
instruction.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Local ARR Web launcher compatibility recovery
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-06
|
||||
- Status: Restored locally; reboot-persistent supervision remains open
|
||||
- Scope: owner-local `arr2-web-8766` launcher and local Web listener only
|
||||
- Last verified: 2026-08-06
|
||||
|
||||
## Evidence
|
||||
|
||||
- No process listened on local ARR ports and `screen -ls` reported no Web session, so the page could not establish a
|
||||
connection.
|
||||
- The Keychain-backed launcher configuration check passed, but its command still supplied `--node-binary` and
|
||||
`--artifact-tool-module`. The current `arr_web.run --help` shows neither option, and its argument parser rejects both
|
||||
before application startup.
|
||||
- Removing only those two retired launch arguments and starting one detached `arr2-web-8766` session restored the
|
||||
service. Local `/healthz` returned HTTP 200; root redirected to the login page, whose browser console had no warnings
|
||||
or errors. At verification, both `127.0.0.1:8766` and the current LAN address `192.168.3.48:8766` returned root
|
||||
redirect HTTP 303.
|
||||
|
||||
## Boundary
|
||||
|
||||
No login, form submission, upload, Finance/object-store/database write, processor run or monthly-worker action was
|
||||
performed. The detached Screen process is still not reboot-persistent; the existing supervision maintenance item
|
||||
continues to apply.
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
| Date | Document / Module | Issue | Next Action |
|
||||
|---|---|---|---|
|
||||
| 2026-08-06 | Daily `PRICE_UNMATCHED` final Finance acceptance / business date 2026-08-05 | Integer UI/API and both finalization defects are repaired and deployed: migration 018 admits the immutable manifest artifact, the Finance INSERT bind count is exact, and a real PostgreSQL rollback slice passes. Latest run 67 is still revision-2 `generation_failed` with frozen GRP1/LBLT `200/0`; it has no Finance version or run outbox. Run 66 separately retains `2300/0`, run 65 remains unset, and rejected version 28 remains immutable | Refresh/login, open latest run 67, verify `200/0` are the intended approved values, then explicitly retry generation once. Do not retry run 66 by mistake. After success, prove 153 retained rows with 2 `manual_review` rows, one active Finance version, matching frozen-manifest SHA and exactly one new final daily-commit/monthly event; do not modify version 28 |
|
||||
| 2026-07-31 | Booking raw Excel parser/review business acceptance | Parser 2.0, migrations 014/015, atomic draft repository, routes, editor, HTTP transport and current runtime are ready. Supplied-workbook replay, 55 expanded tests, live 5/5 processing and a real-PostgreSQL create/edit/activate/rollback slice pass. No authorized real workbook has replaced the current source | Run one operator-authorized complete-workbook upload/review/activation, then one released five-company job and verify all downloads |
|
||||
| 2026-07-31 | Booking review audit depth | Migration 015 stores current confirmed/pending/deleted state but no reviewer, reason, explicit review event, old/new values or immutable revision history. Repository logic serializes and gates activation, but declarative DB guards are limited and same-artifact re-extraction deletes earlier unactivated edits | Confirm whether single-operator latest-state editing is sufficient. If review must be auditable, add actor/reason/event or revision tables, optimistic concurrency and DB transition guards before migration acceptance |
|
||||
| 2026-07-31 | Booking Excel current-source runtime acceptance | Current port 8766 loads the review composition with all readiness flags true; migrations 014/015 are recorded and `booking.current_source_batch` still selects Markdown batch 1. A 14:14 +08 read-only recheck found no reviewing draft; the prior draft is no longer an active task-creation blocker and did not switch the current source. The Markdown five-workbook baseline has been frozen with exact hashes | Run one Markdown-backed five-company Web job after the July period completes if a final-period snapshot is desired, then verify downloads. Keep any later complete-workbook activation operator-authorized, then compare its five overlapping Group Codes with the frozen baseline |
|
||||
@@ -16,7 +17,7 @@
|
||||
| 2026-07-30 | `booking_test` current Finance projection | The earlier 417-row snapshot included accepted run `mvp-v1-fixture-20260727` from `synthetic.xml`/`local_fixture`. A 2026-07-31 14:17 read-only company-report recheck found 986 current supported-company facts, so the old 416/417 remediation target is no longer a complete description of current Finance state | Re-audit current daily-version pins and source provenance before any fixture retirement; require explicit authorization for version changes, then verify the clean target and watermark |
|
||||
| 2026-07-30 | Channel BI refresh lifecycle | Resolved 2026-08-03. Desktop and public H5 now check selected-month metadata every five seconds while visible and reload full analytics only after `updated_at` changes; hidden views pause and transient failures preserve the last good snapshot | Refresh the browser once to load the new static assets, then observe the next authorized publication as a live acceptance check |
|
||||
| 2026-07-30 | Channel BI KPI label | The card labeled `公司数` renders worksheet-level `channel_count`; LianTai GROUP/FIT are two channels, so six does not mean six companies | Decide whether to relabel it `渠道/子表数` or implement an explicit five-company aggregation |
|
||||
| 2026-08-04 | Production monthly-worker packaging | Resolved in code: monthly/company builders are Python/openpyxl-only, new report artifacts use private OSS, and `.web-jobs` remains local. Docker/CentOS acceptance and migration 016 application are still operator-side deployment actions | Apply 016, rebuild the clean image, start Web plus the independent worker with existing OSS secrets, then verify OSS-backed downloads after removing the report cache |
|
||||
| 2026-08-04 | Production monthly-worker packaging | Resolved in code: monthly/company builders are Python/openpyxl-only, new report artifacts use private OSS, and `.web-jobs` remains local. Live `booking_test` function/comment evidence confirms migration-016 semantics are active; its earlier application timestamp is not recorded, and 016 was deliberately not rerun during the 017 rollout. Docker/CentOS acceptance remains operator-side | Rebuild the clean image, start Web plus the independent worker with existing OSS secrets, then verify OSS-backed downloads after removing the report cache |
|
||||
|
||||
## Superseded For ARR2.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user