[site-finder] EPIC 6: 3-слойный склад (open/hidden/future) + индекс будущего давления #950

Closed
opened 2026-06-02 16:32:05 +00:00 by Light1YT · 5 comments
Owner

Часть #944 (Site Finder v2 / ТЗ ГенГеныч).

Статус: NEW · Приоритет: P0 · ТЗ §9.3

Scope

Layer1 open=objective_lots; Layer2 hidden=декларация/domrf_kn_flats минус open; Layer3 future=след.очереди+граддок+инсайды; индекс будущего давления предложения (§9.3). Ядро входа в прогноз + дефицит/затоварка.

Зависимости: EPIC5; L3←EPIC3/4/12
Уже есть (EXTEND): objective_lots, domrf_kn_flats

**Часть #944 (Site Finder v2 / ТЗ ГенГеныч).** Статус: **NEW** · Приоритет: **P0** · ТЗ §9.3 ## Scope Layer1 open=objective_lots; Layer2 hidden=декларация/domrf_kn_flats минус open; Layer3 future=след.очереди+граддок+инсайды; индекс будущего давления предложения (§9.3). Ядро входа в прогноз + дефицит/затоварка. **Зависимости:** EPIC5; L3←EPIC3/4/12 **Уже есть (EXTEND):** objective_lots, domrf_kn_flats
Light1YT added the
GG-форсайт
site-finder
labels 2026-06-02 16:32:06 +00:00
Owner

📊 Ground-truth 2026-06-02 (код + 2 БД)

Layer-1 (открытый склад) и part of Layer-3 (будущие очереди) уже добываются готовым кодом — без нового скрапинга. В tradein-mvp/backend/app/services/scrapers/ написаны и проверены локальным прогоном (ручной запуск под demo, без деплоя):

  • cian_newbuilding.py (631 стр) — офферы по комнатности (open stock), housesByTurn = корпуса по очередям (Layer-3 future), 7-мес динамика цены, наш.дом.рф reliability.
  • yandex_newbuilding.py — класс/рейтинг/отзывы ЖК.
  • snapshot_writer.py + listings_snapshots — подневной снапшот цены/позиции/статуса (живая экспозиция).

В tradein-БД уже лежат: houses, houses_price_dynamics (7-мес ценовой ряд по ЖК), house_reliability_checks, house_reviews, house_metadata, house_placement_history, listings_snapshots (21k снапов, пока 2 дня — копится с 30 мая).

Остаётся не разработка, а продакшенизация: deploy в SF-стек + Celery-beat расписание (накопление подневных снапов) + cross-load houses*/listings_snapshots → gendesign-БД с маппингом схемы (в форму objective_lots или новую newbuilding_listings). Anti-bot (browser_fetcher/cian_session/stealth/cian_state_parser) переиспользуется as-is (пережил дрифты #639).

Layer-2 (скрытый склад): ingredients на месте в gendesign — domrf_kn_flats, domrf_planned_commissioning, domrf_launch_monthly, objective_lots.plan_completion_date. Сам слоистый расчёт + индекс будущего давления §9.3 — net-new.

⚠️ Note: листинги = asking/экспозиция (дополнение к зарегистрированным сделкам Объектива, не замена).

## 📊 Ground-truth 2026-06-02 (код + 2 БД) **Layer-1 (открытый склад) и part of Layer-3 (будущие очереди) уже добываются готовым кодом — без нового скрапинга.** В `tradein-mvp/backend/app/services/scrapers/` написаны и **проверены локальным прогоном** (ручной запуск под demo, без деплоя): - `cian_newbuilding.py` (631 стр) — офферы по комнатности (open stock), **`housesByTurn` = корпуса по очередям** (Layer-3 future), 7-мес динамика цены, наш.дом.рф reliability. - `yandex_newbuilding.py` — класс/рейтинг/отзывы ЖК. - `snapshot_writer.py` + `listings_snapshots` — подневной снапшот цены/позиции/статуса (живая экспозиция). В tradein-БД уже лежат: `houses`, `houses_price_dynamics` (7-мес ценовой ряд по ЖК), `house_reliability_checks`, `house_reviews`, `house_metadata`, `house_placement_history`, `listings_snapshots` (21k снапов, пока 2 дня — копится с 30 мая). **Остаётся не разработка, а продакшенизация:** deploy в SF-стек + Celery-beat расписание (накопление подневных снапов) + **cross-load `houses*`/`listings_snapshots` → gendesign-БД** с маппингом схемы (в форму `objective_lots` или новую `newbuilding_listings`). Anti-bot (`browser_fetcher`/`cian_session`/`stealth`/`cian_state_parser`) переиспользуется as-is (пережил дрифты #639). **Layer-2 (скрытый склад):** ingredients на месте в gendesign — `domrf_kn_flats`, `domrf_planned_commissioning`, `domrf_launch_monthly`, `objective_lots.plan_completion_date`. Сам слоистый расчёт + индекс будущего давления §9.3 — net-new. ⚠️ Note: листинги = asking/экспозиция (дополнение к зарегистрированным сделкам Объектива, не замена).
lekss361 added this to the Site Finder v2 — Foresight (GG-форсайт) milestone 2026-06-02 19:02:52 +00:00
Author
Owner

План реализации EPIC 6 (tech-analyst, 2026-06-03)

L2-feasibility verdict (главное): per-ЖК Layer2 «hidden = declared − open» невозможен сейчас — маппинг domrf↔objective ~2.5% (3-hop через complexes, не join-key) + domrf_kn_flats.status ~99.8% NULL. District-aggregate Layer2 — реально (medium/low confidence), как в market_metrics.py. Object-level сигнал разблокирован через новый domrf_kn_objects.free_flats.

Sub-PR breakdown (sequential, ~200-500 строк каждый)

Step Scope Agent Статус
1 / PR A persist free_flats (freeFlatsInfo.numberFlats) + миграция 124 + backfill из raw backend #1002 merged
2 схема supply_layers table + v_supply_layers_latest view (мигр. 125) database next
3 сервис supply_layers.py — L1 (open) + L2 (hidden, district) backend
4 + L3 (future) детерминированный скелет + stub-источник backend
5 воркер snapshot-writer (UPSERT L1/L2/L3) + beat backend
6 сервис future_supply.py — composite future supply pressure index §9.3 backend
7 (опц.) read-endpoint, если #952/UI потребует backend

Buildable NOW / blocked / degraded

  • L1 open (district+ЖК, high) — objective_lots.
  • 🟡 L2 hidden district (medium/low) — Σ max(0, flat_count − free_flats) − open; fallback flat_count − sold где free_flats NULL.
  • 🔴 L2 per-ЖК — degraded к ~2.5%, только optional confidence='low' на reviewed-маппингах.
  • 🟡 L3 future skeleton (low) — multi-phase из domrf_kn_objects (same dev_group + future ready_dt + low free_flats).
  • 🔴 L3 граддок-parsing — BLOCKED на #956 (LLM-фаза), ships как typed stub-источник в supply_layers.
  • 🔴 L3 insider — нет источника, manual-entry stub.
  • 🟡 future supply pressure index §9.3 — composite, overall confidence = min(компоненты), честно тянется к low из-за тонкого L3.

Out of scope

граддок-NLP (#956) · insider-ingestion · фикс маппинг-coverage (отдельный matcher-effort) · per-flat L2 · frontend.

## План реализации EPIC 6 (tech-analyst, 2026-06-03) **L2-feasibility verdict (главное):** per-ЖК Layer2 «hidden = declared − open» **невозможен** сейчас — маппинг domrf↔objective ~2.5% (3-hop через `complexes`, не join-key) + `domrf_kn_flats.status` ~99.8% NULL. **District-aggregate Layer2 — реально** (medium/low confidence), как в `market_metrics.py`. Object-level сигнал разблокирован через новый `domrf_kn_objects.free_flats`. ### Sub-PR breakdown (sequential, ~200-500 строк каждый) | Step | Scope | Agent | Статус | |---|---|---|---| | **1 / PR A** | persist `free_flats` (freeFlatsInfo.numberFlats) + миграция 124 + backfill из raw | backend | ✅ **#1002 merged** | | 2 | схема `supply_layers` table + `v_supply_layers_latest` view (мигр. 125) | database | next | | 3 | сервис `supply_layers.py` — L1 (open) + L2 (hidden, district) | backend | | | 4 | + L3 (future) детерминированный скелет + stub-источник | backend | | | 5 | воркер snapshot-writer (UPSERT L1/L2/L3) + beat | backend | | | 6 | сервис `future_supply.py` — composite future supply pressure index §9.3 | backend | | | 7 | (опц.) read-endpoint, если #952/UI потребует | backend | | ### Buildable NOW / blocked / degraded - ✅ **L1 open** (district+ЖК, high) — `objective_lots`. - 🟡 **L2 hidden district** (medium/low) — `Σ max(0, flat_count − free_flats) − open`; fallback `flat_count − sold` где free_flats NULL. - 🔴 **L2 per-ЖК** — degraded к ~2.5%, только optional `confidence='low'` на reviewed-маппингах. - 🟡 **L3 future skeleton** (low) — multi-phase из `domrf_kn_objects` (same dev_group + future ready_dt + low free_flats). - 🔴 **L3 граддок-parsing** — BLOCKED на #956 (LLM-фаза), ships как typed stub-источник в `supply_layers`. - 🔴 **L3 insider** — нет источника, manual-entry stub. - 🟡 **future supply pressure index §9.3** — composite, overall confidence = min(компоненты), честно тянется к low из-за тонкого L3. ### Out of scope граддок-NLP (#956) · insider-ingestion · фикс маппинг-coverage (отдельный matcher-effort) · per-flat L2 · frontend.
Collaborator

EPIC 6 — детерминированное ядро завершено (Steps 1-6)

Step PR Что
1 #1002 domrf_kn_objects.free_flats + м.124 (бэкфилл из raw) — на проде
2 #1003 supply_layers table + v_supply_layers_latest + м.125 (dry-run PG16) — на проде
3+4 #1004 сервис supply_layers.py — L1 open / L2 hidden (mapping-free) / L3 future
5 #1005 Celery-воркер + beat Mon 06:00 МСК (UPSERT в supply_layers)
6 #1006 future_supply.py — §9.3 индекс будущего давления (reads v_supply_layers_latest)

Каждый PR: opus worker → opus code-reviewer → merge. Детерминированные, без LLM, house-style market_metrics.py.

Отложено by design: Step 7 (read-endpoint — только если #952/UI потребует; #952 вероятно потребляет in-process) · L3 граддок-population (#956, LLM-фаза) · insider (нет источника).

Прод-данные в supply_layers появятся после первого прогона воркера (Пн 06:00 МСК или ручной триггер); до этого future_supply возвращает None/0 gracefully.

Подробности в vault: inbox/2026-06-03-0900-main-session-sitefinder-v2-949-950.md.

## EPIC 6 — детерминированное ядро завершено (Steps 1-6) ✅ | Step | PR | Что | |---|---|---| | 1 | #1002 | `domrf_kn_objects.free_flats` + м.124 (бэкфилл из raw) — на проде | | 2 | #1003 | `supply_layers` table + `v_supply_layers_latest` + м.125 (dry-run PG16) — на проде | | 3+4 | #1004 | сервис `supply_layers.py` — L1 open / L2 hidden (mapping-free) / L3 future | | 5 | #1005 | Celery-воркер + beat Mon 06:00 МСК (UPSERT в supply_layers) | | 6 | #1006 | `future_supply.py` — §9.3 индекс будущего давления (reads v_supply_layers_latest) | Каждый PR: opus worker → opus code-reviewer → merge. Детерминированные, без LLM, house-style market_metrics.py. **Отложено by design:** Step 7 (read-endpoint — только если #952/UI потребует; #952 вероятно потребляет in-process) · L3 граддок-population (#956, LLM-фаза) · insider (нет источника). **Прод-данные** в `supply_layers` появятся после первого прогона воркера (Пн 06:00 МСК или ручной триггер); до этого `future_supply` возвращает None/0 gracefully. Подробности в vault: `inbox/2026-06-03-0900-main-session-sitefinder-v2-949-950.md`.
Collaborator

📊 L2 hidden — эмпирически подтверждённая граница данных (прод, kn-sweep 2026-06-03).

Триггернул полный kn-sweep region=66. На 1542 объектах: price_min_rub=8, free_flats=8 (оба = весь блок freeFlatsInfo), flat_count=1380 (90%). → freeFlatsInfo присутствует у ~0.5% объектов kn-API dom.рф (не баг #1002; price_min из м.113 тоже 8). flat_count (всего по ПД) известен, но on-sale count — нет.

L2 hidden не вычислим: free_flats 0.5% · domrf_kn_flats.status 99.8% NULL · cross-source mapping 2.5% (разные вселенные). district-aggregate (Σflat_count−Σopen) НЕ строю — ненадёжно (хуже честного «нет данных»).

Измеряемый склад на проде = L1 open (337 495 units / 42 района / HIGH conf, supply_layers наполнен воркером #1005) + L3 future (thin). L2 hidden — задокументированная граница (нужен on-sale-count feed ИЛИ решённый domrf↔objective matcher — отдельный data-effort).

📊 **L2 hidden — эмпирически подтверждённая граница данных (прод, kn-sweep 2026-06-03).** Триггернул полный kn-sweep region=66. На 1542 объектах: `price_min_rub=8`, `free_flats=8` (оба = весь блок freeFlatsInfo), `flat_count=1380` (90%). → **freeFlatsInfo присутствует у ~0.5% объектов kn-API dom.рф** (не баг #1002; price_min из м.113 тоже 8). flat_count (всего по ПД) известен, но on-sale count — нет. **L2 hidden не вычислим:** free_flats 0.5% · domrf_kn_flats.status 99.8% NULL · cross-source mapping 2.5% (разные вселенные). district-aggregate (Σflat_count−Σopen) НЕ строю — ненадёжно (хуже честного «нет данных»). **Измеряемый склад на проде = L1 open (337 495 units / 42 района / HIGH conf, supply_layers наполнен воркером #1005) + L3 future (thin). L2 hidden — задокументированная граница** (нужен on-sale-count feed ИЛИ решённый domrf↔objective matcher — отдельный data-effort).
Collaborator

EPIC 6 (3-слойный склад + индекс будущего давления) полностью реализован:

  • Schema: data/sql/125_supply_layers.sql, 128_supply_layers_dev_group_key.sql
  • L1/L2/L3 модель: supply_layers.py
  • L3 future-supply: latest-snapshot fix #1212 (d587b9e)
  • §6.6 in-app future-supply pressure + pipeline competitors §13.3 (f5aa7ed)
  • L2 hidden via #1220 (lots_pf + objective sync)
  • §25.3 каннибализация (4/4 осей): #1169 PR1 (c9720a6) + PR2 (347203d) own-portfolio overlap

Сервисы: site_finder/supply_layers.py, future_supply.py, competitors.py.

Закрываю как реализованное в проде.

EPIC 6 (3-слойный склад + индекс будущего давления) полностью реализован: - Schema: data/sql/125_supply_layers.sql, 128_supply_layers_dev_group_key.sql - L1/L2/L3 модель: supply_layers.py - L3 future-supply: latest-snapshot fix #1212 (d587b9e) - §6.6 in-app future-supply pressure + pipeline competitors §13.3 (f5aa7ed) - L2 hidden via #1220 (lots_pf + objective sync) - §25.3 каннибализация (4/4 осей): #1169 PR1 (c9720a6) + PR2 (347203d) own-portfolio overlap Сервисы: site_finder/supply_layers.py, future_supply.py, competitors.py. Закрываю как реализованное в проде.
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#950
No description provided.