feat(site-finder): bridge финмодели (DCF) в кокпит Investment Clearance (epic #1881 PR-4) #1885

Merged
bot-backend merged 1 commit from feat/finmodel-sitefinder-bridge into main 2026-06-23 17:55:03 +00:00
Collaborator

Summary

Эпик #1881 PR-4 (финал) — Investment Clearance в site-finder кокпите больше не «—». Синтезируем лёгкий ТЭП из buildability участка (площадь + предельные параметры зоны НСПД/ПЗЗ: КСИТ/%застройки/этажность) → прогоняем через полноценную финмодель (каскад PR-1 + калибр.цена PR-2 + помесячный DCF PR-3) → GDV/Cost/Profit/ROI/IRR/NPV/PBP в кокпите.

Backend

  • new app/services/site_finder/parcel_financial.py (ЧИСТЫЕ функции, без БД): synthesize_teap_from_buildability (GFA=area×max_far, degradation pct+floors; residential=GFA×eff; apartments/parking — нормативы из teap.py, не дублируются) + synthesize_parcel_financial (housing_class из цены, development_type из этажей, land=кадастровая). None когда нельзя строить МКД / нет зонинга / нет площади.
  • parcels.py: 1 вызов в try/except (hot-path-safe → None при сбое) + ключ financial_estimate в /analyze. Схема не тронута (extra="allow" → codegen не нужен). +18 тестов.

Frontend

  • ParcelFinancialEstimate тип (hand-typed). adaptInvestmentClearance(financial) / adaptFinanceDrawer(financial): реальные числа (GDV/Cost/Profit/ROI/IRR + NPV + срок окуп.) или честный placeholder когда null. Локализация класса/типа (high_rise→высотная). analysis прокинут через PticaBottomGrid/drawer-registry. +6 тестов, 144 passed.

Honesty (critical — показывается финдиректору)

HEAVY caveat везде: ОРИЕНТИРОВОЧНАЯ модель по МАКС.застройке НСПД, НЕ реальная концепция; land=кадастровая (не рыночная); график — типовой; IRR proxy-флаг; price_is_calibrated источник. null → честный placeholder, не выдумка.

Test plan

  • backend: 18 тестов (gate-guard None, пороги класса/типа, формулы ТЭП, интеграция buildable→real npv/irr irr_is_proxy=False land=кадастр); mypy strict clean
  • frontend: 144 vitest passed, tsc/lint clean; null→placeholder + real bignums обе ветки
  • схема не тронута (extra=allow) → openapi-codegen-check не затронут; deps/lockfile чисты
  • code-reviewer APPROVE (purity + hot-path safety + honesty проверены; локализация токенов применена)
  • post-deploy QA: открыть buildable ЕКБ-участок → Investment Clearance показывает GDV/Cost/Profit/ROI/IRR/NPV с caveat (не «—»)

Закрывает эпик #1881

Финмодель = полноценная девелоперская DCF, видна в кокпите. Follow-up: финансирование (кредит/займы 15%), §22 sales-pace вместо дефолта, гео-радиус калибровки, mock-фикстура с financial_estimate для локального preview.

Refs #1881

🤖 Generated with Claude Code

## Summary Эпик #1881 **PR-4 (финал)** — Investment Clearance в site-finder кокпите больше **не «—»**. Синтезируем лёгкий ТЭП из buildability участка (площадь + предельные параметры зоны НСПД/ПЗЗ: КСИТ/%застройки/этажность) → прогоняем через полноценную финмодель (каскад PR-1 + калибр.цена PR-2 + помесячный DCF PR-3) → **GDV/Cost/Profit/ROI/IRR/NPV/PBP** в кокпите. ## Backend - **new** `app/services/site_finder/parcel_financial.py` (ЧИСТЫЕ функции, без БД): `synthesize_teap_from_buildability` (GFA=area×max_far, degradation pct+floors; residential=GFA×eff; apartments/parking — нормативы из `teap.py`, не дублируются) + `synthesize_parcel_financial` (housing_class из цены, development_type из этажей, land=кадастровая). **None** когда нельзя строить МКД / нет зонинга / нет площади. - `parcels.py`: 1 вызов в `try/except` (hot-path-safe → None при сбое) + ключ `financial_estimate` в /analyze. Схема не тронута (`extra="allow"` → codegen не нужен). +18 тестов. ## Frontend - `ParcelFinancialEstimate` тип (hand-typed). `adaptInvestmentClearance(financial)` / `adaptFinanceDrawer(financial)`: реальные числа (GDV/Cost/Profit/ROI/IRR + NPV + срок окуп.) или честный placeholder когда null. Локализация класса/типа (high_rise→высотная). analysis прокинут через PticaBottomGrid/drawer-registry. +6 тестов, 144 passed. ## Honesty (critical — показывается финдиректору) HEAVY caveat везде: **ОРИЕНТИРОВОЧНАЯ модель по МАКС.застройке НСПД, НЕ реальная концепция**; land=кадастровая (не рыночная); график — типовой; IRR proxy-флаг; price_is_calibrated источник. null → честный placeholder, не выдумка. ## Test plan - [x] backend: 18 тестов (gate-guard None, пороги класса/типа, формулы ТЭП, интеграция buildable→real npv/irr irr_is_proxy=False land=кадастр); mypy strict clean - [x] frontend: 144 vitest passed, tsc/lint clean; null→placeholder + real bignums обе ветки - [x] схема не тронута (extra=allow) → openapi-codegen-check не затронут; deps/lockfile чисты - [x] code-reviewer ✅ APPROVE (purity + hot-path safety + honesty проверены; локализация токенов применена) - [ ] post-deploy QA: открыть buildable ЕКБ-участок → Investment Clearance показывает GDV/Cost/Profit/ROI/IRR/NPV с caveat (не «—») ## Закрывает эпик #1881 Финмодель = полноценная девелоперская DCF, видна в кокпите. **Follow-up:** финансирование (кредит/займы 15%), §22 sales-pace вместо дефолта, гео-радиус калибровки, mock-фикстура с financial_estimate для локального preview. Refs #1881 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bot-backend added 1 commit 2026-06-23 17:44:28 +00:00
feat(site-finder): bridge финмодели (DCF) в кокпит Investment Clearance (epic #1881 PR-4)
All checks were successful
CI / frontend-tests (pull_request) Successful in 57s
CI / openapi-codegen-check (pull_request) Successful in 1m49s
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Successful in 9m54s
67b65c8d8a
Investment Clearance в site-finder кокпите больше не «—»: синтезируем лёгкий
ТЭП из buildability участка (площадь + предельные параметры зоны НСПД/ПЗЗ —
КСИТ/%застройки/этажность) → прогоняем через полноценную финмодель (каскад
затрат PR-1 + калибр.цена PR-2 + помесячный DCF PR-3) → GDV/Cost/Profit/ROI/
IRR/NPV/PBP в кокпите.

Backend:
- new app/services/site_finder/parcel_financial.py (ЧИСТЫЕ функции, без БД):
  synthesize_teap_from_buildability (GFA=area×max_far, degradation pct+floors;
  residential=GFA×eff; apartments/parking — нормативы teap.py, не дублируются)
  + synthesize_parcel_financial (housing_class из цены, development_type из
  этажей, land_cost=кадастровая). None когда нельзя строить МКД / нет зонинга /
  нет площади.
- parcels.py: 1 вызов в try/except (hot-path-safe → None при сбое) + ключ
  financial_estimate в /analyze. Схема не тронута (AnalyzeResponse extra=allow,
  codegen не нужен). +18 тестов.

Frontend:
- ParcelFinancialEstimate тип (site-finder.ts, hand-typed).
- adaptInvestmentClearance(financial)/adaptFinanceDrawer(financial): реальные
  числа (GDV/Cost/Profit/ROI/IRR + NPV + срок окуп.) или честный placeholder
  когда null. Локализация класса/типа (high_rise→высотная). Прокинут analysis
  через PticaBottomGrid/drawer-registry. +6 тестов, 144 passed.

HEAVY caveat везде: ОРИЕНТИРОВОЧНАЯ модель по МАКС.застройке НСПД, НЕ реальная
концепция; land=кадастровая (не рыночная); график — типовой; IRR proxy-флаг.
mypy strict clean (generative.*), ruff/tsc/lint clean.

Закрывает эпик #1881 (финмодель = полноценная DCF, видна в кокпите).
Follow-up: финансирование (кредит/займы), §22 sales-pace, гео-радиус калибровки.

Refs #1881
bot-backend merged commit 9495c2d157 into main 2026-06-23 17:55:03 +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#1885
No description provided.