tradein/db: recovery-прогон сида 193 упадёт при демоутнутой seed-роли (узкий fail-mode) #2568

Open
opened 2026-07-30 19:27:53 +00:00 by lekss361 · 0 comments
Owner

Найдено deep-review PR #2564 (эпик #2549) уже после фикса manager_id. 🟢 Low — на проде недостижимо через API, но приводит к падающему деплою, если случится.

Суть

После фикса manager_id = COALESCE(tradein_users.manager_id, EXCLUDED.manager_id) (иначе сид тихо обнулял привязки, назначенные через team-API) появилась комбинация, ломающая иерархический CHECK из миграции 192:

UPDATE tradein_users SET role='employee', manager_id=2 WHERE username='praktika';
-- повторный прогон 193 →
ERROR: violates check constraint "tradein_users_role_manager_hierarchy_ck"
DETAIL: Failing row contains (3, praktika, null, manager, 2, ...)   EXIT=3

role подтягивается из EXCLUDED (manager), а manager_id теперь сохраняется через COALESCE → запрещённая пара → откат всей транзакции. При strict exit-1 это падающий деплой на каждой попытке, пока БД не поправят руками.

Достижимость

Близка к нулю: нужно, чтобы seed-аккаунт (admin/kopylov/praktika) оказался в состоянии role='employee' + manager_id NOT NULL. Ни один путь API так не делает — role не мутируется нигде (team.py INSERT хардкодит 'employee', UPDATE роль не трогает), а сам CHECK не даёт выставить manager_id, пока роль top-level. Только ручной SQL.

Размен сознательный: тихое обнуление связей было вероятнее и вреднее падающего деплоя.

Что сделать (одно из)

manager_id = CASE WHEN EXCLUDED.role IN ('admin','manager') THEN NULL
                  ELSE COALESCE(tradein_users.manager_id, EXCLUDED.manager_id) END

либо просто зафиксировать в комментарии файла: «recovery-прогон при демоутнутой seed-роли упадёт на иерархическом CHECK — поправить роль в БД руками перед повторным прогоном».

NB: миграция 193 уже записана в _schema_migrations на проде, повторно не применится — правка влияет только на recovery/staging-прогоны.

Найдено deep-review PR #2564 (эпик #2549) уже после фикса `manager_id`. 🟢 Low — на проде недостижимо через API, но приводит к падающему деплою, если случится. ## Суть После фикса `manager_id = COALESCE(tradein_users.manager_id, EXCLUDED.manager_id)` (иначе сид тихо обнулял привязки, назначенные через team-API) появилась комбинация, ломающая иерархический CHECK из миграции 192: ```sql UPDATE tradein_users SET role='employee', manager_id=2 WHERE username='praktika'; -- повторный прогон 193 → ERROR: violates check constraint "tradein_users_role_manager_hierarchy_ck" DETAIL: Failing row contains (3, praktika, null, manager, 2, ...) EXIT=3 ``` `role` подтягивается из EXCLUDED (`manager`), а `manager_id` теперь сохраняется через COALESCE → запрещённая пара → откат всей транзакции. При strict exit-1 это падающий деплой на каждой попытке, пока БД не поправят руками. ## Достижимость Близка к нулю: нужно, чтобы seed-аккаунт (`admin`/`kopylov`/`praktika`) оказался в состоянии `role='employee' + manager_id NOT NULL`. Ни один путь API так не делает — `role` не мутируется нигде (`team.py` INSERT хардкодит `'employee'`, UPDATE роль не трогает), а сам CHECK не даёт выставить `manager_id`, пока роль top-level. Только ручной SQL. Размен сознательный: тихое обнуление связей было вероятнее и вреднее падающего деплоя. ## Что сделать (одно из) ```sql manager_id = CASE WHEN EXCLUDED.role IN ('admin','manager') THEN NULL ELSE COALESCE(tradein_users.manager_id, EXCLUDED.manager_id) END ``` либо просто зафиксировать в комментарии файла: «recovery-прогон при демоутнутой seed-роли упадёт на иерархическом CHECK — поправить роль в БД руками перед повторным прогоном». NB: миграция 193 уже записана в `_schema_migrations` на проде, повторно не применится — правка влияет только на recovery/staging-прогоны.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#2568
No description provided.