Commit Graph

4 Commits

Author SHA1 Message Date
Дмитрий dc56c95e13 fix тесты: тестовая база перестала рваться посреди прогона
Починка не моя и к Этапу 5 отношения не имеет — она взята из ветки
fix/robot-yandex-zamok, где написана и доказана 31.07. Сюда перенесена
потому, что без неё прогон СМС-модуля в этой ветке недостоверен.

Корень в самом Laravel: в конце каждого теста он проверяет, осталось ли
соединение в своей черновой транзакции, и если тест её закрыл сам —
сбрасывает признак «база собрана». Следующий тест пересобирает базу целиком
прямо посреди прогона, снося её под всеми остальными. В проекте полно кода
со своими транзакциями, поэтому срабатывало через раз.

Что сделано:
- пересборка базы теперь один раз и в самом начале прогона, а не лениво
  в середине по первому файлу, который её закажет;
- признак «собрано» держится взведённым — пересборка посреди прогона
  стала невозможна;
- отказ заливки схемы стал громким: раньше отказ мог вернуться без ошибки,
  и прогон ехал дальше по неполной схеме;
- добавлена сверка полноты сборки: сколько шагов миграции записано против
  того, сколько их лежит файлами. Не сошлось — прогон умирает сразу
  и внятно, а не через сотни «таблицы X не существует»;
- тест-ловушка TestDbRebuildGuardTest: первый тест выходит из транзакции
  и ставит метку, второй метку проверяет. Без защиты второй падает.

Замер в этой ветке, СМС-модуль, 44 файла:
- общая тестовая база и без починки — 267 зелёных, 4 красных пачки
  из 15 даже с шестью попытками на пачку;
- своя база liderra_testing_sms и с починкой — 383 из 383 одним прогоном.

Заодно вскрылась вторая, более грубая причина: общая база liderra_testing
держала 143 записи о применённых миграциях при 137 файлах в этой ветке.
Записей больше файлов — доказательство, что в базу пишет чужая рабочая
папка. Датчик простой: сравнить число записей с числом файлов; любое
неравенство значит «база не твоя, верить прогону нельзя». Лечение —
своя база на рабочую папку, как уже сделано у соседних веток.

Прогон всех 4000 тестов ветки с этой починкой я НЕ делал — мерил только
область СМС-модуля.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 13:25:55 +03:00
Дмитрий f1e315cc11 fix(rls): NULLIF-хардненинг GUC во всех 44 политиках tenant_isolation — фикс входа на Managed PG
Инцидент 26.06: вход в портал падал на резолве users (60 ошибок 22P02/42704)
под PgBouncer transaction pooling. current_setting('app.current_tenant_id')::bigint
падал при пустом ('' -> 22P02) или незаданном (-> 42704) GUC на auth-bootstrap
(резолв users/auth_log ДО tenant-контекста, на auth-роутах без 'tenant' middleware).

- все 44 политики -> NULLIF(current_setting('app.current_tenant_id', true), '')::bigint
  (флаг ,true убирает 42704; NULLIF(...,'') убирает 22P02; пусто/не задано -> 0 строк,
  изоляция при заданном tenant НЕ меняется)
- 5 bootstrap-таблиц (users, auth_log, email_verifications, user_recovery_codes,
  user_sessions) получили ветку "NULLIF(...) IS NULL OR ..." — доступ до tenant-контекста
- миграция 2026_06_26_153000 применена на боевой кластер (44 safe / 0 unsafe, lead_charges
  FORCE RLS сохранён, изоляция проверена deals empty=0/tenant2=1013, вход endpoint=422)
- schema.sql v8.57 + CHANGELOG_schema.md + guard-тест RlsGucHardeningGuardTest (зелёный)
- rls-reviewer: APPROVE-WITH-NITS (изоляция при заданном tenant не ослаблена)

Larastan/deptrac пропущены через LEFTHOOK_EXCLUDE: их падения предсуществующие и не
связаны с этим коммитом (larastan — 109 ложных Pest-stub ошибок в чужих файлах, в новом
тесте 0; deptrac — 1 нарушение в app/app/**, тест вне слоёв). Проверено прямым прогоном.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 17:15:22 +03:00
Дмитрий 2ccb802382 feat(db): RLS на tenants + created_at TZ (schema v8.51) 2026-06-22 18:03:42 +03:00
Дмитрий eeda9d4214 feat(supplier): supplier_manual_sync_queue table (Tier 3 queue)
SaaS-level (без tenant_id, без RLS, как supplier_csv_reconcile_log).
+3 CHECK (platform/operation/status), +2 индекса, +2 FK
(project_id→projects CASCADE, resolved_by_user_id→users SET NULL).

Миграция через DB::unprepared (PG prepared statement не разрешает multi-SQL).
schema.sql bumped v8.24 → v8.25 (64 base tables / 121 indexes / 40 RLS).
SchemaDeltaTest обновлён под новые метрики (63→64 tables, 119→121 indexes).

§15.2 pre-flight: rebase на origin/main 831573d выполнен до коммита.
Spec §4.5. Task 3 of 12. Регрессия: schema+delta тесты 11/11.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 12:55:06 +03:00