feat(forecasting): §9.x→§22 orchestrator (3a) + supply-side district resolution fix #1056

Merged
bot-backend merged 1 commit from feat/forecast-orchestrator-service into main 2026-06-05 03:21:35 +00:00
Collaborator

What — Step 3a: §9.x→§22 orchestrator + a false-BUY bug it surfaced

Orchestrator (forecasting/orchestrator.py, new): build_site_finder_report(db, *, analyze, cad_num, district, obj_class=None, horizons) computes the §9.x layers (market_metrics, supply_layers, future_supply_pressure, demand_supply_forecast, scenarios, score_card, special_indices, recommendation_overlay) with their heterogeneous signatures and feeds the PURE assemble_report → §22 SiteFinderReport. Default segment = modal competitor class; each §9.x call _safe_call-wrapped (graceful). Standalone — no endpoint/Celery/persistence (that's 3b).

Bug surfaced by prod ground-truth + fixed (future_supply.py): compute_future_supply_pressure read the mixed-vocab persisted view v_supply_layers_latest by a SCALAR admin district_name, missing all Layer-1 MICRO-keyed rows → admin parcel Кировский got supply=0 → false +1.0 deficit → "Строить: недонасыщен" (FALSE BUY) despite ~45k competing units. Fix: resolve admin→micros, filter district_name = ANY(CAST(:names AS text[])) where names = micros (L1) + admin (L2/L3), with :has_district EKB-wide guard. Extends PR #1054's resolver to the persisted-view path it missed; future_supply is the ONLY such consumer on the forecast path (verified).

Prod ground-truth (parcel 66:41:0702048:27 / Кировский)

before after
supply 0.0 ~42953
deficit_index +1.0 (false BUY) −1.0 (honest oversupply)
months_of_inventory 0.0 116.6
exec headline "Строить: недонасыщен" "Рассмотреть бизнес как класс" ✓
overall 0.734 (inflated) 0.42 (honest)

§22 assembles, no crash, segment=Комфорт (modal), confidence low (honest). Container restored to deployed code after the test.

Quality

  • code-review APPROVE — verified: future_supply match-set = micros+admin (psycopg3-safe ANY(CAST(:names AS text[]))), only view consumer, orchestrator's 8 §9.x kwargs all correct (signature-trap tests assert wrong-kwarg-absent), graceful + modal-class genuine. 80 module tests pass; ruff clean.

This is the measure-first discipline working: the orchestrator ground-truth caught a false-BUY signal before any endpoint wiring (3b). Refs #961 #969.

## What — Step 3a: §9.x→§22 orchestrator + a false-BUY bug it surfaced **Orchestrator** (`forecasting/orchestrator.py`, new): `build_site_finder_report(db, *, analyze, cad_num, district, obj_class=None, horizons)` computes the §9.x layers (market_metrics, supply_layers, future_supply_pressure, demand_supply_forecast, scenarios, score_card, special_indices, recommendation_overlay) with their **heterogeneous** signatures and feeds the PURE `assemble_report` → §22 `SiteFinderReport`. Default segment = modal competitor class; each §9.x call `_safe_call`-wrapped (graceful). **Standalone — no endpoint/Celery/persistence (that's 3b).** **Bug surfaced by prod ground-truth + fixed** (`future_supply.py`): `compute_future_supply_pressure` read the mixed-vocab persisted view `v_supply_layers_latest` by a SCALAR admin `district_name`, missing all Layer-1 MICRO-keyed rows → admin parcel **Кировский** got supply=0 → **false +1.0 deficit → "Строить: недонасыщен" (FALSE BUY)** despite ~45k competing units. Fix: resolve admin→micros, filter `district_name = ANY(CAST(:names AS text[]))` where names = micros (L1) + admin (L2/L3), with `:has_district` EKB-wide guard. Extends PR #1054's resolver to the persisted-view path it missed; future_supply is the ONLY such consumer on the forecast path (verified). ## Prod ground-truth (parcel 66:41:0702048:27 / Кировский) | | before | after | |---|---|---| | supply | 0.0 | ~42953 | | deficit_index | +1.0 (false BUY) | **−1.0 (honest oversupply)** | | months_of_inventory | 0.0 | 116.6 | | exec headline | "Строить: недонасыщен" ❌ | "Рассмотреть бизнес как класс" ✓ | | overall | 0.734 (inflated) | 0.42 (honest) | §22 assembles, no crash, segment=Комфорт (modal), confidence low (honest). Container restored to deployed code after the test. ## Quality - **code-review APPROVE** — verified: future_supply match-set = micros+admin (psycopg3-safe `ANY(CAST(:names AS text[]))`), only view consumer, orchestrator's 8 §9.x kwargs all correct (signature-trap tests assert wrong-kwarg-absent), graceful + modal-class genuine. 80 module tests pass; ruff clean. This is the measure-first discipline working: the orchestrator ground-truth caught a false-BUY signal before any endpoint wiring (3b). Refs #961 #969.
bot-backend added 1 commit 2026-06-05 03:21:32 +00:00
feat(forecasting): §9.x→§22 orchestrator + fix supply-side district resolution (3a)
All checks were successful
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m37s
Deploy / build-worker (push) Successful in 2m25s
Deploy / deploy (push) Successful in 1m7s
a0e61a38b4
Add build_site_finder_report (orchestrator.py): computes the §9.x layers (market
metrics, supply layers, future-supply pressure, demand/supply forecast, scenarios,
score card, special indices, recommendation overlay) with their heterogeneous
signatures and feeds the PURE assemble_report → §22 SiteFinderReport. Default segment
= modal competitor class; each §9.x call _safe_call-wrapped (graceful). Standalone —
no endpoint/Celery/persistence (that is 3b).

Prod ground-truth of the orchestrator surfaced a false-BUY bug: future_supply
(compute_future_supply_pressure) read the mixed-vocab persisted view
v_supply_layers_latest by a SCALAR admin district_name, missing all Layer-1
micro-keyed rows → admin parcel (Кировский) got supply=0 → false +1.0 deficit →
'Строить: недонасыщен' headline despite ~45k competing units. Fix: resolve
admin→micros, filter district_name = ANY(CAST(:names AS text[])) where names =
micros (L1) + admin (L2/L3), with :has_district EKB-wide guard (extends PR #1054's
resolver to the persisted-view path it missed). future_supply is the only
v_supply_layers_latest consumer on the forecast path (verified).

Prod after: Кировский supply 0→~42953, deficit +1.0→−1.0 (honest oversupply),
MOI 0→116.6, false-BUY headline gone, overall 0.734→0.42. 80 module tests pass
(signature-trap + resolver-regression guards genuine); ruff clean. Refs #961 #969.
bot-backend merged commit a0e61a38b4 into main 2026-06-05 03:21:35 +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#1056
No description provided.