fix(ptica): backfill act_date у 11 строк, куда уехала дата Генплана-2004 (#2464) #2984

Merged
bot-backend merged 1 commit from fix/2464-act-date-backfill into main 2026-08-20 17:37:43 +00:00
Collaborator

Зачем отдельная миграция

#2981 починил извлечение даты, но только вперёд. UPSERT загрузчика заканчивается

ON CONFLICT (cad_num, act_number) DO NOTHING

не DO UPDATE. Значит пятничный прогон (0 7 * * fri) наткнётся на конфликт и существующие строки не перезапишет. Без этой миграции 11 строк остались бы с датой 2004 года навсегда: правка выглядела бы сделанной, а данные на проде — кривыми.

Что чиним

Замер прода 20.08.2026:

right(doc_url,32)                 строк   act_date
89adb28a3677e7df933e2d9ce0f205c8      9   2004-07-06
9b9d9a998f578db56315bb816fc2ebf5      2   2004-07-06

Ровно 9 + 2 = 11 — в точности столько, сколько дал прогон исправленного кода по тем же двум документам.

Верные даты не угаданы: оба PDF загружены с екатеринбург.рф и распознаны тем же трактом, что использует загрузчик (ocr_pdf_text в прод-контейнере). В обоих настоящее основание — постановление Администрации города:

документ было станет основание
развязка Базовый/Комсомольская/Сибирский тракт 2004-07-06 2022-05-27 Постановление № 1413
улица Энергостроителей 2004-07-06 2020-02-12 Постановление № 259

Почему сужение по doc_url обязательно

Без него UPDATE ... WHERE act_date = '2004-07-06' задел бы любую строку с этой датой, включая те, где 06.07.2004 — настоящая дата акта. Это не гипотетика: 06.07.2004 — реальная дата Решения гордумы, и документ, для которого она законна, вполне может появиться.

Миграция идемпотентна: при повторе условие act_date = '2004-07-06' уже не выполнится.

Как проверено

Тест герметичный и прогоняет тело миграции целиком (а не переписанный от руки UPDATE) на временной копии таблицы в прод-форме: 9 строк развязки + 2 Энергостроителей + две контрольные посторонние.

  • Контроль-двойник test_without_the_migration_rows_stay_wrong: без прогона миграции остаётся 12 строк с датой Генплана и 0 с верной. Обязателен — без него тест неотличим от «оно и так было правильно».
  • Мутационно проверено сужение: снятие AND doc_url LIKE ... роняет test_other_documents_with_same_date_are_untouched — тот самый контроль, который для этого и поставлен.
  • Идемпотентность проверена двойным прогоном: строк с 2022-05-27 остаётся 9, а не 18.
  • pytest backend/tests/sql/test_2464_act_date_backfill.py — 6 passed (через туннель). Без БД — skipped, записи внесены в skip_allowlist.txt с причиной.

После деплоя

Отчитаюсь числами: строк с act_date = '2004-07-06' должно остаться 0, с 2022-05-27 — 9, с 2020-02-12 — 2.

Продолжение #2981. Часть эпика #2464.

## Зачем отдельная миграция #2981 починил извлечение даты, но только **вперёд**. UPSERT загрузчика заканчивается ```sql ON CONFLICT (cad_num, act_number) DO NOTHING ``` — **не** `DO UPDATE`. Значит пятничный прогон (`0 7 * * fri`) наткнётся на конфликт и существующие строки не перезапишет. Без этой миграции 11 строк остались бы с датой 2004 года навсегда: правка выглядела бы сделанной, а данные на проде — кривыми. ## Что чиним Замер прода 20.08.2026: ``` right(doc_url,32) строк act_date 89adb28a3677e7df933e2d9ce0f205c8 9 2004-07-06 9b9d9a998f578db56315bb816fc2ebf5 2 2004-07-06 ``` Ровно 9 + 2 = 11 — в точности столько, сколько дал прогон исправленного кода по тем же двум документам. Верные даты не угаданы: оба PDF загружены с екатеринбург.рф и распознаны **тем же трактом, что использует загрузчик** (`ocr_pdf_text` в прод-контейнере). В обоих настоящее основание — постановление Администрации города: | документ | было | станет | основание | |---|---|---|---| | развязка Базовый/Комсомольская/Сибирский тракт | 2004-07-06 | **2022-05-27** | Постановление № 1413 | | улица Энергостроителей | 2004-07-06 | **2020-02-12** | Постановление № 259 | ## Почему сужение по doc_url обязательно Без него `UPDATE ... WHERE act_date = '2004-07-06'` задел бы **любую** строку с этой датой, включая те, где 06.07.2004 — настоящая дата акта. Это не гипотетика: 06.07.2004 — реальная дата Решения гордумы, и документ, для которого она законна, вполне может появиться. Миграция идемпотентна: при повторе условие `act_date = '2004-07-06'` уже не выполнится. ## Как проверено Тест герметичный и прогоняет **тело миграции целиком** (а не переписанный от руки UPDATE) на временной копии таблицы в прод-форме: 9 строк развязки + 2 Энергостроителей + две контрольные посторонние. - **Контроль-двойник** `test_without_the_migration_rows_stay_wrong`: без прогона миграции остаётся 12 строк с датой Генплана и 0 с верной. Обязателен — без него тест неотличим от «оно и так было правильно». - **Мутационно проверено сужение:** снятие `AND doc_url LIKE ...` роняет `test_other_documents_with_same_date_are_untouched` — тот самый контроль, который для этого и поставлен. - **Идемпотентность** проверена двойным прогоном: строк с 2022-05-27 остаётся 9, а не 18. - `pytest backend/tests/sql/test_2464_act_date_backfill.py` — 6 passed (через туннель). Без БД — skipped, записи внесены в `skip_allowlist.txt` с причиной. ## После деплоя Отчитаюсь числами: строк с `act_date = '2004-07-06'` должно остаться **0**, с `2022-05-27` — 9, с `2020-02-12` — 2. Продолжение #2981. Часть эпика #2464.
bot-backend added 1 commit 2026-08-20 16:50:33 +00:00
fix(ptica): backfill act_date у 11 строк, куда уехала дата Генплана-2004 (#2464)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m58s
CI / backend-tests (pull_request) Successful in 17m21s
4e6ed8c044
#2981 починил извлечение даты, но только ВПЕРЁД: UPSERT загрузчика
заканчивается `ON CONFLICT DO NOTHING`, а не DO UPDATE, поэтому
пятничный прогон (`0 7 * * fri`) существующие строки не перезапишет.
Без этой миграции 11 строк остались бы с датой 2004 года навсегда —
правка выглядела бы сделанной, а данные на проде остались бы кривыми.

Замер прода 20.08.2026:

    89adb28a…  развязка Базовый/Комсомольская/Сибирский тракт   9 строк
    9b9d9a99…  улица Энергостроителей                           2 строки
    обе группы: act_date = 2004-07-06

Верные даты не угаданы: оба PDF загружены с екатеринбург.рф и
распознаны тем же трактом, что использует загрузчик (ocr_pdf_text), и в
обоих настоящее основание — постановление Администрации города:
№ 1413 от 27.05.2022 и № 259 от 12.02.2020 соответственно.

Сужение по doc_url обязательно: без него UPDATE задел бы любую строку с
06.07.2004, включая те, где эта дата настоящая. Миграция идемпотентна —
условие `act_date = '2004-07-06'` при повторе не выполнится.

Тест герметичный, прогоняет ТЕЛО миграции целиком на временной копии в
прод-форме (9+2 целевых + 2 контрольных посторонних). Контроль-двойник
`test_without_the_migration_rows_stay_wrong` обязателен: без него тест
неотличим от «оно и так было правильно». Мутационно проверено сужение —
снятие условия по doc_url роняет
test_other_documents_with_same_date_are_untouched.

pytest backend/tests/sql/test_2464_act_date_backfill.py — 6 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Light1YT force-pushed fix/2464-act-date-backfill from 4e6ed8c044 to 668f8c6ffb 2026-08-20 17:14:30 +00:00 Compare
bot-backend merged commit b975451b53 into main 2026-08-20 17:37:43 +00:00
Author
Collaborator

Проверено на проде

Деплой b975451b зелёный. Числа ровно те, что я обещал в описании:

до backfill:                     после:
  2004-07-06   11 строк            2004-07-06    —      (строк не осталось)
  2015-09-29    2                  2015-09-29    2
  2019-04-19    7                  2019-04-19    7
  2019-06-24    7                  2019-06-24    7
                                   2020-02-12    2      ← Энергостроителей
                                   2022-05-27    9      ← развязка
всего 27                         всего 27

По документам:

89adb28a…  (развязка Базовый/Комсомольская/Сибирский тракт)  2022-05-27   9 строк
9b9d9a99…  (улица Энергостроителей)                          2020-02-12   2 строки

Три документа, у которых дата была верной, не сдвинулись — контроль сужения по doc_url сработал не только в тесте.

## Проверено на проде Деплой `b975451b` зелёный. Числа ровно те, что я обещал в описании: ``` до backfill: после: 2004-07-06 11 строк 2004-07-06 — (строк не осталось) 2015-09-29 2 2015-09-29 2 2019-04-19 7 2019-04-19 7 2019-06-24 7 2019-06-24 7 2020-02-12 2 ← Энергостроителей 2022-05-27 9 ← развязка всего 27 всего 27 ``` По документам: ``` 89adb28a… (развязка Базовый/Комсомольская/Сибирский тракт) 2022-05-27 9 строк 9b9d9a99… (улица Энергостроителей) 2020-02-12 2 строки ``` Три документа, у которых дата была верной, не сдвинулись — контроль сужения по `doc_url` сработал не только в тесте.
Sign in to join this conversation.
No reviewers
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#2984
No description provided.