gendesign/backend
Light1YT 4a4a6e8727 feat(rbac): сузить pilot scope только до /trade-in/**
Decision 2026-05-26: pilot аккаунты пилот-программы получают доступ
ТОЛЬКО к разделу Trade-In (оценка вторички). Landing, Analytics,
Site Finder, Concept — admin-only.

Изменения:
- `auth/roles.yaml` — `pilot.paths` сужен с 7 путей до 2:
  `/trade-in/**` + `/trade-in/api/v1/**`. Deny список оставлен
  как есть для defense-in-depth.
- `backend/tests/test_rbac.py` + tradein mirror — переписан
  `test_is_path_allowed_pilot_excludes_admin` → `_pilot_only_tradein`:
  pilot allowed только /trade-in, denied на /, /analytics, /site-finder,
  /concept, /api/v1/parcels. Тест `test_get_user_scope_pilot` ассертит
  что /trade-in/** в allowed, / и /analytics/** нет.
- `frontend/src/lib/__tests__/isPathAllowed.test.ts` — те же parity
  обновления (pilot allowed list сужен, denied list расширен landing
  + non-tradein путями).
- `caddy/users.caddy.snippet` — синхронизирован с VPS-актуальной
  версией: regen'd user1..user10 hashes + admintest/pilottest entries
  (locally added на VPS 2026-05-26 для QA RBAC). Без этого `deploy.yml`
  делал бы `git reset --hard` и стирал бы локальные правки.
- `auth/roles.yaml` users: блок — также добавлены `admintest: admin`
  и `pilottest: pilot` (mirror VPS local edit).

Эффект для UX:
- pilot открывает `/` → frontend RouteGuard → fullscreen «Доступа нет»
  (т.к. `/` не в allowed_paths).
- pilot TopNav на main frontend — только пункт «Trade-In» виден
  (остальные `/analytics`, `/site-finder`, `/concept`, `/admin`
  отфильтрованы `isPathAllowed`).
- pilot открывает `/trade-in` → работает как раньше.
- admin (admintest, kopylov-если бы был admin) — без изменений.

Backend middleware path-enforcement не делает — security guarantee
по-прежнему на admin-only endpoints (`/api/v1/admin/*` блочится для
пилота). Path-filter на UI-уровне через `allowed_paths` /
`deny_paths` в /me response.

Pilot login flow: после basic_auth → main frontend → useMe → /me →
scope (allowed=/trade-in/**). RouteGuard на `/` → NoAccessScreen.
Pilot должен bookmark'ить `https://gendsgn.ru/trade-in/` напрямую.

Follow-up: можно добавить auto-redirect в RouteGuard — если pilot
landing-path → redirect на первый allowed (`/trade-in`). Отдельный PR.

Tests: 20/20 pass на обоих backend стэках, ruff clean.
2026-05-26 12:40:08 +05:00
..
alembic ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
app feat(rbac): role-based access control via X-Authenticated-User middleware (#585) 2026-05-26 06:18:40 +00:00
db/init ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
output feat(geo): NSPD bulk-fetcher без Playwright + resume-friendly UI 2026-05-11 08:53:28 +03:00
tests feat(rbac): сузить pilot scope только до /trade-in/** 2026-05-26 12:40:08 +05:00
.dockerignore fix(scraper): диагностируем «кнопка не работает» — Redis lock + task_received log 2026-04-28 23:17:42 +03:00
.env.example refactor(security): убрать X-Admin-Token (Caddy basic_auth достаточен) (#437) 2026-05-23 10:41:22 +00:00
.env.runtime.example sprint1: nspd scraper industrialization, per-bucket elasticity, cadastre cross-check, sentry releases 2026-04-30 21:51:19 +03:00
alembic.ini ops: alembic baseline, pre-commit, TIGER cleanup, pg_dump scripts 2026-04-26 13:08:51 +03:00
debug.log feat(geo): NSPD bulk-fetcher без Playwright + resume-friendly UI 2026-05-11 08:53:28 +03:00
Dockerfile fix(scraper): диагностируем «кнопка не работает» — Redis lock + task_received log 2026-04-28 23:17:42 +03:00
pyproject.toml feat(rbac): role-based access control via X-Authenticated-User middleware (#585) 2026-05-26 06:18:40 +00:00
uv.lock feat(rbac): role-based access control via X-Authenticated-User middleware (#585) 2026-05-26 06:18:40 +00:00