feat(sf): zone_regulation_cache — ПЗЗ-регламент по zone_index + числовой экстракт (#1067 C8b) #1099
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#1099
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/1067-c8b-zone-regulation-cache"
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?
#1067 C8b — кэш ПЗЗ-регламента по индексу зоны + числовой экстракт предельных параметров
Регламент ПЗЗ идентичен для всех участков одной терзоны, а зон на город ~100 → резолвить ВРИ+предельные параметры через ЕКБ-геопортал urbanCard на каждый участок расточительно (reverse-eng API без SLA). Кэшируем один раз на (city, zone_index).
Что добавлено
data/sql/133_zone_regulation_cache.sql— таблицаzone_regulation_cache: 3 списка ВРИ (540н) + сырой текст предельных параметров (limit_params_raw) + числовой экстракт (params_numericJSONB) + headline-скаляры для capacity (max_far/max_building_pct/underground_pct/min_parcel_area_m2/max_floors/max_height_m). UNIQUE(city, zone_index), GIST не нужен (нет geom). Паттерн м.125/132 (BEGIN/COMMIT, IF NOT EXISTS, guarded DO для UNIQUE).backend/app/services/site_finder/zone_regulation.py:parse_limit_params— чистый regex-экстрактор предельных параметров из свободного текстаotherDescription(без IO; основной тест-таргет).upsert_zone_regulation/get_cached_zone_regulation— запись/чтение кэша (graceful на pre-migration: возвращают None/skip).get_or_fetch_zone_regulation— get-or-fetch: индекс зоны по точке (WFS, дёшево) → если в кэше отдаём без urbanCard, иначе полный резолв + upsert.backend/tests/services/test_zone_regulation_extract.py— 10 тестов на РЕАЛЬНЫХ строках с живого геопортала (probe 2026-06-06: Ц-1, ЦС-1, ЦС-6).Экстрактор — что ловит (на реальном тексте)
минимальная площадь земельного участка - 1500 кв. м→ per-ВРИ список[1500, 3000]максимальный процент застройки … – 100%·процент застройки подземного пространства – 100%коэффициент строительного использования … – 4/– 2,4(десятичная запятая)предельная этажность … – 5 этажей· тысячи через пробел (5 000 кв.м)не подлежат установлению(числа нет → ключ отсутствует)Валидация
pytest tests/services/test_zone_regulation_extract.py→ 10 passedruff check→ clean (line-100)Scope
Self-contained: НЕ трогает
parcels.py(HOT-файл Антона). Wiring в analyze — отдельный flag-gated PR (#1067 D9b). Связь:ird_overlays.zone_index(м.132) JOIN-ится сюда за полным регламентом.✅ APPROVE
C8b кэш ПЗЗ-регламента, чисто и self-contained (parcels.py не тронут, прод-вызовов нет — wiring D9b):
_PARAM_SPECS6 ключей синхронны DDL↔UPSERT↔extractor (DRY, нет key-drift).CAST(:x AS jsonb), скаляры plain:x(NUMERIC/INTEGER, нет::-trap).max_floors→int, прочие float; min для площади, max для прочих (most-permissive capacity).begin_nested+ graceful except (Operational/Programming);get_or_fetchcommit'ит.Минор (advisory, cosmetic):
get_or_fetchделаетdb.commit()даже когда upsert вернул None (table unavailable) — harmless (пустой txn-commit), ноif upsert(...) is not None: commit()явнее. Не блок.Merge → deploy-verify. NB: DDL-PR — прод-health недостаточен (миграция до compose-up); подтверждение «таблица создана» за postgres/qa-окном.