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

558 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Файлы в контексте консолидации — план для репозитория 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: Скопировать модель**
```bash
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`.
Затем:
```bash
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: Проверка**
```bash
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: Коммит**
```bash
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**
```bash
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 в документах**
```bash
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: Коммит**
```bash
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: Проверка**
```bash
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: Коммит**
```bash
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: Проверка**
```bash
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: Коммит**
```bash
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: Проверка репозитория**
```bash
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**
```bash
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 — следом».