# ARR Web Portal The portal exposes four surfaces: - 日报处理: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. ## 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 `: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 /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` 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`. ## Verification ```bash PYTHONPYCACHEPREFIX=/private/tmp/arr-web-pyc \ python3 -m unittest tests.test_arr_web_repository_schema tests.test_arr_web -v ``` The full fake-transport end-to-end suite remains privacy-safe and uses synthetic identifiers only.