gendesign/backend/tests
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
..
api feat(sf-b1): GET /parcels/by-bbox — map entry endpoint + parcel_user_status table (#336) 2026-05-17 21:25:48 +00:00
integration test(infra): integration phantom column gate (#197) (#216) 2026-05-16 13:07:13 +00:00
scrapers fix(#231): repair test_rate_limit_semaphore regression + docstring sync 2026-05-17 10:22:16 +03:00
services feat(22d): domrf_catalog_object scraper — fill ~25 NULL kn_objects cols from SSR __NEXT_DATA__ (#335) 2026-05-17 21:26:22 +00:00
smoke fix(parcels): _parse_floors handle int (post-migration #169) (#176) 2026-05-15 15:08:16 +03:00
workers feat(22d): catalog scraper — skip-today filter + force flag (#348) 2026-05-17 23:15:22 +00:00
__init__.py init 2026-04-25 13:45:19 +03:00
test_admin_weight_profiles.py feat(#114): seed 3 default weight presets + include_system API param 2026-05-16 22:49:56 +03:00
test_concepts_stub.py init 2026-04-25 13:45:19 +03:00
test_gate_verdict.py feat(#29,#232): wire cad_parcels.permitted_use in analyze + cad_zouit fallback (G2+G3) 2026-05-17 08:17:22 +03:00
test_health.py init 2026-04-25 13:45:19 +03:00
test_layout_signature.py feat(parcels): layout signature schemas + extractor (#113 PR A) (#193) 2026-05-16 07:52:34 +00:00
test_layout_tz_pdf.py feat(layouts): PDF ТЗ endpoint + BestLayoutsBlock UI (#113 PR D) (#199) 2026-05-16 09:53:05 +00:00
test_nspd_client.py fix(#231): address re-review blockers — per-instance semaphore + time_limit + test mocks 2026-05-17 10:13:34 +03:00
test_nspd_sync.py fix(#244): harvest_quarter — CAST CASE WHEN params (psycopg3 AmbiguousParameter) (#246) 2026-05-17 05:53:08 +00:00
test_poi_score.py feat(sf-b6): GET /parcels/{cad}/poi-score — weighted top-7 (#333) 2026-05-17 21:11:25 +00:00
test_quarter_dump_lookup.py feat(site-finder): integrate nspd_quarter_dumps cache в analyze_parcel (#94 Sprint 1.1 FINAL) (#116) 2026-05-13 09:14:19 +03:00
test_rbac.py feat(rbac): сузить pilot scope только до /trade-in/** 2026-05-26 12:40:08 +05:00
test_sentry_init.py feat(backend): sentry-sdk init для FastAPI + Celery (#204 backend) (#207) 2026-05-16 15:09:16 +00:00
test_velocity.py feat(obj-3): SF backend migrate to objective_lots ground truth (price 0.3% -> 81%) (#324) 2026-05-17 20:08:17 +00:00
test_weight_profiles.py feat(site-finder): weight profiles service — Pydantic + CRUD (#114 sub-PR 2/4) (#137) 2026-05-15 00:29:37 +03:00