feat(forecast): wire admin→micro district resolver into §9.x filters — Step 2 #1054
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#1054
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/wire-district-resolver"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What — Step 2 of forecast wiring (resolver into §9.x filters)
Wires the Step-1
ekb_district_aliasbridge into the §9.x district filters so an ADMIN district name resolves to its MICRO-districts → real data (was: admin name → 0 rows → silent empty forecast).site_finder/district_resolver.py::resolve_objective_districts(db, district) -> list[str] | None: admin→clean micros (ekb_district_alias,note IS NULL); None/"не определён"→None (EKB-wide); admin-without-aliases→None (never empty list); raw-micro→[micro]passthrough. 8-admin name set cached per-process; DB errors degrade safely (logged).market_metrics(§9.2 stock+sales),supply_layersL1 (§9.3 open),sales_seriesSources A(crm)+B(objective_lots) — crm shares the same 35-micro vocab (prod-verified full overlap). Scalar filter → psycopg3-safe= ANY(CAST(:districts AS text[])); EKB-wide branch preserved.supply_layersL2/L3 deliberately NOT wired (they filterdomrf_kn_objects.district_name= already admin vocab; regression-pinned).Prod ground-truth (before → after)
Quality
:x::typecheck clean.Deferrals (Step 3)
confidence-penalty on EKB fallback (never triggers — all 8 admins resolve on prod);
market_metricselasticity (_elasticity_coef, separate analytics_queries path). Refs #969 #949./analyze passes the official ЕКБ admin district (ekb_districts polygon, e.g. 'Кировский'), but objective_lots/corpus_room_month store informal micro-districts ('Втузгородок','ЖБИ') -> admin name matched 0 rows -> silent empty forecast. Add resolve_objective_districts() (site_finder/district_resolver.py) mapping an admin name to its clean micros via ekb_district_alias (note IS NULL), with None -> EKB-wide fallback and raw-micro pass-through. Wire into the objective_lots district filters of market_metrics (§9.2 stock+sales), supply_layers L1 (§9.3), and sales_series Sources A+B (crm shares the micro vocab, prod-verified), switching the scalar filter to psycopg3-safe = ANY(CAST(:districts AS text[])). supply_layers L2/L3 keep the admin name (domrf_kn_objects.district_name is admin vocab). Prod: Кировский/Ленинский/Орджоникидзевский obj_count 0 -> 32/64/31. Tests mutation-verified non-vacuous. 192 module tests pass; ruff clean. Refs #969 #949.