feat(sf-b5): extend /parcels/{cad}/analyze with 15 fields (EGRN/encumbrance/red_lines/risks/district prices) #332
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#332
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/sf-b5-analyze-extend"
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?
Summary
SF Wave 1 / Group A / sub-task B5 из SiteFinder Backend Migration Plan May17. Extend POST
/parcels/{cad_num}/analyzeresponse с 15 новыми полями.Files
backend/app/api/v1/parcels.py— extend response (competitors block untouched — уже работает после OBJ-3 + PR #328)15 new fields
EGRN block (9):
egrn.cadastral_value_rub,cadastral_value_per_m2,land_category,permitted_use_text,last_egrn_update_date,area_m2,ownership_type,right_type,status,addressEncumbrance block (3):
encumbrance.has_zouit,zouit_types,zouit_count(изcad_zouit)Red lines (2):
red_lines.intersects,count(через ST_Intersects наcad_red_lines)Metro placeholder (1):
metro.nearest_top3= null (заполнится после merge metro scraper)District price ranges (4, из objective_lots по району):
district_price_per_m2_min/max/median/sample_sizeRisks (3):
risks.flood_zone(cad_risk_zones),noise_score(osm_noise_sources_ekb),geology_risk_label(proxy)Compatibility
competitorsблок не trog'нут — OBJ-3 PR #324 + PR #328 продолжают работатьmarket_pulse,market_avg_price_per_m2остаются (top-level keys)Test plan
POST /api/v1/parcels/66:41:0204016:10/analyze→ 200 + 15 новых полейegrn.cadastral_value_rubpopulated (или null если нет вcad_parcels)encumbrance.has_zouitbooleandistrict_price_per_m2_median∈ [110k, 220k] для ЕКБPart of plan vault
code/patterns/SiteFinder_Backend_Migration_Plan_May17.md§B5.SF-B5: добавить 15 новых полей в POST /parcels/{cad_num}/analyze: - egrn: cadastral_value_rub/per_m2, land_category, permitted_use_text, last_egrn_update_date, area_m2, ownership_type, right_type, status, address - encumbrance: has_zouit, zouit_types, zouit_count (из cad_zouit) - red_lines: intersects, count (из cad_red_lines via ST_Intersects) - metro: nearest_top3 = null placeholder (заполнится после merge metro scraper) - district_price_per_m2_min/max/median/sample_size (из objective_lots по району) - risks: flood_zone (cad_risk_zones), noise_score, geology_risk_label (proxy) Не трогает competitors block (OBJ-3 + PR #328 уже работают).Deep Code Review — verdict: APPROVE
Files: 1 (P1: backend/app/api/v1/parcels.py) · +221/-0 · purely additive
Field-by-field
egrn(10 fields)cad_parcelsPK lookup_area_m2 > 0), dates ISO-formattedencumbrance(3)cad_zouitST_Intersectsred_lines(2)cad_red_linesST_Intersectsmetro(1)district_price_*(4)objective_lotsdistrict medianPERCENTILE_CONT(0.5)(NOT AVG-over-zero — explicitly avoids Bug #21 shape), sample_size>0 gate, outlier filter 30k-600k, round-w-None guardsrisks(3)cad_risk_zones+ hydrology proxyCompliance
CAST(:c AS text)andCAST(:dn AS text)— no::typetrap (grep:[a-z_]+::[a-z]clean)import psycopg2, noprint(), no f-string SQL, no hardcoded credsdistrict_row(L1197),noise_db_max/noise_score(L1525/1546),hydrology(L1590),geom_wktavailableBackward compat / no regressions
obj_pricingCTE (L1351) — intactmarket_pulseaggregates from OBJ-3 (L2146-2192) — intactcompetitorsblock (L41 import, L2223 output) — intactPerformance
All spatial queries use existing GIST indexes (
cad_zouit_geom_gist,cad_red_lines_geom_gist,cad_risk_zones_geom_gist).objective_lotsWHERE usesobjective_lots_district_class_idx.cad_parcelslookup hits PK. No N+1.Minor nit (non-blocking)
Two separate ST_Intersects scans (red_lines + risk_zones) — could be one CTE for fewer planner calls, but separate try/except gives better partial degradation. Keep as-is.
Merging.