fix(yandex-valuation): cap area_m2 sanity (drop >10000 or ≤0) #538
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#538
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-yandex-area-sanity-cap"
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
_parse_item_textdropsarea_m2values > 10_000 m² or ≤ 0 (sets to None)area_m2=NULLinstead of blowing up the entire batchWhy
Live observation from sweep on
Базовый переулок, 52(PR #536 follow-up):house_placement_history.area_m2isNUMERIC(8,2)→ values ≥10⁶ overflow. The 2_025_106.7 came from Yandex page text occasionally concatenating digits across DOM boundaries. Whole batch of 30 items from page=1 was lost. After this PR, junk area is dropped and the row still saves with the other fields intact.Tests
Deep Code Review — verdict APPROVE
Summary
4939d04Key checks
Where applied: parse-time in
_parse_item_text— single chokepoint serving both Strategy 1 (data-test container) and Strategy 2 (chunked-text fallback). Correct placement: the bug originates in the chunked-text path (200-char window swallows digits across DOM boundaries), and parse-time drop is preferable to query-time filtering (junk never enters DB → no retroactive cleanup churn).Lower bound (
area_m2 <= 0): handled, testtest_parse_item_drops_zero_areacovers0 м². Reasonable to NOT pick an arbitrary residential floor (e.g. <5 m²) — storage rooms and micro-units exist; drop only on impossible-by-definition values.Upper bound (10 000 m²): safe ceiling. Yandex
/otsenka-kvartiry-po-adresu-onlayn/URL is APARTMENT valuation (not commercial), so false-negatives for промзоны/торговые центры are out of scope. DB columnhouse_placement_history.area_m2 numeric(8,2)overflows at 10⁶ — 10k leaves 100× safety margin.Retroactive cleanup: not needed. NumericValueOutOfRange aborted the whole batch (cited in PR body: «30 items from page=1 was lost»), so no historical rows with area > 10⁶ in
house_placement_historyforsource='yandex_valuation'. Constraint actively rejected bad data. Zero-area rows may exist historically but are harmless (dedup key includesarea_m2, downstreamestimator.py:858area_m2 BETWEEN :area_min AND :area_maxcorrectly excludes NULL).Observability:
logger.warning("yandex_valuation: dropping nonsensical area_m2=%s …")— good audit trail for upstream parser regressions.Persistence gap check (memory rule):
_save_yandex_history_itemsatestimator.py:380referencesitem.area_m2directly, no parallel field to forget — clean.Dedup interaction: when multiple items in a chunk get cap'd, they collapse to
(date, None, floor)inseenset — degradation rather than crash. Acceptable.Tests: 28/28 passing claimed. Three new regression tests cover overflow, normal pass-through, zero-area. Coverage matches intent.
Vault cross-ref: fits the Yandex parser fix series — PR #508 (listing_date), PR #526 (removed_date+total_floors+NBSP). All driven by chunked-text strategy edge cases; series suggests text-chunking robustness should remain a watch-item.
Minor observations (non-blocking)
area_m2(e.g.-5 м²), but<= 0semantics are unambiguous — regex unlikely to emit a sign anyway.area_m2: float | Noneproperly explicit for mypy.Positive
Risk / blast radius