114 lines
13 KiB
Markdown
114 lines
13 KiB
Markdown
# 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`
|
||
каждого репозитория. **Первая задача агента — прочитать шаблон и дополнить документы.**
|
||
- `docker-compose` workspace-уровня (в `docs/dev/` или корне workspace): PostgreSQL, NATS JetStream, MinIO (S3),
|
||
эмулятор ИС Сканирование (отдаёт `fixtures/ocr/aep_N.json`), три сервиса. `make up/test/lint/migrate` в каждом репо.
|
||
- Контракт `docs/contracts/recognition-result.schema.json` v1.0 + pydantic-модели контракта в общем пакете
|
||
`arm-ka-contracts` (публикуется из `docs/` или живёт копией в каждом сервисе с проверкой идентичности в CI — решить в A).
|
||
- Alembic: миграция 0001 — **все** таблицы и enum'ы DBML v5.13 (генерировать из ORM, сверить с DBML скриптом
|
||
`scripts/check_dbml_vs_orm.py` — считать расхождения ошибкой CI).
|
||
- Seed: `regional_office` (ГО + пара РФ), `role` (7), `permission` (8 объектов × 7 действий — только осмысленные
|
||
сочетания), `role_permission` по §10, `chart_of_account` из плана счетов 1С (csv), `elimination_rule` v1 из §4
|
||
(только ББ), `required_document_rule` для BASIC/EXTENDED.
|
||
- 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)` в коде.
|