Andrey Epifancev 93cd1f8aa0 feat(seed): dev-ГК под документы fixtures — «Русский Бисквит» из выгрузки ЕЦП и владельцы форм ДКБ
seed/dev/company_groups.yaml: ГК «Русский Бисквит» ровно как в fixtures/directories/ecp-export-russkiy-biskvit.xlsx
(20 ЮЛ/ИП, crm_id, филиал «Санкт-Петербургский РФ», ГСК из РБ и Счастливочной), ГК Унагранде/НПЗ/Межениновская по
ИНН из форм ББ/ОФР; алиасы под имена контрагентов и шапок ОСВ («Юг-Финанс / ПЕКАРНЯ СЧАСТЛИВОЧНАЯ», ...), чтобы
документы из fixtures ложились на «своих» ЮЛ и резолвились. Загрузчик проверяет ИНН, виды, ссылки членов и
уникальность «ЮЛ в одной ГСК/ГСЗ» до записи; apply — upsert по name/inn/(ГК, name), коды из последовательностей
API, без удалений. `--no-dev-groups` / `run_seed(dev_groups=False)` — dev-данные без ГК; фикстуры тестов API
используют его, чтобы начинать с пустых справочников.

make check: 1132 passed; интеграция seed/import: 23 passed. Два теста падают и на main из-за обновлённых golden
(test_mapping_golden 88 → 113, test_consolidation_fixtures UNMAPPED_TOTAL) — отдельная issue.

Closes #31

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
2026-10-06 17:05:46 +04:00

9.7 KiB
Raw Permalink Blame History

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: Dev-ГК под документы fixtures

  • WHEN python -m scripts.seed --dev на пустой схеме
  • THEN созданы ГК «Русский Бисквит» (crm_id и состав — выгрузка ЕЦП CRM из fixtures: 20 ЮЛ/ИП, филиал «Санкт-Петербургский РФ», ГСК из АО «Русский бисквит» и ООО «Пекарня Счастливочная») и ГК владельцев форм пакета ДКБ (Унагранде, НПЗ, Межениновская); у ЮЛ 3528104476 алиасы «Юг-Финанс / ПЕКАРНЯ СЧАСТЛИВОЧНАЯ» и имя из шапки ОСВ, так что документы из fixtures ложатся на «своих» ЮЛ с counterparty_check = MATCH; коды GK-/GSK-NNNNNN — из тех же последовательностей, что API; повторный запуск ничего не меняет; без --dev ни одной ГК и ЮЛ нет

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 — сообщение об отказе, БД не затронута