arm-ka-docs/context/09-delivery-plan.md
Andrey Epifancev 0c04127aec docs: OpenSpec change slice-0-skeleton — сквозной скелет Среза 0
openspec init (config с контекстом docs-репозитория) и change slice-0-skeleton: proposal, design
(11 решений без обсуждения, открытые вопросы к человеку), спеки recognition-contract,
dev-environment, ci-template, tasks в порядке зависимостей между репозиториями. 06-test-data.md §6:
справочники продукта — seed arm-core, не фикстуры. 09-delivery-plan.md: Срез 0 по факту (change'и,
compose в docs/dev, контракт копией без общего пакета, seed).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 02:44:14 +04:00

14 KiB
Raw Blame History

09. План работ вертикальными срезами

Принцип: каждый срез — рабочий end-to-end кусок (миграции + API + минимальный UI + тесты на реальных фикстурах), который можно показать аналитику. Порядок выбран так, чтобы самое рискованное (парсер ОСВ, матчинг ВГО) проверялось на реальных данных как можно раньше, а внешние зависимости (ИС Сканирование, РАИСА, NATS платформы) не блокировали.

Каждый срез = OpenSpec change в каждом затронутом репозитории (openspec/changes/<slug>/ с proposal.md, specs/, tasks.md), сквозная часть — change в docs/; задачи — issues в Gitea; PR — по одному на репозиторий. Jira-эпики пользователя маппятся на срезы (пользователь ведёт соответствие сам).

Срез 0 — Скелет (2–3 дня, три репозитория + docs)

  • Три репозитория из нулевого коммита шаблона команды; соглашения шаблона — в 03-architecture.md и в CLAUDE.md каждого репозитория. Первая задача агента — прочитать шаблон и дополнить документы. (Сделано: раздел «Соглашения шаблона команды» в 03-architecture.md; в tabular-parser/scan-gateway фронт и БД вырезаются задачами среза.)
  • OpenSpec change'и среза: docs/openspec/changes/slice-0-skeleton (сквозной: контракт, compose, CI-шаблон, документы) и по одному openspec/changes/slice-0-skeleton в arm-core, tabular-parser, scan-gateway; issue #1 в каждом репозитории.
  • docker-compose workspace-уровня (docs/dev/docker-compose.yml): PostgreSQL 15, NATS 2.10 JetStream, MinIO (S3, один бакет arm-ka), эмулятор ИС Сканирование (часть scan-gateway, отдаёт fixtures/ocr/aep_N.json), три сервиса (профиль services). Makefile с up/test/lint/migrate в каждом репо (шаблон Makefile не содержит — добавляется).
  • Контракт v1.0 — три схемы в docs/contracts/: recognition-request, recognition-result-message (конверты NATS) и recognition-result (файл результата) + examples/. Общий пакет arm-ka-contracts не публикуется: каждый сервис хранит копию схем в api/contracts/ и pydantic-модели в src/contract/, идентичность с docs/contracts проверяется в CI (решение D-1 change slice-0-skeleton в docs).
  • Alembic: миграция 0001 — все таблицы и enum'ы DBML v5.13 (черновик из ORM, сверка с DBML скриптом api/scripts/check_dbml_vs_orm.py — расхождение = ошибка CI).
  • Seed (arm-core/api/seed/, идемпотентно): regional_office (ГО; примеры РФ — только --dev), role (7), permission (16 осмысленных сочетаний объект × действие по §10), role_permission по §10, chart_of_account (План счетов 94н + типовые субсчета 1С, OQ-47), elimination_rule v1 из §4 (только ББ), required_document_rule для BASIC/EXTENDED (OQ-46).
  • Auth: валидация JWT + dev-эмитент; app_user seed (по одному на роль); зависимость require(permission).
  • audit_event middleware/helper; s3_object клиент; outbox-паблишер и consumer recognition.result (пустые обработчики).
  • CI: lint, mypy, pytest, миграции с нуля и обратно, сборка образов.
  • DoD: GET /api/v1/me возвращает пользователя и его эффективные права; все миграции применяются; CI зелёный.

Срез 1 — Справочники (ГК / ЮЛ / ГСК / ГСЗ / филиалы) + пользователи и роли

  • CRUD ГК (с code, crm_id nullable, закрепление за РФ, архив, история SCD4), ЮЛ/ИП (ИНН 10/12, алиасы, перевод в другую ГК с legal_entity_history.event_type/effective_date, закрытие), ГСК/ГСЗ и состав (SCD2, одна группа на ЮЛ).
  • Импорт из файла (xlsx/csv) с логом ошибок и стратегией дублей; audit_event(DIRECTORY_IMPORT).
  • Экран администратора: пользователи, роли, матрица прав (ROLE_PERMISSION_CHANGE).
  • Policy-слой: видимость ГК по филиалу/ЗО.
  • Фикстуры: ГК «Русский бисквит» с двумя ЮЛ (+ кандидаты из OQ-25), ГСК из двух.
  • UI: справочник по макету (левая панель ГК, правая — ЮЛ/ГСК/ГСЗ, модалки).

Срез 2 — Загрузка файлов + табличный парсер (ОСВ, ББ, ОФР из Excel) — самый рискованный, делать рано

  • arm-core: stored_file + s3_object + recognition_job (outbox) + дедуп по content_hash + замена файла (SUPERSEDED).
  • tabular-parser: динамическое обнаружение структуры (§1.0): поиск листов с ОСВ/ББ/ОФР по содержимому, заголовка таблицы и колонок сумм по тексту, иерархии строк каскадом стратегий (outline level → отступ → шаблон кода → суммы), шапки регулярками; классификация по group_schema; контрольные суммы; ББ/ОФР из Excel по §12 в тот же statementDocument; словари синонимов rules/*.yaml; результат по контракту; NATS request/result; S3 results/.
  • Маппинг результата в ядре: document (OSV) + osv_entry (все строки, OQ-01) + резолв account_id, account_root, counterparty_id по ИНН/имени/алиасу; document.period_check / counterparty_check; статусы.
  • Тесты: property-тесты инвариантов на всех файлах fixtures/osv/** и fixtures/statements-xlsx/** («Итого» = корень; тождество сальдо/оборотов; Σ детей = родитель; формулы §7 для форм) + синтетика для форматов, которых нет в фикстурах (шапка вариант 2, без outline level, csv-подобный лист, Вал./Кол., xlsb, ББ+ОФР на одном листе, текстовые числа). Снимок результатов → fixtures/golden/expected_osv_parse/.
  • Маппинг ББ/ОФР в ядре из statementDocument — общий для Excel и OCR (Срез 3 его переиспользует).
  • UI: панель «Первичные документы», окно загрузки, таблица ОСВ с деревом строк и подсветкой нераспознанных контрагентов.
  • DoD: все реальные файлы и вся синтетика проходят без единого правила под конкретный файл или координату; в коде парсера нет литералов букв колонок/номеров строк/имён листов (проверяется тестом-линтером).

Срез 3 — ББ/ОФР: scan-gateway, маппинг форм, логические проверки, подтверждение документа

  • scan-gateway: горячие папки (по FNR02) с заглушкой-эмулятором ИС Сканирование для dev (возвращает aep_*.json по имени файла); сырой ответ → S3 raw/; нормализация в контракт результата; таймаут 5 мин.
  • Маппинг: financial_statement_meta/column/line/value из JSON; числа, скобки, confidence; ИНН/имя сверка.
  • Логические проверки §7 (чистые функции domain/checks.py), акцепт КА, «Подтвердить данные» → CONFIRMED, RECOGNIZED_DATA_EDIT с before/after.
  • Чек-лист required_document_rule × периметр − document CONFIRMED (API + модалка + CSV).
  • UI: экран «Проверка распознавания» (исходник слева — PDF.js, результат справа, блок «Логические ошибки»).
  • Тесты: пары aep_N.pdf/json; машиночитаемые PDF АО РБ 2024 как dev-путь без OCR (опционально pdfplumber).

Срез 4 — Консолидация: карточка, версии, периметр, периоды, сводная ОСВ

  • consolidation / consolidation_version / consolidation_member / consolidation_document; статусы INITIATED → DOCUMENTS_PROCESSING → DATA_CORRECTION; consolidation_lock.
  • Приведение квартальных ОСВ к нарастающим (§2) как вычисляемое представление.
  • Сводная ОСВ (§3) как запрос; признак контрагента; ручное сопоставление с алиасами и автоприменением.
  • UI: список консолидаций, карточка, состав, сводная ОСВ с фильтрами и экспортом xlsx.
  • Тест: сводная ОСВ группы РБ за 9 мес. 2024: строки «Юг-Финанс / ПЕКАРНЯ СЧАСТЛИВОЧНАЯ» → ГСК после одного ручного сопоставления.

Срез 5 — ВГО: автоматическое сопоставление, шахматка, корректировки

  • elimination_rule как данные + версия в consolidation_version; матчинг §5 (чистые функции на pydantic-моделях); шахматка §6; correction с дочерними строками, контроль 5 %, статусы DRAFT/APPLIED/REVOKED; ADJUSTMENT.
  • UI: шахматка (ячейки с комментариями), таблица пар (авто/ручные/несопоставленные), таблица корректировок с импортом/экспортом xlsx.
  • Тест: пара 60.01 АО РБ ↔ 62.01 Счастливочная на 30.09.2024 = 106 311 116,46 (точный матч по правилу № 6); заём 42 млн 66.03 ↔ 58.03; сверка «в т. ч. взаимные обязательства» с Консолидация_Группа РБ.xlsx лист 01.10.2024.

Срез 6 — КФО: результат, гудвилл, пороги, сравнение с клиентом

  • kfo_result(_line, _line_company): сумма → авто-элиминация → корректировки → гудвилл → итог; единицы (OQ-26); пороги §8; goodwill; client_kfo_line для CONFIRM.
  • UI: КФО (колонки как в эталонном Excel), сводка расхождений, гудвилл, подтверждение КФО клиента, экспорт xlsx.
  • Тест: КФО группы РБ на 01.10.2024 vs эталонный лист (допуск на ручные правки аналитика — зафиксировать расхождения и показать аналитику).

Срез 7 — Маршрут согласования, ЕХ, журнал, выгрузки

  • Полная машина статусов §9.1 с consolidation_status_history, policy по ролям/филиалам; № и дата УОБ; новая версия.
  • VERIFIED → ex_snapshot/_member/_item (payload по схеме docs/contracts/ex-payload-v1.schema.json); read-only.
  • ЛК ЕХ: дерево ГК → ГСК → организации, просмотр payload, скачивание первички, выгрузка xlsx на лету.
  • Журнал действий: экран с фильтрами по разделам/объектам/полям.
  • Экспорт: настраиваемые колонки, audit_event(EXPORT), S3 exports/ 7 дней.

Срез 8 — Нефункциональные: ретеншн, архивирование, производительность, безопасность

  • Lifecycle S3 и удаление по ТЗ 8.4 (5 лет), архив в data lake (ссылка), объёмы osv_entry (индексы, partitioning по году при необходимости), нагрузочный тест парсера (1000-строчные ОСВ × 20 компаний), OWASP-проверка, аудит доступа.

Поперечные правила

  • Любой срез, затрагивающий модель, начинается с diff к DBML (новая версия v5.14+ с записью в changelog) и миграции.
  • Вычисляемые объекты — только domain/ + repositories/ запросы; никаких таблиц «для ускорения» без DECISION.
  • Каждый алгоритм из 05-domain-rules.md — отдельный модуль с docstring-ссылкой на § и тестами на фикстурах.
  • Открытые вопросы — только через 07-open-questions.md с ASSUMPTION(OQ-nn) в коде.