Additive opt-in: when horizon_months is passed, attach an ADVISORY forecast overlay under scope["forecast"] via new forecasting/recommendation.py (demand_supply when cad_num set → #981 rank_segments; demand_only otherwise → per-room-bucket demand pace, NO fabricated supply). Default path stays byte-identical — overlay is try/except-guarded and never crashes the live mix. - schemas/recommend.py: horizon_months + cad_num inputs; RecommendForecast{Segment, Overlay} output models (ride open scope dict; RecommendMixOutput 4 fields intact) - forecasting/recommendation.py: pure room/class bridges (inverse of _BUCKET_PRETTY, drift-guarded) + build_forecast_overlay (graceful, advisory always True) - analytics_queries.recommend_mix: +horizon_months/cad_num params + guarded tail - api/v1/analytics.py: endpoint passthrough - tests: bridges both directions, both modes, graceful, invariance, crash isolation NOTE: live recommend endpoint now has a DORMANT path into the advisory forecast engine (frontend sends no horizon_months yet); wiring point when #951 backtest lands. 45 tests; 413 forecasting+velocity green. opus code-review ✅ (7 live-endpoint gates). |
||
|---|---|---|
| .. | ||
| api | ||
| integration | ||
| scrapers | ||
| services | ||
| smoke | ||
| sql | ||
| workers | ||
| __init__.py | ||
| test_admin_weight_profiles.py | ||
| test_concepts_stub.py | ||
| test_gate_verdict.py | ||
| test_health.py | ||
| test_layout_signature.py | ||
| test_layout_tz_pdf.py | ||
| test_nspd_client.py | ||
| test_nspd_sync.py | ||
| test_ping.py | ||
| test_poi_score.py | ||
| test_quarter_dump_lookup.py | ||
| test_rbac.py | ||
| test_sentry_init.py | ||
| test_velocity.py | ||
| test_weight_profiles.py | ||