recompute_form (services/statement_recompute.py) собирает вход из БД, зовёт engine.recompute и пишет needs_review
строк и значений, form_variant, parent_row_index расшифровок, записи relation/soft и core по P3-8, статус через
form_status_v2. GET/confirm/accept читают нарушения §7 из document_issue. Правка header.report_date пересчитывает
relative:* колонки. Временный код A12/A13 удалён.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
form_confirmable заменён на form_blocker: PERIOD_REQUIRED -> LINES_UNRESOLVED -> DUPLICATE_FORM -> CHECKS_NOT_PASSED.
Ручное и автоподтверждение используют одну функцию.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
Правило «подстрока относится к ближайшей четырёхзначной строке выше с теми же тремя цифрами,
иначе к строке из первых четырёх цифр» вынесено в subline_parents; им пользуются проверка
«сумма подстрок = родитель» и ответ GET /documents/{id}/statement (поле lines[].parent_code,
вычисляется, в БД не хранится).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CellPatch адресует ячейку ровно одним из line_id / line_code. Строка справочника
редакции, которой нет в форме, создаётся при первой непустой правке
(line_code_original_value = NULL — признак «не из источника»); отсутствующая
ячейка существующей строки тоже создаётся. Адресация (колонка, строка, код)
проверяется целиком до первой вставки, две ячейки новой строки делят одну
строку, повтор line_code после создания даёт 422 UNKNOWN_CELL. Аудит — одно
RECOGNIZED_DATA_EDIT на запрос, у созданной ячейки before = null.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
GET …/statement добавляет строки справочника редакции, которых нет в форме
(id = null, origin = template), и недостающие ячейки существующих строк
(id = null, все значения пусты). В БД ничего не пишется. Добавлено поле
LineOut.origin (source | template).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Условия подтверждения формы ББ/ОФР вынесены в statement_hard_failures и form_confirmable
(модульные функции services/statements.py); ручной путь (documents._check_statement) использует
тот же statement_hard_failures и отвечает 409. Тест с нарушением строгого соотношения на 2200
(соотношения с 2400 в словаре мягкие).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
I-1: `_editable` брал шапку без перечитывания, и после ожидания блокировки видел устаревший акцепт и значения
шапки. `get_meta(..., refresh=True)` читает с populate_existing после lock_file и lock_document.
T6.1: тесты — содержимое аудита правки значения и акцепта, исходное значение даты отчёта, дата не на конце квартала,
сброс акцепта правкой только значения, неизменность формы после INVALID_INN, свежесть шапки под блокировкой.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
PATCH /documents/{id}/statement и POST /documents/{id}/statement/checks/accept: блокировки «файл → документ»,
409 FILE_SUPERSEDED/DOCUMENT_READONLY/DOCUMENT_NOT_STATEMENT, 422 INVALID_INN/UNKNOWN_CELL/DUPLICATE_CELL,
один audit_event на запрос, сброс акцепта правкой, пересчёт статуса D-6.
Замечания ревью Task 5: пара формы ищется только среди документов с шапкой формы (T5.1), строки формы упорядочены
по (line_code, id) (T5.3), слабый тест межформенной проверки удалён (T5.4), локальный импорт в тестах убран (T5.6).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
Схемы формы, StatementService (видимость, 409 DOCUMENT_NOT_STATEMENT, проверки §7 и межформенная),
репозиторий (get_meta, load_form, pair_amounts), маршрут GET с DOCUMENT_VIEW, тесты API и детерминированный
тест межформенной проверки.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2