Иначе после мержа у alembic две головы (0062 и 0063) и upgrade head
падает. Функции 0063 (_apply_form_cell, v_form2/4_sheet_sections,
v_svod2_rf) в 0060–0062 не переопределяются.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Конфликты после #323/#331/#334: импорты в Cell.jsx и тесты в конце
test_vsp.py — оставлены обе стороны. Дерево совпадает с пробным
слиянием всех PR (backend 1041 passed / 10 известных, фронт 263/263).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v_svod2_rf: q1..q4.transfer_to_economy вычисляется по формулам листа, сырое поле
budget_line_quarter.transfer_to_economy игнорируется. Эталон RF обновлён: фонд
экономии строк теперь расчётный (GO без изменений).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Миграция 0063: v_form2_sheet_sections считает q*.transfer_econ по шаблону Excel
((cp-aq) минус подколонки переноса минус переносы через квартал), total = остаток
после факта, групповые строки тем же; _apply_form_cell запрещает запись
q*.transfer_econ для FORM_2; v_form4_sheet_sections возвращена к версии 0033.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Возврат тестировщика 12.11.
- Шапка «План {year} (тыс. руб.) {vat_plan}» подставляла текст подколонок:
Ф.1 АХР и все листы Ф.4 выгружались «без НДС», а на экране — «с учётом
складского НДС» (Ф.4 КВ — «с учётом НДС»). Теперь у шапки своя подпись
по экрану (FORM1/FORM4_SHEET_PLAN_VAT_WORDING), подколонки не менялись.
- Раскладки Excel (FORM1/FORM2 depth, АХР-сателлиты, проекты, SMETA формы 2/4,
патчи формы 4): «тыс. руб.» по тому же правилу, что на экране; у комментариев
убран подзаголовок «Сумма, тыс. руб. (…)».
- «Коллегиальные органы → Сумма (без НДС)» (collegial.approved,
collegial_approval.approved_amount NUMERIC) считалась текстом (AURORA-1899):
не масштабировалась разрядностью и не получала единицу. Теперь денежная.
- test_export_unit_labels.py: на реальных раскладках выгрузки форм 1/2/4 у каждой
денежной колонки есть «тыс. руб.», у текстовых нет, шапка плана — как на экране.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /dict/info: status=active|closed|all (по умолчанию active), close_date_start/end;
закрытые сортируются по дате закрытия по убыванию. Удалён неиспользуемый
close_date_is_null и мёртвый return в VSPRepository.get_list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Миграция 0062: v3.upd_vsp получает p_clear_closed_at (DROP + CREATE), снятие
даты пишется в аудит. Репозиторий передаёт флаг при closed_at=null, сервис
ставит is_active=True при null или будущей дате.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- VSPRepository.get: with_deleted=True означает «включая удалённые», а не «только удалённые»
- VSPService.update: ключ closed_at (имя поля модели) вместо close_date (входной alias)
- тесты: integration test_vsp.py, unit test_vsp_service_close_date.py
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
notify_ahr_about_satellite_change рассылал на АХР row_deleted по скрытой
(AURORA-1887) строке сателлита с пустым result: фронт не находил строку
и не получал пересчитанных заголовков — итоги статьи, раздела и сметы
оставались прежними до перезагрузки.
Теперь в result — заголовки ROOT/GROUP/ITEM/SUB_ITEM/SUB_SUB_ITEM по пути
статьи удалённой строки (как del_budget_line для обычных листов). Поиск
строки по аудиту и выборка заголовков вынесены в
SheetRepository/SheetService.get_form2_ahr_satellite_delete_delta.
Протокол WS и фронт не меняются.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
T1.1 каскад hard_delete проверяется по AHR_LIMIT; T1.2 тесты триггеров
rent/utility/security/fixed_asset_report; T1.3 NaN в set_cell_formulas
отклоняется (0059 правится на месте); T3.1 unit-кейсы asyncpg-обёртки;
T3.2 предусловие SAVEPOINT-теста и комментарий к 403; T4.1 проверка
незаписи значения при 422 отчёта проекта; T4.2 убрана мёртвая логика.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PATCH cell/cells отчёта проекта пишут формулу в той же транзакции, GET
.../report/{year}/{report_type}/formulas возвращает формулы отчёта.
Тесты: roundtrip, снятие формулы, каскад удаления проекта, триггер
rf_project_report_line (del_form3_line и прямой DELETE).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SheetService.update_cell_with_formula/update_cells пишут формулу после значения в одной
транзакции, GET /form/{id}/sheet/{sheet}/formulas. Ошибки БД с обёрткой asyncpg
"<class ...>: invalid_formula: ..." теперь корректно мапятся в 422.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- sql_migration._split_statements узнаёт только $tag$, пустой $$ ломал разбиение:
DO $$ … $$ → DO $do$ … $do$.
- test_form_phases_delete_removes_only_named_phase: ?sheet= без direction
фильтрует direction IS NULL — читаем весь список и отбираем AHR в тесте.
- test_form_phases_duplicate_without_direction_rejected: после ошибки
сессия клиента откатывается, число строк не проверяем; защиту БД
проверяет новый test_form_phase_nodir_unique_index_blocks_duplicate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Интеграционные тесты одноимённых этапов, PATCH/DELETE одного этапа, дубль без направления, direction в аудите.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ORM: direction входит в PK (nullable), одноимённые этапы Support/Development больше не склеиваются
- get_list: ORDER BY sheet, direction (NULL первыми), opens_at, phase_code
- 0059: del_form_phase фильтрует по phase_code, direction в v_phase_id (add/upd/del) и в payload upd,
чистка дублей без направления и частичный уникальный индекс form_phase_nodir_uidx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Возврат тестирования 10.11: в выгрузке формы 2 не было цветных заливок.
XlsxDepthSheetWriter._set_palette искал цвет только по пути ключей дерева
колонок (section_code, god.….q2), а FORM2_COLORS ключуется путём данных
(header.section_code, booking.y2026.q2) — совпадений 0 из 162. Теперь, если
по пути дерева цвета нет, он берётся по плоскому ключу данных колонки.
Форма 1 не меняется (её цвета находятся по пути дерева, как раньше).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0053 пересоздала v3.get_form2_ahr_satellite_delta по телу из 0031 с
сопоставлением лимитного шаблона «ei.depth = 3 AND (item_id OR
num_group_id)» и откатила правку 0037. Лимиты с кодом num_group_id статьи
глубины 4 (принтеры / МФУ / копиры) не попадали в target_lines, дельта
была пустой, и открытый АХР не обновлял сумму до перезагрузки.
Миграция 0058 пересоздаёт функцию с матчером 0037
((depth = 3 AND item_id = code) OR num_group_id = code); остальное тело —
как в 0053.
Тест-защита 0037 ждал в дельте INPUT-строку, которую AURORA-1887 скрыл на
листе AHR, — теперь проверяет заголовок SUB_SUB_ITEM статьи глубины 4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
После AURORA-1848 GET листа вырезает null-поля, поэтому у заголовка статьи
без плана в квартале ключа plan.qN нет вовсе, и чтение «до» падало
KeyError до проверки самой логики. Заменено на plan.get("qN") or 0.
Продуктовый код не меняется: с правкой все 7 тестов зелёные на test
(после PR #295).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JIT добавлял ~1,4 с к вызову с буквальными параметрами (стенд масштаба 1: 1500 мс против 43 мс).
Тест: функции svod2 имеют jit=off. Убран тест формы плана: функция с SET не разворачивается.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
В v3.svod2_lines counterparty/reference/deadline/comment берутся как COALESCE(detail, summary).
Оракулы (Python, JS, векторы) отбрасывают null при слиянии, legacy_full() снова читает
ответ без параметров. Тесты: пустое поле detail, отсутствие строки detail, перекрытие непустым detail.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Контрольный тест тяжёлых GET (AURORA-1848) требовал одну ссылку на BaseListResponse;
режим страниц добавляет второй вариант ответа.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Конфликты summary.py, summary_repository.py, summary_service.py,
test_summary2_related_records_sql.py: сохранены новые методы страниц и фасетов,
режим без параметров идёт по быстрому JSON-пути test (AURORA-1848).
Миграция переименована в 0057 (down_revision 0056); в svod2_lines добавлена
поправка 0050 (СПОД аренды, только ГО). Эталон svod2_legacy_golden перезаписан
под ответ без null-полей; legacy_full оракулов строится прямым вызовом функции.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R-4 (решение пользователя 08.11). В миграцию 0056 добавлен v3.add_budget_line:
тело = 0051_form2_ahr_satellite_new_line + только created_by = current_user_id() в
двух INSERT (обычная строка и заготовка записи сателлита). Авто-зеркальные строки
sync (_ensure_form2_ahr_*_sync_line) остаются с NULL. Backfill не делается.
del_budget_line: NULL-автор -> удаляет только ADMIN (комментарий в SQL + тесты).
xfail-тест владельца снят; добавлены тесты NULL-автора (исполнитель 403, ADMIN 200).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>