248 Commits

Author SHA1 Message Date
Andrey Epifancev
daed54d436 fix(export): Смета РФ — выгрузка Операц/АХР/КВ своей раскладкой, не формы 1
Листы Операц/АХР/КВ формы «Смета РФ» (FORM_2) выгружались раскладкой формы 1
(FORM1_DEPTH_COLUMNS, 180 колонок формы 1) — из 163 колонок экрана совпадали
по ключу только 83, 97 колонок выгрузки были всегда пустыми (блоки формы 1,
которых нет в данных формы 2), заголовки групп — от формы 1. Также на экране
был лишний столбец «Адрес ВСП», которого нет в исходной форме РФ, и ВСП
выгружался бы числовым id вместо номера, который виден на экране.

- FORM2_DEPTH_COLUMNS/FORM2_COLORS (export_mappings.py) — сгенерированы из
  web/src/.../FORM_2/{OPER,AHR,CAP}.js (колонки идентичны у всех трёх листов,
  проверено программно; различаются только цвета). 162 листа дерева —
  байт-в-байт тот же порядок, что на экране, минус header.vsp_address.
  Каждая группа — чисто визуальная обёртка ("key": None), каждый лист несёт
  полный путь данных как "key" (например "booking.y2027.q1"), поэтому порядок
  вложенности групп для Excel-заголовков не завязан на реальный путь к данным.
- Form2DepthRowNormalizer (export_normalizers.py) — в отличие от
  Form1DepthRowNormalizer, не поднимает header.* на верхний уровень: FORM_2
  ожидает их как header.section_code, header.vsp_id и т.д.
- _create_xlsxwriter_sheet_writers: отдельная ветка для FormTypeEnum.FORM_2
  (раньше FORM_2 попадала в общий else вместе с FORM_1). Сателлиты АХР
  (AHR_RENT/UTILITY/SECURITY, AURORA-1904) и STRUCTURE не трогал.
- VSPRepository.get_reg_numbers_by_ids + ExportService._resolve_form2_vsp_numbers:
  один запрос резолвит все встретившиеся header.vsp_id (включая закрытые ВСП)
  в registration_number перед записью в Excel, как уже показывает экран.
- web/.../FORM_2/{OPER,AHR,CAP}.js: убран столбец «Адрес ВСП» (E1) и его цвет —
  по умолчанию, т.к. его нет в исходной форме РФ (см. Rulings в PR). Убрана
  мёртвая ссылка на него в Stages/constants.js.

Issue: #252 (AURORA-1902, эпик AURORA-1876, Высокий приоритет)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 21:47:24 +04:00
Andrey Epifancev
c01356736f fix(form2): Смета РФ — итоги групп и IV кв. на свои места
На листе «Смета» формы «Смета РФ» итоговые колонки каждой группы
(план/утверждённые/факт «Итого: Поддержка» и IV квартал скорректированной
сметы) были оторваны от своих групп и собраны в отдельную группу
«В тыс. рублей» справа — хотя в шаблоне идут сразу после своего квартала.

- Перенёс H/N/T (data.*.support.year) в конец соответствующих групп план/
  утверждённые/факт, X (data.corrected.support.q4) — в конец группы
  скорректированной сметы после III квартала.
- Удалил опустевшую группу «В тыс. рублей»; accessorKey групп
  (v_tys_rubley_*) нигде больше не использовались (grep по web/src).
  columnLetter и leaf accessorKey (data.*) не менял — видимые значения
  те же, меняется только расположение колонок.
- Тест читает FORM_2/SMETA.js как текст (модуль не грузится напрямую —
  импортирует '../columnColors' без расширения) и проверяет порядок
  accessorKey листьев и отсутствие заголовка «В тыс. рублей».

Issue: #251 (AURORA-1901, эпик AURORA-1876, Высокий приоритет)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 18:12:29 +04:00
Andrey Epifancev
b95029f70a fix(forms): запретить удаление чужих строк, добавить подтверждение
Удаление строки в формах 1/2/4 не проверяло владельца: любой исполнитель
мог удалить чужую строку мгновенно, без подтверждения.

- v3.del_budget_line (миграция 0050): не-admin может удалить только
  budget_line, где created_by совпадает с current_user_id() (проверка
  и для обычных листов, и для AHR_RENT/UTILITY/SECURITY — через
  created_by связанной budget_line). Нарушение -> role_not_allowed:
  (403), по существующей конвенции PG_403_ERRORS.
- RealtimeTable: кнопка «Удалить строку» теперь открывает
  ConfirmDeleteRowModal, реальное удаление — только после подтверждения.
- Интеграционные тесты: новый исполнитель isp2 (fixture.sql) в том же
  org_unit, что и budget_form id=1 — проверяют 403 при чужой строке,
  200 при своей и при удалении администратором.

Issue: #249 (AURORA-1936, эпик AURORA-1876, Высокий приоритет)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 18:06:52 +04:00
Andrey Epifancev
edaed04a03 fix(auth): session no longer drops after access-token expiry
Access-токен жил 60 минут без обновления: фронт не слал response-interceptor
на 401, refresh-токен лежал в localStorage неиспользуемым, WebSocket-сокеты
(форма, статусы выгрузки) не переподключались после закрытия с auth-кодом,
а после редиректа на /login пользователь терял исходную страницу.

- tokenRefresh.js: чистые getTokenExp/msUntilRefresh/createSingleFlight (TDD).
- auth.js: refreshTokens — обновление токена вне интерсепторов api (без
  рекурсии), централизованно чистит токены и шлёт auth:expired при неудаче.
- client.js: response-interceptor повторяет запрос после обновления токена.
- AuthProvider: при старте и по 'auth:expired'/'auth:refreshed' не выкидывает
  из системы, пока жив refresh; проактивный таймер обновления + visibilitychange.
- Routes/LoginPage: PrivateRoute сохраняет исходный location, вход возвращает
  туда же вместо /tasks; убрана мёртвая ветка loading.
- useWebSocket/exports: переподключение после 1008/4401 с одной попыткой
  refreshTokens() перед тем как сдаться.

Issue: #248 (AURORA-1877, эпик AURORA-1876, Критичный приоритет)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-30 17:18:11 +04:00
Andrey Epifancev
dfccd209a7 fix(realtime-table): плавная прокрутка колесом с накоплением цели вместо мгновенного прыжка
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 18:37:02 +04:00
Andrey Epifancev
36d8192221 perf(realtime-table): шаг прокрутки колесом мыши ×2 (AURORA-1944)
Хук useWheelScrollStep перехватывает щелчок колеса мыши над таблицей и
прокручивает вдвое больше (~100 px браузера -> 200 px). Тачпад, Ctrl и
Shift + колесо, горизонтальная прокрутка и поля ввода не меняются.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 18:26:04 +04:00
Andrey Epifancev
ef83a6c361 test(realtime-table): шаг прокрутки колесом — чистые функции
Чистые функции getWheelScrollDelta и canScrollBy для шага прокрутки
колесом мыши в таблице форм (AURORA-1944), с тестами node:test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 18:26:04 +04:00
Andrey Epifancev
f7e553a7ab style(table): переименовать параметр escape в activeCellCss (biome)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:14:53 +04:00
Andrey Epifancev
21aded26cc perf(table): статичные стили ячеек в CSS контейнера, overscan строк 2 и колонок 3
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:14:38 +04:00
Andrey Epifancev
4393e964f4 perf(realtime): убрать console.log каждого WebSocket-сообщения
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:10:30 +04:00
Andrey Epifancev
17dddc21d3 perf(realtime): updateCells без structuredClone и мутации входа
Копируются только строки на пути к затронутой, остальные сохраняют идентичность;
без изменений возвращается тот же data. Отсутствующие в row.data ключи теперь
вставляются (нужно для AURORA-1844/1848). Тесты с паритетом к прежней реализации.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:10:30 +04:00
Andrey Epifancev
12a315b04a perf(table): фиксированная высота строк вместо measureElement (лист, свод 1, свод 2)
Высота строки и ячейки задана явно в rem, виртуализатор не читает offsetHeight.
Мёртвая muiTableRowProps удалена. Overscan строк свода 2: 8 -> 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:10:21 +04:00
Andrey Epifancev
bdb00afc5a test(table): хелпер createFixedRowVirtualizerOptions без чтения layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:10:21 +04:00
Andrey Epifancev
365becc55a perf(таблица): стабильные колбэки поиска для SettingsPanel
onSearchNext/onSearchPrevious были стрелками в JSX и ломали memo панели.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:09:26 +04:00
Andrey Epifancev
c724197682 perf(таблица): вынести состояние модалок листа из RealtimeTable в SheetModals
Открытие модалки больше не перерисовывает RealtimeTable: состояние живёт
в memo-компоненте SheetModals, наружу открывается через ref.open(kind).
Проверки выделенной строки остаются в таблице. Редьюсер вынесен в
utils/sheetModalsState.js с node-тестом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:09:11 +04:00
PotapovaA
7174703149 изменение дублей accessorKey 2026-10-20 16:21:42 +03:00
PotapovaA
bce897f4ed правки 2026-10-16 14:55:58 +03:00
PotapovaA
6c3cd5b2e0 добавление селекта для изменения разрядности в твблицах 2026-10-16 14:41:19 +03:00
PotapovaA
f3539a5f36 новые своды для проектов 2026-10-01 18:20:30 +03:00
172b343c69 export-optimize-refresh: очередь загрузки при экспорте 2026-09-30 20:40:21 +03:00
341e8b3936 last-column: Колонка Сумма оплаты структуры формы 4 2026-09-30 14:02:41 +03:00
PotapovaA
02a24954e5 исправила цвета колонок 2026-09-29 15:48:11 +03:00
PotapovaA
253e5d7c82 удаление задач 2026-09-28 19:12:03 +03:00
PotapovaA
056d00b2b4 Merge branch 'test' into ui-tasks 2026-09-28 17:38:04 +03:00
1e02b0ca61 fix-columns: добавил комментарий, строки из Лимита не удаляются 2026-09-28 13:19:26 +03:00
PotapovaA
d5728c8e08 изменен список задач + удалила не используемые файлы 2026-09-25 14:45:27 +03:00
d6da54ecf4 form3-expense: добавил новые статьи в форму 3, возможность удаления задач 2026-09-25 14:20:04 +03:00
e01c0c105f Merge pull request 'add-columns-spod-4-form' (#176) from add-columns-spod-4-form into test
Reviewed-on: #176
2026-09-24 15:11:46 +03:00
PotapovaA
b4ba58a8d8 переезд на новую версию либы 2026-09-24 15:11:09 +03:00
PotapovaA
15ac95f7d7 добавила колонки + переехала на @babel/traverse@^7.28.5 2026-09-24 15:10:52 +03:00
adfc2dda81 form3-pages: новая разметка третьей формы, сводные отчеты по третьей форме на бэке 2026-09-24 12:28:27 +03:00
PotapovaA
f87098f11e исправила цвета, сделала поярче breadcrumbs и исправила поиск в этапах 2026-09-18 16:14:52 +03:00
9ea88f99e9 Merge pull request 'fixes-form: добавил новые статьи' (#164) from fixes-form into test
Reviewed-on: #164
2026-09-16 15:44:03 +03:00
96f550caed fixes-form: добавил новые статьи 2026-09-16 15:40:35 +03:00
PotapovaA
7668b0ad70 исправила формат ячейки в ахр лимиты 2026-09-16 13:07:53 +03:00
PotapovaA
02ffff6861 fix 2026-09-16 12:57:34 +03:00
PotapovaA
7bbc1189ec поправила доступ для исполнителй дфипа, отсупы для смет и - вместо 0 в SummaryTable (проекты) 2026-09-16 12:15:54 +03:00
PotapovaA
befbc64837 исправила формат для id нуменклатуры в проектах + убрала админа из фильтра 2026-09-16 11:19:57 +03:00
5effd7b6f4 Merge pull request 'add-stage-front' (#159) from add-stage-front into test
Reviewed-on: #159
2026-09-15 12:45:21 +03:00
PotapovaA
e7f0fb665d добавила страницу с созданием/редактированием для предопрделенных этапов 2026-09-15 12:39:43 +03:00
922add04ef new-rows: новые строки в формах 2026-09-15 10:30:27 +03:00
PotapovaA
e1596e8782 fix style 2026-09-14 12:51:20 +03:00
PotapovaA
37a93f400d исправила цвета в таблице 2026-09-14 11:39:14 +03:00
PotapovaA
51019c16b6 fix button 2026-09-11 15:33:37 +03:00
PotapovaA
9f19695db4 добавить навигацию и отметки последних открытых задач и листов 2026-09-11 15:22:22 +03:00
PotapovaA
e82999f2a6 переименовала навзание колонок в AHR 2026-09-10 17:06:47 +03:00
PotapovaA
3e7f44f8d4 правки для таблицы 2026-09-10 16:33:25 +03:00
169353e115 Merge pull request 'добавила кнопки "сбросить фильтр"' (#152) from add-btn-reset-filter into test
Reviewed-on: #152
2026-09-09 18:35:34 +03:00
PotapovaA
4acb6ac658 добавила кнопки "сбросить фильтр" 2026-09-09 18:35:07 +03:00
4c31eab244 vsp-choice-fix: можно добавить выбор всп в этап 2026-09-09 13:47:16 +03:00