fix(tradein/newbuilding): счётчики записи различают вставку и обновление (#2807) #2809
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
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#2809
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2807-price-dynamics-counter"
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?
Что было не так
newbuilding_enrich_backfill.py:605считал свою работу разницейCOUNT(*)до и после сохранения. Это прирост числа строк в таблице, а не число записанных точек: вставка идётON CONFLICT ON CONSTRAINT houses_price_dynamics_dim_key DO UPDATE, поэтому переписывание существующей точки даёт ноль.Прод 10.08, прогон 3578:
"price_dynamics_rows": 0при 64 строках с обновлённойrecorded_atпо 10 домам за окно прогона. Их вставил прогон 3563 накануне — у него в тех же counters стояло 64. Ноль читался как «динамика цен снова не пишется».Оба соседних счётчика в том же месте врали по своим причинам:
reliability_rows— строку вставляли обычным INSERT, а следом_dedup_reliabilityсхлопывал дубль; net-прирост повторного прогона 0 при реально записанной строке;review_rows—_save_cian_reviewsуже возвращал число записанных отзывов, и код это число выбрасывал в пользу разницы COUNT'ов.Класс или случай
Случай, хоть и тройной.
git grepпо приёму «count после − count до» для счётчиков прогона даёт единственное второе совпадение —lots_dropped_secondaryвpipeline.py:2597, и там это длина списка до/после фильтрации, то есть измерение честное по построению. Гипотеза «это класс» опровергнута, чинится одно место.Как починено
Различать вставку и обновление умеет только сам писатель:
RETURNING (xmax = 0) AS is_insert— идиома, уже применяемая в репозитории (backend/app/services/scrapers/gisogd66.py:301).save_newbuilding_enrichmentвозвращаетNewbuildingSaveCounts(price_inserted, price_updated, reliability_inserted); вызывающий перестал восстанавливать число по таблице, аreview_writtenберётся из того, что_save_cian_reviewsи так возвращал. Остальные три вызова (cian_history_backfill, SERP-sweep вpipeline, admin-ручка) результат игнорируют — их сигнатура не ломается.COUNT(*)до сохранения остался ровно там, где нужен по делу:had_reliabilityдля дедупа.Ключи counters переименованы:
price_dynamics_inserted/price_dynamics_updated/reliability_inserted/review_upserted. У старых имён в истории прогонов другой смысл (net-прирост), и поменять его молча под тем же именем — ровно тот дефект, ради которого правка и делается. Читателей у ключей вне задачи и её тестов нет (git grep: толькоnewbuilding_enrich_backfill.py+ 2 теста).Сторож нулевого результата — проверено, не ослаблен
mark_backfill_finished(#2695) судит поattempted/enriched/gone/blocked; сторож #2703 читаетtotal_seen/lots_fetched/unique_fetched, которых у этой задачи нет вовсе. Числа записи в решение не входят ни до, ни после правки — и это закреплено тестами, а не рассуждением: прогон сenriched=0иprice_dynamics_updated=64остаётсяfailed, аprice_dynamics_updated=999не двигает вердикт.Test plan
tests/test_2807_write_counters_honesty.py— 8 тестов (вставка/обновление на 64 точках прода, пустой график остаётся нулём, точка без цены не считается записанной, 4 теста на неприкосновенность сторожа). На коде до правки модуль не собирается:NewbuildingSaveCountsне существует.test_newbuilding_enrich_backfill+test_2767+test_2725+test_scraper_kit_group_c_backfill_kit_parity+test_2703— 75 passed.tests/— 3737 passed; 11 падений идентичны падениям на origin/main (локальное окружение), новых нет.Прод-верификация (критерий записан ДО факта)
newbuilding_enrichбежит ежесуточно ~00:28 UTC. Первый прогон после деплоя обязан показать вscrape_runs.countersнепустоеprice_dynamics_updatedприprice_dynamics_insertedблизком к нулю — потому что 301 из 301 fetchable-домов уже обогащены, и работа этого прогона по определению состоит из обновлений. Если оба поля нули приsucceeded > 0— правка не доехала или писатель молчит.Closes #2807