feat(slice-4): консолидация — версии, периметр, блокировка, привязка документов, сводная ОСВ, экспорт xlsx #19
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/18-slice-4-consolidation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Срез 4 — консолидация: версии, периметр, блокировка, привязка документов, сводная ОСВ, экспорт xlsx. Closes #18.
Порядок мержа: сначала docs PR RSHB/arm-ka-docs#20 (DBML v5.16), затем этот:
Makefileссылается наdata-model-v5.16.dbml,make dbml-checkв основном checkout упадёт, пока docs не смержен.Что внутри
osv_entry.counterparty_match_kind(INN/NAME/ALIAS/MANUAL/PROPAGATED), миграция 0004 с backfill; маппинг пишет шаг резолва.POST /consolidations, список по ГК с деревом версий, карточка версии,PUT …/members,POST/DELETE …/lockс перехватом по причине,POST …/status(CANCELLED, возврат в INITIATED),GET …/checklist.consolidation_documentпри подтверждении, подхват при создании версии и расширении периметра, отвязка при автозамене; переходы INITIATED → DOCUMENTS_PROCESSING (загрузка сconsolidation_version_id) → DATA_CORRECTION (NEEDS_CHECK при маппинге, подтверждение).domain/consolidated_osv.py): выбор источников, склейка кварталов, пробелы, признак ГСК/ГК/Внешний, дорезолв на чтение;GET …/osv,GET …/osv/summary,GET …/counterparty-candidates,POST …/osv/entries/{id}/counterparty(алиас, перенос, автоприменение),GET …/osv/export(xlsx, два листа).openspec/changes/slice-4-consolidation/(design #1–#85), ledgerdocs/superpowers/plans/2026-10-06-slice-4-consolidation-ledger.md.Прогоны
make check-fullна98922cc— EXIT 0: unit 1106, integration 670, fixtures 14 passed + 1 skipped (e2e без профиля services), dbml-check v5.16, docker build, web-check. На HEAD42c2531: unit 1106, integration 677. Финальное ревью (opus): Critical нет, Important I-1 исправлена (42c2531).Rulings I made
lock_versions_for_entityблокирует надмножество версий; создание версии берёт advisory-lock по ГК; порядок файл → документ → advisory ГК → версииlock_document/lock_file_documents→FOR NO KEY UPDATEFOR UPDATEдавал взаимоблокировкуResolutionвdomain/osv_mapping.pyEntityFilesState— Task 2,unconfirmed_documents— Task 8counterparty_match_kindпоследняя колонка в ORM и DBMLADD COLUMNкладёт в конецNOT_FOUND, идентификатор — в текстеin_work_onlyубирает пустые периоды; невидимая ГК/ГСК → 404; чужая ГСК или gsz → 422RELATED_GROUP_MISMATCHcounterparty_id; на подтверждение владельцу (OQ-126)entity_namesубран изbuild_workbookunmapped_totalпадает на число строк сводаpropagatedсчитаетosv_entry, свод склеивает кварталыDeferred (в follow-up issue при закрытии)
T1.1, T2.1–T2.6, T5.2–T5.3, T6.1 (вынос
transitionв листовой модуль), T7 (N+1 в хуке маппинга), T8.3, T9.b (версия Q1, OQ-125), T9.c–T9.d, T10.1 (IN(ids)против лимита параметров), T10.2–T10.3, T11.3 (aliases.removeбез блокировки), T11.4–T11.7, M-4 (тест advisory-блокировки алиаса), M-6 (границы входов,FOR UPDATEдо проверки видимости), M-7 (общиеosv_entryдля версий не «в работе», до Среза 7, OQ-123), design #85 (OpenAPI без доменных 422-кодов).🤖 Generated with Claude Code
https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
POST /consolidations (версия №1 INITIATED, периметр из текущих членов ГСК, история, CONSOLIDATION_CREATE с consolidation_version_id), GET /company-groups/{id}/consolidations и GET /consolidations/versions/{id}. reporting_date по OQ-40; подхват документов — заглушка bind_confirmed до Task 6, чек-лист в карточке пуст до Task 8. UNIQUE периода -> 409 CONSOLIDATION_EXISTS; RequestAudit.record принимает consolidation_version_id. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2PUT /consolidations/versions/{id}/members: замена состава ЮЛ версии, проверка принадлежности ГК (ENTITY_NOT_IN_GROUP), минимум два ЮЛ, diff с отвязкой документов ушедших (unbind_entity) и подхватом добавленных (bind_confirmed, заглушка до Task 6), аудит MEMBERSHIP_CHANGE. Общий пролог «lock → видимость → редактируемость» вынесен в services/consolidation_guard.py (T4.2). Решения #25–#29. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2T7.0: двухсессионный тест маппинг ∥ перевод версии в DOCUMENTS_PROCESSING (ловит мутант statuses={DOCUMENTS_PROCESSING}). T7.1 (R-10, design №43): ошибка перехода после загрузки логируется, принятые файлы и 201 сохраняются. T7.3: лог пропуска без uploaded_by только при наличии NEEDS_CHECK. T7.4: TransactionFactory импортируется из session_audit. T7.2/T7.5: дополнена строка design №39. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2Домен `checklist` (Rule, CellStatus, Cell, order_rules, build) — чистые функции без ORM; ячейка (ЮЛ, правило): CONFIRMED по привязанным документам (ОСВ: нарастающий за квартал версии либо квартальные Q1..Qn, пробел → missing_quarters; ББ/ОФР: документ за квартал версии), NEEDS_CHECK/RECOGNIZED по неподтверждённому подходящему, PROCESSING, ERROR, иначе MISSING; правило ОСВ закрывает только точный код счёта. Репозиторий: rules_for, unconfirmed_documents. Сервис: checklist(), ячейки в карточке версии. Маршрут GET /consolidations/versions/{id}/checklist. Схема использует CellStatus домена (T2.8). Решения №44-49 в design.md. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2GET /consolidations/versions/{id}/osv и /osv/summary (CONSOLIDATION_VIEW): ConsolidatedOsvService собирает свод чистой функцией от версии (периметр, привязанные ОСВ, load_osv_rows, один CounterpartyIndex, один SELECT legal_entity) и режет страницу в памяти; чтение любой версии, включая CANCELLED, без блокировок и аудита. OsvFilters отделён от OsvPageParams (T2.7), суммы всегда с двумя знаками; account_sort_key устойчив к «6²»/«①» (T9.a). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2GET …/counterparty-candidates (scope group|all, QUERY_TOO_SHORT, recommended по нормализованному имени строки) и POST …/osv/entries/{entry_id}/counterparty: проверка строки свода версии, ЮЛ без policy, ALIAS_TAKEN с owners / перенос алиаса, MANUAL строке и PROPAGATED строкам с тем же strip()-именем без противоречия ИНН, один OSV_COUNTERPARTY_MAP и LEGAL_ENTITY_CHANGE на каждый алиас. Строки общие для версий блокируются FOR NO KEY UPDATE ORDER BY id; advisory-блокировка алиаса общая со справочником. Решения #62–#70 в design.md; 4.3 отмечена. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2GET /consolidations/versions/{id}/osv/export: лист «Сводная ОСВ» (15 колонок D-14, суммы — числовые ячейки #,##0.00 из Decimal) и лист «Пробелы» по своду целиком; фильтры как у GET …/osv без пагинации; Content-Disposition с filename* (чистый ASCII); audit_event(EXPORT) с filters и rows. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2spec(slice-4): OpenSpec change консолидации (ревью спеки)to feat(slice-4): консолидация — версии, периметр, блокировка, привязка документов, сводная ОСВ, экспорт xlsx