9 Commits

Author SHA1 Message Date
Andrey Epifancev
5e11f0d0bf fix: seed --dev только при DEBUG=true (OQ-60, #9 п.1)
CLI `python -m scripts.seed --dev` сверяется с `DEBUG` (`check_dev_allowed`) до
чтения seed и подключения к БД; при `DEBUG=false` — код возврата 2 и сообщение
«--dev доступен только при DEBUG=true (dev-пользователи не для прода)».
`run_seed(session, dev=True)` защиты не имеет (её вызывают тесты).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 13:13:30 +04:00
Andrey Epifancev
458392e94d feat(model): DBML v5.14 — related_group_member.kind, audit_action +2, миграция 0002, последовательности кодов
- RelatedGroupMember.kind (related_group_kind, NOT NULL) между legal_entity_id и valid_from, как в DBML;
  частичный уникальный индекс uq_related_group_member_entity_kind_current (legal_entity_id, kind) WHERE is_current —
  ЮЛ одновременно в одной ГСК и одной ГСЗ.
- AuditAction: LEGAL_ENTITY_CHANGE (после GROUP_CHANGE), USER_CHANGE (после USER_ROLE_CHANGE).
- Последовательности company_group_code_seq / related_group_code_seq в metadata (design D-5).
- Миграция 0002_dbml_v5_14: related_group_member пересоздаётся с переносом строк (kind из группы), чтобы порядок
  колонок совпал с DBML и create_all; ALTER TYPE ADD VALUE ×2; downgrade пересоздаёт audit_action v5.13.
- DBML_VERSION = 5.14, пути к data-model-v5.14.dbml (Makefile, dbml_parity), тесты: откат на шаг, перенос строк,
  уникальность gsk+gsz, офлайн-SQL до head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 20:49:32 +04:00
Andrey Epifancev
81bb79e600 feat: make check-full — check, dbml-check, интеграционные тесты против compose, docker build, web; .env.test на порты compose
Цели docker-build, web-check, check-infra (подсказка «make up»); .env.test переведён на 5432/4222/9000 (R-19),
test_config и README обновлены. Цикл миграций входит в test-integration и отдельным шагом не дублируется.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 00:58:57 +04:00
Andrey Epifancev
cb2723c3a2 feat: dev-seed (2 РФ и по пользователю на роль) по флагу --dev, проверка ссылок до записи
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 21:41:07 +04:00
Andrey Epifancev
176999cb71 feat: seed правил элиминации ББ (§4) и чек-листа обязательных документов, проверка счетов до записи
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 21:29:16 +04:00
Andrey Epifancev
caf009d343 feat: seed плана счетов 94н с субсчетами правил и чек-листа, шаг загрузчика chart_of_account
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 21:17:18 +04:00
Andrey Epifancev
186ae802e6 feat: seed ролей, прав, матрицы §10 и Головного офиса, загрузчик scripts.seed
Двухфазный загрузчик: валидация yaml целиком до записи (SeedError), затем upsert по
натуральному ключу без удалений; run_seed(session, *, dev, seed_dir) без commit, CLI коммитит.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 21:07:07 +04:00
Andrey Epifancev
7ea1e67f4e fix: сверка DBML — табличные UNIQUE и CHECK, действия FK, неизвестные классы типов
I-1: табличный UniqueConstraint ORM сверяется как уникальный индекс по колонкам
(флаг колонки unique=True — по-прежнему в свойствах колонки); любое CHECK в ORM —
«отсутствует в DBML».
I-2: у совпавших целей FK сравниваются ON DELETE / ON UPDATE (нет в DBML = NO ACTION),
DEFERRABLE и INITIALLY.
I-3: неизвестный класс типа отрисовывается repr с параметрами (VARCHAR(length=50),
Uuid(as_uuid=False)) и никогда не совпадает с именем типа DBML.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 20:11:25 +04:00
Andrey Epifancev
e064830702 feat: scripts/check_dbml_vs_orm.py — CLI сверки ORM с DBML (версия, таблицы, колонки, типы, FK, индексы, enum'ы)
Ядро сверки перенесено из tests/dbml_parity.py в scripts/dbml_parity.py (единственная
реализация, R-14); tests/dbml_parity.py и dbml_helpers.py — тонкие обёртки с пропуском
теста без docs. Единый формат строк: `<объект>: ожидалось X / фактически Y`,
`<объект>: отсутствует в ORM|DBML`; тип и nullability — одной строкой в нотации DBML.
Версия из шапки DBML сверяется с DBML_VERSION до сравнения таблиц. Коды: 0/1/2.
Без рабочего .env скрипт берёт api/.env.example. Makefile: dbml-check (в check-full),
mypy проверяет scripts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 19:56:58 +04:00