477 lines
46 KiB
Markdown
477 lines
46 KiB
Markdown
# Current State
|
||
|
||
## Current Focus
|
||
|
||
ARR2.0 owns the deterministic XML-to-Finance path and the complete post-commit monthly publication path. The user
|
||
uploads XML once. After an accepted Finance commit, a dedicated worker consumes the durable outbox event, derives the
|
||
month and “更新至” watermark from committed `ARRIVAL` facts, publishes a validated workbook, and records a durable
|
||
download identity.
|
||
|
||
The company-channel detail generator now separates generation permission from calendar completeness: a current-month
|
||
or historical C/O period can be generated from the current committed Finance snapshot, while future report months stay
|
||
blocked. A not-yet-ended period keeps its fixed C/O cutoff and must be rerun after later source facts arrive if the final
|
||
workbook needs those facts. Duplicate publication of the same semantic snapshot is idempotent: the first validated
|
||
archive/result pair remains authoritative even if a retry rebuilds different XLSX bytes.
|
||
|
||
Monthly and company-channel XLSX generation is now Web/container deployable with Python/openpyxl only. The monthly
|
||
builder preserves sheet/header/row/formula/semantic validation, including `=R[row]*C[row]*G[row]`; the company builder
|
||
preserves its no-formula contract. Both publishers upload new workbook and `result.json` objects through the existing
|
||
immutable OSS adapter, while download routing retains controlled-local compatibility for historical records and keeps
|
||
`.web-jobs` queue state local.
|
||
|
||
## Completed On 2026-08-04
|
||
|
||
- Repaired deployment availability for monthly and company report artifacts. Removed the monthly Node/private-package
|
||
runtime path and the stale Node builders/package manifests, added Python/openpyxl monthly validation, and added
|
||
shared OSS publication/read routing with hash/size/MIME rechecks. Migration 016 allows OSS monthly artifact
|
||
identities while preserving historical local rows. Local fake-object-store, builder, publisher, download-router and
|
||
migration tests pass; the development machine has no Docker, so CentOS image/Compose acceptance is explicitly handed
|
||
to the operator. No live report or business data was changed.
|
||
- Fixed the reported `MONTHLY_REPORT_OUTPUT_VALIDATION_FAILED` false negative for the 2026-08-03 440-row monthly
|
||
workbook. `_validate_workbook` now scans read-only sheets sequentially with `iter_rows` and compares Excel-decimal
|
||
readback values within `0.000001`; sheet order, headers, dimensions, semantic identity, formula count and exact
|
||
`=R[row]*C[row]*G[row]` formulas remain strict. A 440-row/five-sheet decimal regression and the 18-case monthly
|
||
builder/publishing/worker/service/repository suite pass. The dead/pending outbox events were not modified.
|
||
|
||
## Completed On 2026-08-03
|
||
|
||
- Removed the private npm dependency from the company-channel report deployment path after CentOS Docker build failed
|
||
with `@oai/artifact-tool` 404. The company workbook builder now uses Python/openpyxl inside Web, keeps formula-injection
|
||
text escaping, produces no preview PNGs, and validates regenerated workbooks after saving. `compose.yaml` starts Web
|
||
with `--enable-company-reports`; HTTP/IP test overrides must keep that flag while omitting `--secure-cookies`.
|
||
Focused company-report and deployment-entrypoint tests pass 19/19. No database migration or live server deployment was
|
||
performed from this workstation.
|
||
- Made the mobile H5 dashboard publicly readable without weakening the desktop/operator boundary. Anonymous users can
|
||
load `/h5`, its H5 assets and purpose-built `/api/public/h5/months` plus `/api/public/h5/analytics` aggregate routes;
|
||
the public projection omits source hashes and operational metadata. Generic analytics, legacy H5 APIs, desktop pages,
|
||
detailed health, jobs/traces, downloads and all write paths remain authenticated. H5 keeps optional authenticated
|
||
logout, uses no-detail `/healthz` for its connection indicator, and 71 `test_arr_web*` tests plus syntax checks pass.
|
||
No live service restart or public deployment was performed.
|
||
- Clarified ARR trace semantics for internet-facing deployment. `artifact_callback` traces now expose additive
|
||
`execution_scope=arr_runtime`, `processor_mode=fixed_processor` and `remote_dispatch=none`; legacy `direct_mcp`
|
||
traces identify remote Agent/MCP delivery. User-visible messages no longer call ARR output “本地处理”, and the
|
||
queued downstream message explicitly says Finance database commit is complete while the outbox waits for its
|
||
consumer. Persisted `local-...` delivery keys and existing trace fields remain unchanged. Trace/Web tests (27) plus
|
||
Python/JavaScript syntax and diff checks pass; no live task or business data was mutated.
|
||
- Performed a read-only live diagnosis after a user reported that Daily Report uploaded but monthly did not update.
|
||
Daily run 39 is accepted and Finance version 14 is active with 111 retained rows for 2026-08-01; its
|
||
`arr.daily_version_committed` outbox event was initially pending with zero attempts. The dedicated worker was then
|
||
started in detached Screen, consumed the backlog through event 20, and published active August V01 (`更新至
|
||
2026-08-01`, 111 rows); July V05 (`更新至 2026-07-27`, 987 rows) also became active while older July V04 was
|
||
superseded. The registered XLSX/result pair exists and the Web health endpoint remains ready. The worker is running
|
||
for this session, but reboot-persistent supervision is still open; no re-upload or source-code change was made.
|
||
- Performed a second read-only BI freshness diagnosis after August publication advanced. Active August V02 is now
|
||
`更新至 2026-08-02` with 268 rows, and a fresh repeatable-read analytics query returns the same watermark and
|
||
`updated_at=2026-08-03 14:21:29 +08`. An already-open BI page can still show 8.1 because `app.js` loads analytics
|
||
only at boot, first BI entry or month change; the monthly page's four-second poll does not refresh BI. This is a
|
||
frontend freshness bug, not a monthly worker/database publication failure. No code or business data changed.
|
||
- Implemented BI freshness detection for desktop and public H5. While visible, each surface checks its lightweight
|
||
month metadata endpoint every five seconds and reloads full analytics only when the selected month's `updated_at`
|
||
changes or the selected month changes. Polling pauses while hidden, resumes with an immediate check, preserves the
|
||
last good snapshot during transient failures, and keeps the existing four-second monthly-history polling separate.
|
||
Static BI/Web tests pass 5/5 and 19/19; both JavaScript syntax checks and `git diff --check` pass. No API, report or
|
||
business data behavior changed.
|
||
- Fixed company-report duplicate publication. A retry now validates the existing archive/result pair against the
|
||
deterministic reservation and builder `semantic_sha256`, verifies the archive hash against the result JSON, and
|
||
reuses the first successful artifact metadata instead of comparing the new XLSX binary SHA. Partial, corrupt or
|
||
semantically conflicting pairs fail closed; an existing `current` file is not overwritten, while a missing one can be
|
||
repaired from the authoritative archive. First-publication rollback behavior and monthly publication code are
|
||
unchanged. Publisher tests pass 6/6, company-report tests pass 32 with five optional ArtifactTool skips, Web
|
||
company/trace tests pass 13/13 and Python compilation is clean. No live report rerun or business-data mutation was
|
||
performed; the historical 2026-07 `11-20` retry remains to be rerun as a separate acceptance action.
|
||
- Added Booking Excel to company-report traceability. New report jobs persist a safe source summary captured server-side
|
||
at submission (batch id, filename, activation time and counts); the company page now shows the active source, job
|
||
detail shows the submission-time source, and history adds a source column. Re-uploading the same active workbook is
|
||
treated as an informational refresh that keeps the existing source and report history; it does not re-extract or
|
||
auto-generate a report. Historical jobs without source metadata remain readable and show that the source was not
|
||
recorded. Full discovery passes 360 tests with 10 optional skips; no live upload, activation, report generation or
|
||
service restart was performed because the available browser session was unauthenticated.
|
||
- A read-only live follow-up found accepted Booking Excel batch 7 active with 72 rows and no review draft. The latest
|
||
August `01-10` jobs contain `source: null` and all five company results fail at `publish` with
|
||
`COMPANY_REPORT_PUBLISH_FAILED` after building row counts. The port-8766 Web process predates both source-traceability
|
||
and current duplicate-publication handling, so a controlled Web restart followed by one authorized rerun is required;
|
||
no restart or backfill was performed.
|
||
- Clarified company-report source and publication status copy for operators. The job panel now says `本次任务使用的
|
||
Excel`; missing metadata says `未记录,无法确认使用了哪份 Excel` and explains that the filename/batch were not saved.
|
||
`COMPANY_REPORT_PUBLISH_FAILED` now says the data reached publication but the official Excel was not saved, and
|
||
explicitly distinguishes that error from successful reuse of a complete identical version. Focused Web/company and
|
||
publisher tests plus JavaScript syntax checks pass. Existing `source: null` jobs remain untraceable and no live
|
||
restart, report rerun or business-data mutation was performed.
|
||
- Removed the redundant Booking Excel provenance card from company-report job details and the provenance column from
|
||
generation history. The upload/review current-source panel and server-side job `source` metadata remain intact for
|
||
operation and audit. Web/company regression passes 29 tests, JavaScript syntax and runtime-reference checks pass,
|
||
and no report or business data changed.
|
||
- After the operator-reported 8766 restart and another `2026-08/01-10` attempt, job
|
||
`253ce23dc7544d34a6e0fb9405ac4d9a` again built all five row sets (`54/18/7/1/15`) but failed at `publish`; the prior
|
||
`c5358fa293184f5f9bad85178afada22` succeeded with the same counts and complete artifacts. Read-only process evidence
|
||
still shows PID `11176` started on 2026-08-02 12:20, before the current duplicate-publication source change, so the
|
||
effective 8766 listener was not replaced. Publish copy was simplified to direct restart-and-retry instructions; no
|
||
report, database or output mutation was performed by this recheck.
|
||
- The operator's latest `2026-08/01-10` retry, job `087dceca79e64bebb719ad06e7813465`, finished at 15:29 +08 with the
|
||
same five row counts and the same publish-only failures. At 15:37 +08, TCP 8766 was still owned by PID 11176 under
|
||
the 2026-08-02 Screen session; the launcher preflight is ready, but the listener still predates the current publisher
|
||
and job-source modules. The earlier successful five archive/result pairs and current downloads all remain
|
||
SHA-256-consistent, and six focused publisher tests pass. No restart, rerun, file repair or business-data write was
|
||
performed; exact listener replacement remains the required operational fix.
|
||
- With explicit operator confirmation, the exact stale PID 11176 was stopped and replaced by PID 54127 at 15:46:29
|
||
+08 through the existing launcher. One authorized job `05cc547d62854df281b0c9cac60e6f6d` then succeeded at 15:48:37
|
||
+08 for all five companies with row counts `54/18/7/1/15`; the new job recorded active Booking batch 7 source
|
||
metadata, reused the same version numbers/artifact descriptors as `c5358fa...`, and all five authenticated HTTP
|
||
downloads returned 200 with matching archive/current/result hashes. The prior files were not overwritten, the
|
||
temporary session was logged out, and no Booking/Finance source or fact mutation occurred.
|
||
- Confirmed the source contracts for repeated Booking/report workflows: byte-identical activated Excel uploads reuse the
|
||
activated source; same rows with different XLSX bytes create a new reviewable source; unchanged report snapshots
|
||
reuse their complete publication pair; changed Finance or Booking version pins create a new report version; and an
|
||
activated subset changes Booking detail coverage without deleting the Finance fact rows. Focused source/publisher/
|
||
integration checks pass 14 tests with two optional ArtifactTool skips. The controlled 8766 replacement and one live
|
||
5/5 rerun now pass; reboot-persistent supervision remains a separate deployment gap.
|
||
- Confirmed a separate operator-visibility gap: the publisher reuses the archive/result pair internally, but neither
|
||
`PublicationOutcome`, `CompanyRunResult` nor the public company-job projection exposes a reuse disposition or prior file
|
||
identity. A successful retry therefore looks like a normal new successful job with a download link; no code change was
|
||
made in this read-only check.
|
||
|
||
## Completed On 2026-08-02
|
||
|
||
- Restored cross-month history visibility for Daily Report, monthly processing and company-channel generation history.
|
||
Each list now has an independent previous/month/next/`本月` navigator and defaults to its latest non-empty month using
|
||
authenticated read-only `GET /api/history-months`. Counts and empty states name the active month and can jump to the
|
||
latest month with records. Company `生成月份` is now visibly labeled and independent from history `查看月份`; monthly
|
||
polling follows the viewing month without changing generation contracts. A guarded live read returns July counts of
|
||
30 daily and four monthly records, while company state retains four July jobs. The full 356-test suite passes with 10
|
||
skips, and isolated Chinese/English/Thai browser QA at 1440/900/390 pixels found no page overflow. Port 8766 was
|
||
restarted under detached Screen and is `ready`; no upload, report generation, source activation or business-data write
|
||
occurred.
|
||
|
||
## Completed On 2026-07-31
|
||
|
||
- Refined the Channel BI utility surface in preserve mode: removed the visible BI panel heading and ready-state
|
||
`数据库已连接` copy while retaining the navigation label, browser metadata and semantic status dot. Compressed the
|
||
month selector to a compact control on desktop/H5, and changed task-log/logout utilities from button chrome to
|
||
low-emphasis accessible links without changing their behavior. JavaScript syntax plus focused BI, daily visual,
|
||
task-log and auth tests pass; no API or business data changed.
|
||
- Tightened the Channel BI panel's top rhythm after the heading removal: the desktop panel now starts 20px higher
|
||
relative to the shared 38px page padding, while the responsive desktop shell keeps a 10px mobile-only adjustment.
|
||
The four-tab bar, panel content and BI data behavior are unchanged; focused Web regression remains green.
|
||
- Refined the Channel BI presentation and data-range contract. Removed the BI-only CHANNEL PERFORMANCE, snapshot
|
||
watermark copy and visible TOTAL PRICE labels on desktop and H5, and added a localized 数据范围 line below the
|
||
company-sales title. The read-only analytics payload now supplies the minimum and maximum ARRIVAL coverage dates
|
||
from one repeatable-read current-version snapshot; no Finance/report business data changed. JavaScript syntax and
|
||
focused analytics/Web/UI tests pass.
|
||
- Implemented the ARR Web Chinese/English/Thai presentation layer. Desktop, H5 and login now share `arr_web/static/i18n.js` with locale selectors, localStorage/cookie preference, `html.lang`, dynamic prompt/API-error translation, Bangkok/Gregorian/Latin-digit date/number formatting and locale-aware duration/money display. The runtime preserves original source strings so switching back to Chinese is safe. `ARR Report`, operational proper nouns, business/API behavior and XLSX/monthly/company report output contracts remain unchanged. Scoped Web regression passed 61/61; full discovery still has only the pre-existing environment errors for missing `httpx`/unavailable OSS client.
|
||
- Rotated both ARR Web operator credential values in separate macOS Keychain items without recording either value in
|
||
source, launcher arguments, logs or project memory. The exact port-8766 listener was stopped by controlled SIGINT and replaced at
|
||
15:30 +08 under one detached `arr2-web-8766` Screen session. Live acceptance rejects the prior pair, accepts the new
|
||
pair, verifies hardened cookie/session/CSRF/logout, desktop/H5, anonymous route boundaries, all six detailed readiness
|
||
flags and loopback/LAN health. Two read-only snapshots stayed at 30 daily jobs, 4 monthly versions and 4 company jobs;
|
||
the newest business records predate the restart, so no business write occurred. Nine focused auth/deployment tests and
|
||
credential-literal scans of the workspace, launcher, state logs and process list pass. The requested password still
|
||
matches the username, so the distinct high-entropy password follow-up remains open.
|
||
- Simplified the three company-channel generation cards by removing the visible `第一期`/`第二期`/`第三期`
|
||
labels and making the C/O ranges the primary card values: `C/O:01-10`, `C/O:11-20` and a month-aware final range
|
||
(`C/O:21-30` for 30-day months or `C/O:21-31` for 31-day months).
|
||
Completion-state chips (`周期未结束` / `周期已结束`) and Bangkok completion times remain, while the underlying period
|
||
keys and generation payload are unchanged. An incomplete period is now still generatable; future months remain blocked.
|
||
JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and isolated 1280x720/390x844 browser QA
|
||
pass with no overflow or page-console warnings. The shared port-8766 service was restarted at 14:36:45 +08 and
|
||
its `/healthz` endpoint returns `ready`.
|
||
- Simplified company report results for end users: duplicate review problems are collapsed by type/code/period so a
|
||
repeated `同房型存在不同静态价格,需人工复核` item appears once per company and period. Replaced the internal
|
||
`版本`/`version_no` display with `生成时间`, using the completed job time and falling back to its created time;
|
||
API version metadata remains intact. JavaScript/HTML checks, 28 focused Web/company tests and targeted deduplication
|
||
execution pass.
|
||
- Rebuilt the company-channel report setup as a dense four-card desktop row: `上传 Excel 报表` followed by the first,
|
||
second and third C/O periods. At that point the `报表月份` picker was a compact visually unlabeled control in the large
|
||
setup card's upper-right corner; the 2026-08-02 history repair later labeled it `生成月份` and moved history filtering
|
||
to its own control. All period CTAs read `生成` with responsive card-sized widths. Replaced the
|
||
browser-native generation confirm with an in-page accessible dialog showing month/period context; cancel, backdrop
|
||
and Escape dismiss without submitting, while explicit confirmation preserves the existing payload, generation polling
|
||
and business behavior. JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and isolated
|
||
1280x720/390x844 browser QA pass with no overflow or console warnings; the shared port-8766 service was restarted at
|
||
14:36:45 +08 and its `/healthz` endpoint returns `ready`.
|
||
- Rebalanced the company-channel setup surface for the current Finance workflow. The fixed five-company scope now sits
|
||
beside `公司渠道明细` as pale helper text, the Excel upload action is bounded to a 760px desktop rail and remains
|
||
full-width/single-column on mobile, and `刷新任务` exposes a read-only scope tooltip. The generation month remains the
|
||
C/O report-month selector for period completeness and the generation payload; its former history-filter role was
|
||
removed by the 2026-08-02 cross-month history repair. No report,
|
||
upload or database behavior changed. JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and
|
||
isolated 1280x720/390x844 browser QA pass with no overflow or console warnings. Port 8766 was not mutated by QA.
|
||
- Compressed the daily overview row to a compact equal-height desktop treatment. The upload card now uses a horizontal
|
||
icon-and-copy dropzone, reduced heading/footer spacing and smaller controls, while the three KPI cards stretch to the
|
||
same row height. Mobile upload layout remains unchanged. JavaScript syntax and 20 focused Web/static/trace tests pass;
|
||
no upload, API or processing behavior changed.
|
||
- Refined the company-channel generation controls for dense Finance use. The three period CTAs are now compact
|
||
104–124px actions centered inside each card, while `提取并核对` uses the same 42px button family and is centered
|
||
inside the upload action column on desktop and mobile. Labels remain single-line, upload/report behavior is
|
||
unchanged, 28 focused Web/company tests and the 348-test discovery pass, and the restarted port-8766 service is
|
||
healthy at 13:37:49 +08.
|
||
- Restored equal card heights across the daily overview row. The ARR.XML upload panel and the three KPI cards now
|
||
stretch to the same grid-row height, with KPI content centered inside each card; mobile stacking remains unchanged.
|
||
JavaScript syntax and 20 focused Web/static/trace tests pass; no upload, API or processing behavior changed.
|
||
- Reverted the KPI width shrink after clarification. The three daily cards now retain their original grid-column widths,
|
||
while their height is content-sized and vertically centered in the upload module's shared desktop row. JavaScript
|
||
syntax and 20 focused Web/static/trace tests pass; no upload, API or processing behavior changed.
|
||
- Centered the shortened daily KPI cards within the upload module's shared desktop grid row, preserving their widths,
|
||
270px height and mobile content-sized fallback. JavaScript syntax and 20 focused Web/static/trace tests pass; no
|
||
upload, API or processing behavior changed.
|
||
- Tightened the three daily KPI cards so they no longer inherit the upload panel's full grid-row height. The desktop
|
||
cards keep their existing widths and data hierarchy, use a compact 270px height with smaller decorative rings, and
|
||
return to content-sized cards on narrow screens. JavaScript syntax and 20 focused Web/static/trace tests pass; no
|
||
upload, API or processing behavior changed.
|
||
- Recomposed the daily overview into one desktop row containing the ARR.XML upload station plus the ARRIVAL DATE,
|
||
processing-duration and NO. OF ROOM cards. Removed the duplicate top `Daily Report` heading and `THIS MONTH` eyebrow,
|
||
renamed the daily-history heading to `Daily Report`, and kept the upload request, inline progress estimate and
|
||
on-demand task-log behavior unchanged. JavaScript syntax and 20 focused Web/static/trace tests pass; no API or
|
||
processing behavior changed.
|
||
- Updated the daily XML upload surface so submitting ARR.XML stays on the daily page instead of opening the task-log
|
||
dialog automatically. The upload card now shows a compact stage-based estimate for upload, fixed processing,
|
||
validation and database commit, finalizing at 100% on success and retaining an inline error state on failure. The
|
||
header task-log button and daily-history row actions still open the existing trace dialog on demand. JavaScript
|
||
syntax and 15 focused Web/static/trace tests pass; no API or processing behavior changed.
|
||
- Simplified the desktop monthly page into a single six-column download table. The redundant standard-monthly heading,
|
||
`VERSION HISTORY`/version-record copy, visible monthly `版本` column and C/O-period footer note are removed; the
|
||
navigation label is now `月报`; the list is identified by a compact `月报处理` heading. The visible `更新至` cell reads the explicit `max_arrival_date` API field, which is
|
||
backed by the published run's `as_of_date` (the maximum included `ARRIVAL`) while retaining the legacy field and
|
||
version ordering for compatibility. The remaining panel uses a compact live-status toolbar and responsive table
|
||
spacing; focused Web/schema/task-log tests and JavaScript/Python syntax checks pass. No report or business data changed.
|
||
- Froze the Markdown-backed July company-channel baseline before any Booking Excel activation. The read-only,
|
||
non-publishing package binds the exact `RES_COMMENT_TYPE_OF_ROOM.md` hash to accepted Booking batch 1, five pinned
|
||
Finance daily versions, processor 1.2.0/rule identity and five generated XLSX files. All 314 output rows independently
|
||
match the Markdown-derived Booking Room expectation; 27 are filled and 287 are correctly blank. The builder reopened
|
||
and exact-value checked every workbook, rendered all 15 sheets, and the retained SHA-256 inventory verifies every
|
||
package file. One reviewing Excel draft remained separate; the current Booking pointer and room-item counts were
|
||
unchanged.
|
||
- Refined the Booking record-extraction review surface for dense operator work. The page now renders 50 records at a
|
||
time, supports individual and all-visible selection, and deletes 1-50 unique selected records through one bounded
|
||
atomic backend operation. Single and batch delete share a count-aware in-page dialog; cancel, backdrop and explicit
|
||
Escape handling never submit and restore focus. The separate accepted-source status/summary is removed; the open
|
||
review now identifies its own extraction records with the validated uploaded workbook filename directly below
|
||
`Booking记录提取`, wrapping fully on narrow screens. The requested review/upload helper copy is removed. Isolated authenticated browser QA covered one/two/50-row
|
||
selection plus 390×844 layout without calling delete; the full suite passes 346 tests with 10 expected optional skips.
|
||
- Implemented the deterministic Booking Excel extraction program requested for raw Tour Code/`โรงแรม` workbooks.
|
||
It applies physically-last-row replacement/cancellation, splits bracketed room items, normalizes agreed TWN/DBL
|
||
variants, preserves quantities on unknown labels, and routes unknown/unbracketed room names to editable/deletable
|
||
pending records. The supplied workbook replays to 26 Tour Codes, 37 items and 7 pending items; `LLT260715AC` becomes
|
||
`TWN/12 + DBL/9`, while `LT260715LD` becomes `U-TWN/17 + pending/2`. Durable review/activation, paged desktop UI and
|
||
bounded GET/POST/PATCH/DELETE transport are present. A real-PostgreSQL transaction probe created a two-item draft,
|
||
corrected its pending item, atomically activated one three-room source row and then rolled the outer transaction back;
|
||
source batch 1, zero drafts and zero synthetic artifacts were restored. No persistent Booking/report business write
|
||
was performed.
|
||
- Confirmed end-to-end readiness boundaries. The company-channel processor already reads current Booking views at report
|
||
generation; a live read-only July snapshot produced valid 5/5 results from 417 Finance facts and 27 matched Booking
|
||
Group Codes, with missing/unmatched Booking Room blank. The expanded Booking/company/real-XLSX suite passed 55/55.
|
||
The controlled real-PostgreSQL draft/edit/activation path passed inside an outer rollback. July `21-month-end` does not open until
|
||
2026-08-01 00:00 Bangkok, and a shared-database test workbook must be a deliberate complete replacement.
|
||
- Audited Booking parser 2.0's human-review requirements across the live schema, current source and active Web process.
|
||
During the audit, concurrent work applied migrations 014/015: the live database now has a current-source pointer plus
|
||
empty draft/item tables supporting basic confirmed/pending/deleted latest-state editing. It still lacks actor, reason
|
||
and revision history. Its earlier GET/POST-only transport finding was subsequently repaired with PATCH/DELETE handlers
|
||
and real socket coverage; real PostgreSQL write/rollback acceptance now passes. The audit itself made no persistent
|
||
database/runtime/business-data mutation.
|
||
- Completed a privacy-minimized, read-only Booking dimension/database audit. `Group Code + room type + quantity` is the
|
||
sufficient normalized allocation model for current data, whose nonblank codes do not cross stay/company/channel;
|
||
missing/unmatched enrichment is blank as designed. Its initial parser/importer snapshot was superseded by the dedicated
|
||
manual-review audit above; migrations 014/015 are formally applied and the transaction boundary is verified, while the
|
||
first operator-authorized real workbook activation remains incomplete.
|
||
No business data changed by this audit.
|
||
- Reduced the ARR login gateway to one clear brand statement and one form. The old workflow marketing copy, numbered
|
||
steps, repeated welcome/access copy and help/footer disclaimers are removed; the remaining field labels are
|
||
`username` and `password`. Existing password visibility, loading/error, safe-return and authentication behavior is
|
||
unchanged. Thirty-three focused Web/auth/UI tests pass, and live 390x844 plus 1280x720 checks show no horizontal
|
||
overflow or browser warnings/errors.
|
||
|
||
## Completed On 2026-07-30
|
||
|
||
- Added application-owned Finance login across desktop, H5, APIs, uploads, traces and downloads. Runtime credentials are
|
||
required, login attempts are bounded, random server-side sessions retain hardened cookies/CSRF, logout revokes the
|
||
session, and only login assets plus no-detail `/healthz` remain anonymous. Caddy now owns HTTPS only.
|
||
- Added a responsive ARR login gateway and desktop/H5 logout/session-expiry behavior. The live source passed wrong and
|
||
correct login, password visibility, safe `/`/`/h5` return, both logout paths, zero-console-error checks and
|
||
375/768/1024/1440 no-overflow verification.
|
||
- Added and applied additive migration 013. New uploads store the validated browser XML basename on
|
||
`ingestion.processing_runs`, while private source artifacts and processor input remain canonical `source.xml`.
|
||
Daily history and task trace read only the new provenance; pre-013 rows render `—`.
|
||
- Added and applied additive migration 012. The `reporting` schema stores monthly versions, Finance daily-version
|
||
lineage, channel row-count manifests and two artifact references without duplicating business/guest rows.
|
||
- Replaced in-memory monthly identities with database IDs, sequential versions, canonical snapshot hashes, atomic
|
||
activation/supersession, persisted failures and idempotent published-snapshot replay.
|
||
- Made the report's `as_of_date` equal the greatest `ARRIVAL` actually included in its snapshot. XML filenames and the
|
||
wall clock are ignored.
|
||
- Added a standalone `monthly_reports.worker` process with leases, `FOR UPDATE SKIP LOCKED`, expired-lease reclaim,
|
||
bounded retry/backoff and dead-letter behavior.
|
||
- Made outbox acknowledgement conditional on a registered active/superseded report and both workbook/result artifacts.
|
||
- Replaced the synthetic monthly list and unavailable download resolver with `reporting.monthly_runs` reads and
|
||
confined path/size/SHA-256 checked downloads.
|
||
- Removed month/cutoff/manual-generation controls from the primary page. The guarded POST route remains only as a
|
||
controlled recovery surface when explicitly enabled.
|
||
- Changed every XLSX data-row `TOTAL PRICE` cell to the exact row-relative `=R[row]*C[row]*G[row]` formula and validates
|
||
the complete formula matrix again after reopening the workbook.
|
||
- Removed the monthly refresh control. The visible monthly tab now performs one non-overlapping list read every four
|
||
seconds, stops while hidden/inactive, reloads immediately when restored, and preserves the last good list during a
|
||
transient background failure.
|
||
- The desktop and H5 headers use the plain `ARR Report` identity with no decorative icon. The daily content heading is
|
||
`Daily Report`; the duplicated daily/monthly explanatory copy has been removed without changing automatic publishing.
|
||
- The desktop header utility formerly labeled `手机看板` is now `任务日志` and opens the existing black task console in
|
||
a native modal. The console no longer occupies the daily-processing layout; upload completion and daily-history row
|
||
activation open the selected job directly. `/h5` remains available by direct URL. Both history and trace SQL are
|
||
explicitly limited to `pipeline_type = 'opera_daily'`, so this is a one-daily-job processing trace rather than a
|
||
global server, monthly-run or company-report log.
|
||
- Refined the daily desktop surface after visual review. `ARR Report` remains the dominant workspace title while
|
||
`Daily Report` is smaller; `任务日志` is a compact outlined button at the adjacent status-label size; the upload
|
||
station is centered and responsive; decorative `01 / UPLOAD` and `本月留痕` labels are gone; and `开始处理` is a
|
||
compact right-aligned action. No upload, API, route or trace behavior changed.
|
||
- Daily, monthly and selected-month company histories use 50 records per page. Each footer shows the exact monthly
|
||
total, current visible range, page number and previous/next controls; counts and rows are read from one database
|
||
snapshot or coordinator lock. Channel BI remains an aggregate view rather than a paginated detail list.
|
||
|
||
## Live Acceptance
|
||
|
||
- Five `arr.daily_version_committed` events have produced July publications: one is the earlier database acceptance
|
||
fixture `mvp-v1-fixture-20260727`; four are real 07-20/07-21/07-22/07-23 uploads.
|
||
- Report ID 4/version 4 is active for 2026-07 with `as_of_date=2026-07-27`, 417 rows and six channels; V03/V02/V01 are
|
||
superseded. Its persisted date equals max current `ARRIVAL` structurally, but that maximum comes from the fixture.
|
||
- The superseded V03 workbook has 308 authorized `TOTAL PRICE` formulas and zero mismatches. Its 40,635 bytes and SHA-256
|
||
`494fb78283f68cb7bffce2501b3531613c494d148a56a7ccc8d2aabe46b1e29c` match the registered artifact.
|
||
- Earlier browser/access-log verification showed V03/V02/V01 downloads and repeated monthly API reads at the
|
||
four-second cadence. The current API now lists V04 active above those versions; ARR2 Web remains green and the worker
|
||
remains separate.
|
||
- ARR2 Web is active on all local interfaces at port 8766 under detached Screen session `arr2-web-8766`. The current
|
||
trusted-Wi-Fi entry is `http://192.168.3.103:8766/`; anonymous root redirects to login and `/login` plus `/healthz`
|
||
return HTTP 200. The current process restarted at 2026-07-31 19:27:42 +08 to load the Web i18n static resources
|
||
after the source implementation; it loads the Booking bulk-review
|
||
composition; the public health check returns `ready`.
|
||
Authenticated acceptance reports database, processing, monthly reports, downloads, company reports and company-source
|
||
upload ready. At the earlier 11:30 acceptance the draft endpoint returned no open draft; this later UI task did not
|
||
authenticate against, inspect or mutate the shared draft contents. Anonymous PATCH/DELETE reach the application auth gate and return JSON
|
||
401 rather than transport-level 501. Migrations 014/015 are live and the current pointer selects batch 1; no persistent
|
||
Booking write was performed. Legacy port 8765 remains closed; the mode-0700 launcher keeps secrets outside the repository.
|
||
- The active ARR2 analytics API on port 8766 returns 417 rooms because the known one-row fixture remains current.
|
||
- Live pagination acceptance on port 8766 currently reports 30 daily jobs, 4 monthly versions and 4 company jobs. All
|
||
three render page 1/1 with correct disabled boundary controls; a 390-pixel viewport has no horizontal overflow.
|
||
- Migration 013 is live in `booking_test`: 25 total processing runs, zero falsely backfilled upload filenames and a
|
||
validated constraint. A rolled-back Unicode-basename probe proved history/trace return the upload name while the
|
||
artifact remains `source.xml`.
|
||
- The pre-012 privacy-minimized metadata checkpoint is
|
||
`runtime/backups/booking_test_pre_012_20260730T151922+0800/manifest.json`, SHA-256
|
||
`230206eb074fd5877132744eb592b3dc6cd6638d12a3dd4d71a8101a9bd2998e`.
|
||
|
||
## Active Data-Quality Incident
|
||
|
||
- The company-report cutoff-10 and cutoff-20 Web jobs both completed 5/5 with valid zero-row workbooks because every
|
||
current supported-company fact has C/O in the 21-to-month-end period. Processor 1.2.0 implements the final
|
||
user-confirmed fallback: no Group Code leaves both `RES_COMMENT`/`Booking Room` blank; a present Group Code that
|
||
cannot resolve in Booking remains visible while only `Booking Room` is blank. A repeatable-read July 31 preview is
|
||
now valid 5/5: LianTai 138 rows/122 blank Booking Rooms, QBD 139/128, DY-AI-Easy-KB 1/1, FengRun 33/33 and HanaTour
|
||
3/3. No report or business-data mutation was performed. The active port-8766 runtime now loads the current processor
|
||
and reports company-report readiness true; one controlled 5/5 Web job remains a separate acceptance action, with a
|
||
post-completion rerun recommended if later source facts should be reflected.
|
||
- Finance current version 2 is `synthetic.xml` from provider `local_fixture`; it adds 1 room, 3 room-nights, 5,400
|
||
revenue and a synthetic room type to Channel BI and all July monthly publications.
|
||
- V01's legitimate operational source is exactly 119 rows with `ARRIVAL=2026-07-21`; its persisted lineage and
|
||
hash-matched workbook also contain the one-row 07-27 fixture, which is why the stored report says 120 rows and
|
||
`as_of_date=2026-07-27`. This is contaminated content, not a metadata-only date error.
|
||
- Excluding the fixture leaves the verified four-day business total of 416 rows/rooms, 853 room-nights and 1,451,350
|
||
revenue through ARRIVAL 2026-07-23. Hash matching and isolated replay prove the accepted file mapping is
|
||
07-20=100, 07-21=119, 07-22=88 and 07-23=109; the user's total was right but the 07-20/07-22 labels were reversed.
|
||
- No database repair was performed during diagnosis. The fixture should be retired from the current projection without
|
||
deleting immutable history, followed by a clean July republication and live API verification.
|
||
- Channel BI now checks the selected month's `updated_at` every five seconds while visible, so an already-open view
|
||
reloads its aggregate data after a new Finance version is published. The historical 308/417 observation above is
|
||
retained as evidence of the earlier stale-view behavior, separate from the one-row fixture contamination.
|
||
- The BI `公司数` card actually counts worksheet channels; LianTai GROUP/FIT are separate, so six channel keys can still
|
||
correspond to five top-level companies.
|
||
|
||
## Verification Status
|
||
|
||
- The 2026-07-31 Web i18n implementation passed JavaScript syntax checks, a DOM/runtime locale smoke (Chinese → English → Thai → Chinese), and 61 focused ARR Web tests. A full 298-test discovery was attempted; eight import/runtime errors are environment-only (`httpx` absent and OSS client unavailable), with no i18n-related failure.
|
||
- Migration 012 passed transaction-only up/down probes, including a synthetic active publication followed by rollback.
|
||
- The 38-test monthly/migration/Web regression set passed, including real XLSX build/reopen checks.
|
||
- A clean full-suite rerun with the optional ARR1 compatibility dependency installed passed 291 tests in 108.2 seconds
|
||
with 7 explained environment/fixture skips and no failures or errors.
|
||
- The automatic-list follow-up passed 18 focused Web/schema tests, JavaScript syntax checking and a clean 291-test full
|
||
discovery in 110.8 seconds with the same 7 explained environment/fixture skips.
|
||
- The post-update BI diagnosis passed 24 focused analytics/contracts/Web tests and reconciled both live Web APIs against
|
||
a repeatable-read, read-only database snapshot.
|
||
- Hash-matched local source inspection and isolated deterministic replay reproduced `0720.XML=100` and `0722.XML=88`;
|
||
the 07-23 accepted run was traced to its 16:12:27 commit and 109 retained rooms.
|
||
- The final scoped company/Booking/report suite ran 32 tests successfully with three expected private-fixture skips; it
|
||
included real XLSX export, value verification after reopen, rendering and the dedicated no-Group-Code path. Four Web
|
||
company-task coordinator tests also passed.
|
||
- The 50-row pagination follow-up passed JavaScript syntax, 29 focused Web/repository tests and the complete 305-test
|
||
discovery with 10 existing environment-dependent skips. Live desktop and 390-pixel checks confirmed all three
|
||
totals/ranges and boundary-button states.
|
||
- The upload-filename change passed 69 focused tests, JavaScript/Python syntax checks and a clean 312-test full
|
||
discovery in 99.280 seconds with 10 environment/fixture skips.
|
||
- The application-login change passed a 33-test focused auth/Web/company/deployment set after final compatibility edits,
|
||
JavaScript/Python syntax checks, Ruby static Compose parsing and the clean 317-test full discovery in 97.311 seconds
|
||
with 10 environment/fixture skips. Docker is not installed locally, so live `docker compose config` was not claimed.
|
||
- The expanded absent-or-unmatched company-report fallback passed a 37-test
|
||
company/Booking/real-XLSX/Web-coordinator suite with three expected private-fixture skips and no failures; the current
|
||
controlled July 31 projection previewed valid 5/5. A separate non-publishing real-data vertical slice built, reopened,
|
||
value-checked and rendered all five actual workbooks in a temporary directory.
|
||
- The daily visual-polish follow-up passed JavaScript syntax and 33 authenticated Web/auth/daily-visual/task-log tests.
|
||
Live 375/768/1024/1440 checks confirmed the corrected title hierarchy, centered upload geometry, compact actions,
|
||
task-log dialog focus restoration, zero horizontal overflow and zero browser warnings/errors.
|
||
- Live login activation passed anonymous root/API rejection, exact credential login, hardened cookie/session/CSRF,
|
||
authenticated desktop/H5/history reads, all five readiness flags, logout revocation and loopback/LAN health. Read-only
|
||
totals at initial activation were 24 daily jobs, 4 monthly versions and 3 company jobs; no upload, report job or worker
|
||
was started.
|
||
- The 2026-07-31 credential rotation passes prior-pair rejection, new-pair login, hardened cookie/session/CSRF, logout
|
||
revocation, desktop/H5 and all six current detailed readiness flags. Two read-only snapshots remained 30 daily jobs,
|
||
4 monthly versions and 4 company jobs, with their latest creation times before the 15:30 restart. No upload, report
|
||
generation, Booking activation or monthly worker action occurred.
|
||
- Booking extraction runtime acceptance passed authenticated health/source-draft reads, clean logout, anonymous
|
||
PATCH/DELETE application routing and direct read-only repository access. At that probe all relevant readiness flags
|
||
were true, source batch 1 remained current and no draft existed. A later operator upload created one reviewing draft;
|
||
the Markdown baseline freeze proved it remained isolated and did not change batch 1. A 2026-07-31 14:14 +08 live
|
||
read-only recheck found no reviewing draft and still found Markdown batch 1 current with 867 rows, six worksheets and
|
||
348 Group Codes, so the draft blocker is currently clear without any Booking source switch.
|
||
- The same live recheck found that the current July company-report projection has advanced beyond the frozen
|
||
five-version baseline: 986 supported-company Finance facts now all have C/O dates from July 21 through July 30.
|
||
Read-only processor 1.2.0 output remains valid 5/5 with 598 rows, 224 filled Booking Rooms and 374 blanks. The earlier
|
||
314-row package remains correct for its pinned snapshot; it is not the expected row count for this later live
|
||
projection. The first two July periods can now be generated from the current snapshot before their calendar
|
||
completion; any later Finance facts within the fixed C/O ranges require a rerun.
|
||
- Final post-change discovery ran 343 tests in 102.451 seconds: all passed, with 10 explained optional
|
||
renderer/private-fixture skips. JavaScript syntax, Python compilation, supplied-workbook replay and the 17 focused
|
||
parser/review/coordinator/router/socket tests are also green.
|
||
- Booking review persistence passed a real-PostgreSQL transaction-only vertical slice: draft creation exposed two items
|
||
with one pending, edit confirmed the pending item, activation produced one source row with quantity three, and the outer
|
||
rollback restored batch 1 with no synthetic draft, source or artifact residue.
|
||
- A 2026-08-03 diagnosis reproduced the 2026-07 `11-20` company-report retry failure: all five companies failed at
|
||
`publish` after an earlier same-period success because repeated XLSX builds had identical semantic SHA-256 values but
|
||
different binary SHA-256 values. Publisher idempotency now reuses a complete matching archive/result pair and fails
|
||
closed on partial or conflicting state; the historical retry still needs a deliberate live rerun.
|
||
- Isolated authenticated browser checks covered the upload-first desktop flow, editable review table, fixed-company text
|
||
and responsive 375/390-pixel layouts with no horizontal overflow or console errors.
|
||
|
||
## Remaining Deployment Work
|
||
|
||
- Perform the first operator-authorized real workbook upload/review/activation, then run one controlled five-company
|
||
report and verify all five downloads. The database transaction boundary is accepted, but this task intentionally did not
|
||
replace the current business Booking source. Because activation replaces the whole source, supply a complete workbook
|
||
and restoration plan.
|
||
- Decide whether Booking confirmation is a simple single-operator correction loop or an auditable approval workflow;
|
||
add actor/reason/revision history and stronger declarative DB transitions if audit-grade confirmation is required.
|
||
- Upload one controlled raw Tour Code/`โรงแรม` workbook, review/activate it, confirm
|
||
replacement semantics and run one controlled company report. A period may be generated before its Bangkok completion
|
||
boundary, but rerun it after completion if the source snapshot changes; the currently open July periods contain zero
|
||
rows and cannot prove populated Booking Room. Before real use, confirm whether 23 fixture Group Codes shared by
|
||
`DY-AI-Easy-KB` and `LIANTAI-FIT` are intentionally additive; the current view merges them globally.
|
||
- The prior 8766 outage and credential gate are resolved. The current Web process is a detached local Screen session,
|
||
not a reboot-persistent service; `/Users/chillishark/.local/bin/arr2-web-8766 --check` validates its private route and
|
||
Keychain inputs without printing them before a controlled restart.
|
||
- Live authentication/readiness and one controlled 5/5 company-report job with all five downloads are accepted. One
|
||
no-PII XML upload should still confirm migration-013 filename provenance after restart; the Web/worker sessions remain
|
||
detached and are not reboot-persistent.
|
||
- The latest operator-selected Web credentials were rotated on 2026-07-31, but the password still matches the username.
|
||
Rotate it again to a distinct high-entropy value in Keychain, followed by one controlled Web restart.
|
||
- The workstation runs Web and worker as separate processes. The checked-in Compose image supports both report paths
|
||
through Python/openpyxl; the worker still needs the existing database/OSS secrets and may use `/app/outputs` only for
|
||
staging and local `.web-jobs` state. A formally controlled no-PII CentOS Docker acceptance run remains appropriate.
|
||
- ARR2.0 now has Git metadata; `main` tracks `origin/main`. Runtime credential values remain outside Git and project
|
||
files.
|
||
|
||
## Last Updated
|
||
|
||
2026-08-04
|