feat(sql): ekb_district_alias micro→admin vocab bridge (131) — forecast wiring Step 1 #1053

Merged
bot-backend merged 1 commit from feat/district-vocab-reconciliation into main 2026-06-05 01:40:26 +00:00
Collaborator

What — Step 1 of the §9.x forecast wiring (the gate)

Adds ekb_district_alias — a curated micro→admin district vocabulary bridge.

Why: §9.x forecast metrics filter objective_lots.district (informal MICRO-districts, 35 distinct: ВИЗ, Уралмаш, Уктус…) but /analyze resolves the official ADMIN district from ekb_districts (8 polygons: Кировский, Ленинский…). Admin name → 0 rows → silent empty forecast (ground-truthed: market_metrics('Кировский')→obj_count=0; the test parcel sits in Академический which exists in both vocabularies, masking the bug).

How — curated seed, NOT spatial

Spatial via complexes was verified unreliable and rejected: objective_lots.complex_id = complexes.id joins only ~28% of rows; complexes is multi-city (coords span beyond ЕКБ) → ST_Contains scatters every micro across all 8 admins. So the 35 micros are mapped to their PRIMARY admin by ЕКБ administrative geography (spatial used only as a sanity-check; conflicts documented per-row).

  • ekb_district_alias(admin_district, micro_district UNIQUE, note) — idempotent (CREATE TABLE IF NOT EXISTS + INSERT … ON CONFLICT DO NOTHING, BEGIN/COMMIT, additive, no DROP/TRUNCATE).
  • 4 cross-city values (Н.Тагил/Каменск — a real objective_lots data-quality gap) bucketed into one note='cross-city:…' row, trivially filterable (WHERE note IS NULL).
  • Coverage proof (prod): 8/8 admins resolve to ≥1 micro with lots>0; 35/35 mapped; 0 unmapped.
  • Resolver + NULL/unmapped→EKB-wide+confidence-penalty fallback documented in the header. psycopg v3 CAST form for the app-facing resolver.

Applied to prod + registered in _schema_migrations (idempotent re-apply confirmed INSERT 0 0) → deploy-gate will no-op on merge.

Step 2 (wire the resolver into market_metrics/the §9.x orchestrator) is a separate PR. Refs #969 #949.

## What — Step 1 of the §9.x forecast wiring (the gate) Adds `ekb_district_alias` — a curated **micro→admin** district vocabulary bridge. **Why:** §9.x forecast metrics filter `objective_lots.district` (informal MICRO-districts, 35 distinct: ВИЗ, Уралмаш, Уктус…) but `/analyze` resolves the official ADMIN district from `ekb_districts` (8 polygons: Кировский, Ленинский…). Admin name → 0 rows → **silent empty forecast** (ground-truthed: `market_metrics('Кировский')`→obj_count=0; the test parcel sits in Академический which exists in both vocabularies, masking the bug). ## How — curated seed, NOT spatial Spatial via `complexes` was verified **unreliable** and rejected: `objective_lots.complex_id = complexes.id` joins only ~28% of rows; `complexes` is multi-city (coords span beyond ЕКБ) → `ST_Contains` scatters every micro across all 8 admins. So the 35 micros are mapped to their PRIMARY admin by ЕКБ administrative geography (spatial used only as a sanity-check; conflicts documented per-row). - `ekb_district_alias(admin_district, micro_district UNIQUE, note)` — idempotent (`CREATE TABLE IF NOT EXISTS` + `INSERT … ON CONFLICT DO NOTHING`, BEGIN/COMMIT, additive, no DROP/TRUNCATE). - 4 cross-city values (Н.Тагил/Каменск — a real `objective_lots` data-quality gap) bucketed into one `note='cross-city:…'` row, trivially filterable (`WHERE note IS NULL`). - **Coverage proof (prod): 8/8 admins resolve to ≥1 micro with lots>0; 35/35 mapped; 0 unmapped.** - Resolver + NULL/unmapped→EKB-wide+confidence-penalty fallback documented in the header. psycopg v3 CAST form for the app-facing resolver. **Applied to prod + registered in `_schema_migrations`** (idempotent re-apply confirmed `INSERT 0 0`) → deploy-gate will no-op on merge. Step 2 (wire the resolver into `market_metrics`/the §9.x orchestrator) is a separate PR. Refs #969 #949.
bot-backend added 1 commit 2026-06-05 01:40:23 +00:00
feat(sql): add ekb_district_alias micro->admin vocab bridge (131)
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 27s
Deploy / build-worker (push) Successful in 27s
Deploy / deploy (push) Successful in 58s
b83ffedec3
§9.x forecast metrics filter objective_lots.district (informal micro-districts)
but /analyze resolves the official admin district from ekb_districts → admin
name matched 0 rows → silent empty forecast (market_metrics('Кировский')→0).
Add a curated micro→admin alias table seeding all 35 micro values to their
primary admin (8 EKB admins). Curated not spatial: complex_id join hits only
~28% of rows and complexes is multi-city, so ST_Contains scatters micros
uniformly. 4 cross-city values (Н.Тагил/Каменск) contained in one noted bucket.
Coverage: 8/8 admins resolve, 35/35 mapped, 0 unmapped. Idempotent + additive
(CREATE TABLE IF NOT EXISTS + INSERT ON CONFLICT DO NOTHING); applied to prod
+ registered in _schema_migrations. Resolver/fallback documented in header;
market_metrics wiring is Step 2 (separate PR). Refs #969 #949.
bot-backend merged commit b83ffedec3 into main 2026-06-05 01:40:26 +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#1053
No description provided.