feat: sync latest ARR implementation
This commit is contained in:
@@ -1,100 +1,39 @@
|
||||
# ARR Web Portal
|
||||
# ARR 2.0 Web
|
||||
|
||||
The portal exposes four surfaces:
|
||||
Web 层提供固定页面和审计友好的 API。生产 XML 写路径为:
|
||||
|
||||
- 日报处理:XML upload, remote processing status, ARR validation and database result;
|
||||
- 月报处理:ordinary program generation from current database facts;
|
||||
- 渠道 BI:live read-only aggregation from current retained facts;
|
||||
- 渠道使用情况:company ten-day report jobs.
|
||||
`POST /api/jobs` → `ProgrammaticUploadCoordinator` → 固定处理器 → `DeliveryValidator` → PostgreSQL 原子提交。
|
||||
|
||||
## Current database model
|
||||
|
||||
`arr_web.repository.PostgresPortalRepository` reads migration 008 relations:
|
||||
|
||||
- `ingestion.processing_runs` / `ingestion.artifacts` for daily history and artifacts;
|
||||
- `finance.daily_versions` / `finance.current_daily_versions` for validated dates;
|
||||
- `finance.v_active_daily_facts` and current channel metrics through `channel_analytics`.
|
||||
|
||||
There are no database `report_versions`. The monthly-runs read endpoint exposes a source-ready monthly projection (dates, channels and row count) and does not claim an XLSX artifact. Generated monthly files live in the controlled publishing/OSS layer.
|
||||
|
||||
## Local run
|
||||
|
||||
```bash
|
||||
PYTHONPYCACHEPREFIX=/private/tmp/arr-web-pyc \
|
||||
.venv/bin/python -m arr_web.run \
|
||||
--host 127.0.0.1 \
|
||||
--port 8765 \
|
||||
--db-config /path/to/private/booking-test-db.env \
|
||||
--enable-processing \
|
||||
--enable-agent-writeback \
|
||||
--enable-monthly-generation \
|
||||
--enable-company-reports \
|
||||
--node-binary /absolute/path/to/node \
|
||||
--artifact-tool-module /absolute/path/to/artifact_tool.mjs
|
||||
```
|
||||
|
||||
- Desktop: `http://127.0.0.1:8765/`
|
||||
- H5: `http://127.0.0.1:8765/h5`
|
||||
- Health: `http://127.0.0.1:8765/api/health`
|
||||
|
||||
The active test target is the controlled `<ARR_DB_HOST>:5432/booking_test`. The old `booking-test-lan-db.env` is retained only for temporary rollback checks and should not receive new writes.
|
||||
|
||||
`--enable-processing` is also fail-closed. It reports `processing_ready=true`
|
||||
only when PostgreSQL, the guarded OSS uploader and the Open Agent client all
|
||||
initialize; the dispatched message contains one `fetch_oss_file` attachment
|
||||
descriptor and no OSS credential.
|
||||
|
||||
`--enable-agent-writeback` is fail-closed. `GET /api/health` reports
|
||||
`agent_writeback_ready=true` only after the current processor policy, PostgreSQL
|
||||
state/repository, independent HMAC verifier, Aliyun OSS backend and controlled
|
||||
output reader all initialize successfully. Missing or incompatible deployment
|
||||
configuration keeps the callback route unavailable instead of accepting an
|
||||
unverified result.
|
||||
|
||||
The local LaunchAgent wrapper optionally loads
|
||||
`/path/to/private/agent-writeback.env`. It refuses a symlink,
|
||||
non-regular file, foreign owner or permissions other than `0600`; no real
|
||||
secret belongs in this repository or `.env.example`.
|
||||
|
||||
Local secrets use the macOS Keychain account `arr-web`. The launcher maps the
|
||||
OSS key ID/secret and the Agent Open API key from their dedicated service names
|
||||
into process environment variables; the callback HMAC remains an independent
|
||||
Keychain item. At present the launchd label and launcher/log paths still use
|
||||
the historical project location even though the process runs this repository;
|
||||
that deployment-path cleanup is separate from application readiness.
|
||||
|
||||
## Security
|
||||
|
||||
- Browsers never receive a PostgreSQL DSN or OSS credential.
|
||||
- Read transactions are repeatable-read/read-only and reject any database other than `booking_test`.
|
||||
- Writes use same-origin session/CSRF; machine result callbacks use signed result verification.
|
||||
- Downloads are resolved from server-owned artifact identity, then rechecked for path, type, size and SHA-256.
|
||||
- Production needs dedicated reader/writer roles and a provider-backed private OSS reader; the current test database owner and local fixture reader are not production configuration.
|
||||
|
||||
## API
|
||||
主要接口:
|
||||
|
||||
- `GET /login`、`POST /api/login`、`POST /api/logout`
|
||||
- `GET /api/session`
|
||||
- `GET /api/health`
|
||||
- `GET|POST /api/jobs`
|
||||
- `GET|POST /api/monthly-runs`
|
||||
- `GET /api/months`
|
||||
- `GET /api/analytics`
|
||||
- `GET /api/h5/months` (legacy H5 raw compatibility)
|
||||
- `GET /api/monthly/{month_key}/analytics` (analytics 1.2 raw compatibility)
|
||||
- `GET /api/channel-detail`
|
||||
- `GET|POST /api/company-reports/jobs`
|
||||
- `POST /api/integrations/super-agent/results`
|
||||
- `GET /healthz`:仅供容器读取的无详情 readiness 探针
|
||||
- `POST /api/jobs`
|
||||
- `GET /api/jobs`
|
||||
- `GET /api/jobs/{job_id}/trace`
|
||||
- `GET /api/download/daily`
|
||||
- `GET /api/monthly-runs?month=YYYY-MM`:读取已持久化的月报版本
|
||||
- `GET /api/download/monthly?report_id=...`:下载登记为 active/superseded 的月报并复核路径、大小和 SHA-256
|
||||
- `POST /api/company-reports/source`:上传并提取原始 Booking XLSX,先创建复核草稿
|
||||
- `GET /api/company-reports/source/draft`:分页读取当前复核草稿
|
||||
- `PATCH`/`DELETE /api/company-reports/source/draft/items/{id}`:人工保存房型/数量或删除记录
|
||||
- `DELETE /api/company-reports/source/draft/items`:在同一事务中批量删除最多 50 条所选记录
|
||||
- `DELETE /api/company-reports/source/draft`、`POST /api/company-reports/source/draft/activate`:放弃草稿或在零待人工时原子启用
|
||||
- BI 与公司报表接口
|
||||
|
||||
The machine callback accepts the canonical signed body described in
|
||||
[`AGENT_WRITEBACK_CONTRACT.md`](../AGENT_WRITEBACK_CONTRACT.md). HTTP `200`
|
||||
means that the delivery is committed (or is an identical idempotent replay),
|
||||
not merely that the remote Agent Run reported `success`.
|
||||
ARR 2.0 不注册 `/api/integrations/super-agent/results`。访问旧回调地址返回 `404 ROUTE_NOT_FOUND`。
|
||||
|
||||
## Verification
|
||||
除登录静态资源、`POST /api/login` 和 `/healthz` 外,页面、API、上传与下载均要求应用登录。Web 进程从 `ARR_WEB_USERNAME` / `ARR_WEB_PASSWORD` 读取 Finance 操作员凭据;缺失时启动失败。会话 cookie 为 `HttpOnly`、`SameSite=Strict`,HTTPS 部署必须启用 `--secure-cookies`。Caddy 仅终结 HTTPS,不再使用浏览器原生 Basic Auth。
|
||||
|
||||
```bash
|
||||
PYTHONPYCACHEPREFIX=/private/tmp/arr-web-pyc \
|
||||
python3 -m unittest tests.test_arr_web_repository_schema tests.test_arr_web -v
|
||||
```
|
||||
`--enable-processing` 只有在数据库、OSS、固定处理器和独立验证器全部初始化成功时才使 `processing_ready=true`。上传处理是同步终态边界:HTTP 保持 `202` 兼容页面,但响应前已经完成验证/入库或记录失败。
|
||||
|
||||
The full fake-transport end-to-end suite remains privacy-safe and uses synthetic identifiers only.
|
||||
日报历史和任务日志中的“文件”只显示浏览器上传的 XML basename。内部源工件继续规范化为 `source.xml`,不会暴露到这两个用户界面;迁移前的历史任务没有可还原的上传名,页面显示 `—`。
|
||||
|
||||
月报主页面没有月份、截止日、手动生成或手动刷新控件。日报提交成功后,独立 `monthly_reports.worker` 消费 outbox 事件;它从数据库内纳入数据的最新 `ARRIVAL` 派生“更新至”。月报页可见时每四秒自动读取 `reporting.monthly_runs`,新版本发布后直接新增;页面隐藏或离开该页时停止轮询,恢复时立即读取。Web 内部 POST 生成端点只作为显式启用的受控恢复入口,不属于用户主流程。
|
||||
|
||||
公司渠道明细的 Booking XLSX 使用“提取 → 人工核对 → 整表启用”边界。上传只写私有源工件和
|
||||
`booking.extraction_*` 草稿;自动/人工记录都能编辑或删除,待人工项目不会进入有效房量。只有草稿不存在
|
||||
待人工项目且至少保留一条确认记录时,后端才在一个事务中生成 accepted Booking 批次并切换
|
||||
`booking.current_source_batch`。打开草稿期间禁止创建新的公司渠道明细任务。
|
||||
|
||||
Reference in New Issue
Block a user