feat: continue roadmap acceptance work

This commit is contained in:
ik
2026-09-20 15:17:21 +07:00
parent d438c40542
commit b0edae98c6
19 changed files with 547 additions and 50 deletions
+162
View File
@@ -0,0 +1,162 @@
# Актуальный технический аудит RF4 Spotter — 20 сентября 2026
База аудита: ветка `main`, commit `d438c40`, рабочая копия проверена 20.09.2026.
Изменения до аудита уже существовали в рабочем дереве только в `README.md` и
`docs/ROADMAP.md`; они сохранены и не смешаны с результатами аудита.
Цель — отделить фактически проверенное локально от исторических результатов,
которые требуют повторного Docker/browser/production-прогона.
## Итог
Проект представляет собой функциональный single-owner alpha MVP на Astro SSR,
FastAPI, PostgreSQL, MinIO и Caddy. Кодовая база сейчас проходит локальные
quality gates: Python — `190 passed, 1 skipped`, Astro check — `0 errors / 0
warnings / 0 hints`, production build — успешен, web unit — `1 passed`, media
audit — без issues и orphan-файлов. Production Compose файл корректно
интерполируется с безопасными временными значениями, а Alembic graph имеет
единственную голову `0020`.
Открытая альфа ещё не готова к объявлению production-ready. Не подтверждены в
этой сессии: запуск чистого полного Compose stack, фактический `alembic current`
против PostgreSQL, внешний DNS/TLS/backup/restore, browser acceptance тем,
административных сценариев и B25 media. Это инфраструктурные и приёмочные
ограничения, а не обнаруженная ошибка сборки.
## Архитектура и границы ответственности
| Слой | Текущее состояние | Оценка |
|---|---|---|
| Caddy | Production proxy, TLS/Basic Auth для `/admin`, API routing, headers, CSP | готово локально; внешний TLS не проверен |
| Astro | SSR Node adapter, public/admin pages, server-side form/API bridges | сборка и check проходят |
| FastAPI | роутеры activity/catalog/media/public/admin/submissions, health/readiness | API contract и тесты проходят |
| PostgreSQL | SQLAlchemy 2, Alembic, persistent rate-limit/import history | миграционный graph проверен, живая БД не запущена |
| MinIO/S3 | отдельный app user/policy, Git media proxy и provenance | offline media audit проходит |
| Scheduler/import | opt-in Compose profiles, общий cooldown/backoff контур | запуск источников намеренно не включён по умолчанию |
Архитектурное решение Astro + FastAPI + PostgreSQL сохраняется. API уже
разделён на роутеры, поэтому старое замечание о монолитном `main.py` из аудита
10 сентября больше не актуально. `main.py` оставляет composition root,
middleware, health/readiness и регистрацию роутеров.
## Проверки и доказательства
| Проверка | Результат | Комментарий |
|---|---:|---|
| `.venv/bin/pytest -q` | `190 passed, 1 skipped` | 72 deprecation warnings FastAPI/`asyncio.iscoroutinefunction`; skip — PostgreSQL integration |
| `npm --prefix apps/web run check` | 0/0/0 | 61 Astro files inspected |
| `npm --prefix apps/web run build` | passed | SSR Node production build |
| `npm --prefix apps/web run test:unit` | `1 passed` | Node unit suite |
| `media_cli --audit` | 704 entries, 0 issues | 466 approved, 226 superseded, 1 duplicate, 11 invalid; no orphans |
| `media_cli --quality-report` | 253 fish published | 252 are 1024×1024 WebP; one 48×48 fallback remains |
| `docker compose -f compose.production.yaml config --quiet` | passed | checked with temporary non-secret values only |
| dev `docker compose up --build --wait` | passed | PostgreSQL, MinIO, API and web healthy; migration service exited 0 |
| live `/health`, `/ready`, public routes | passed | health/readiness and public `/`, `/waterbodies/`, `/records/` returned expected responses from container network |
| Alembic `heads` / live `current` | `0020 (head)` | both repository graph and running PostgreSQL verified |
| waterbody catalog import/audit | `19/19`, 0 failures | canonical snapshot applied; no missing, duplicate or provenance issues |
| OpenAPI | passed after Q16 fix | `apps/api/export_openapi.py --check` passes with `36 paths`; artifact regenerated from FastAPI, not manually edited |
| Browser acceptance | not confirmed | in-app browser backend unavailable in the current session |
The dev stack was stopped after the checks without removing its named volumes.
This is a local integration gate, not a production deployment or external
browser acceptance.
## Backend and data layer
### Strengths
- API endpoints are separated into focused routers and have a tracked OpenAPI
generator/artifact; Q16 was closed by regenerating the artifact and passing
the deterministic check.
- Alembic migrations are linear through `0020`; latest migrations cover
waterbody provenance, coordinate precision, fish counts and detail fields.
- Official/community import paths preserve old data on incomplete or failed
responses, use provenance, and keep network fetching opt-in.
- Admin media publish/rollback keeps fallback assets and provenance; public
media is content-addressed and served locally rather than hotlinked.
- Rate limiting uses a persistent, privacy-preserving HMAC client hash and
trusted-proxy handling.
### Remaining risks
- The single-owner admin model still uses a shared Bearer token and proxy Basic
Auth. A05 (personal accounts, roles, revocation and operator IDs) is correctly
deferred until the pilot has more than one operator.
- Public cache is process-local; shared invalidation/Redis is explicitly a
post-pilot decision and should not be added before measured need.
- Production query p95 and real data growth are not measured in this workspace.
The existing query-plan gate is a local fixture gate, not a production SLO.
- The waterbody canonical index has 19 verified entries, but detail snapshots
currently cover only the first waterbody. W02W08 remain open.
## Frontend, accessibility and visual system
Astro SSR pages include public catalogs, fish/waterbody/spot detail, official
records, reports, status, media and admin screens. The current implementation
has semantic light/dark tokens, system/manual theme selection, forced-colors
rules, nonce-based JSON-LD CSP, noindex/no-store handling for admin/error
surfaces, responsive pagination and reduced-motion styles.
Automated structural checks pass, but visual acceptance is not equivalent to
`astro check`. B25, D05/D07 and A06 remain open for desktop/mobile light/dark,
forced-colors, focus order, long data, empty/error states and screenshots.
## Security and operations
### Confirmed in code/config
- Production settings reject demo/short admin, rate-limit and S3 credentials.
- Production CORS requires explicit HTTPS origins; demo seeding is forbidden.
- Caddy and API set HSTS, `nosniff`, restrictive referrer/permissions policy,
anti-framing headers and CSP; Astro uses a per-response nonce for JSON-LD.
- Production MinIO app credentials are separated from root credentials and
limited to one bucket's list/location/get/put/delete operations.
- CI contains locked dependency installation, pip-audit, clean migration,
Compose E2E and scheduled production-bootstrap drill definitions.
### Not yet proven for release
- No production server, DNS, TLS certificate, real secrets or external backup
restore were exercised here.
- `compose.yaml` intentionally contains local demo defaults; only
`compose.production.yaml` has fail-fast production secret requirements.
- The scheduled bootstrap workflow exists, but its latest successful run is a
repository history fact, not a fresh verification in this workspace.
- The Docker operator account remains a high-privilege operational boundary;
SSH/firewall/VPN restrictions belong to deployment hardening.
## Media and provenance snapshot
The manifest contains 704 records: 466 approved, 226 superseded, one
provenance-only duplicate and 11 invalid records. Fish quality-upgrade processing
completed for 226 alternatives; 253 fish assets are published, 252 with
1024×1024 WebP and one explicit low-resolution fallback. Offline media audit
reports no checksum/dimension/MIME/provenance/orphan problems.
This does not close B25: browser checks for broken images, responsive overflow,
light/dark presentation and source links are still required. It also does not
grant new source permissions; Q01 remains the source-rights gate.
## Prioritized action plan reflected in ROADMAP
1. **Release blockers:** repeat the clean production Compose/bootstrap gate;
verify readiness, migration current, proxy routing, backup/restore and
production secret/preflight checks (A07 and open-alpha gate).
2. **Browser gates:** complete B25 media, A06 admin/accessibility and D07 full
visual matrix when a Chromium/browser backend is available.
3. **Waterbody data:** process the remaining 18 detail snapshots under the
shared cooldown, then complete W03W08 without assigning unreviewed media
roles.
4. **Source governance:** attach durable primary permission evidence and image
rights before expanding public catalog coverage (Q01).
5. **After pilot:** personal admin identities (A05/M06), shared cache only after
measurement, production p95 and external search/analytics integrations.
## Scope decisions
- No Next.js/Vinext migration, Redis addition, broad CSS rewrite or unrelated
refactor is justified by this audit.
- No external source was fetched during this audit.
- No media was downloaded, replaced or automatically promoted.
- Historical audits remain historical; this document and `ROADMAP.md` are the
current decision context.