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

@@ -11,10 +11,11 @@
7. Compute integer `NIGHTS = DEPARTURE - ARRIVAL`. Zero is legal; negative is invalid.
8. Validate the complete fixed price table, then apply the approved zero-price exception or exact three-key match. Classify unmatched candidates as `price_unmatched`.
9. Assign `channel_key` and conditional `kb_amount` as row facts.
10. Generate the 19-column daily XLSX, `result.json`, and path-free `structured-result.json` from the same in-memory records.
11. Independently replay the XML, rules, prices, routing, workbook, artifacts, outcomes, and structured records before reporting success.
10. If all actionable errors are `PRICE_UNMATCHED`, emit `review_required`: exact fixed-price rows become controlled `candidate` rows, unmatched rows stay explicit, issues are grouped by normalized company, rate code and Opera price, and no XLSX is made.
11. Otherwise generate the 19-column daily XLSX, `result.json`, and path-free `structured-result.json` from the same in-memory records.
12. Independently replay XML, rules, prices, routing, workbook (when present), artifacts, outcomes, and structured records before reporting a final result.
Any row-level validation or price error fails the formal invocation. On failure, already excluded, duplicate, or price-unmatched outcomes remain explicit. Other candidates that did not reach a validated result become `validation_failed` with `BATCH_NOT_VALIDATED`.
Only a non-empty error set composed entirely of `PRICE_UNMATCHED` may become `review_required`. Any XML, fixed-table, routing, output, structural, or mixed error remains a formal failure. On failure, already excluded, duplicate, or price-unmatched outcomes remain explicit. Other candidates that did not reach a validated result become `validation_failed` with `BATCH_NOT_VALIDATED`.
## Rate-code whitelist
@@ -56,7 +57,8 @@ Use bundled `价格对照.xlsx` as a fixed, non-user-editable rule source.
- Every other retained row must exactly match normalized `COMPANY_NAME + RATE_CODE + EFFECTIVE_RATE_AMOUNT`.
- Write reference `总价` as static `REAL PRICE`.
- Write static `TOTAL PRICE = REAL PRICE * NO_OF_ROOMS * NIGHTS`.
- An unmatched candidate fails the entire invocation.
- An unmatched candidate normally requires review only when it is the sole actionable error family. The review artifact contains no price substitution.
- A final review replay may price only the exact unmatched keys listed in its frozen manifest. `real_price` is a non-negative two-decimal value (including `0.00`), uses `pricing_method = manual_review` and `MANUAL_PRICE_APPLIED`, and never changes the fixed table or any XML field.
## Channel facts