feat(site-finder): POI saturation per capita по районам ЕКБ (#42) #1329

Merged
bot-backend merged 1 commit from feat/poi-saturation-percapita into main 2026-06-14 15:05:23 +00:00
Collaborator

Summary

  • Демография 8 районов ЕКБ (Росстат 01.01.2025): миграция 154 ekb_district_demographics (население/площадь/ОКАТО — факт) + backfill ekb_districts.population
  • saturation.py: обеспеченность школа/детсад/поликлиника на 1000 чел. целевой когорты vs норматив СП 42.13330 → provision_ratio + severity (дефицит/норма/профицит) + score_multiplier (×1.2 дефицит / ×0.5 профицит)
  • analyze: infra.saturation блок (best-effort, SAVEPOINT-изолирован — не валит analyze)
  • Возрастные когорты — региональная оценка (нет публичных район-уровневых данных Росстат), помечены age_cohorts_estimated=TRUE + cohort_estimated в API

Test plan

  • ruff clean + 40 pytest (test_saturation 18 + test_poi_score 22) зелёные
  • code-reviewer APPROVE (p95 ок — GIST обе стороны, single scoped query; crash-safe)
  • database-expert APPROVE migration 154 (idempotent, FK имена match, км²→м² ×1e6 верно)
  • post-deploy smoke: analyze возвращает infra.saturation для участка с районом

Known limitation (MVP, documented)

OSM не хранит вместимость → _OBJECT_CAPACITY (школа 600/детсад 200) — допущение; OSM-категория school конфлейтит school+college+university → возможен ложный «профицит». Изолированные константы для калибровки. Hospital (1 объект = 1 учр.) — самый достоверный.

Refs #42

## Summary - Демография 8 районов ЕКБ (Росстат 01.01.2025): миграция 154 `ekb_district_demographics` (население/площадь/ОКАТО — факт) + backfill `ekb_districts.population` - `saturation.py`: обеспеченность школа/детсад/поликлиника на 1000 чел. целевой когорты vs норматив СП 42.13330 → `provision_ratio` + severity (дефицит/норма/профицит) + `score_multiplier` (×1.2 дефицит / ×0.5 профицит) - analyze: `infra.saturation` блок (best-effort, SAVEPOINT-изолирован — не валит analyze) - Возрастные когорты — региональная **оценка** (нет публичных район-уровневых данных Росстат), помечены `age_cohorts_estimated=TRUE` + `cohort_estimated` в API ## Test plan - [x] ruff clean + 40 pytest (test_saturation 18 + test_poi_score 22) зелёные - [x] code-reviewer APPROVE (p95 ок — GIST обе стороны, single scoped query; crash-safe) - [x] database-expert APPROVE migration 154 (idempotent, FK имена match, км²→м² ×1e6 верно) - [ ] post-deploy smoke: analyze возвращает infra.saturation для участка с районом ## Known limitation (MVP, documented) OSM не хранит вместимость → `_OBJECT_CAPACITY` (школа 600/детсад 200) — допущение; OSM-категория school конфлейтит school+college+university → возможен ложный «профицит». Изолированные константы для калибровки. Hospital (1 объект = 1 учр.) — самый достоверный. Refs #42
bot-backend added 1 commit 2026-06-14 14:56:13 +00:00
feat(site-finder): POI saturation per capita по районам ЕКБ (#42)
All checks were successful
CI / changes (push) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m57s
CI / openapi-codegen-check (pull_request) Successful in 1m51s
CI / backend-tests (push) Successful in 8m52s
CI / backend-tests (pull_request) Successful in 8m50s
1b77f479e7
Демография 8 районов ЕКБ (Росстат 01.01.2025) + обеспеченность
социнфраструктурой на 1000 чел. целевой когорты vs норматив СП 42.13330.

- migration 154: ekb_district_demographics (население/площадь/ОКАТО факт,
  возрастные когорты — региональная оценка, помечены) + backfill
  ekb_districts.population
- saturation.py: provision_ratio (школа/детсад/поликлиника), severity,
  score_multiplier (x1.2 дефицит / x0.5 профицит)
- analyze: infra.saturation блок (best-effort, SAVEPOINT-изолирован)
- tests: 18 (вкл. acceptance — дефицитный район -> school x1.2)

Refs #42
bot-backend merged commit 72e0b050f9 into main 2026-06-14 15:05:23 +00:00
bot-backend deleted branch feat/poi-saturation-percapita 2026-06-14 15:05:23 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1329
No description provided.