Загрузка с consolidation_version_id: проверки до приёма (404/409/422), после приёма INITIATED -> DOCUMENTS_PROCESSING в отдельной транзакции без блокировки версии. Маппинг: on_documents_mapped переводит версии DOCUMENTS_PROCESSING в DATA_CORRECTION при подходящем документе NEEDS_CHECK (changed_by = uploaded_by), привязки не создаёт. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
65 lines
7.2 KiB
Markdown
65 lines
7.2 KiB
Markdown
# Tasks: Срез 4 — arm-core
|
||
|
||
Каждая задача ≤ половины дня, начинается с тестов, заканчивается зелёным `make check` и интеграционными тестами своей
|
||
области. Допущения в коде — `# ASSUMPTION(OQ-nn)`. DBML v5.16 — `../docs/model/data-model-v5.16.dbml` (ветка
|
||
`feat/19-slice-4-consolidation` в `.wt/slice-4/docs`). Детальный план с кодом — `docs/superpowers/plans/` (writing-plans).
|
||
|
||
## 1. Модель
|
||
|
||
- [x] 1.1 **DBML v5.16, миграция 0004, `match_kind` в маппинге.** `CounterpartyMatchKind` enum, колонка
|
||
`OsvEntry.counterparty_match_kind`; миграция `0004_dbml_v5_16` (enum, колонка, backfill SQL, downgrade); `DBML_VERSION`,
|
||
`Makefile`, `dbml_parity`, `test_migrations` (HEAD), `test_enums`, `test_check_dbml_script` (фиктивная 5.17);
|
||
`CounterpartyIndex.resolve` → `Resolution(entity_id, kind) | None`; `result_mapping._with_counterparty` пишет kind;
|
||
`EntryOut.match_kind`. Тесты: backfill на трёх строках, golden-маппинг с kind, `test_counterparty_resolve`.
|
||
- [x] 1.2 **Фабрики и репозиторий.** `tests/factories.py`: `make_consolidation(session, *, group, year, quarter, members, status)`,
|
||
`make_lock`, `make_confirmed_osv(entity, account, year, quarter, cumulative, rows)`; `repositories/consolidations.py`:
|
||
`get_version(scope)`, `list_periods(group)`, `lock_version`, `lock_versions_for_entity(entity_id, statuses)`, `active_lock`,
|
||
`members`, `bound_documents`, `load_osv_rows`, `history`; `CommittedJobs.cleanup()` знает таблицы консолидации.
|
||
|
||
## 2. Версии, периметр, блокировка, статусы
|
||
|
||
- [x] 2.1 **Создание, список, карточка.** `schemas/consolidations.py` (D-16), `services/consolidations.py:create/list_periods/card`,
|
||
`domain/consolidation_periods.py:reporting_date`, эндпоинты `POST /consolidations`, `GET /company-groups/{id}/consolidations`,
|
||
`GET /consolidations/versions/{id}`, роутер. Тесты: сценарии `consolidations-api` «Создание», «Список и карточка», policy 404.
|
||
- [x] 2.2 **Статусы и политика.** `domain/policy.py:IN_WORK_STATUSES, ensure_version_editable`; `services/consolidation_status.py:
|
||
transition(version, to, by, comment, *, manual)` с таблицей Среза 4; `POST …/status`. Тесты: `CANCELLED` с/без комментария,
|
||
возврат в `INITIATED`, `TRANSITION_NOT_ALLOWED`, `VERSION_NOT_EDITABLE`, `LOCK_REQUIRED`.
|
||
- [x] 2.3 **Блокировка.** `services/consolidation_locks.py:take/release`, `POST/DELETE …/lock`, `IntegrityError` → `LOCKED_BY_OTHER`.
|
||
Тесты: сценарии «Взять в работу», гонка двух `POST` (`test_api_constraint_races`), `CANCELLED` снимает блокировку.
|
||
- [x] 2.4 **Периметр.** `PUT …/members` с подхватом/отвязкой (вызывает 3.1), `MEMBERSHIP_CHANGE`. Тесты: сценарии «Периметр версии».
|
||
|
||
## 3. Привязка документов и чек-лист
|
||
|
||
- [x] 3.1 **Привязка.** `services/consolidation_documents.py:fits(document, version)`, `bind_confirmed(version, entity_ids)`,
|
||
`unbind_entity`, `on_document_confirmed(document, user)`, `on_file_superseded(file, documents)`; правки
|
||
`DocumentService.confirm` (версии `FOR UPDATE` после документа), `supersede_previous` (`unbound_version_ids` в аудите).
|
||
Тесты: сценарии `documents-api` (привязка, период, `CANCELLED`, подхват, две версии документа), `primary-files`
|
||
«Заменённый документ был в версии», порядок блокировок (подтверждение ∥ правка периметра).
|
||
- [x] 3.2 **Статусы по событиям файлов.** `upload.py`: `consolidation_version_id` (проверки, переход после приёма);
|
||
`result_mapping`: хук `on_documents_mapped` (NEEDS_CHECK → `DATA_CORRECTION`, `uploaded_by`, пропуск при NULL).
|
||
Тесты: сценарии `primary-files` «Загрузка в контексте версии», `osv-result-mapping` «Предупреждение маппинга».
|
||
- [ ] 3.3 **Чек-лист.** `domain/checklist.py:build(rules, members, documents, files)` (чистая), `GET …/checklist`, ячейки в карточке.
|
||
Тесты: пробел Q2, субсчёт, `PROCESSING`, `ERROR`, ББ/ОФР за квартал версии.
|
||
|
||
## 4. Сводная ОСВ
|
||
|
||
- [ ] 4.1 **Домен.** `domain/consolidation_periods.py:select_sources` (нарастающий/квартальные/пробел), `domain/consolidated_osv.py:
|
||
build(...)` (склейка по ключу, нули, дубли, `entry_ids`, `warnings`, дорезолв, признак, фильтры, порядок). Тесты без БД:
|
||
все сценарии «Выбор источников», «Строки свода», фильтры, версия за Q1, дубль ключа, расхождение `counterparty_id`.
|
||
- [ ] 4.2 **API свода.** `services/consolidated_osv.py:page/summary`, `GET …/osv`, `GET …/osv/summary`. Тесты: страница на
|
||
PostgreSQL с тремя кварталами, `unmapped`, `match_kind`, `q`, чтение `CANCELLED`, `curator_go` читает.
|
||
- [ ] 4.3 **Кандидаты и сопоставление.** `GET …/counterparty-candidates`, `POST …/osv/entries/{id}/counterparty`
|
||
(`services/counterparty_mapping.py`: алиас, `ALIAS_TAKEN`, перенос, `MANUAL`/`PROPAGATED`, ИНН-противоречие, аудит).
|
||
Тесты: все сценарии «Кандидаты», «Ручное сопоставление», блокировка/статус.
|
||
- [ ] 4.4 **Экспорт.** `services/osv_export.py` (openpyxl, два листа, `BytesIO`), `GET …/osv/export`, `Content-Disposition`,
|
||
аудит `EXPORT`. Тест: файл читается `openpyxl`, суммы равны API, лист «Пробелы».
|
||
|
||
## 5. Сквозной тест и документы
|
||
|
||
- [ ] 5.1 **Фикстуры РБ.** `tests/test_consolidation_fixtures.py` (маркер `fixtures`): маппинг golden-снимков ОСВ РБ и
|
||
Счастливочной за Q1–Q3 2024 → подтверждение → консолидация 2024 Q3 → свод: счета 60/62 у обеих и 76 у Счастливочной,
|
||
остальные в `gaps`; одно сопоставление «Пекарня Счастливочная ООО» → `GSK` у всех строк РБ с этим именем;
|
||
экспорт открывается.
|
||
- [ ] 5.2 **Документы.** README (консолидации, статусы Среза 4, свод, сопоставление, экспорт, коды ошибок), CLAUDE.md
|
||
(новые модули, порядок блокировок), `openspec` спеки; синхронизация с docs-change (OQ, §2/§3/§9).
|