(medium) 062 address cleaner: regex 'Площадь \\d' усекает легитимные адреса ЕКБ ('Площадь 1905 года') #1365

Closed
opened 2026-06-14 18:09:14 +00:00 by bot-backend · 1 comment
Collaborator

Описание

Деструктивный UPDATE срезает всё от 'Площадь <цифра>' до конца строки (case-insensitive). Намерение — убрать scraped-шум вроде 'Площадь 45 м²', но паттерн также матчит реальное название площади Екатеринбурга — 'Площадь 1905 года' — часть настоящих адресов ('Екатеринбург, Площадь 1905 года, 1'). Такой адрес молча усекается, портя listings.address, на который опираются downstream street-matching (067 street_sales_vs_listings) и tradein_normalize_short_addr (063). Запускается на каждом деплое для всех avito-строк, попадающих в WHERE.

Корень

\d (любая одна цифра) без word-boundary и без требования единицы измерения (м²/м2) матчит первую цифру '1905'; .*$ стирает остаток.

Evidence

062_clean_avito_addresses.sql:6-13:

regexp_replace(..., '\s*(Площадь \d|от \d+\s?мин\.|css-[a-z0-9_-]+).*$', '', 'i')
... WHERE source='avito' AND (address ~* 'css-...' OR address ~* 'Площадь \d|от \d+\s?мин\.')

WHERE на строке 13 тоже использует Площадь \d, так что строка с «Площадь 1905 года» отбирается и затем калечится.

Suggested fix

Заанкорить шумовой паттерн к фактической форме утёкшего label (например требовать единицу: Площадь\s+\d+(?:[.,]\d+)?\s*м² / м2) вместо голого 'Площадь \d', либо исключить известный landmark ('Площадь 1905'), чтобы реальные адреса площадей не усекались.

Обоснование severity

medium: затрагивает целостность данных для конкретного, но реального набора адресов ЕКБ; downstream street-matching (062→063→067) молча получает усечённый адрес без ошибки. confidence 0.93.


week ревью 1 · multi-agent аудит 2026-06-14 · severity=medium · category=data-integrity

Затронутые файлы:

  • /Users/anton/Птица/gendesign/tradein-mvp/backend/data/sql/062_clean_avito_addresses.sql
## Описание Деструктивный UPDATE срезает всё от 'Площадь <цифра>' до конца строки (case-insensitive). Намерение — убрать scraped-шум вроде 'Площадь 45 м²', но паттерн также матчит реальное название площади Екатеринбурга — 'Площадь 1905 года' — часть настоящих адресов ('Екатеринбург, Площадь 1905 года, 1'). Такой адрес молча усекается, портя `listings.address`, на который опираются downstream street-matching (067 street_sales_vs_listings) и `tradein_normalize_short_addr` (063). Запускается на каждом деплое для всех avito-строк, попадающих в WHERE. ## Корень `\d` (любая одна цифра) без word-boundary и без требования единицы измерения (м²/м2) матчит первую цифру '1905'; `.*$` стирает остаток. ## Evidence `062_clean_avito_addresses.sql:6-13`: ```sql regexp_replace(..., '\s*(Площадь \d|от \d+\s?мин\.|css-[a-z0-9_-]+).*$', '', 'i') ... WHERE source='avito' AND (address ~* 'css-...' OR address ~* 'Площадь \d|от \d+\s?мин\.') ``` WHERE на строке 13 тоже использует `Площадь \d`, так что строка с «Площадь 1905 года» отбирается и затем калечится. ## Suggested fix Заанкорить шумовой паттерн к фактической форме утёкшего label (например требовать единицу: `Площадь\s+\d+(?:[.,]\d+)?\s*м²` / `м2`) вместо голого 'Площадь \d', либо исключить известный landmark ('Площадь 1905'), чтобы реальные адреса площадей не усекались. ## Обоснование severity medium: затрагивает целостность данных для конкретного, но реального набора адресов ЕКБ; downstream street-matching (062→063→067) молча получает усечённый адрес без ошибки. confidence 0.93. --- _week ревью 1 · multi-agent аудит 2026-06-14 · severity=**medium** · category=`data-integrity`_ Затронутые файлы: - `/Users/anton/Птица/gendesign/tradein-mvp/backend/data/sql/062_clean_avito_addresses.sql`
bot-backend added the
week ревью 1
label 2026-06-14 18:09:14 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:01:53 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: tradein-mvp/backend/data/sql/062_clean_avito_addresses.sql:10 (паттерн в regexp_replace) и :13 (WHERE). Файл присутствует и обёрнут в BEGIN;/COMMIT; (строки 4, 15).

Корень: Голый Площадь \d (одна цифра, без word-boundary и без единицы измерения) + .*$ матчит первую цифру в «Площадь 1905 года» и стирает остаток адреса. Та же подстрока в WHERE (address ~* 'Площадь \d|от \d+\s?мин\.', стр. 13) отбирает легитимный адрес в выборку для UPDATE → молчаливое усечение.

Что править:

  • Заменить Площадь \d на привязку к фактической форме scraped-шума: требовать единицу площади, напр. Площадь\s+\d+(?:[.,]\d+)?\s*(?:м²|м2) — и в regexp_replace (стр. 10), и в WHERE (стр. 13).
  • Альтернатива/дополнение: явно исключить landmark Площадь 1905 (negative-lookahead или AND address !~* 'Площадь\s+1905').
  • Миграция уже применена на прод (NN auto-apply) — для ре-чистки уже-усечённых строк потребуется отдельный backfill из исходного raw-источника, regexp ретроактивно не восстановит.

Что посмотреть:

  • Код: 062_clean_avito_addresses.sql:10,13; downstream-потребители listings.address063 (tradein_normalize_short_addr), 067 (street_sales_vs_listings); добавить unit-тест на «Екатеринбург, Площадь 1905 года, 1» → не усекается.
  • Vault: decisions/Decision_TradeIn_DataQuality_8PR_Roadmap.md (PR 1 «Очистка address Avito» — там же исходный паттерн re.split(r"Площадь \d|от \d+\s?мин\.") и грязный пример «…56к1Площадь 1905 года.css-…», то есть это известный side-effect того же фикса).
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `tradein-mvp/backend/data/sql/062_clean_avito_addresses.sql:10` (паттерн в `regexp_replace`) и `:13` (WHERE). Файл присутствует и обёрнут в `BEGIN;`/`COMMIT;` (строки 4, 15). **Корень:** Голый `Площадь \d` (одна цифра, без word-boundary и без единицы измерения) + `.*$` матчит первую цифру в «Площадь **1**905 года» и стирает остаток адреса. Та же подстрока в WHERE (`address ~* 'Площадь \d|от \d+\s?мин\.'`, стр. 13) отбирает легитимный адрес в выборку для UPDATE → молчаливое усечение. **Что править:** - Заменить `Площадь \d` на привязку к фактической форме scraped-шума: требовать единицу площади, напр. `Площадь\s+\d+(?:[.,]\d+)?\s*(?:м²|м2)` — и в `regexp_replace` (стр. 10), и в WHERE (стр. 13). - Альтернатива/дополнение: явно исключить landmark `Площадь 1905` (negative-lookahead или `AND address !~* 'Площадь\s+1905'`). - Миграция уже применена на прод (NN auto-apply) — для ре-чистки уже-усечённых строк потребуется отдельный backfill из исходного `raw`-источника, regexp ретроактивно не восстановит. **Что посмотреть:** - Код: `062_clean_avito_addresses.sql:10,13`; downstream-потребители `listings.address` — `063` (`tradein_normalize_short_addr`), `067` (street_sales_vs_listings); добавить unit-тест на «Екатеринбург, Площадь 1905 года, 1» → не усекается. - Vault: `decisions/Decision_TradeIn_DataQuality_8PR_Roadmap.md` (PR 1 «Очистка address Avito» — там же исходный паттерн `re.split(r"Площадь \d|от \d+\s?мин\.")` и грязный пример «…56к1Площадь 1905 года.css-…», то есть это известный side-effect того же фикса).
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1365
No description provided.