feat(forecasting): monthly sales series builder for §9.6 (#951c) #1008

Merged
bot-backend merged 1 commit from feat/951c-forecasting-sales-series into main 2026-06-03 05:52:33 +00:00
Collaborator

Site Finder v2 / EPIC 7 — #951 sub-PR 1. Детерминированный, без LLM, data-независимый. Часть #944.

forecasting/sales_series.py — месячный ряд проданных лотов (+площадь+ср.цена) на SegmentSpec, Y-ось для §9.6 регрессии. Два источника с разной зоной ответственности:

  • Source A objective_corpus_room_month — агрегаты класс/район (полные ДДУ+ДКП, count-weighted цена ×1000 тыс→₽).
  • Source B objective_lots — room×area×price сегментация (GROUP BY date_trunc('month', registration_date); survivorship-caveat задокументирован).

Чистые DB-free helpers price_bucket_of/room_area_bucket_of/log_diff/fill_month_grid. In-SQL CASE использует те же константы порогов, что и helpers (bound-params) → нет Python↔SQL дрейфа. Месяц без продаж → units=0 (реальный ноль), area/price → None. Graceful empty → low + zero-grid.

62 теста (forecasting/ всего 113). code-reviewer opus OK (все 8 чеков: бакеты консистентны, weighted-price/scale верны, log_diff без -inf/nan, units=0 сохраняется, case-insensitive, survivorship surfaced). room_bucket source-specific (документировано на SegmentSpec). Refs #951

**Site Finder v2 / EPIC 7 — #951 sub-PR 1.** Детерминированный, без LLM, data-независимый. Часть #944. `forecasting/sales_series.py` — месячный ряд проданных лотов (+площадь+ср.цена) на `SegmentSpec`, Y-ось для §9.6 регрессии. Два источника с разной зоной ответственности: - **Source A** `objective_corpus_room_month` — агрегаты класс/район (полные ДДУ+ДКП, count-weighted цена ×1000 тыс→₽). - **Source B** `objective_lots` — room×area×price сегментация (`GROUP BY date_trunc('month', registration_date)`; survivorship-caveat задокументирован). Чистые DB-free helpers `price_bucket_of`/`room_area_bucket_of`/`log_diff`/`fill_month_grid`. In-SQL CASE использует те же константы порогов, что и helpers (bound-params) → нет Python↔SQL дрейфа. Месяц без продаж → units=0 (реальный ноль), area/price → None. Graceful empty → low + zero-grid. **62 теста** (forecasting/ всего 113). code-reviewer opus OK (все 8 чеков: бакеты консистентны, weighted-price/scale верны, log_diff без -inf/nan, units=0 сохраняется, case-insensitive, survivorship surfaced). room_bucket source-specific (документировано на SegmentSpec). Refs #951
bot-backend added 1 commit 2026-06-03 05:52:32 +00:00
Add backend/app/services/forecasting/sales_series.py — deterministic monthly
sold-units (+area+avg price) time series per SegmentSpec, the Y-axis foundation
for the §9.6 key-rate regression. Two sources with distinct authority:
objective_corpus_room_month (class/district aggregates, full ДДУ+ДКП, count-
weighted price ×1000 тыс→₽) and objective_lots (room×area×price segmentation,
GROUP BY date_trunc registration_date; survivorship caveat documented).

Pure DB-free helpers price_bucket_of / room_area_bucket_of / log_diff /
fill_month_grid, unit-tested. In-SQL CASE bucketing shares the same threshold
constants as the helpers (bound params) → no Python↔SQL drift. Months with no
sales → units=0 (real zero), area/price → None. Graceful empty/thin → low
confidence, zero-filled grid. Mirrors macro_series.py (PR2). room_bucket
semantics are source-specific (documented on SegmentSpec). 62 tests, ruff clean.
bot-backend merged commit c7bfc9e22a into main 2026-06-03 05:52:33 +00:00
bot-backend deleted branch feat/951c-forecasting-sales-series 2026-06-03 05:52:33 +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#1008
No description provided.