# ADR-001: Automatic Monthly Trigger And TOTAL PRICE Formula

- Status: Implemented
- Date: 2026-07-29
- Source: User correction in the current session

## Context

Earlier discussion incorrectly treated monthly-report generation as a separate user action and described year, month, or cutoff date as user-submitted values. An earlier report specification also treated generated price cells as static values.

## Decision

1. The user's workflow begins and ends with uploading the XML.
2. ARR's frozen processor produces structured data for independent validation and database persistence; the production path has no Agent/MCP dependency.
3. Only after that structured result is successfully committed does the business system emit `arr.daily_version_committed`; a dedicated worker process consumes it and runs the monthly-report program.
4. `report_year`, `report_month`, `as_of_date`, or equivalent values may remain as internal execution and audit fields, but the backend must derive them. The worker uses committed retained `ARRIVAL` facts to select the affected month, and the greatest `ARRIVAL` actually included in the snapshot is the report's `as_of_date`/“更新至”. The XML filename and wall clock are never authorities for this value.
5. The report keeps the `TOTAL PRICE` dimension/field. Each XLSX data-row cell must contain a formula with the business meaning:

   `TOTAL PRICE = REAL PRICE × NIGHTS × NO_OF_ROOMS`

   With the current 19-column layout, this is equivalent to `=R2*C2*G2` for row 2 and must fill relatively for later rows.
6. The monthly page automatically discovers newly published versions. A user must not need a separate refresh action
   after the worker finishes.

## Consequences

- A manual month/as-of form or endpoint is not the primary product flow and must not be presented as a required user step.
- The monthly processor may still accept internally supplied month/cutoff arguments through a controlled recovery CLI/API, but the primary page exposes none of them.
- The dedicated worker leases outbox rows, retries transient publication failures, dead-letters exhausted events, and acknowledges success only after both registered artifacts are active/downloadable.
- Durable `reporting` metadata records the snapshot identity, Finance daily-version lineage, channel manifest and local artifact identities without duplicating monthly business rows.
- The implemented workbook writes and reopens one exact row-relative `TOTAL PRICE` formula per data row.
- The portal uses a visibility-aware, non-overlapping list poll while the monthly tab is open and reloads immediately
  when the tab becomes active again. A transient background error keeps the last good list and retries automatically.

## Supersedes

- Any conversation or planning note that says the user submits the report year, month, or cutoff date.
- The intermediate correction that said the user clicks a monthly-report button while the backend derives those values.
- Any report-output rule requiring `TOTAL PRICE` data cells to be static values or requiring a zero-formula workbook.
