Files
portal/.squawk.toml
T
Дмитрий f502b0058d phase1(backend): multi-tenant фундамент развёрнут — schema v8.5→v8.6 + migrate:fresh
Backend multi-tenant фундамент развёрнут на dev-БД liderra: 68 таблиц
(52 обычных + 16 партиций) + 36 RLS-policies + 5 функций + 13 триггеров.
`php artisan migrate:fresh` за 870 ms через одну raw-SQL миграцию
`load_initial_schema.php` (DB::unprepared с db/schema.sql).

Первый реальный запуск schema.sql на pristine PG 16 поймал 2
несовместимости v8.5, исправлены архитектурно (CTO-17):

1. CREATE UNIQUE INDEX на партиционированной deals (schema:1263)
   PG требует partition key (received_at) в UNIQUE; включить нельзя —
   ломает идемпотентность webhook'ов. Решение: новая таблица
   webhook_dedup_keys (не партиционированная, PK (tenant_id, source_crm_id)
   → deal_id, composite FK на deals(id, received_at) ON DELETE CASCADE,
   RLS tenant_isolation USING+WITH CHECK). UNIQUE INDEX в deals
   заменён на обычный. Webhook handler — двустадийная UPSERT.

2. GENERATED ALWAYS AS на pd_subject_requests.deadline_at (schema:1999)
   `+ INTERVAL '30 days'` не immutable. Решение: обычная TIMESTAMPTZ
   NOT NULL + триггер trg_pd_subject_requests_deadline + функция
   set_pd_subject_request_deadline().

Изменения:

- db/schema.sql: v8.5 → v8.6 (заголовок, 1 новая таблица, 1 RLS-policy,
  1 функция, 1 триггер, замена UNIQUE на обычный INDEX, замена GENERATED
  на TIMESTAMPTZ NOT NULL)
- db/CHANGELOG_schema.md: новая запись §X v8.5→v8.6
- db/00_create_roles.sql (NEW): deployment-скрипт 4 ролей PG для production
  (crm_app_user, crm_admin_user BYPASSRLS, crm_migrator BYPASSRLS+CREATEDB,
  crm_audit_writer). На dev — postgres superuser (schema §13 разрешает)
- db/02_grants.sql (NEW): GRANT/REVOKE из закомментированных секций §13
  schema. REVOKE на 6 saas-таблицах для crm_app_user (defense-in-depth
  поверх RLS, OPEN-И-14). REVOKE DELETE на 4 финансовых таблицах для
  crm_admin_user (только soft markers)
- app/database/migrations: удалены 3 default Laravel (users/cache/jobs
  дублировались с нашей schema), создан 0001_01_01_000000_load_initial_schema.php
- .squawk.toml: + excluded_paths для db/00_create_roles.sql (psql client-side
  variables :'name' не парсятся libpg_query)
- docs/Открытые_вопросы_v8_3.md: v1.18 → v1.19, CTO-17 закрыт фиксом,
  70  / 5 🟦 / 4 ⏸. Техдолг: ТЗ §15-16 webhook handler нужно обновить
  под двустадийную dedup-логику
- CLAUDE.md: v1.9 → v1.10 (§0 ссылки на schema v8.6 + реестр v1.19;
  §2 метрики БД 54→55/91→92/35→36/12→13/4→5; §6 фундамент развёрнут)
- cspell-words.txt: +9 новых терминов

Smoke-test через Boost MCP database-query:
- 68 таблиц (включая webhook_dedup_keys + 16 партиций)
- 36 RLS-policies
- 35 RLS-enabled (relkind='r'; +2 partitioned 'p' = 37 total)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:48:24 +03:00

45 lines
3.0 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# .squawk.toml — конфигурация squawk (Прил. Н #15) для Лидерры
# =============================================================================
# Документация: https://squawkhq.com/docs/configuration
# Инструмент: линтер миграций PostgreSQL
# Применяется автоматически при запуске `squawk` без явного --config
# =============================================================================
#
# Стратегия проекта (Прил. Н v1.6, §10.3):
#
# 1. Этот конфиг тихо обрабатывает `db/schema.sql` (initial bootstrap, не миграция).
# Поэтому отключены:
# • правила безопасной миграции (require-timeout-settings, prefer-robust-stmts,
# require-concurrent-index-creation, constraint-missing-not-valid,
# adding-foreign-key-constraint) — нерелевантны для initial bootstrap
# (заливается на пустую БД при `db:reset`).
# • дизайнные предпочтения (prefer-identity, prefer-text-field,
# prefer-bigint-over-int, prefer-bigint-over-smallint) —
# в проекте сознательно используются BIGSERIAL и VARCHAR(N) с длинами
# для UI-валидации; SMALLINT для денормализованных status_code.
#
# 2. Для будущих **Laravel-миграций** в `app/database/migrations/*.sql`
# создавать локальный `.squawk.toml` рядом или запускать squawk без
# `--exclude`, чтобы получить полную проверку лайв-миграции.
# =============================================================================
excluded_paths = [
"db/00_create_roles.sql", # psql client-side variables (:'name') не парсятся libpg_query
]
excluded_rules = [
# --- Bootstrap-неприменимые ---------------------------------------------
"require-timeout-settings", # initial setup, не run-time миграция
"prefer-robust-stmts", # IF NOT EXISTS не нужен на пустой БД
"require-concurrent-index-creation", # нет конкурирующих подключений
"constraint-missing-not-valid", # initial CREATE, не ADD CONSTRAINT
"adding-foreign-key-constraint", # initial CREATE с FK inline
# --- Дизайнные решения проекта ------------------------------------------
"prefer-identity", # BIGSERIAL по консистентности (см. §6.4)
"prefer-text-field", # VARCHAR(N) для UI-валидации длин
"prefer-bigint-over-int", # INT для счётчиков с лимитом
"prefer-bigint-over-smallint", # SMALLINT для status_code (денорм.)
]