diff --git a/openspec/changes/statements-v2/.openspec.yaml b/openspec/changes/archive/2026-10-19-statements-v2/.openspec.yaml similarity index 100% rename from openspec/changes/statements-v2/.openspec.yaml rename to openspec/changes/archive/2026-10-19-statements-v2/.openspec.yaml diff --git a/openspec/changes/statements-v2/design.md b/openspec/changes/archive/2026-10-19-statements-v2/design.md similarity index 100% rename from openspec/changes/statements-v2/design.md rename to openspec/changes/archive/2026-10-19-statements-v2/design.md diff --git a/openspec/changes/statements-v2/proposal.md b/openspec/changes/archive/2026-10-19-statements-v2/proposal.md similarity index 100% rename from openspec/changes/statements-v2/proposal.md rename to openspec/changes/archive/2026-10-19-statements-v2/proposal.md diff --git a/openspec/changes/statements-v2/specs/document-review-ui/spec.md b/openspec/changes/archive/2026-10-19-statements-v2/specs/document-review-ui/spec.md similarity index 100% rename from openspec/changes/statements-v2/specs/document-review-ui/spec.md rename to openspec/changes/archive/2026-10-19-statements-v2/specs/document-review-ui/spec.md diff --git a/openspec/changes/statements-v2/specs/primary-files-ui/spec.md b/openspec/changes/archive/2026-10-19-statements-v2/specs/primary-files-ui/spec.md similarity index 100% rename from openspec/changes/statements-v2/specs/primary-files-ui/spec.md rename to openspec/changes/archive/2026-10-19-statements-v2/specs/primary-files-ui/spec.md diff --git a/openspec/specs/document-review-ui/spec.md b/openspec/specs/document-review-ui/spec.md index 263c403..6c4a45e 100644 --- a/openspec/specs/document-review-ui/spec.md +++ b/openspec/specs/document-review-ui/spec.md @@ -26,16 +26,18 @@ ### Requirement: Форма ББ/ОФР — просмотр и правка Экран SHALL показывать `GET /documents/{id}/statement`: шапку (ИНН, дата отчёта, единицы — значение и исходное при правке; наименование, ОКУД/ОКПО) и таблицу «строка (код, наименование) × колонки» с суммами из `values[]`, включая -строки и ячейки, достроенные сервером по справочнику редакции (`id = null`). Ячейки с `confidence < 100` или -`is_recognized = false` SHALL подсвечиваться как «требует внимания», с `is_modified = true` — как «исправлено» с -исходным значением `original_amount` в подсказке; пустая достроенная ячейка не подсвечивается. Строки «БАЛАНС» формы -`BALANCE` (коды 1600 и 1700) SHALL выделяться фоном `#f9f0ff` и жирным шрифтом; подсветка ячейки перекрывает фон строки. -Единицы (`header.units`) SHALL выводиться над таблицей. Пока документ не `CONFIRMED`, ячейка SHALL быть редактируемой: -ввод проверяется по формату суммы (до 2 знаков после точки, знак минус допустим, пустое — `null`), сохранение -отправляет `PATCH /documents/{id}/statement {values: [...]}` суммой-строкой: ячейка строки из БД — `{line_id, -column_id, amount}`, ячейка достроенной строки (`id = null`) — `{line_code, column_id, amount}`; ответ заменяет -состояние экрана. Правка шапки (ИНН, дата отчёта, единицы) SHALL отправляться тем же `PATCH` в `header`; -`inn: null` не отправляется. +строки и ячейки, достроенные сервером по справочнику редакции (`id = null`). Ячейки с `needs_review = true` SHALL +подсвечиваться как «требует внимания» (подсветки напрямую по `confidence < 100` или `is_recognized = false` нет), с +`is_modified = true` — как «исправлено» с исходным значением `original_amount` в подсказке; пустая достроенная ячейка не +подсвечивается. Строки «БАЛАНС» формы `BALANCE` (коды 1600 и 1700) SHALL выделяться фоном `#f9f0ff` и жирным шрифтом; +подсветка ячейки перекрывает фон строки. Единицы (`header.units`) SHALL выводиться над таблицей. Пока документ не +`CONFIRMED`, ячейка SHALL быть редактируемой: ввод проверяется по формату суммы (до 2 знаков после точки, знак минус +допустим, пустое — `null`), сохранение отправляет `PATCH /documents/{id}/statement {values: [...]}` суммой-строкой: +ячейка строки из БД — `{line_id, column_id, amount}`, ячейка достроенной строки (`id = null`) — `{line_code, +column_id, amount}`; ответ заменяет состояние экрана. Правка шапки (ИНН, дата отчёта, единицы, наименование +организации) SHALL отправляться тем же `PATCH` в `header`; `inn: null` не отправляется. Правка строк, колонок и +подтверждений в том же `PATCH` (`columns`, `lines`, `values[].confirmed`) описана в требовании «Правка строк, колонок и +подтверждение в режиме «Редактировать»». #### Scenario: Исправление ячейки - **WHEN** аналитик меняет значение ячейки и сохраняет @@ -63,14 +65,21 @@ column_id, amount}`, ячейка достроенной строки (`id = nul - **THEN** блок проверок показывает акцепт, нарушения остаются видимыми ### Requirement: Подтверждение документа -Кнопка «Подтвердить» SHALL отправлять `POST /documents/{id}/confirm` и быть недоступна для `CONFIRMED` и `ERROR`. При 409 -`CHECKS_NOT_PASSED` экран SHALL показать `detail.failures[]` и предложить акцепт; при 409 `PERIOD_REQUIRED` — подсказать -исправить дату отчёта; прочие ошибки — `message`. После успеха экран SHALL перейти в режим только чтения. +Кнопка «Подтвердить данные» SHALL отправлять `POST /documents/{id}/confirm` и быть недоступна для `CONFIRMED` и `ERROR`, а +также при наличии строк `unreadable` / `missing` с суммой или нераспознанным текстом в ячейках (подсказка «Разберите +строки без кода: N» с переходом к первой такой строке). При 409 `CHECKS_NOT_PASSED` экран SHALL показать +`detail.failures[]` и предложить акцепт; при 409 `PERIOD_REQUIRED` — подсказать исправить дату отчёта; при 409 +`LINES_UNRESOLVED` — показать тот же текст, что у отключённой кнопки; при 409 `DUPLICATE_FORM` — со ссылкой на +подтверждённую форму; прочие ошибки — `message`. После успеха экран SHALL перейти в режим только чтения. #### Scenario: Подтверждение с неакцептованными нарушениями - **WHEN** аналитик подтверждает форму с жёсткими нарушениями без акцепта - **THEN** показан список нарушений из ответа и кнопка «Принять с комментарием» +#### Scenario: Дубль подтверждённой формы +- **WHEN** сервер отвечает 409 `DUPLICATE_FORM` +- **THEN** экран показывает ошибку со ссылкой на уже подтверждённую форму + ### Requirement: ОСВ-документ Для `OSV` экран SHALL показывать строки `GET /documents/{id}/entries` (все страницы, `limit` ≤ 2000) плоской таблицей строк нижнего уровня (договоры отдельными строками не идут — их сумма в строке контрагента) с колонками: @@ -101,3 +110,61 @@ column_id, amount}`, ячейка достроенной строки (`id = nul #### Scenario: Большая ОСВ - **WHEN** аналитик открывает ОСВ-документ на ~29 000 строк - **THEN** документ открывается, число строк в DOM не зависит от размера документа, прокрутка до конца, поиск и фильтр по субсчёту работают, «Итого по документу» совпадает с суммой по всему документу + +### Requirement: Раскладка строк формы со статусами +Экран проверки формы ББ/ОФР ([41]) SHALL сохранять раскладку «как на бумаге» (Р-14): разделы, внутри — строки `ok` по +возрастанию кода, несколько строк одного кода — в порядке файла (`row_index`), шаблонные строки на своих местах, +пятизначные подстроки под родителем. Строка `unreadable` / `missing` SHALL стоять под ближайшей предыдущей по +`row_index` строкой, размещённой по коду, а без такой — в начале первого раздела; она подсвечена целиком, в ячейке +кода серым — сырой текст `line_code_text` с подсказкой. Строки `detail` SHALL быть скрыты под переключателем +«Показать расшифровки (N)» и показываться под родителем (`parent_row_index`) с отступом. Экран показывает справочное +имя строки (`reference_name`), файловое (`line_name`) — рядом, если отличается. Переключателя «как в файле» нет. + +#### Scenario: Код-мусор на своём месте +- **WHEN** строка `unreadable` «ИЧ,250» в файле стоит после строки 1240 +- **THEN** на экране она стоит сразу под 1240, подсвечена, в ячейке кода серым «ИЧ,250» + +#### Scenario: Расшифровки скрыты +- **WHEN** у формы три строки `detail` +- **THEN** по умолчанию их не видно, переключатель «Показать расшифровки (3)»; включённый показывает их под родителями + +### Requirement: Подсветка и предупреждения у места +Экран SHALL подсвечивать ячейки только по `needs_review` (в подсказке — `text` и уверенность), строки — по +`needs_review` строки, поля шапки — по `needs_review_fields` (в подсказке у поля — `header.source.<поле>`: сырой текст и +уверенность). Предупреждения и нарушения (`issues`, `checks`) SHALL показываться у места: у строк (`line_ids`), ячеек +(`line_ids` + `column_id`), полей шапки (`field`) или у документа (в том числе запись с `column_index` без `column_id` — +столбец вне колонок формы); уровень `error` отличается от `info`. Подсветки по `confidence < 100` и `is_recognized = +false` напрямую нет. У значений строк `detail` `needs_review` всегда `false` (Р-23): при показанных расшифровках их +сомнительные ячейки не подсвечиваются, но подсказка с `text` и уверенностью есть. + +#### Scenario: Догадка подтверждена проверкой +- **WHEN** значение `is_recognized = false`, `needs_review = false` +- **THEN** ячейка не подсвечена; в подсказке сырой текст и уверенность + +### Requirement: Правка строк, колонок и подтверждение в режиме «Редактировать» +В режиме «Редактировать» экран SHALL давать: у `unreadable` / `missing` — поле ввода кода с подсказкой из справочника +(код → справочное имя) и пункт меню строки «Это расшифровка»; у `detail` — «Назначить код»; у строки `ok` — «Сделать +расшифровкой», смену кода и «Подтвердить код» у строки с `needs_review`; подтверждение ячейки без правки; ввод даты у +колонки без даты (`period_kind = none`) или с предупреждением о дате (в том числе подтверждение той же даты); снятие подтверждения ячейки и кода (`confirmed: +false`); правка наименования организации в шапке; подтверждение даты отчёта из `needs_review_fields` без изменения (тем +же значением). «Сохранить» отправляет один `PATCH …/statement` (`header`, `values`, `columns`, `lines`). Кнопка «Подтвердить данные» при строках `unreadable` / `missing` с суммами +SHALL быть отключена с подсказкой «Разберите строки без кода: N» и переходом к первой такой строке; ответ сервера 409 +`LINES_UNRESOLVED` показывается тем же текстом, 409 `DUPLICATE_FORM` — со ссылкой на подтверждённую форму, 409 +`LINE_CODE_TAKEN` — у поля кода. Кнопка «Подтвердить данные» учитывает строки `unreadable` / `missing` с суммой или +нераспознанным текстом в ячейках. + +#### Scenario: Назначить код +- **WHEN** аналитик вводит 1250 в ячейку кода строки `unreadable` и сохраняет +- **THEN** уходит `PATCH` с `lines: [{line_id, line_code: "1250"}]`; после ответа строка встаёт на место 1250 + +#### Scenario: Подтверждение заблокировано +- **WHEN** у формы две строки `missing` с суммами +- **THEN** «Подтвердить данные» отключена, подсказка «Разберите строки без кода: 2», клик по подсказке ведёт к первой + +### Requirement: Предупреждения ОСВ-документа +Экран ОСВ-документа SHALL показывать предупреждения документа из `DocumentOut.issues[]` (коды `OSV_*`) блоком над +таблицей; все записи относятся к документу (строки ОСВ `line_ids` не адресуются); уровень `error` отличается от `info`. + +#### Scenario: Предупреждение листа ОСВ +- **WHEN** у ОСВ-документа в `issues` есть запись с кодом `OSV_*` +- **THEN** над таблицей показан блок предупреждений с текстом записи и уровнем diff --git a/openspec/specs/primary-files-ui/spec.md b/openspec/specs/primary-files-ui/spec.md index 43988cd..9192740 100644 --- a/openspec/specs/primary-files-ui/spec.md +++ b/openspec/specs/primary-files-ui/spec.md @@ -65,3 +65,13 @@ SHALL перечитывать этот список раз в 5 секунд и #### Scenario: Опрос останавливается - **WHEN** все файлы активного списка перешли в `PROCESSED` или `ERROR` - **THEN** запросы списка файлов прекращаются + +### Requirement: Предупреждения файла и документа в карточке файла +Карточка файла (панель файлов) SHALL читать `job.warnings` как список структур `{code, severity, message, locator}` +(после выкладки ядра v5.19 это не строки; у старых заданий ядро отдаёт строки, обёрнутые в `LEGACY_WARNING`), показывать +`message` и `locator`, отличая `error` от `info`; предупреждения листа ОСВ и документа — из `DocumentOut.issues[]`. +`job.mapping_warnings` остаётся списком строк. + +#### Scenario: Потерянный ОФР в карточке +- **WHEN** у задания `job.warnings = [{code: "JSON_FAILED", severity: "error", message: "…", locator: "file:x_ofr.json"}]` +- **THEN** карточка показывает предупреждение уровня «ошибка» с текстом и местом; экран не падает на объекте вместо строки