Audit #1871/#1926: competitor block computed flats_sold from domrf_kn_flats.status (LIKE '%прод%'/'sold'), populated in only ~0.2% of rows (99.8% NULL) -> massive undercount (~1600 units in reported case) and divergence from MarketMetrics, which counts sold via objective_lots.contract_date (100% populated for sold lots). Fix: new _SOLD_COUNT_SQL counts sold lots from objective_lots.contract_date IS NOT NULL, bridged domrf obj_id -> objective_complex_mapping.domrf_obj_id -> objective_complex_mapping.objective_complex_name == objective_lots.project_name (same 1:1 mapping pattern as _OBJECTIVE_PRICE_FALLBACK_SQL primary_price CTE). This is the exact source MarketMetrics._STOCK_SQL uses, so the two paths agree. Dropped the domrf_kn_flats.status count from _AVG_PRICE_SQL (price-only now). No schema/Pydantic field change (flats_sold/sold_pct already existed) -> codegen not needed. psycopg v3 CAST style preserved. Tests: updated mock DB ordering (+ sold-count execute), added test_competitors_flats_sold_from_contract_date (120/200 -> 60% sold) and phantom-column EXPLAIN check for _SOLD_COUNT_SQL. |
||
|---|---|---|
| .. | ||
| api | ||
| core | ||
| models | ||
| observability | ||
| schemas | ||
| scrapers | ||
| services | ||
| templates | ||
| workers | ||
| __init__.py | ||
| main.py | ||