878 Commits

Author SHA1 Message Date
aep
60cc190066 Merge pull request 'aurora-1544 добавление таблицы гудвил' (#220) from feat/goodWill into main 2026-11-06 18:07:59 +03:00
Andrey Epifancev
c2a52d9ec8 Merge remote-tracking branch 'origin/main' into feat/goodWill 2026-11-06 19:07:28 +04:00
aep
d1e3000dc0 Merge pull request 'feat/goodwillback: бэкенд гудвилл' (#222) from feat/goodwill-back into main 2026-11-06 18:07:13 +03:00
Andrey Epifancev
8485b2c53e Гудвилл: правки по финальному ревью ветки
I-1: сохранённая доля неактивной строки нормализуется (numeric(7,4) читается как 80.1200)
и не даёт INVALID_SHARE при null в пакете; экспорт помечает строку «Нет вложений» (сценарий
спеки); design/tasks/docstring без устаревшего «построчного» PUT, R-7/R-8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:52:59 +04:00
Andrey Epifancev
6be3936d9f Гудвилл: снятая галочка с неверной долей не блокирует сохранение
Финальное ревью I-1: у неотмеченной строки поле доли скрыто — effectiveRow отправляет
сохранённую долю вместо неверного ввода; подсказка у «Сохранить» называет строки с ошибкой
и предупреждает о скрытых фильтром. design.md goodwill-ui: R-4…R-6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:50:27 +04:00
Andrey Epifancev
5f2b0e890f Гудвилл: UI-спека goodwill-ui, правки по проверке на стенде
OpenSpec change goodwill-ui (таблица, редактирование, переключатель/фильтр/экспорт;
вкладка «Гудвилл» в intercompany-matrix-ui больше не заглушка; R-1…R-3). По стенду:
стрелка раскрытия блока — у названия, «Выделить все» в одну строку, текст пустой таблицы.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:44:02 +04:00
Andrey Epifancev
3bfcc2e2aa Гудвилл: контракт в docs, README, OpenSpec под ревью
Тест контракта читает ../docs/dev/api-contract-goodwill.openapi.yaml (без docs — skip);
README: раздел гудвилла и коды INVALID_SHARE/DUPLICATE_ROW/MONEY_OUT_OF_RANGE;
OpenSpec goodwill-table: пакетное сохранение, доля два знака, итоги по ГО и УК,
единицы, Decisions made without discussion R-1…R-6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:41:20 +04:00
Andrey Epifancev
2f5b455aaa Гудвилл: вкладка по API и DOC-259025
Суммы null — прочерк, ноль — 0,00; «Нет вложений» серым без чекбокса; предупреждения
иконкой с подсказкой; итоги «Всего» и «Итого по листу» из groups/totals ответа; в режиме
редактирования — предпросмотр P/G, проверка доли (два знака, без обрезки) и комментария,
групповой чекбокс по действующим строкам блока с indeterminate; сохранение одним пакетом
изменённых строк, ошибка 422 подсвечивает поле своей строки; переключатель «Учитывать
гудвилл в КФО»; фильтр «Нулевые»; экспорт с текущим фильтром.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:37:11 +04:00
Andrey Epifancev
66acde7786 Гудвилл: типы и запросы по API бэка, чистые функции вкладки
Типы по schemas/goodwill.py (has_investments, warnings, nullable суммы, groups,
УК в итогах), пакетный saveGoodwillRows, экспорт с sign; utils/goodwill.ts —
parseShare (два знака, без обрезки), previewAmounts в копейках (HALF_UP, как бэк),
matchesSign (null — только «все»), changedRows (только изменённые строки).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:33:14 +04:00
Andrey Epifancev
fe4c5db0e6 Гудвилл: ветка без правок вне задачи, влит main
Откатены к main правки справочников, шахматки, корректировок и types/api.ts
(обработка ошибок, Alert, удалённые комментарии) — не относятся к AURORA-1544 и
конфликтовали с #219/#221; шахматка переведена на общий фильтр единиц
components/ConsolidationFormatTableFilter; удалены тестовые MOCK_DATA; формат.
План доводки — docs/superpowers/plans/2026-11-06-goodwill-review-front.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:31:47 +04:00
Andrey Epifancev
eeb0ce48da Гудвилл: единицы ББ по словарю arm_statements
StatementsEngine.canonical_units — нормализация подписи единиц шаблонами пакета;
УК ДО переводится в рубли и при единицах, исправленных аналитиком вручную.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:26:17 +04:00
Andrey Epifancev
46fba8875b Гудвилл: пакетное сохранение таблицы одной транзакцией
PUT …/goodwill {rows: [...]} вместо построчного PUT …/goodwill/{head}/{sub}: все строки
проверяются до записи, ошибка любой (NOT_FOUND, INVALID_SHARE, COMMENT_REQUIRED,
MONEY_OUT_OF_RANGE, DUPLICATE_ROW) несёт ключ пары и откатывает пакет; неизменённые
строки не перезаписываются и аудит не пишут (DOC-259025 §5.1 п. 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:24:49 +04:00
Andrey Epifancev
a086c39a78 Гудвилл: доля до двух знаков, итоги по ГО и УК с бэка
participation() — единственное место формулы доли участия; totals с УК, group_totals
по ГО, GoodwillTableOut.groups; экспорт берёт «Всего» и «Итого по листу» из ответа таблицы;
доля 0–100 не больше двух знаков (DOC-259025 §5.2), ответ — два знака.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:22:26 +04:00
Andrey Epifancev
3e07276a96 Гудвилл: заготовка вклада КФО вынесена в AURORA-1546
Удалены contributions/load_for_kfo и фильтры общего свода ОСВ (load_osv_rows,
build_with_members возвращены к main); OpenSpec change без требований вклада КФО.
План доводки по ревью — docs/superpowers/plans/2026-11-06-goodwill-review-back.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 18:20:04 +04:00
aep
8bb05dbea5 Merge pull request 'AURORA-1916: Справочники: импорт ГК и организаций из выгрузки ЕЦП' (#217) from feat/1916-import-directory into main 2026-11-06 16:50:16 +03:00
fbc6645239 [AURORA-1678]: Чек-лист документов:
- добавлен фильтр по документам
- в запрос на загрузку добавлен параметр documents
- Labeled вынесен в components/, убраны дубли в шахматке, таблице корректировок
2026-11-06 16:47:08 +03:00
Andrey Epifancev
a8ea8c6cc2 [1916] Импорт ЕЦП: сводка и после записи, предупреждения в таблице
Ревью PR #217, раунд 2:
- после записи (без «Пробного прогона») показывается та же сводка с заголовком
  «Импорт завершён» и одной кнопкой «Закрыть»; список справочника обновляется сразу;
- «ГК/ЮЛ пропущено» → «без изменений»: это GK_EXISTS/LE_EXISTS, не ошибки;
- таблица «Ошибки и предупреждения»: кроме шести кодов пропуска — предупреждения
  RF_CREATED и UNKNOWN_FLAG (§13.2) с тегом уровня;
- тесты issueLines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:40:34 +04:00
Andrey Epifancev
03803e98fd Merge remote-tracking branch 'origin/main' into feat/1916-import-directory 2026-11-06 17:36:07 +04:00
aep
8c5d749089 Merge pull request 'openspec archive: итоги шахматки (#218, #225)' (#226) from chore/archive-matrix-totals into main 2026-11-06 16:22:51 +03:00
Andrey Epifancev
f9644a952e openspec archive: intercompany-matrix-totals, intercompany-matrix-totals-ui (#218, #225)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:22:24 +04:00
aep
4ab792ee39 Merge pull request 'AURORA-1757: итоги шахматки из API, фильтр компаний на сервере' (#225) from feat/224-chess-totals-ui into main 2026-11-06 16:21:36 +03:00
aep
593456d6e4 Merge pull request 'AURORA-1756' (#218) from AURORA-1756 into main 2026-11-06 16:21:14 +03:00
Andrey Epifancev
5115704f63 AURORA-1757: итоги шахматки из API, фильтр компаний на сервере (#224)
- клиент на единый POST …/intercompany-matrix и …/export
- матрица: колонка «Итого Дт» и строка «Итого Кт» из total_debit/total_credit,
  клиентское сложение убрано
- фильтр «Компании» уходит в запрос (legal_entity_ids), варианты — весь
  периметр из ответа без выбора; выгрузка с тем же выбором
- результирующая таблица без строки «Итого», колонка «Итого по группе»
- change intercompany-matrix-totals-ui

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:08:28 +04:00
Andrey Epifancev
e71c14bc2c AURORA-1756: тест фильтра ЮЛ — _source берёт пару из первых двух ЮЛ (падал на периметре из трёх)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:08:28 +04:00
Andrey Epifancev
df4e171cc5 AURORA-1756: подписи итогов в xlsx — «Итого Дт» / «Итого Кт», как на экране и в DOC-221277
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:00:46 +04:00
Andrey Epifancev
6faa4fb325 AURORA-1756: ревью #218 — без общего итога, total_debit, change OpenSpec
- grand_total результирующей таблицы убран из API и xlsx: аналитик 03.11 попросил
  убрать итог снизу, сумма ДЗ + КЗ + ФВ + займов смысла не имеет
- total_debet переименовано в total_debit, как во всём API
- итоги матрицы квантуются до двух знаков ("0.00" и при одном ЮЛ)
- правки openspec/specs перенесены в change intercompany-matrix-totals
- README: фильтр ЮЛ и итоги

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 16:42:52 +04:00
Andrey Epifancev
362d20c1c1 feat(#190): признак скан/цифровой PDF при загрузке (§14.6)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 13:41:25 +04:00
Andrey Epifancev
110b2ce61d feat(#190): регистрация сырого ответа ИС Сканирование (s3_bucket_role.raw)
_register_raw_object (по образцу _register_result_object) регистрирует raw_s3_key
в s3_object с bucket_role=raw; бакет берётся у файла задания (stored_file -> s3_object),
не у message.result_s3 (отсутствует при status=error) — именно error чаще всего и даёт
сырой ответ без результата. Регистрация не зависит от message.status (R-2). Поле
RecognitionJob.raw_s3_object_id уже существовало (Task 1) — решение v5.13 «не
регистрируется» отменено v5.25 (OQ-179), комментарий contract/message.py обновлён.

Тесты — tests/test_recognition_inbox.py (там же тестируются _apply_result и
_register_result_object через handle_message, а не в test_recognition_exchange.py,
который покрывает только outbox/вахтёр).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 13:27:18 +04:00
Andrey Epifancev
fa36602487 fix(#190): вернуть ассерцию OTHER в её тест, убрать из FILE_REPROCESS
Ревью задачи 10 нашло сплайс: при реконструкции после обрыва сессии
`assert DocumentType.OTHER not in rm.INTAKE_FACT_DOCUMENT_TYPES` приклеилась
к концу test_file_reprocess_keeps_failure_fact_of_first_attempt_and_adds_new_intake
(FILE_REPROCESS, §14.5) вместо своего теста
test_intake_fact_document_types_excludes_disclosure_and_other, чья докстрока
обещала проверку обоих исключённых типов (DISCLOSURE/OTHER), но проверяла
только DISCLOSURE. Строка перемещена на своё место — ровно 1 строка туда,
1 строка оттуда, больше ничего в файле не менялось.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 13:16:02 +04:00
Andrey Epifancev
494e789fbf docs(#190): зафиксировать решение задачи 10 про error_code отказов маппинга в design.md
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 13:13:27 +04:00
Andrey Epifancev
7f184d895f feat(#190): факт технического отказа (TIMEOUT/NO_ACK/SERVICE_ERROR/MAPPING, §14.5)
Задача 10: quality_failure_fact на 6 точках отказа — вахтёр сроков
(expire_deadlines, TIMEOUT, батчем на все просроченные задания), dlq
(_process_one, NO_ACK), невалидный запрос и результат сервиса со
status=error (_process_one/_apply_result, SERVICE_ERROR), неповторяемая
и исчерпанная ошибки маппинга (_fail/_register_failure, MAPPING).
Измерения ЮЛ/ГК/is_scan — отдельным запросом по file_id (батчем у
вахтёра), отсутствие строки ЮЛ не прерывает обработку, только лог.

Восстановление после обрыва сессии: имплементер задачи 10 (agent
a7ad86adedbac1d8a) закончил работу, но коммит и отчёт не состоялись —
диф остался в рабочем дереве незакоммиченным. Коммит и прогон
проверок — контроллером (ruff/mypy/pytest -m "not integration" чисты;
один magic-value в новом тесте поправлен тут же), не ревью находка.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 13:00:12 +04:00
Andrey Epifancev
68dc5118f6 docs(#190): зафиксировать решение задачи 9 об статусе ERROR в design.md
Документирует находку ревью задачи 9 (minor, deferred): почему supersede_previous не
исключает ERROR-статус из факта исхода, в отличие от primary_files.delete.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 11:39:29 +04:00
Andrey Epifancev
9a1584281d fix(#190): задача 9 — добавить совпадающий по ключу документ в тесты 1/2
Ревью фикс-раунда 1: у old_file в обоих тестах был только один документ
(account="62"), ключ которого не совпадал ни с одним документом нового
файла (account="60") — _replaceable не находила совпадений, file_ids
оставался пустым, и supersede_previous возвращала [] на раннем
`if not file_ids: return []`, до locked/хука. Тесты не проверяли
SUPERSEDED/SUPERSEDED_AFTER_CONFIRM, а падали бы с NoResultFound при
реальном прогоне. Добавлен документ account="60" в old_file каждого
теста — триггер замены файла; account="62" остаётся выпавшим документом,
на котором проверяется факт исхода.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 11:34:58 +04:00
Andrey Epifancev
5edcad6e9c feat(#190): факт исхода SUPERSEDED/SUPERSEDED_AFTER_CONFIRM при автозамене
§14.3 (design quality-metrics §4.2, AURORA-1759): supersede_previous пишет
один факт исхода на каждый документ BALANCE/INCOME/OSV заменённого файла —
и выпавший (без ключа среди документов нового файла, OQ-154), и совпавший
по ключу («rest»): замена идёт файлом целиком (design №33), поэтому факт
не ограничивается только выпавшими документами. CONFIRMED на момент замены
(в т. ч. вручную — здесь, в отличие от удаления файла, нет 409-проверки) →
SUPERSEDED_AFTER_CONFIRM, иначе SUPERSEDED; primary_cause всегда NULL (вне
матрицы причин). Счётчик нарушений — одним запросом на все документы всех
заменяемых файлов.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 11:22:09 +04:00
Andrey Epifancev
3a325e886c docs(#190): зафиксировать решения задачи 8 (DELETED/DELETED_AFTER_CONFIRM) в design.md
Перенос трёх решений, делегированных брифом исполнителю и задокументированных в докстринге
PrimaryFilesService._write_delete_outcome_facts, в раздел «Decisions made without discussion»
по правилу CLAUDE.md о маркировке находок.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 11:08:55 +04:00
Andrey Epifancev
6390b36188 feat(#190): факт исхода DELETED/DELETED_AFTER_CONFIRM
Удаление файла (PrimaryFilesService.delete) пишет факт качества quality_outcome_fact
по каждому документу типа BALANCE/INCOME/OSV до физического удаления строк: DELETED —
документ не подтверждался (RECOGNIZED/NEEDS_CHECK), DELETED_AFTER_CONFIRM —
автоподтверждённый CONFIRMED (вручную подтверждённые сюда не доходят, дают 409 раньше
в том же методе). primary_cause=None явно (§14.3 правило 1, вне матрицы причин),
payload — минимальный снимок без построчных данных (build_outcome_payload(document, fixes=())).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 11:06:35 +04:00
Andrey Epifancev
9bb9fba901 fix(#190): правка задачи 7 — PDF-добавленная строка «наш разбор», before у _header_fix
Ревью задачи 7, раунд 1: (1) добавлена строка design.md 06.11.2026 — решение
«нет сырого текста → наш разбор» для value/code/header фиксов задокументировано
отдельно (не то же, что 1250\n1260); тем же рядом исправлено направление для
PDF-добавленной строки — "наш разбор", не "сервис" (пустой raw_line_codes не
должен давать service через attribute_added_row, это противоречило уже принятому
27.10.2026 решению). (2) _added_row_fix для PDF больше не вызывает
attribute_added_row с заведомо пустым raw_line_codes — атрибуция "ours" прямо.
(3) _header_fix теперь возвращает "before" (meta.<field>_original_value), как
у _value_fix/_code_fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-06 10:53:19 +04:00
eb65c2dc1c исправлен задний фон инпута доля владений 2026-11-06 09:24:06 +03:00
5304c97fb4 форматирование 2026-11-06 09:09:24 +03:00
1ee71355da футер таблицы гудвила вынесен в отдельный компонент 2026-11-06 09:08:39 +03:00
67899fc963 форматирование 2026-11-06 08:52:33 +03:00
29a630c5e5 функция раскрытия на весь экран вынесена в отдельный хук useFullScreen 2026-11-06 08:51:16 +03:00
db8641a1a8 обновленна логика отображения ошибок сервера 2026-11-06 08:37:53 +03:00
Andrey Epifancev
bb1714b096 feat(#190): факт исхода CONFIRMED с атрибуцией правок (§14.2-14.4)
DocumentService._write_confirm_outcome_fact — третий хук quality_outcome_fact
(outcome=CONFIRMED). В отличие от AUTO_CONFIRMED правки возможны: суммы и коды
строк сравниваются с живыми *_modified/original_*/source_text (не с JSON факта
приёма), добавленные строки и правки шапки — через attribute_* (Task 3), период/
счёт ОСВ — всегда "наш разбор". primary_cause — по приоритету сервис > наш разбор
> документ клиента > как есть. Гейт типа документа (BALANCE/INCOME/OSV) —
OUTCOME_FACT_DOCUMENT_TYPES, DISCLOSURE/OTHER без факта.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-05 19:58:03 +04:00
Andrey Epifancev
d26804a85d fix(#190): факт исхода только для BALANCE/INCOME/OSV (§14.3 п.5)
Ревью нашло: хук писал quality_outcome_fact для ЛЮБОГО автоподтверждённого
документа, в том числе DISCLOSURE/OTHER — у них нет факта приёма
(INTAKE_FACT_DOCUMENT_TYPES, Task 5), и факт исхода без пары превратился бы
в сироту при соединении по document_id. Добавлен гейт
OUTCOME_FACT_DOCUMENT_TYPES = {BALANCE, INCOME, OSV} (не импортируется из
result_mapping.py — там уже отложенный импорт auto_confirm во избежание
цикла); auto_confirm для DISCLOSURE/OTHER не меняется — только пропускает
запись факта. Поправлен вводивший в заблуждение комментарий в
_outcome_fact_fields. Тест на DISCLOSURE: автоподтверждение проходит,
quality_outcome_fact не появляется.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-05 19:36:11 +04:00
Andrey Epifancev
2a9ed10a29 feat(#190): факт исхода AUTO_CONFIRMED (§14.3 п.5)
Хук в auto_confirm: на каждый документ, подтверждённый системой,
пишется quality_outcome_fact (outcome=AUTO_CONFIRMED,
primary_cause=WITHOUT_PARTICIPATION всегда — правок при автоподтверждении
не бывает, D-3 блокирует формы с нарушениями). payload строится
build_outcome_payload по тому же шаблону, что факт приёма (Task 5):
ОСВ — osv_warnings/row_count, формы — lines/values/header_source,
issue_count_at_outcome — все нарушения документа без фильтра.
Запись в транзакции маппинга, без flush/commit (Task 4 insert_outcome_fact).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-05 19:25:03 +04:00
Andrey Epifancev
12ea8acd42 feat(#190): факт приёма документа при маппинге (§14.1)
Хук в _map_candidate (result_mapping.py): после map_file, до auto_confirm — для
каждого документа BALANCE/INCOME/OSV строит снимок build_intake_payload и пишет
quality_intake_fact через insert_intake_fact. Чисто добавочный шаг: не меняет
документы, статусы и прочий результат маппинга; DISCLOSURE/OTHER факта не получают.

Счётчики строк/значений — из financial_statement_* (BALANCE/INCOME) и document_issue;
warning_count/osv_warnings — предупреждения источника service (document_issue.source =
service): для BALANCE/ОФР 1.x таких записей нет, для ОСВ это коды OSV_*. Для ОСВ
построчные счётчики не считаются (их в ядре нет), только row_count в payload.

Тесты в test_result_mapping.py (маркер integration, не запускались — нет PostgreSQL
в песочнице, подтверждена только коллекция) + один DB-free тест на множество типов
документов хука.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-05 19:07:02 +04:00
Andrey Epifancev
a2d24fe802 feat(#190): репозиторий записи фактов качества
Тонкие функции insert_intake_fact / insert_outcome_fact / insert_failure_fact: session.add
без flush и commit, факт попадает в транзакцию вызывающего (design §4).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-11-05 18:48:11 +04:00
Andrey Epifancev
5603dd1898 feat(#190): атрибуция правки сервис/наш разбор (§14.2)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-05 18:37:57 +04:00
446cd583d5 исправление багов 2026-11-05 17:34:59 +03:00