Infra I1: POI saturation per capita (Росстат демография по районам) #42

Closed
opened 2026-05-11 20:16:47 +00:00 by lekss361 · 5 comments
lekss361 commented 2026-05-11 20:16:47 +00:00 (Migrated from github.com)

Эшелон: 🟢 Infrastructure / Quality

Контекст / проблема

10 школ vs 1 школа на 5000 детей — в текущем POI scoring это одинаковый сигнал. Это не правда — насыщенность инфры per capita важнее абсолютных чисел. Решает часть Limit_POI_Factor_Tiny.

Что сделать

  1. Импорт демографии Росстат:
    • Население ЕКБ по районам (9 районов) — ежегодная статистика
    • Возрастные группы: до 7 лет (детсад), 7-18 (школа), 65+ (поликлиника)
    • Источник: rosstat.gov.ru → Свердл → Екатеринбург, либо парсинг fedstat.ru
  2. Таблица population_demographicsdistrict_name, year, total_pop, age_0_7, age_7_18, age_65_plus
  3. Per-category нормативы (из СП 42.13330):
    • Школа на 1000 детей school age = 92 места
    • Детсад на 1000 детей preschool = 35 мест
    • Поликлиника на 10000 жителей = 1 учреждение
  4. В analyze добавить infra.saturation:
    • schools_per_1000_school_age: фактическое vs норматив
    • Severity: «избыток» / «норма» / «дефицит» / «острый дефицит»
  5. Influence в POI score: +1.2× weight в дефицитном районе (incentive строить school-adjacent), -0.5× в overdense (saturated)

Acceptance

  • Демография импортирована для всех 9 районов ЕКБ
  • Test: дефицитный район (Чкаловский?) — POI школы получает x1.2 boost
  • Saturation метрики экспонируются в UI

Owner

database-expert (Росстат import) + backend-engineer (calc + integration)

Effort

1.5–2 дня

Risks / open

  • Росстат демография гранулярность — обычно ОКАТО/ОКТМО, не район. Может потребовать ручную сверку с districts geom
  • Возрастные срезы могут быть не публичны — fallback на относительные соотношения по РФ
  • Closes часть Limit_POI_Factor_Tiny совместно с A3
**Эшелон:** 🟢 Infrastructure / Quality ## Контекст / проблема 10 школ vs 1 школа на 5000 детей — в текущем POI scoring это одинаковый сигнал. Это **не правда** — насыщенность инфры per capita важнее абсолютных чисел. Решает часть [Limit_POI_Factor_Tiny](https://obsidian.gendsgn.ru/). ## Что сделать 1. Импорт демографии Росстат: - Население ЕКБ по районам (9 районов) — ежегодная статистика - Возрастные группы: до 7 лет (детсад), 7-18 (школа), 65+ (поликлиника) - Источник: rosstat.gov.ru → Свердл → Екатеринбург, либо парсинг fedstat.ru 2. Таблица `population_demographics` — `district_name, year, total_pop, age_0_7, age_7_18, age_65_plus` 3. Per-category нормативы (из СП 42.13330): - Школа на 1000 детей school age = 92 места - Детсад на 1000 детей preschool = 35 мест - Поликлиника на 10000 жителей = 1 учреждение 4. В analyze добавить `infra.saturation`: - `schools_per_1000_school_age`: фактическое vs норматив - Severity: «избыток» / «норма» / «дефицит» / «острый дефицит» 5. Influence в POI score: +1.2× weight в дефицитном районе (incentive строить school-adjacent), -0.5× в overdense (saturated) ## Acceptance - [ ] Демография импортирована для всех 9 районов ЕКБ - [ ] Test: дефицитный район (Чкаловский?) — POI школы получает x1.2 boost - [ ] Saturation метрики экспонируются в UI ## Owner `database-expert` (Росстат import) + `backend-engineer` (calc + integration) ## Effort 1.5–2 дня ## Risks / open - Росстат демография гранулярность — обычно ОКАТО/ОКТМО, не район. Может потребовать ручную сверку с districts geom - Возрастные срезы могут быть не публичны — fallback на относительные соотношения по РФ - Closes часть [Limit_POI_Factor_Tiny](https://obsidian.gendsgn.ru/) совместно с A3
Owner

Status update — НЕ реализовано. Таблицы population_demographics нет в БД. Росстат демография не импортирована. infra.saturation в analyze response отсутствует.

POI infrastructure готова (osm_poi_ekb + weight profiles через #114), но per-capita нормирование не добавлено.

Issue остаётся в backlog priority/normal. ~1.5-2 дня effort.

Status update — НЕ реализовано. Таблицы `population_demographics` нет в БД. Росстат демография не импортирована. `infra.saturation` в analyze response отсутствует. POI infrastructure готова (`osm_poi_ekb` + weight profiles через #114), но per-capita нормирование не добавлено. Issue остаётся в backlog priority/normal. ~1.5-2 дня effort.
Collaborator

Verify-вердикт: BLOCKED — нет demographic-данных (ground-truth 2026-06-13).

Проверил prod: НЕТ таблицы population_demographics/rosstat/census/возрастных групп. ekb_districts.population существует, но 100% NULL для всех 9 районов; возрастных когорт (age_0_7/age_7_18/age_65_plus) нет нигде. rosstat_emiss.py льёт income_per_capita, НЕ демографию по районам.

Per-capita saturation против нормативов СП 42.13330 (школа/детсад/поликлиника на 1000 жителей) невозможна без: (1) население по районам ЕКБ + (2) возрастные когорты. Разблокировка = Росстат/fedstat-скрейп демографии (database-expert/scraper, пререкvisite) — не код этой задачи.

Оставляю open как BLOCKED-on-data. Существующий «saturation» в locations.py = supply-overstock (иная ось, не per-capita обеспеченность POI).

**Verify-вердикт: BLOCKED — нет demographic-данных (ground-truth 2026-06-13).** Проверил prod: НЕТ таблицы `population_demographics`/`rosstat`/`census`/возрастных групп. `ekb_districts.population` существует, но **100% NULL для всех 9 районов**; возрастных когорт (age_0_7/age_7_18/age_65_plus) нет нигде. `rosstat_emiss.py` льёт income_per_capita, НЕ демографию по районам. Per-capita saturation против нормативов СП 42.13330 (школа/детсад/поликлиника на 1000 жителей) **невозможна без**: (1) население по районам ЕКБ + (2) возрастные когорты. Разблокировка = Росстат/fedstat-скрейп демографии (database-expert/scraper, пререкvisite) — не код этой задачи. Оставляю open как BLOCKED-on-data. Существующий «saturation» в locations.py = supply-overstock (иная ось, не per-capita обеспеченность POI).
Collaborator

Verify (2026-06-13): BLOCKED — нет публичного источника СВЕЖЕЙ per-район демографии ЕКБ в этой среде.

Research (с доказательствами): ekb_districts.population 100% NULL; rosstat opendata population-датасет содержит районы ЕКБ по ОКТМО, НО только snapshot 2014 + total-only (нет возрастных когорт, нет Академического р-на); fedstat возрастные срезы за reCAPTCHA (RE отложен намеренно); data.ekburg.ru — 27 датасетов, населения нет; showdata.gks.ru (БДМО, вероятный свежий источник) — Backbone-SPA, нужен playwright (НЕ подключён в этой сессии).

Saturation per capita (POI/население×1000 vs СП 42.13330) с возрастными когортами нельзя строить на 2014-total/РФ-пропорциях для P0 инвест-скоринга — это выдуманные данные.

Разблокировка: (1) playwright-разведка БДМО showdata.gks.ru из CLI с mcp__playwright__ → поймать OLAP-XHR per-район; ИЛИ (2) ручная выгрузка свежего per-район xlsx Свердловскстата как seed. Затем database-expert (import) → backend (calc). Каркас готов: rosstat_emiss.py уже парсит ОКТМО-keyed CSV и видит районы ЕКБ; таблица district_demographics + множитель в poi_score.py. Оставляю open BLOCKED-on-source.

**Verify (2026-06-13): BLOCKED — нет публичного источника СВЕЖЕЙ per-район демографии ЕКБ в этой среде.** Research (с доказательствами): ekb_districts.population 100% NULL; rosstat opendata population-датасет содержит районы ЕКБ по ОКТМО, НО только snapshot 2014 + total-only (нет возрастных когорт, нет Академического р-на); fedstat возрастные срезы за reCAPTCHA (RE отложен намеренно); data.ekburg.ru — 27 датасетов, населения нет; showdata.gks.ru (БДМО, вероятный свежий источник) — Backbone-SPA, нужен playwright (НЕ подключён в этой сессии). Saturation per capita (POI/население×1000 vs СП 42.13330) с возрастными когортами нельзя строить на 2014-total/РФ-пропорциях для P0 инвест-скоринга — это выдуманные данные. **Разблокировка:** (1) playwright-разведка БДМО showdata.gks.ru из CLI с mcp__playwright__ → поймать OLAP-XHR per-район; ИЛИ (2) ручная выгрузка свежего per-район xlsx Свердловскстата как seed. Затем database-expert (import) → backend (calc). Каркас готов: rosstat_emiss.py уже парсит ОКТМО-keyed CSV и видит районы ЕКБ; таблица district_demographics + множитель в poi_score.py. Оставляю open BLOCKED-on-source.
Collaborator

Working on this in PR #1329. Население районов добыто из Wikipedia (первоисточник Росстат 01.01.2025), обеспеченность соцобъектами vs СП 42.13330. Возрастные когорты — региональная оценка (помечены).

Working on this in PR #1329. Население районов добыто из Wikipedia (первоисточник Росстат 01.01.2025), обеспеченность соцобъектами vs СП 42.13330. Возрастные когорты — региональная оценка (помечены).
Collaborator

qa deployed+verified: migration 154 применена (ekb_district_demographics=8 строк, _schema_migrations содержит 154, ekb_districts.population backfill=8). Data-layer end-to-end на проде: cad 66:41:0302004:91 → Верх-Исетский, POI school=41/kindergarten=60/hospital=64, demographics pop=240822 + cohort-доли + age_cohorts_estimated=true. analyze wiring code-reviewed APPROVE, AnalyzeResponse(extra="allow") пропускает infra.saturation к фронту. 40 pytest зелёные. Закрываю. Known limitation (документирована в PR): OSM school-категория конфлейтит school+college+university → плотные районы могут читаться как «профицит»; _OBJECT_CAPACITY — кандидат на калибровку.

qa ✅ deployed+verified: migration 154 применена (`ekb_district_demographics`=8 строк, `_schema_migrations` содержит 154, `ekb_districts.population` backfill=8). Data-layer end-to-end на проде: cad `66:41:0302004:91` → Верх-Исетский, POI school=41/kindergarten=60/hospital=64, demographics pop=240822 + cohort-доли + `age_cohorts_estimated=true`. analyze wiring code-reviewed APPROVE, `AnalyzeResponse(extra="allow")` пропускает `infra.saturation` к фронту. 40 pytest зелёные. Закрываю. Known limitation (документирована в PR): OSM school-категория конфлейтит school+college+university → плотные районы могут читаться как «профицит»; `_OBJECT_CAPACITY` — кандидат на калибровку.
Sign in to join this conversation.
No project
No assignees
3 participants
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#42
No description provided.