arm-ka-docs/docs/superpowers/plans/2026-10-09-console-files-docs.md
Andrey Epifancev 1cf067cd8b plan: console-files — план для репозитория docs (#90)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 23:10:32 +04:00

46 KiB
Raw Blame History

Файлы в контексте консолидации — план для репозитория docs

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Поднять модель данных до v5.18 (stored_file.consolidation_id) и привести документы контекста, правила домена, гайды API/QA и открытые вопросы к решениям владельца 09.10.2026 о загрузке файлов в консолидацию.

Architecture: Только документы: новая версия DBML и entities копированием предыдущей с правкой, замена ссылок v5.17 → v5.18, правка §9.5 и §9.1 правил, гайдов и QA-сценариев под новые маршруты /consolidations/{cid}/legal-entities/{le}/files. Кода нет; код — дочерние планы arm-core и arm-web.

Tech Stack: Markdown, DBML, make check репозитория docs (validate-contracts, validate-openspec, test-snapshot), make diagrams (Node/npx), git, tea.

Spec: openspec/changes/console-files/ (proposal.md, design.md) в этом репозитории.

Global Constraints

  • Работать только в worktree /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs, ветка feat/90-console-files; git-команды — git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs ….
  • Язык документов и коммитов — русский; идентификаторы — как в DBML (английские).
  • docs/source/** не редактировать.
  • Нумерацию версий DBML задним числом не менять: новая версия — v5.18, файлы v5.17 остаются как история.
  • Имя колонки — ровно consolidation_id (nullable, FK → consolidation.id); индекс — (legal_entity_id, consolidation_id).
  • Маршруты — ровно POST /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files и GET /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files; query consolidation_version_id у POST /legal-entities/{id}/files удаляется.
  • Коды ошибок загрузки в консоль: 404 NOT_FOUND, 409 CONSOLIDATION_NOT_EDITABLE, 422 ENTITY_NOT_IN_PERIMETER.
  • Каждый коммит заканчивается строкой Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>.

Review Focus

  1. Файл, загруженный без контекста и подтверждённый, подхвачен версией — он должен быть описан как часть рабочего стола (BOUND), иначе читатель §9.5 решит, что стол — только consolidation_id. Проверяется grep'ом в Task 3.
  2. Файл SUPERSEDED на рабочем столе — скрыт по умолчанию, виден при include_superseded=true; формулировка должна быть одинаковой в §9.5, гайде фронта и контракте. Проверяется grep'ом в Task 4.
  3. Переход INITIATED → DOCUMENTS_PROCESSING теперь у всех версий консоли «в работе» с ЮЛ в периметре — таблица §9.1 и п. 8 §9.5 не должны говорить «версия» в единственном числе. Проверяется в Task 3.
  4. Решение владельца 07.10.2026 «фильтра файлов ЮЛ в контексте версии нет и не будет» (гайд фронта) пересмотрено 09.10.2026: строка не удаляется, а зачёркивается со ссылкой. Проверяется в Task 4.
  5. QA-сценарии, где consolidation_version_id=V использовался только ради перехода статуса (U17, K8, 7.1), должны стать загрузкой в консоль $C — иначе гайд описывает удалённый параметр. Проверяется grep'ом в Task 5.

Task 1: DBML v5.18

Files:

  • Create: model/data-model-v5.18.dbml (копия model/data-model-v5.17.dbml с правками)
  • Modify: Makefile (переменная DBML)
  • Modify: model/diagrams/part04_files_jobs.{svg,png}, part07_consolidation.{svg,png} — перерисовка make diagrams

Interfaces:

  • Produces: файл model/data-model-v5.18.dbml — его читают Task 2 (entities) и дочерний план arm-core (make dbml-check).

  • Step 1: Скопировать модель

cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
cp model/data-model-v5.17.dbml model/data-model-v5.18.dbml
  • Step 2: Шапка и changelog

В model/data-model-v5.18.dbml первую строку заменить на:

// ДКБ · Модель данных v5.18: справочники, файлы/распознавание, консолидация, КФО, аудит, ЕХФД

После строки // страница аналитики (md); экран макета dkb_24.09.26; версия модели, в которой таблица появилась (v4 = исходная DBML аналитики). и пустой // вставить перед блоком // v5.17 (…):

// v5.18 (решения владельца 09.10.2026; RSHB/arm-ka-docs#90, openspec/changes/console-files):
//   1. stored_file.consolidation_id (uuid, nullable, FK → consolidation): консолидация (ГК + год + квартал), в контексте
//      которой загружен файл, — «рабочий стол консоли», общий для всех версий периода. NULL — загрузка без контекста
//      (страница ЮЛ, монозаёмщики, API). Пишется один раз при загрузке (POST /consolidations/{id}/legal-entities/{le}/files);
//      при автозамене новый файл без контекста наследует consolidation_id заменённого. Индекс (legal_entity_id, consolidation_id).
//      Что использует конкретная версия, по-прежнему определяет consolidation_document; заморозка после VERIFIED — привязки и ex_snapshot.
//      Миграция 0006 arm-core: backfill по consolidation_document (при нескольких периодах — самый ранний).
//   2. Note recognition_job.reply_deadline: срок ответа OCR — 20 мин (OQ-159, решение владельца 09.10.2026), структура не меняется.
//
  • Step 3: Колонка и индекс stored_file

В блоке Table stored_file { после строки legal_entity_id uuid [not null, ref: > legal_entity.id, note: 'организация-владелец (выбрана при загрузке)'] добавить:

  consolidation_id           uuid           [ref: > consolidation.id, note: 'v5.18: консолидация (период ГК), в контексте которой загружен файл — «рабочий стол консоли», общий для всех версий периода; NULL — без контекста. Пишется при загрузке; при автозамене файл без контекста наследует значение заменённого']

В Indexes { того же блока после (legal_entity_id, status) добавить строку:

    (legal_entity_id, consolidation_id) [note: 'v5.18: рабочий стол консоли для ЮЛ']

Note таблицы stored_file (строка Note: 'v5.13: физический файл одной загрузки …') дополнить в конце перед закрывающей кавычкой: . v5.18: consolidation_id — где загружен; что использует версия — consolidation_document.

  • Step 4: Note consolidation и reply_deadline

В блоке Table consolidation { строку Note: 'Логическая консолидация ГК за период; версии различаются периметром (consolidation_member). Прошлые периоды — по company_group_id' заменить на:

  Note: 'Логическая консолидация ГК за период; версии различаются периметром (consolidation_member). Прошлые периоды — по company_group_id. v5.18: файлы, загруженные в консолидацию, — stored_file.consolidation_id (рабочий стол, общий для версий периода)'

Найти в Table recognition_job колонку reply_deadline и в её note заменить OCR — 5 мин на OCR — 20 мин (OQ-159). Проверить: grep -n "reply_deadline" model/data-model-v5.18.dbml — в note нет «5 мин».

  • Step 5: Makefile и диаграммы

В Makefile строку DBML ?= model/data-model-v5.17.dbml заменить на DBML ?= model/data-model-v5.18.dbml. Затем:

cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs && make diagrams 2>&1 | tail -5
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs status --short model/diagrams | head

Ожидание: изменились part04_files_jobs.* (новая колонка и FK) и part07_consolidation.*; остальные могут перерисоваться без смысловых изменений — это допустимо. Если make diagrams падает из-за окружения (нет сети для npx), не чинить: записать в итоговый отчёт «диаграммы не перерисованы», шаг не блокирует.

  • Step 6: Проверка
cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
diff <(sed -n '/^Table stored_file {/,/^}/p' model/data-model-v5.17.dbml) <(sed -n '/^Table stored_file {/,/^}/p' model/data-model-v5.18.dbml)
grep -c "v5.18" model/data-model-v5.18.dbml

Ожидание: diff показывает ровно добавленную колонку, индекс и хвост Note; счётчик ≥ 5.

  • Step 7: Коммит
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs add Makefile model/data-model-v5.18.dbml model/diagrams
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs commit -q -m "$(cat <<'EOF'
model: DBML v5.18 — stored_file.consolidation_id, рабочий стол консоли (#90)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
EOF
)"

Task 2: entities v5.18 и ссылки на версию модели

Files:

  • Create: model/entities-v5.18.md (копия model/entities-v5.17.md с правками)
  • Modify: context/04-data-model-guide.md, context/08-source-docs-index.md, context/00-workspace-layout.md, context/03-architecture.md, context/06-test-data.md, context/KICKOFF-PROMPT.md, dev/checks.md, repo-templates/arm-core.CLAUDE.md, /Users/andrey.epifancev/projects/awp-ca/CLAUDE.md (вне git — workspace)

Interfaces:

  • Consumes: model/data-model-v5.18.dbml (Task 1).

  • Step 1: Скопировать и переписать шапку entities

cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
cp model/entities-v5.17.md model/entities-v5.18.md

В model/entities-v5.18.md:

  • заголовок → # АРМ КА — описание сущностей модели данных v5.18;
  • строку 3 (Источник истины по структуре — \data-model-v5.17.dbml` …`) заменить на:
Источник истины по структуре — `data-model-v5.18.dbml` (полный). Диаграммы по частям — `diagrams/` (part01…09 svg/png; перерисовываются `make diagrams` из текущего DBML). Здесь — что каждая таблица значит для бизнеса, как связана с соседями и откуда взялась.
  • перед разделом ## Что изменилось в v5.17 … вставить:
## Что изменилось в v5.18 (решения владельца 09.10.2026, RSHB/arm-ka-docs#90)

| № | Изменение | Решение |
|---|---|---|
| 1 | `stored_file.consolidation_id` (`uuid`, nullable, FK → `consolidation`) + индекс `(legal_entity_id, consolidation_id)` | Файл загружается **в консолидацию** (период ГК) и становится частью её «рабочего стола», общего для всех версий периода; `NULL` — загрузка без контекста (страница ЮЛ, монозаёмщики, API). Панель «Первичные документы» в версии показывает рабочий стол консоли для ЮЛ плюс файлы с документами, привязанными к версиям консоли. Что использует конкретная версия — по-прежнему `consolidation_document`; заморозка после `VERIFIED` — привязки и `ex_snapshot`. Привязка файла к **версии** (`consolidation_file`) отвергнута: рабочие версии периода делят первичку, а новая версия после `VERIFIED` подхватывает подтверждённое (`openspec/changes/console-files/design.md`) |
| 2 | Note `recognition_job.reply_deadline` | Без изменения структуры: срок ответа OCR — 20 мин (OQ-159) |

Остальные таблицы и enum — как в v5.17. Реализация — миграция `0006` в `arm-core` (backfill `consolidation_id` по `consolidation_document`).

  • Step 2: Строки таблиц stored_file и consolidation

В таблице части 04 строку | \stored_file` | v5.13: только физический файл …` заменить на:

| `stored_file` | **v5.13: только физический файл** одной загрузки: чей (ЮЛ), формат, hash, кто/когда загрузил, статус обработки (`UPLOADED → PROCESSING → PROCESSED / ERROR / SUPERSEDED`), версия при замене. **v5.18:** `consolidation_id` — консолидация, в контексте которой файл загружен («рабочий стол консоли», общий для версий периода; `NULL` — без контекста). Что внутри файла — `document`. Замена — файл целиком со всеми документами. | → `legal_entity`, `consolidation`, `s3_object`, `recognition_job`; ← `document`, `recognition_job` | ТЗ 6.2, 8.2; UC-01…05 |

Строку | \consolidation` | Логическая консолидация: ГК + отчётный период. …` заменить на:

| `consolidation` | Логическая консолидация: **ГК** + отчётный период. ГСК фиксируется/создаётся при верификации по фактическому периметру. Уникальна по (ГК, год, квартал). **v5.18:** файлы, загруженные в консолидацию, — `stored_file.consolidation_id` (рабочий стол, общий для версий периода). | → `company_group`, `related_group`; ← `consolidation_version`, `stored_file` | ТЗ 6.10, 7.2 |
  • Step 3: Ссылки v5.17 → v5.18 в документах
cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
for f in context/00-workspace-layout.md context/03-architecture.md context/08-source-docs-index.md context/KICKOFF-PROMPT.md dev/checks.md repo-templates/arm-core.CLAUDE.md; do
  sed -i '' -e 's/data-model-v5\.17\.dbml/data-model-v5.18.dbml/g' -e 's/entities-v5\.17\.md/entities-v5.18.md/g' -e 's/DBML v5\.17/DBML v5.18/g' "$f"
done
sed -i '' -e 's/data-model-v5\.17\.dbml/data-model-v5.18.dbml/g' -e 's/entities-v5\.17\.md/entities-v5.18.md/g' -e 's/приведённая к именам v5\.17/приведённая к именам v5.18/' -e 's/(v5\.14–v5\.17 имена не меняли)/(v5.14–v5.18 имена не меняли)/' /Users/andrey.epifancev/projects/awp-ca/CLAUDE.md
grep -n "v5\.17" context/00-workspace-layout.md context/03-architecture.md context/08-source-docs-index.md context/KICKOFF-PROMPT.md dev/checks.md repo-templates/arm-core.CLAUDE.md /Users/andrey.epifancev/projects/awp-ca/CLAUDE.md

Ожидание: grep пуст, кроме исторических упоминаний (в 08-source-docs-index.md строка про changelog v5.1…v5.17 → вручную заменить на v5.1…v5.18; в 06-test-data.md строка «с v5.17 диаграммы перерисовываются» — история, оставить). 08-source-docs-index.md строка | \diagrams/part01…09.{svg,png}` | диаграммы v5.17 по частям …→v5.18`.

  • Step 4: 04-data-model-guide.md

  • Заголовок → # 04. Как читать модель данных v5.18.

  • Строки 3–5: data-model-v5.17.dbml → data-model-v5.18.dbml, entities-v5.17.md → entities-v5.18.md, v5.13…v5.16 → v5.13…v5.17 (оба упоминания), «диаграммы v5.17» → «диаграммы v5.18».

  • Строку 61 (… v5.17 — тоже (колонка \legal_entity.kpp`), поэтому таблица справедлива и для v5.14…v5.17.) дополнить: , v5.18 — тоже (колонка `stored_file.consolidation_id`), поэтому таблица справедлива и для v5.14…v5.18.(заменив хвости для v5.14…v5.17.`).

  • Заголовок таблицы строки 63: | В v5.13 / v5.14 / v5.15 / v5.16 / v5.17 | → | В v5.13 / v5.14 / v5.15 / v5.16 / v5.17 / v5.18 |.

  • В разделе про файлы (где описан stored_file ↔ document, найти grep -n "stored_file" context/04-data-model-guide.md) добавить предложение: «v5.18: stored_file.consolidation_id — в какую консолидацию (период ГК) загружен файл; это рабочий стол консоли, общий для её версий. Что использует версия — consolidation_document.»

Проверка: grep -n "v5\.17" context/04-data-model-guide.md — только исторические упоминания (список версий, «введён в v5.17»).

  • Step 5: Коммит
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs add model/entities-v5.18.md context dev/checks.md repo-templates
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs commit -q -m "$(cat <<'EOF'
docs: entities v5.18 и ссылки на модель v5.18 (#90)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
EOF
)"

Task 3: Правила домена §9.1 и §9.5

Files:

  • Modify: context/05-domain-rules.md (§9.1 таблица переходов, §9.5 п. 1, 3, 8; новый п. 11)

Interfaces:

  • Produces: формулировки, на которые ссылаются спеки arm-core (primary-files, documents-api) в дочернем плане.

  • Step 1: §9.1 — переход при загрузке

Строку | загрузка файла с \consolidation_version_id`, принят ≥ 1 файл | INITIATED → DOCUMENTS_PROCESSING | загрузивший |` заменить на:

| загрузка файла в консолидацию (`POST /consolidations/{id}/legal-entities/{le}/files`), принят ≥ 1 файл | INITIATED → DOCUMENTS_PROCESSING у **каждой** версии консолидации «в работе», где ЮЛ в периметре | загрузивший |
  • Step 2: §9.5 п. 1 — два маршрута загрузки

В п. 1 заменить начало 1. **Загрузка** (\POST /legal-entities/{id}/files`, право `DOCUMENT_EDIT`, ЮЛ в видимости):` на:

1. **Загрузка** (`POST /legal-entities/{id}/files` — без контекста, `stored_file.consolidation_id = NULL`; в консолидацию —
   п. 8; право `DOCUMENT_EDIT`, ЮЛ в видимости):
  • Step 3: §9.5 п. 3 — наследование при автозамене

В п. 3 после предложения … \version_no` нового = максимум заменённых + 1.` добавить:

Новый файл без контекста (`consolidation_id IS NULL`) наследует `consolidation_id` первого (по `id`) заменённого файла, у
которого он задан; файл, загруженный в консолидацию, сохраняет свою (v5.18).
  • Step 4: §9.5 п. 8 — загрузка в консолидацию

Пункт 8 целиком заменить на:

8. **Загрузка в консолидацию** (`POST /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files`,
   `DOCUMENT_EDIT`; v5.18, решения владельца 09.10.2026, RSHB/arm-ka-docs#90): до приёма — консолидация видима (404
   `NOT_FOUND`), ЮЛ видимо (404), есть версия консолидации «в работе» (409 `CONSOLIDATION_NOT_EDITABLE`), ЮЛ — член
   периметра хотя бы одной такой версии (422 `ENTITY_NOT_IN_PERIMETER`). Принятый файл получает
   `stored_file.consolidation_id`; `FILE_UPLOAD.after_value.consolidation_id`. После приёма хотя бы одного файла, отдельной
   транзакцией, каждая версия консолидации «в работе» с этим ЮЛ в периметре и статусом INITIATED переходит в
   DOCUMENTS_PROCESSING (§9.1; версии блокируются `FOR UPDATE` по возрастанию `id`, статус перечитывается); сбой перехода не
   отменяет принятые файлы. Блокировка версии для загрузки не нужна. Query `consolidation_version_id` у
   `POST /legal-entities/{id}/files` (Срез 4) удалён.
  • Step 5: §9.5 новый п. 11 — рабочий стол консоли

После п. 10 добавить:

11. **Рабочий стол консоли** (`GET /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files`,
    `DOCUMENT_VIEW`; 404 на невидимые консолидацию или ЮЛ; `limit`, `offset`, `include_superseded`): файлы ЮЛ с
    `consolidation_id` этой консолидации **плюс** файлы ЮЛ, у которых есть документ, привязанный (`consolidation_document`)
    к любой версии этой консолидации (подхваченные ОСВ за `Q1` и файлы, загруженные без контекста); новые первыми
    (`uploaded_at` desc, `id`); `SUPERSEDED` — только при `include_superseded=true`. Карточка файла та же, что в
    `GET /legal-entities/{id}/files` (`FileOut` + `consolidation_id`). Рабочие версии одного периода видят один стол;
    верифицированная версия заморожена привязками и `ex_snapshot` (Срез 7), отдельного «замороженного списка» в панели
    нет. Панель [39] из карточки версии показывает стол консоли; переключатель «Все документы организации» —
    `GET /legal-entities/{id}/files` с подписью консолидации у файла.
  • Step 6: Проверка
cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
grep -n "consolidation_version_id" context/05-domain-rules.md
grep -n "каждой\* версии\|каждая версия консолидации" context/05-domain-rules.md
grep -n "привязанный (\`consolidation_document\`)\|привязанный (.consolidation_document.)" context/05-domain-rules.md

Ожидание: первый grep — только исторические упоминания (строка про Срез 4 в п. 8 «удалён» и §3/OQ, если есть) — ни одного описания действующего параметра; второй и третий — по одной строке.

  • Step 7: Коммит
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs add context/05-domain-rules.md
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs commit -q -m "$(cat <<'EOF'
rules: §9.1/§9.5 — загрузка в консолидацию и рабочий стол консоли (#90)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
EOF
)"

Task 4: Гайд фронта, контракты API, пользовательский путь

Files:

  • Modify: dev/frontend-api-guide.md (changelog, §5.5, таблица экранов), dev/api-contract-files-directories.md, dev/api-contract-slice-4.md, context/10-user-journey.md (п. 2.5), mockup/INDEX.md (строка 39)

Interfaces:

  • Consumes: формулировки §9.5 п. 8 и 11 (Task 3).

  • Step 1: Changelog гайда фронта

В dev/frontend-api-guide.md сразу после строки |---|---|---| таблицы «Когда, PR | Что изменилось в API | Что сделать в клиенте» (строка 31) вставить:

| 09.10, docs #90 (DBML v5.18; arm-core и arm-web — дочерние PR) | **Файлы в контексте консолидации.** Новые маршруты `POST /consolidations/{cid}/legal-entities/{le}/files` (загрузка в консоль: 404; 409 `CONSOLIDATION_NOT_EDITABLE` — нет версии «в работе»; 422 `ENTITY_NOT_IN_PERIMETER`) и `GET /consolidations/{cid}/legal-entities/{le}/files` (рабочий стол консоли для ЮЛ: файлы консоли + файлы с документами, привязанными к её версиям; `include_superseded`). Query `consolidation_version_id` у `POST /legal-entities/{id}/files` **удалён**; `FileOut.consolidation_id: uuid \| null`. Отменяет решение 07.10 «фильтра файлов ЮЛ в контексте версии нет» | панель [39] — стол консоли (`current_consolidation_id` из строки списка `con_id` / карточки версии `consolidation_id`), переключатель «Все документы организации» → `GET /legal-entities/{id}/files` с подписью консолидации у файла; загрузка [40] — новым маршрутом, кнопка недоступна, если версия не «в работе» |

Строку | 07.10, решение владельца | Фильтра «файлы ЮЛ в контексте версии» нет и не будет | drawer [39] показывает все файлы ЮЛ; подходящесть — по \document_ids` ячеек чек-листа |` заменить на:

| 07.10, решение владельца | ~~Фильтра «файлы ЮЛ в контексте версии» нет и не будет~~ (пересмотрено 09.10, см. docs #90 выше) | ~~drawer [39] показывает все файлы ЮЛ~~; подходящесть документа версии — по-прежнему по `document_ids` ячеек чек-листа |
  • Step 2: §5.5 гайда фронта

В таблице §5.5 строку | \POST /legal-entities/{legal_entity_id}/files` | EDIT | multipart, поле `files` повторяется на каждый файл (не `files[]`); query `consolidation_version_id?` | … |` заменить на две строки:

| `POST /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files` | EDIT | multipart, поле **`files`** повторяется на каждый файл (не `files[]`) — загрузка **в консолидацию** (панель [40] внутри версии) | 201 `UploadResult {accepted[] {file_id, job_id, name}, rejected[] {name, code, message, file_id?}}`, если принят ≥ 1 файл; **422 тем же телом**, если ни одного | 404 (консолидация или ЮЛ), 409 `CONSOLIDATION_NOT_EDITABLE` (нет версии «в работе»), 422 `ENTITY_NOT_IN_PERIMETER` (объектом `detail`), 503 `STORAGE_UNAVAILABLE` |
| `POST /legal-entities/{legal_entity_id}/files` | EDIT | то же, **без контекста** (страница ЮЛ, монозаёмщики): `consolidation_id = null` | как выше | 404, 503 `STORAGE_UNAVAILABLE` |

После строки | \GET /legal-entities/{legal_entity_id}/files` | VIEW | … |` добавить:

| `GET /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files` | VIEW | `limit`, `offset`, `include_superseded` | `Page[FileOut]` — **рабочий стол консоли** для ЮЛ: файлы с этим `consolidation_id` плюс файлы, чьи документы привязаны к любой версии консолидации; новые первыми | 404 |

В списке «Загрузка:» пункт - С \consolidation_version_id` версия должна быть видима, «в работе» и содержать ЮЛ; первый принятый файл переводит версию `INITIATED` → `DOCUMENTS_PROCESSING`. Блокировка версии для загрузки не нужна.` заменить на:

- Загрузка в консолидацию: консолидация видима, есть версия «в работе», ЮЛ в её периметре; первый принятый файл переводит
  **каждую** версию консолидации «в работе» с этим ЮЛ из `INITIATED` в `DOCUMENTS_PROCESSING`. Блокировка версии для загрузки
  **не нужна**. `FileOut.consolidation_id` — куда загружен файл (`null` — без контекста).

В таблице экранов строки [39] и [40] заменить на:

| [39] Первичные документы ЮЛ | `GET /consolidations/{cid}/legal-entities/{id}/files` (+ опрос при `UPLOADED`/`PROCESSING`); переключатель «Все документы организации» — `GET /legal-entities/{id}/files`, подпись консолидации у файла по `consolidation_id` (год и квартал — из списка консолидаций ГК, `null` — «вне консолидации»); «Загрузил» — `GET /users/brief?ids=…`; удалить — `DELETE /files/{id}` |
| [40] Загрузить документы | `POST /consolidations/{cid}/legal-entities/{id}/files` → показать `accepted`/`rejected` → опрос списка; кнопка недоступна, если версия не «в работе» |
  • Step 3: Контракты

dev/api-contract-files-directories.md, таблица §2: строку GET /legal-entities/{legal_entity_id}/files оставить, после неё добавить:

| `GET /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files` | VIEW | query `limit`, `offset`, `include_superseded` | `Page[FileOut]` — рабочий стол консоли для ЮЛ (файлы с этим `consolidation_id` + файлы с документами, привязанными к версиям консолидации), новые первыми | 404 | [39] drawer внутри версии (v5.18, docs #90) |

Строку POST /legal-entities/{legal_entity_id}/files заменить на две:

| `POST /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files` | EDIT | multipart, поле `files` (повторяется) — загрузка в консолидацию | 201 `UploadResult` (принят хотя бы один файл) / 422 `UploadResult` (ни один) | 404 (консолидация, ЮЛ), 409 `CONSOLIDATION_NOT_EDITABLE`, 422 `ENTITY_NOT_IN_PERIMETER`, 503 `STORAGE_UNAVAILABLE` | [40] |
| `POST /legal-entities/{legal_entity_id}/files` | EDIT | multipart, поле `files` (повторяется) — без контекста (`consolidation_id = null`); query `consolidation_version_id` удалён (v5.18) | 201 / 422 `UploadResult` | 404, 503 `STORAGE_UNAVAILABLE` | страница ЮЛ, монозаёмщики |

В описании FileOut этого файла (найти grep -n "FileOut" dev/api-contract-files-directories.md) добавить поле consolidation_id: uuid | null с пояснением «консолидация, в которую загружен файл (v5.18)».

dev/api-contract-slice-4.md: строку | \POST /legal-entities/{legal_entity_id}/files?consolidation_version_id=` | …` заменить на:

| `POST /consolidations/{consolidation_id}/legal-entities/{legal_entity_id}/files` | `DOCUMENT_EDIT` | multipart `files` (v5.18, docs #90; прежний query `consolidation_version_id` у `POST /legal-entities/{id}/files` удалён) | как в Срезе 2c: 201/422 `{accepted[], rejected[]}` | 404 (консолидация или ЮЛ), 409 `CONSOLIDATION_NOT_EDITABLE`, 422 `ENTITY_NOT_IN_PERIMETER` | [39] / [40] |

и строку | [39]/[40] Документы организации | \GET /legal-entities/{id}/files` (все файлы ЮЛ, …` на:

| [39]/[40] Документы организации | `GET /consolidations/{cid}/legal-entities/{id}/files` (рабочий стол консоли; «Все документы организации» — `GET /legal-entities/{id}/files`; опрос во время распознавания — им же или `GET /files/{id}`; схема — `dev/api-contract-files-directories.md`), `POST /consolidations/{cid}/legal-entities/{id}/files` |
  • Step 4: Пользовательский путь и макет

context/10-user-journey.md строка п. 2.5: фрагмент **API:** загрузка — \POST /legal-entities/{id}/files?consolidation_version_id=`; документы и подтверждение — `/files`, `/documents` (Срез 2c); подтверждённый документ привязывается к версиям «в работе» автоматически` заменить на:

**API:** список — `GET /consolidations/{cid}/legal-entities/{id}/files` (рабочий стол консоли: файлы, загруженные в эту консолидацию, и файлы с документами, привязанными к её версиям; переключатель «Все документы организации» — `GET /legal-entities/{id}/files`, у файла подпись консолидации); загрузка — `POST /consolidations/{cid}/legal-entities/{id}/files` (только в версии «в работе»); документы и подтверждение — `/files`, `/documents` (Срез 2c); подтверждённый документ привязывается к версиям «в работе» автоматически (v5.18, docs #90)

mockup/INDEX.md, строка | \39` | Панель «Первичные документы» …: в колонке «В модели» (`stored_file`, `document.period_check/…`, `comment`) добавить stored_file.consolidation_idпервым элементом: ``stored_file(+consolidation_id`, v5.18: панель внутри версии показывает рабочий стол консоли) ``.

  • Step 5: Проверка
cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
grep -n "consolidation_version_id" dev/frontend-api-guide.md dev/api-contract-files-directories.md dev/api-contract-slice-4.md context/10-user-journey.md
grep -n "include_superseded" dev/frontend-api-guide.md dev/api-contract-files-directories.md context/05-domain-rules.md | grep -c "consolidations/{"

Ожидание: первый grep — только упоминания «удалён» и исторические (changelog, consolidation_lock, osv-маршруты); второй — ≥ 3 (стол описан с include_superseded во всех трёх документах).

  • Step 6: Коммит
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs add dev/frontend-api-guide.md dev/api-contract-files-directories.md dev/api-contract-slice-4.md context/10-user-journey.md mockup/INDEX.md
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs commit -q -m "$(cat <<'EOF'
dev: маршруты файлов консолидации в гайде фронта, контрактах и пути пользователя (#90)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
EOF
)"

Task 5: QA-гайд, открытые вопросы, план срезов, проверка и PR

Files:

  • Modify: dev/qa-guide.md (U17, 6.6, K8, 7.1, W17, 8.7), context/07-open-questions.md (OQ-159, новый OQ-160), context/09-delivery-plan.md (Срез 2d), openspec/changes/console-files/design.md (решение R-9)

  • Step 1: QA-гайд — curl и сценарии

В dev/qa-guide.md все вызовы вида localhost:8000/api/v1/legal-entities/$LE…/files?consolidation_version_id=$V заменить на localhost:8000/api/v1/consolidations/$C/legal-entities/$LE…/files (три места: блок в 6.6/7, два цикла в 7.1; $LE_RB, $LE_SCH сохраняются). Перед первым таким вызовом (блок команд раздела 7, строка с curl -s -X POST localhost:8000/api/v1/consolidations …) дополнить комментарий ответа: # 201: VersionCard; V = ответ.id, C = ответ.consolidation_id, status = INITIATED, reporting_date = 2024-10-01.

Строку U17: загрузить ОСВ ЮЛ с \consolidation_version_id=V`, где `V` в статусе «Корректировка данных»→загрузить ОСВ ЮЛ в консолидацию `C` (`POST /consolidations/$C/legal-entities/$LE/files`), у которой версия `V` в статусе «Корректировка данных»`.

Строку K8: загрузить ОСВ ЮЛ периметра с \?consolidation_version_id=V` (раздел 6.6)→загрузить ОСВ ЮЛ периметра в консолидацию `C` (раздел 6.6); в ожидании несуществующая версия — 404→несуществующая консолидация — 404; консолидация без версии «в работе» (после `CANCELLED`) — 409 `CONSOLIDATION_NOT_EDITABLE`; `GET /consolidations/$C/legal-entities/$LE/files` — загруженный файл в списке, `consolidation_id = C``.

Строку W17: без \consolidation_version_id`→без консолидации — маршрутом ЮЛ; в ожидании добавить в конец: ; в панели [39] версии этот файл виден только по переключателю «Все документы организации» с подписью «вне консолидации»`.

В 8.7 строку - Панель документов показывает первые 100 файлов ЮЛ; загрузка — только из панели ЮЛ внутри версии. → - Панель документов показывает первые 100 файлов рабочего стола консоли (или ЮЛ — по переключателю); загрузка — только из панели ЮЛ внутри версии «в работе».

Строку K17-примечания … во всех — \consolidation_version_id`.` не трогать (речь об аудите версий).

  • Step 2: Открытые вопросы

В context/07-open-questions.md в строке OQ-159 колонку статуса открыт: код и §9.4 — 20 мин; note DBML правится с ближайшей версией модели → **закрыт 09.10.2026:** note исправлен в DBML v5.18 (docs #90).

После строки OQ-159 добавить:

| OQ-160 | Целевая модель версий консолидации (владелец, 09.10.2026): несколько рабочих версий одного периода с **разным периметром** делят первичку (рабочий стол консоли, `stored_file.consolidation_id`); после `VERIFIED` новая версия (`previous_version_id`) может менять документы при **том же** периметре. Ядро сейчас создаёт только версию 1 (`POST /consolidations`), «новая версия» и параллельные версии не реализованы. Нужны правила: создание второй рабочей версии (обязательно другой периметр?), создание версии после `VERIFIED` (копия периметра, подхват привязок), что видит панель [39] у верифицированной версии до Среза 7 (ЕХ) | brainstorming docs #90, `openspec/changes/console-files/design.md` R-6, R-7 | срез «версии консолидации» (после Среза 4), Срез 7 | открыт: модель файлов совместима; реализация — отдельный срез |
  • Step 3: План срезов

В context/09-delivery-plan.md в разделе ### Срез 2d — UI «Первичные документы» после строки - Панель «Первичные документы», окно загрузки, таблица ОСВ с деревом строк и подсветкой нераспознанных контрагентов. добавить:

- **Доработка 09.10.2026 (docs #90, DBML v5.18):** файлы в контексте консолидации — `stored_file.consolidation_id`, маршруты
  `POST/GET /consolidations/{cid}/legal-entities/{le}/files`, панель [39] показывает рабочий стол консоли; спецификация —
  `openspec/changes/console-files/`; дочерние PR arm-core и arm-web. Целевая модель версий — OQ-160.
  • Step 4: design.md — решение R-9

В openspec/changes/console-files/design.md в конец раздела «Decisions made without discussion» добавить:

9. 09.10.2026 — **R-9:** решение владельца 07.10.2026 «фильтра файлов ЮЛ в контексте версии нет и не будет»
   (`dev/frontend-api-guide.md`) считается пересмотренным решениями 09.10.2026; строка в гайде зачёркнута со ссылкой на
   docs #90, не удалена. Цена ошибки: низкая — документальная.
10. 09.10.2026 — **R-10:** note `recognition_job.reply_deadline` (OQ-159, «20 мин») исправлен в v5.18 попутно: владелец
    просил править при ближайшей версии модели. Цена ошибки: нулевая.
  • Step 5: Проверка репозитория
cd /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs
grep -rn "consolidation_version_id" dev/qa-guide.md | grep -v "аудит\|во всех —\|versions/" 
make check CHANGE=console-files 2>&1 | tail -15

Ожидание: grep пуст или только строки про аудит; make check зелёный (валидация контрактов, openspec validate console-files --strict, снимок).

  • Step 6: Коммит и PR
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs add dev/qa-guide.md context/07-open-questions.md context/09-delivery-plan.md openspec/changes/console-files/design.md docs/superpowers/plans/2026-10-09-console-files-docs.md
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs commit -q -m "$(cat <<'EOF'
docs: QA-гайд, OQ-160 (целевая модель версий), план срезов — файлы консолидации (#90)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
EOF
)"
git -C /Users/andrey.epifancev/projects/awp-ca/.wt/console-files/docs push -u origin feat/90-console-files

PR — через superpowers:finishing-a-development-branch (tea pulls create --login home --repo RSHB/arm-ka-docs …): заголовок «DBML v5.18: файлы в контексте консолидации — stored_file.consolidation_id, маршруты консоли (#90)», в описании — ссылка на issue #90, список решений R-1…R-10 из design.md, вывод make check, пометка «дочерние PR arm-core и arm-web — следом».