# reference-data-seed Specification ## Purpose Справочники продукта (роли, права и их матрица, план счетов, правила элиминации, состав обязательных документов) и dev-данные загружаются из файлов репозитория одной идемпотентной командой; повторный запуск ничего не дублирует. ## Requirements ### Requirement: Идемпотентный seed справочников продукта Команда `python -m scripts.seed` (из `api/`) SHALL загрузить из `api/seed/core/`: `regional_office` (Головной офис, `is_head_office = true`), `role` — 7 системных ролей ТЗ 8.1 (`KA_RF`, `KA_GO`, `RKA`, `CLIENT_MANAGER`, `CURATOR_GO`, `EXPERT`, `ADMIN`, `is_system = true`), `permission` — 16 сочетаний объект × действие из §10 правил с кодами `_` (`EXPORT` при совпадении), `role_permission` по матрице §10 (ASSUMPTION(OQ-16)), `chart_of_account`, `elimination_rule` + `elimination_rule_account` версии 1 для ББ (§4), `required_document_rule` для `BASIC` и `EXTENDED`. Записи SHALL вставляться или обновляться по натуральному ключу; удаление MUST NOT выполняться. Исключение — матрица `role_permission` (ей после первичной загрузки владеет администратор, issue #9): в ПУСТУЮ таблицу матрица файла SHALL загружаться целиком; в заполненную SHALL вставляться только пары, у которых роль или право вставлены этим же запуском seed (их администратор снять не мог), а остальные пары файла MUST NOT добавляться — право, снятое администратором, не возвращается, добавленное сверх файла не отзывается. Отчёт команды SHALL сообщать, что матрица пропущена (или сколько добавлено пар новых ролей и прав). #### Scenario: Первый запуск на пустой схеме - **WHEN** после `alembic upgrade head` выполняется `python -m scripts.seed` - **THEN** в `role` 7 строк, в `permission` 16, в `role_permission` — число строк равно сумме прав по матрице §10, в `elimination_rule` 8 строк с `statement_type = balance`, `version_no = 1`, в `required_document_rule` для `BASIC` 10 строк (BALANCE, INCOME, OSV × 01, 58, 60, 62, 66, 67, 76, 90) и для `EXTENDED` 27 строк #### Scenario: Повторный запуск - **WHEN** `python -m scripts.seed` выполняется второй раз без изменения файлов - **THEN** число строк во всех затронутых таблицах не меняется, команда завершается с кодом 0, в отчёте `role_permission` помечена как пропущенная #### Scenario: Право, снятое администратором - **WHEN** администратор снял с роли `EXPERT` право `EX_VIEW`, после чего seed запущен снова - **THEN** связь `EXPERT × EX_VIEW` не восстановлена, остальная матрица не изменилась #### Scenario: Новые роль и право в файлах seed - **WHEN** матрица заполнена, а в `permissions.yaml` добавлено новое право, в `roles.yaml` — новая роль, и в `role_permissions.yaml` — их пары (новое право существующей роли, существующее право новой роли) - **THEN** seed вставляет ровно эти пары; снятые ранее администратором связи существующих ролей и прав не возвращаются #### Scenario: Администратор снял все связи - **WHEN** таблица `role_permission` пуста и seed запущен снова - **THEN** матрица файла загружается целиком, как при первом запуске #### Scenario: Изменение названия роли в файле - **WHEN** в `roles.yaml` изменено `name` роли `EXPERT` и seed запущен снова - **THEN** строка `role` с `code = EXPERT` обновлена, новая не создана ### Requirement: Счета правил и чек-листа существуют в плане счетов Все коды счетов, на которые ссылаются `elimination_rules_v1.yaml` и `required_document_rules.yaml`, SHALL резолвиться в `chart_of_account.code` после seed; `elimination_rule_account.is_excluded = true` SHALL быть у исключений вида «76 кроме 76.07.5, 76.07.9»; `chart_of_account.kind` SHALL быть задан для всех синтетических счетов, `is_off_balance = true` для 001–011. #### Scenario: Правило № 6 (основная пара) - **WHEN** seed завершён - **THEN** у правила `rule_no = 6` сторона 1 содержит счета 60.02, 60.22, 60.32, 62.01, 62.03, 62.21, 62.31, 76 и исключения 76.07.5, 76.07.9; сторона 2 — 60.01, 60.03, 60.21, 60.31, 62.02, 62.22, 62.32, 76 и исключение 76.07.1; `elimination_mode = min`, `measure = closing`, `side_1 = D` #### Scenario: Ссылка на несуществующий счёт - **WHEN** в файл правил добавлен счёт, которого нет в `chart_of_accounts.csv` - **THEN** seed падает до записи в БД с сообщением, какой счёт и в каком правиле не найден ### Requirement: Dev-данные только по явному флагу `python -m scripts.seed --dev` SHALL дополнительно загрузить из `api/seed/dev/`: примеры региональных филиалов и по одному `app_user` на каждую системную роль (`@armka.local`, активные, с назначенной ролью через `user_role`). Без флага `--dev` эти данные MUST NOT загружаться. Флаг `--dev` SHALL приниматься только при `DEBUG=true`: при `DEBUG=false` команда MUST завершиться с кодом 2 и сообщением «--dev доступен только при DEBUG=true (dev-пользователи не для прода)» до чтения файлов seed и обращения к БД (OQ-60). #### Scenario: Dev-пользователи - **WHEN** выполнен `python -m scripts.seed --dev` - **THEN** в `app_user` 7 строк с email вида `ka_rf@armka.local`, каждая связана ровно с одной ролью через `user_role` #### Scenario: Прод-режим - **WHEN** выполнен `python -m scripts.seed` без `--dev` - **THEN** таблица `app_user` пуста, `regional_office` содержит только Головной офис #### Scenario: `--dev` без DEBUG - **WHEN** при `DEBUG=false` выполнен `python -m scripts.seed --dev` - **THEN** код возврата 2, в stderr — сообщение об отказе, БД не затронута