plan: statement-template-lines — план реализации; уточнения спеки (#80)

Спека: «1600 = 1700» проверяется при потерянной 1700 (цель 1600 есть);
цвет строк «БАЛАНС» — #f9f0ff (синий занят «исправлено»); R-8 has_lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019qoydUVv8g1qHxc123u2RR
This commit is contained in:
Andrey Epifancev 2026-10-09 10:39:23 +04:00
parent f540c7f661
commit dba7273a2d
4 changed files with 1650 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@ -101,8 +101,8 @@ pydantic: коды — четыре цифры, без повторов внут
Гонки двух правок одной формы исключены блокировкой документа: второй запрос ждёт и видит строку, созданную первым
(получит 422 «передайте line_id» и перечитает форму). Уникальный индекс `(meta_id, line_code)` — страховка.
Аудит — одно `RECOGNIZED_DATA_EDIT` на запрос, как сейчас; в `before/after` ячейки созданной строки ключ —
`line_code` + `column_index`, `before.amount = null`.
Аудит — одно `RECOGNIZED_DATA_EDIT` на запрос, как сейчас; ключ созданной ячейки — тот же `value:<id>` (id новой
ячейки), `before = null`.
### D-5. Пустые шаблонные строки вне проверок и статуса
Достроенные строки в БД нет — `statement_amounts`, `value_flags`, `has_lines`, `_line_amount` (межформенная) их не
@ -118,10 +118,10 @@ pydantic: коды — четыре цифры, без повторов внут
(`is_recognized = null`), введённое значение подсвечивается как правка. `formLayout` уже раскладывает строки по разделам —
меняется только то, что разделы теперь всегда полные. **Строки «БАЛАНС» (1600 по активу, 1700 по пассиву) выделяются
цветом** (просьба владельца 09.10.2026: сейчас итог баланса сливается с обычными строками и «Итого по разделу»): фон
всей строки — светло-синий (`#e6f4ff`, токен antd `colorPrimaryBg`; отличается от серого фона заголовков разделов),
шрифт 700 у наименования, кода и сумм. Подсветка ячейки «требует проверки» / «правлено» перекрывает фон строки —
всей строки — светло-фиолетовый (`#f9f0ff`, purple-1 палитры antd): серый `#f2f4f7` уже у заголовков разделов,
светло-синий `#e6f4ff` — «исправлено», оранжевый `#fff7e6` — «требует проверки»; шрифт 700 у наименования, кода и сумм. Подсветка ячейки «требует проверки» / «правлено» перекрывает фон строки —
сигнал о данных важнее оформления. Признак — `formLayout` (`LayoutRow.grand: true` для 1600/1700 у `BALANCE`), цвет —
`StatementTable`. Сверка с макетом [41] (PNG `docs/mockup/screens/`) в Playwright и
`StatementTable`. В arm-web — свой OpenSpec change `statement-template-lines` (дельта `document-review-ui`). Сверка с макетом [41] (PNG `docs/mockup/screens/`) в Playwright и
ручной прогон сценария: пустая строка → ввод → «Сохранить» → проверки пересчитаны.
## Risks / Trade-offs
@ -144,4 +144,5 @@ pydantic: коды — четыре цифры, без повторов внут
| R-4 | 09.10.2026 | Без редакции (нет даты периода) строки не достраиваются, недостающие ячейки — достраиваются | Не из чего выбрать состав; дата периода нужна и для подтверждения (`PERIOD_REQUIRED`) — после её правки строки появятся | Аналитик не видит пустых строк, пока не введёт дату отчёта |
| R-5 | 09.10.2026 | `line_code` для кода, уже существующего в форме, — 422 `UNKNOWN_CELL`, а не тихая правка существующей строки | Один способ адресации существующей ячейки (`line_id`), второй запрос в гонке не перезапишет чужую правку молча | Лишний круг фронта: перечитать форму и повторить |
| R-6 | 09.10.2026 | Ячейка, которой нет у существующей строки, создаётся при правке по `line_id` | Та же проблема, что с отсутствующей строкой; отдельного API не требует | — |
| R-7 | 09.10.2026 | Цвет строк «БАЛАНС» — светло-синий `#e6f4ff` + жирный 700; подсветка ячейки перекрывает фон строки; ОФР не выделяется | Владелец просил выделить баланс по активу и пассиву, цвет не задал; в макете [41] строки «БАЛАНС» не видно; синий не спорит с серым фоном разделов и жёлтым «требует проверки» | Цвет не понравится — правка одной константы |
| R-7 | 09.10.2026 | Цвет строк «БАЛАНС» — светло-фиолетовый `#f9f0ff` + жирный 700; подсветка ячейки перекрывает фон строки; ОФР не выделяется | Владелец просил выделить баланс по активу и пассиву, цвет не задал; в макете [41] строки «БАЛАНС» не видно; фиолетовый не занят: серый — разделы, синий — «исправлено», оранжевый — «требует проверки» | Цвет не понравится — правка одной константы |
| R-8 | 09.10.2026 | `has_lines` (условие D-6 «в форме есть строки») учитывает и строки, созданные правкой | Форму, у которой источник не дал строк (не найдена колонка кодов), аналитик может заполнить вручную — это его данные, как любая правка; статус всё равно требует пройденных проверок и завершённого задания | Документ без строк источника станет `RECOGNIZED` после ручного заполнения — ожидаемо |

View File

@ -31,6 +31,7 @@ SHALL быть значение по каждой колонке формы —
- **WHEN** у формы `BALANCE` за 2025 Q1 в БД нет строки 1700 (OCR склеил «1500\n1700» до OQ-156)
- **THEN** в `lines` есть 1700: `id = null`, `origin = template`, `line_name = "БАЛАНС"`, значения по всем колонкам
`id = null`, `amount = null`, `is_recognized = null`; статус документа и `checks` — те же, что без достройки
(`1600 = 1700` нарушено: 1700 отсутствует и считается 0)
#### Scenario: Недостающая ячейка
- **WHEN** у строки 1150 в БД есть значение только для колонки 0, а у формы две колонки

View File

@ -33,7 +33,8 @@ relation, expected, actual}`; MUST NOT храниться в БД.
#### Scenario: Пустая шаблонная строка не проверяется
- **WHEN** в форме нет строки 1700 (в ответе она достроена пустой), 1300 + 1400 + 1500 = 2 371 333 в колонке 0
- **THEN** `1700 = 1300 + 1400 + 1500` и `1600 = 1700` не проверяются, `failed` — как без достройки
- **THEN** соотношения с целью 1700 (`1700 = 1300 + 1400 + 1500`) не проверяются; `1600 = 1700` (цель 1600 есть в
форме, 1700 = 0) нарушено — как и без достройки: потерянная строка «БАЛАНС» сама по себе даёт `NEEDS_CHECK`
#### Scenario: Заполненная шаблонная строка проверяется
- **WHEN** аналитик заполнил 1700 = 2 371 333 только в колонке 0, а в колонке 1 1300 + 1400 + 1500 = 2 000 000