Files
wyndham-ARR/.project-docs/20-architecture/system-overview.md
2026-08-03 20:59:59 +08:00

4.3 KiB

System Overview

Current Architecture

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

Main Components

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_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
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
arr_web.job_trace Read-only programmatic trace from persisted run/attempt/delivery/version/outbox facts
monthly_reports.worker Dedicated leased outbox consumer with retry/dead-letter behavior
monthly_reports.repository / reporting schema ARRIVAL-derived snapshots, report versions, lineage, manifests and artifact identities
monthly_reports, channel_analytics, company_reports Deterministic downstream consumers of committed facts; company reports build official XLSX files in Python/openpyxl inside Web
Web + Caddy Compose Web-owned login/session boundary behind Caddy HTTPS; no browser-native Basic Auth and no MCP service

Important Boundaries

  • The uploaded source is re-materialized from committed object storage before processing.
  • Login documents/assets, the H5 read-only page/assets, purpose-built public H5 aggregate endpoints, POST /api/login and minimal /healthz readiness are anonymous Web routes. The desktop portal redirects to login; generic business APIs, detailed health, uploads, traces and downloads return 401 without an authenticated server-side session.
  • 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.
  • 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.
  • PostgreSQL state, not HTTP/console output, is authoritative for success.
  • Daily downloads are read from OSS and rechecked; monthly downloads resolve only registered active/superseded local artifacts and recheck path, size and SHA-256.
  • Fresh uploads are new jobs/versions; exact delivery replay is idempotent.
  • Monthly success is acknowledged only after both artifacts are registered and the publication is active; replay of the same snapshot returns the existing report.

Last Updated

2026-08-03