Refs #26 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
54 lines
5.9 KiB
Markdown
54 lines
5.9 KiB
Markdown
# Design: Срез 2b (сквозное) — контракт v1.2, §12, OQ
|
||
|
||
## Context
|
||
|
||
Контракт `recognition-result.schema.json` v1.1: `statementDocument` рассчитан на OCR (поля `*_confidence`,
|
||
`is_recognized`), `document_type ∈ {BALANCE, INCOME, OTHER}`, результатов проверок у форм нет (у `osvDocument` есть
|
||
`checks`); `osvDocument.header` описывает период текстом, годом и кварталом, границы диапазона месяцев выразить нельзя
|
||
(OQ-131). Правило версионирования: MINOR — необязательные поля и новые значения enum; потребители обновляют копии раньше
|
||
производителя. Потребители копий: `tabular-parser` (тест идентичности в `make check`), `arm-core` (тест идентичности,
|
||
pydantic-модели результата в `services/result_mapping.py`), `scan-gateway` (копия и модели).
|
||
|
||
## Decisions
|
||
|
||
### D-1. Состав v1.2
|
||
- `$defs.statementDocument.properties.document_type.enum`: `["BALANCE", "INCOME", "DISCLOSURE", "OTHER"]`.
|
||
- `$defs.statementDocument.properties.checks` (object, необязательное): `relations_failed` и `soft_relations_failed` —
|
||
массивы объектов `{column_index: integer, relation: string, expected: money, actual: money}` (все четыре обязательны);
|
||
`duplicate_line_codes` — массив строк. Описание: отсутствие объекта — «не проверялось» (OCR-путь), пустые массивы —
|
||
«проверено, сошлось».
|
||
- `$defs.osvDocument.properties.header.properties`: `period_start`, `period_end` — `["string", "null"]`, `format: date`;
|
||
`is_from_year_start` — `["boolean", "null"]`. Описание: границы периода по шапке; для квартала/года — первое и последнее
|
||
число; для диапазона месяцев — его границы; `is_from_year_start` = `period_start` — 1 января.
|
||
- `title`, `description` схемы и `schema_version.description` — «1.2». `$comment` о версионировании не меняется.
|
||
- `recognition-request.schema.json` и `recognition-result-message.schema.json` не меняются; `result_schema_version`
|
||
в сообщении — строка, новых значений не требует.
|
||
|
||
### D-2. Примеры
|
||
`result-statement-minimal.json` получает `checks: {relations_failed: [], soft_relations_failed: [], duplicate_line_codes: []}`
|
||
и `schema_version: "1.2"`. Новый `result-statement-excel.json`: `service.name = tabular-parser`, три документа —
|
||
`BALANCE` с `locator = "sheet:Бухгалтерский баланс. Лист 1,Бухгалтерский баланс. Лист 2"`, тремя колонками, строками
|
||
1110/11101/1100/1600 и `checks` с одним нарушением в `soft_relations_failed`; `INCOME` на одном листе; `DISCLOSURE` без
|
||
`columns`/`lines`; `status = needs_check` с предупреждением о единицах. `result-osv-minimal.json` — `period_start`,
|
||
`period_end`, `is_from_year_start`. Все примеры валидируются тестами контракта в трёх сервисах.
|
||
|
||
### D-3. §12 — текст решений владельца
|
||
§12 переписывается по пунктам 1–8 с сохранением нумерации и добавлением п. 9 «Склейка листов и страниц», п. 10 «Статус
|
||
документа и книги», п. 11 «Что отложено» (запасной путь по именам, нормализация единиц, признак продолжения). Формулы §7
|
||
остаются в §7; в §12 п. 7 — ссылка и правило «жёсткие/мягкие, допуск ±1, двойной расчёт знаков». Текст решений — из
|
||
brainstorming 06.10.2026 (вопросы 2–6) и design дочернего change (D-2…D-8).
|
||
|
||
### D-4. Порядок раскатки
|
||
docs (этот change) → bounded-PR в arm-core и scan-gateway «копия схемы v1.2 + модели, без логики» → tabular-parser
|
||
(производитель 1.2) → fixtures (golden). Тест идентичности в сервисах пропускается только при недоступном docs, поэтому
|
||
между мержем docs и мержем копий тесты сервисов на main падают; окно минимизируется одновременным открытием PR.
|
||
|
||
## Decisions made without discussion
|
||
|
||
| № | Дата | Решение | Обоснование | Цена ошибки |
|
||
|---|---|---|---|---|
|
||
| 1 | 2026-10-06 | `checks` форм — отдельная структура, не переиспользование `osvDocument.checks` | у форм нарушения по колонкам и соотношениям, у ОСВ — по строкам | поле остаётся необязательным |
|
||
| 2 | 2026-10-06 | `expected`/`actual` в нарушении — `money` (строка с двумя знаками), не число | единый тип денег контракта | смена типа — MAJOR, поэтому сразу строка |
|
||
| 3 | 2026-10-06 | `is_from_year_start` — отдельное поле, `is_cumulative` не переопределяется | `is_cumulative` ядро уже трактует по OQ-02/124; новое поле не ломает семантику | два похожих поля |
|
||
| 4 | 2026-10-06 | Пример `result-statement-excel.json` со статусом `needs_check` и `DISCLOSURE` | иллюстрирует все новые элементы одним файлом | нет |
|