fix(ptica): гео-проход не тратит геокод на занятых кандидатов и не «подтверждает» их (#2464) #2929
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#2929
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/2464-geo-pass-taken-candidates"
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?
Что не так
Разбирая неоднозначные ядра,
find_geo_matchesгеокодил всех objective-кандидатов ядра — включая тех, чьё имя уже занято вobjective_complex_mapping.Записать занятое имя нельзя в принципе:
apply_geo_matchesвставляет сON CONFLICT (objective_complex_name, objective_group) DO NOTHING, а_TAKEN_NAMES_SQLвыбирает ровно по этому ключу. То есть отсев занятых не может отменить ни одной записи, которая иначе бы произошла — он убирает только то, что запись и так отбрасывала.Три следствия на боевом пути:
confirmed→ прогон рапортует подтверждение, запись молча ничего не делаетtoo_farambiguous_multi, хотя выбор единственныйambiguous_multiall_candidates_taken, ноль вызовов DaDataЗамер на проде (19.08)
Честно про масштаб: 14 строк из 930, гео-проход запускается вручную и записал за всё время 2 строки (
auto_core_geo_v6). Правка маленькая; ценность — не в объёме, а в том, что «подтверждено» перестаёт означать «ничего не записано».Заодно: причина отказа перестаёт врать
ambiguous_multiставилась и при пустомin_radius. После отсева занятых случай «остался один кандидат, и он далеко» становится частым, и старая метка читалась бы оператором как факт неоднозначности. Теперьtoo_farпри нуле близких,ambiguous_multi— только при нескольких.Проверка
Три новых теста, каждый доказан двусторонне против
origin/main:origin/main..._ignores_taken_candidate_and_resolvesassert 0 == 1— свободный не резолвится..._taken_candidate_not_confirmed_when_only_one_nearassert [GeoMatch(...)] == []— занятый попал в confirmed..._all_candidates_taken_rejects_without_geocodeAssertionError: DaData не должна вызыватьсяКонтроли: остальные 30 тестов файла зелёные по обе стороны — при
taken_names=[]поведение не меняется.pytest tests/services→ 3055 passed, 14 skipped, rc=0 (код возврата снят без конвейера; сторож пропусков молчит).Имена в тестах взяты в боевой форме: ядро схлопывается только при кавычках —
Бутик-квартал "Меридиан"→меридиан, аБутик-квартал Меридианбез кавычек даёт другое ядро. Первая версия тестов на этом и упала.Refs #2464
Почему починен только гео-проход, хотя находка #2464 говорит про оба
Находка формулирует дефект для core-pass и гео-прохода. Взял только гео — и это не экономия, а разный статус безопасности. Проверил данными, а не рассуждением.
Все 14 неоднозначных строк — пары «один занятый + один свободный». Смотрю, чем эти двое различаются:
Застройщики различаются в 14 из 14 пар, адреса — во всех.
Главное здесь — третья пара.
СтартиСТАРТотличаются только регистром, и первым делом я заподозрил дубль одной записи: тогда моя правка связала бы domrf-объект с дублем, а не с настоящим ЖК. Адреса это опровергают — Есенина 22 и Вонсовского 93 находятся в разных концах города. Это разные ЖК с одинаковым именем.Отсюда и граница:
СтартvsСТАРТимя не различает вовсе, а совпадение застройщика — сигнал слабый: он подтверждает «наш ли это девелопер», а не «который из двух его ЖК». Автоматический выбор «остался один свободный» там означал бы выбор вслепую с последующей записью в mapping. Не трогаю.То есть половина находки закрыта, половина сознательно оставлена открытой. Отмечать пункт #2464 целиком закрытым по этому PR нельзя — в эпике напишу то же самое.
Прод-проверка после деплоя
Проверял не «код смержен», а что механизм отвечает по-другому на живых данных. Запуск
find_core_matchesв работающем контейнере (только SELECT, наружу не ходит):До правки все 14 уходили в геокод парами, и половина вызовов DaData тратилась на кандидатов, которых запись отбрасывает по
ON CONFLICT.Чего проверка не доказывает: ни одна из 14 пока не резолвлена на самом деле — для этого нужен запуск гео-прохода, а он ручной и тратит квоту DaData. Критерий приёмки на будущее: после следующего
run_geo_passстрок сmatch_method='auto_core_geo_v6'должно стать больше 2, и в логе должны появиться reject'ы с причинойtoo_farвместоambiguous_multiтам, где близких кандидатов нет.