# Public Mobile H5 Dashboard

## Request

Make the mobile dashboard publicly viewable while preserving the authenticated Finance/operator surface.

## Public contract

- Anonymous `GET /h5`, `/h5.html`, `/assets/h5.css` and `/assets/h5.js` are allowed. `i18n.js` was already public as a
  login asset.
- Anonymous `GET /api/public/h5/months` returns only month key, update time and maximum ARRIVAL watermark.
- Anonymous `GET /api/public/h5/analytics?month=YYYY-MM` returns aggregate channel/room metrics and date coverage.
  The public projection omits `source_monthly_sha256`, filenames and operational metadata; JSON responses are
  `Cache-Control: no-store`.
- H5 uses anonymous `/healthz` for its connection indicator and does not require a CSRF token for read-only data. When a
  logged-in operator opens H5, the existing session is still detected and the optional logout control remains available.

## Protected contract retained

Anonymous desktop `/`, `/api/health`, generic `/api/months`, `/api/analytics`, legacy `/api/h5/months`, legacy
`/api/monthly/{month}/analytics`, jobs, traces, downloads, uploads, Booking/company/report routes and mutations remain
protected by the existing session/CSRF boundary.

## Verification

- `python3 -m unittest tests.test_arr_web_auth tests.test_arr_web` — 26 passed.
- `python3 -m unittest discover -s tests -p 'test_arr_web*.py'` — 71 passed.
- `node --check arr_web/static/h5.js`, `node --check arr_web/static/app.js` and `python3 -m py_compile arr_web/app.py` — passed.
- `git diff --check` — passed.
- No live service restart, public deployment, database write or business/report mutation was performed.
