feat: add daily manual price review workflow

This commit is contained in:
Wyndham ARR
2026-08-06 22:40:18 +08:00
parent aae3d8e1db
commit ca3e8e18fa
77 changed files with 7750 additions and 602 deletions

View File

@@ -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