Files
wyndham-ARR/.project-docs/40-domain/business-rules.md

7.9 KiB
Raw Permalink Blame History

Business Rules

Durable Rules

  • Human access to the desktop Finance workspace, detailed health, generic business APIs, uploads, traces and downloads requires an authenticated ARR Web session. The H5 mobile dashboard is an intentional anonymous read-only exception: only its page/assets, /api/public/h5/months, /api/public/h5/analytics and no-detail /healthz are public; the H5 projection contains aggregate channel/room metrics and omits source hashes and operational metadata.
  • The single-operator login identity is injected as ARR_WEB_USERNAME / ARR_WEB_PASSWORD; real credentials are never stored in source or returned/logged. Missing credentials fail Web startup closed.
  • Login failures use a generic message and bounded attempt blocking. Logout revokes the server-side session; authenticated mutations continue to require CSRF.
  • The user uploads XML; the user does not submit a report year, report month, cutoff date, or separate monthly-generation request in the primary workflow.
  • Daily history and task trace show the validated browser-uploaded XML basename. Canonical internal source name source.xml is not user-facing; historical rows with no recorded basename display an unknown marker rather than a guessed filename.
  • Daily, monthly-publication and company-generation histories have independent viewing months and default to the most 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.
  • 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.
  • The worker derives the affected month from retained ARRIVAL facts belonging to the committed daily version.
  • The monthly as_of_date/“更新至” is the greatest ARRIVAL actually included in the current monthly snapshot. The XML filename and wall-clock date are never authorities for it.
  • Year, month, cutoff/as-of date, and similar fields are internal derived execution/audit values. Their presence in code or metadata does not make them user inputs.
  • The monthly output contains the exact business dimension/field TOTAL PRICE.
  • Each monthly XLSX data-row TOTAL PRICE cell is a formula whose business meaning is REAL PRICE × NIGHTS × NO_OF_ROOMS (current layout example: =R2*C2*G2).
  • A stored database total_price may be used for integrity checking, but it does not replace the required formula in the exported workbook.
  • Monthly business/guest rows remain derived from current Finance facts. PostgreSQL persists only publication identity, lineage, channel counts and artifact metadata.
  • The outbox event is marked published only after a report is active/superseded and both workbook/result artifacts are registered; replay of the same snapshot must not create a duplicate publication.
  • A published monthly version automatically appears in the open monthly list; the primary workflow has no manual list-refresh step.
  • Company-channel detail generation is allowed for any period in the selected current month and for historical months. A future report month is rejected so the system does not create an intentionally empty future workbook.
  • Company-channel C/O periods keep fixed report cutoffs: 01-10 uses the 10th, 11-20 uses the 20th and 21-month-end uses the selected month's natural month-end. The workbook uses the current committed Finance snapshot through that cutoff even when the calendar period has not ended; later-arriving facts require a rerun to be included.
  • The company-channel UI labels calendar status as 周期未结束 or 周期已结束. These labels describe whether the selected period has reached its Bangkok completion boundary; they are not generation permission states.
  • In a company-channel detail workbook, a Finance fact with no normalized Group Code remains visible as its own row; RES_COMMENT and Booking Room are blank, and this expected blank does not create a warning or duplicate highlight.
  • A Finance stay segment with a consistent nonblank Group Code keeps that Group Code and its normal aggregation. When no current accepted Booking room can be resolved, only Booking Room is blank; the lookup miss does not create an error or warning and does not block the company's workbook.
  • The company-report Booking allocation model consists of normalized Group Code, room type and quantity. A raw intake adapter may derive these fields from a source workbook, but raw workbook columns and normalized result dimensions are separate contracts; worksheet, physical row, artifact hash and parse version remain provenance.
  • A raw Booking workbook is recognized only on a worksheet containing one Tour Code/Group Code header and the exact Thai โรงแรม header. Tour Codes are Unicode-normalized and all whitespace is removed before matching.
  • For repeated Tour Codes, the physically last source row replaces earlier rows. A final row with an explicit textual cancellation removes the Tour Code; cell color or other formatting alone never means cancellation.
  • Room extraction reads parenthesized hotel segments. A 【label】 token takes the following integer as quantity and defaults to one when no following integer exists. Multiple tokens become separate items even when they normalize to the same room type.
  • Numeric suffix variants of U-TWN and U-DBL normalize to U-TWN and U-DBL; 高级房TWN/高级房DBL normalize to TWN/DBL. Unknown bracket labels retain their raw text and parsed/default quantity as pending. Recognized unbracketed names such as 6+4, Family Suite, Junior Suite and Superior Garden also remain pending because the source omitted brackets. Surcharge, child-breakfast and guide-room tokens are not guest-room allocations.
  • Pending items do not contribute accepted Booking room quantity. Automatic and manual rows are both editable and deletable; activation requires zero pending items and at least one confirmed item. Re-extraction rebuilds the review draft from source and intentionally discards draft-only edits/deletions.
  • The review UI pages at 50 records. A delete request contains 1-50 unique item IDs and is all-or-nothing: every item must still be undeleted, belong to the same reviewing draft and be deletable, otherwise the transaction rolls back.
  • An open Booking review displays the draft artifact's validated browser-uploaded filename directly below Booking记录提取. Accepted historical-source readiness is not shown as provenance for draft extraction records.
  • Once accepted, a manually uploaded Booking workbook replaces the complete current source rather than appending silently to the previous workbook. Migrations 014/015 and the HTTP GET/POST/PATCH/DELETE adapter represent this boundary; the first real draft activation remains a controlled business acceptance action.
  • Booking normalizes the complete Group Code and globally aggregates repeated (Group Code, room type) rows by summed quantity. Worksheet, company/channel and stay dates are not current Booking join dimensions. This contract therefore requires one Group Code to identify one room allocation across those scopes; a different business reality requires a schema/view/report-join change, not merely extra unused Excel columns.
  • Contradictory Group Code source fields and invalid Finance dates, nights or price details remain strict company-report errors; the blank fallback applies only to absent or unresolved Booking enrichment.

Last Reviewed

2026-07-31