Andrey Epifancev 096d53b10c feat(seed): полный план счетов 1С в seed (488 строк)
Seed chart_of_accounts.csv заменён выгрузкой 1С: буквенные субсчета (01.К, 62.ОТ, 76.АВ),
забалансовые 001–012 и буквенные корни (МЦ, ГТД…), «Я…». Валидатор seed принимает буквенные
коды, 000 и 012, сирот выгрузки («Я68.01» без «Я68») с пустым parent_code; kind — из «Вида» 1С.
18 из 19 кодов реальных ОСВ теперь получают account_id (60.АВ — только в синтетике, в 1С нет).
ASSUMPTION(OQ-113): выгрузка считается полной.

Closes #23

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 12:57:20 +04:00

93 lines
8.7 KiB
Markdown
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.

# 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 правил с кодами
`<OBJECT>_<ACTION>` (`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–012 и буквенных корней плана 1С (МЦ, НЕ, ГТД, ИНВ, КВ, ОТ, РВ, УСН) со всеми их субсчетами.
`chart_of_accounts.csv` SHALL содержать полный план счетов 1С заказчика (`fixtures/directories/chart-of-accounts-1c.xlsx`,
488 строк, включая буквенные субсчета `01.К`, `62.ОТ`, `76.АВ`; ASSUMPTION(OQ-113): выгрузка полна); `kind` строки — «Вид»
1С (у субсчёта может отличаться от родителя); субсчёт без родителя в выгрузке (`Я68.01`) загружается с пустым `parent_code`.
#### 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** seed завершён
- **THEN** в `chart_of_account` есть `01.01`, `66.01`, `76.01`, `76.ОТ`, `01.К` и `МЦ.04` (строки ОСВ с этими кодами получают
`account_id`); `60.АВ` в плане 1С нет, `account_id` таких строк остаётся `NULL`
#### Scenario: Ссылка на несуществующий счёт
- **WHEN** в файл правил добавлен счёт, которого нет в `chart_of_accounts.csv`
- **THEN** seed падает до записи в БД с сообщением, какой счёт и в каком правиле не найден
### Requirement: Dev-данные только по явному флагу
`python -m scripts.seed --dev` SHALL дополнительно загрузить из `api/seed/dev/`: примеры региональных филиалов и по одному
`app_user` на каждую системную роль (`<role>@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 — сообщение об отказе, БД не затронута