Commit Graph

16 Commits

Author SHA1 Message Date
Дмитрий Соловьев 33b56ba951 feat(slots): снятие брони пачками с прогрессом (симметрично бронированию)
Бэк (slots-service):
- DELETE /booking/batch (cancelReqSlots) — снятие выбранных броней пачкой;
  одиночный DELETE теперь request-aware (нужен requestId), чтобы шаренный
  между заявками слот рвал только связь своей заявки, а не сносил бронь.
- BookedSlotViewDTO (+toViewDTO) с cycle БРОНИ — slotKey совпадает с ответом
  POST booking/request; GET booking/by-request отдаёт View.

Фронт (pcp-tgu-ui-service):
- runChunked + ChunkProgress: бронь и снятие идут пачками по 200 с общим
  прогресс-баром (стиль/позиция как у оверлея «Расчёт слотов…», сверху).
- «Снять выбранные», «Снять всё» и ✕ в строке — единый чанковый движок
  runCancel (а не bulk-запрос), брони слиты в строки таблицы и выбираемы.

Тесты: SlotServiceCancelTest (шаринг/единоличная/cycle-регрессия), runChunked,
slotsApi.cancelBookedSlots/fetchBookedSlotsByRequest.
2026-06-15 14:26:06 +03:00
Дмитрий Соловьев b9adbce207 style(design): FINDING-003 — занятый слот приглушённо-красным бейджем (статусы сканируются) 2026-06-15 11:45:51 +03:00
Дмитрий Соловьев 1c9cdf4ad2 style(design): FINDING-002 — заголовки таблицы слотов на --text-muted (контраст AA) 2026-06-15 11:43:36 +03:00
Дмитрий Соловьев 6db196066d style(design): FINDING-001 — числовые колонки слотов (Длит./Крен) по правому краю + tabular-nums 2026-06-15 11:43:00 +03:00
Дмитрий Соловьев 7f9cd34ae9 build(tgu-ui): lockfile для @tanstack/react-virtual; игнорировать requests.json (скретч) 2026-06-15 11:35:16 +03:00
Дмитрий Соловьев a5f3f0e375 fix(tgu-ui): таблица слотов — слить виток/цикл, секунды в начале, длительность
По замечаниям: Крен и Статус не помещались (8 колонок на узкую панель).
- «Виток» теперь = виток / ветвь / цикл (281 / восх / 1); отдельная «Слот/цикл» убрана
- «Начало» с секундами (formatLocalDateTimeSeconds) — слоты короткие, без секунд начало=конец
- «Конец» заменён на «Длит., с» (slotDurationSec); colSpan распорок 8→7
- Крен и Статус снова видны

Тесты 70/70, build чисто.
2026-06-15 11:10:49 +03:00
Дмитрий Соловьев c64222a90d feat(tgu-ui): бронирование слотов — виртуализация, автоподбор покрытия, эргономичный мультивыбор
Вкладка «Слоты» масштабирована под ~20k слотов/мес без торможения:
- wktCache: контур слота парсится один раз (кэш по slotKey), не на каждый ререндер сцены
- виртуализация таблицы (@tanstack/react-virtual): в DOM только видимое окно строк
- автоподбор покрытия: проброс coverageStrategy (GREEDY/CONTINUOUS) в request-cover,
  результат — преднабор брони (solver не дублируется, используется бэкендный)
- мультивыбор: Shift-диапазон по отсортированному списку, «все сутки»/«видимые»,
  счётчик охвата выбора
- бронь крупных наборов чанками (по 200) + подтверждение выше 500 + прогресс
- отмена расчёта (AbortController), мягкая подсказка перегруза карты
- чистая логика выбора/чанкинга вынесена в slotSelection.ts + юнит-тесты

Тесты: 70/70 (17 новых). tsc -b и vite build чисто.
2026-06-11 17:09:58 +03:00
Дмитрий Соловьев 345529cde0 chore: сохранение текущих изменений (deploy local-bundle/local-jar, request-service, slots UI markedObjectIds)
Безопасный коммит незакоммиченной работы перед реализацией бронирования слотов.
Вне коммита оставлены: package-lock.json (пустой, мусор), requests.json (scratch-данные).
2026-06-11 14:00:12 +03:00
Дмитрий Соловьев 6689351ef0 feat(tgu-ui): вкладка «Слоты» — расчёт покрытия и бронирование слотов заявки
- новая вкладка: заявки интервала на карте, выбор заявки кликом/инспектором,
  расчёт слотов покрытия, бронирование и снятие брони
- выбор заявки без выпадающего списка (не масштабируется на ~10к): все заявки
  на карте, панель справа с кнопкой «Выбрать», имя выбранной заявки в тулбаре,
  кнопка «Сброс», фильтр заявок по интервалу
- бронь отмечаем по ответу POST booking/request (by-request отдаёт слот в чужом
  cycle-фрейме — ключ не совпадал, бейдж «бронь» не появлялся)
- подсветка и автоскролл активной строки по клику на слот (ручной scrollBy)
- меню выбора при плотном наложении слотов (SlotPickMenu); контур заявки
  pickable:false, чтобы не «съедать» меню; панель не закрывается при выборе
- фильтр отображения по суткам (SlotDaySelector)
- gateway: маршрут slots (/api/pcp-slots/**)
- карточка полосы обзора (swath): КА и виток в инспекторе
2026-06-11 12:20:28 +03:00
Дмитрий Соловьев 802c966347 fix(tgu-ui): подхватывать существующий черновик вместо ошибки «Conflict» при добавлении съёмки
При первой правке плана ensureDraft→createDraft(replace) падал 409, если по КА
уже есть открытый черновик на это окно (осиротевший с прошлой сессии — авто-отмена
best-effort). В UI это показывалось голым «Conflict» (на стенде не подхвачен
include-message у tgu).

Теперь на 409 от createDraft редактор подхватывает существующий черновик того же
КА с тем же окном (adoptExistingDraft через fetchDraftPlans, сверка окна ±2 c) и
продолжает в нём; если подходящего нет — читаемое сообщение со ссылкой на вкладку
«Планы» вместо «Conflict».
2026-06-10 16:13:59 +03:00
Дмитрий Соловьев 7202f7cb02 refactor(tgu-ui): единый инспектор объектов карты (MapObjectInspector) на вкладках «Карта» и «Комплексный план»
Обобщил ComplexInfoPanel в общий MapObjectInspector (tgu-map-2d): карточки для
всех типов объектов — заявка, включение комплексного плана, ячейка тепловой карты,
маршрут planWorks, станция, маркер КА, линия; список с раскрытием при наложении.

Вкладка «Карта» переведена на enableObjectChooser + onObjectsAtPoint + правый
инспектор — заменила разрозненные Tgu2DMapRequestsPanel/Tgu2DMapStationPanel (удалены)
и объектную часть нижней плашки (Tgu2DMapDetails ужат до контекста плана). Вкладка
«Комплексный план» использует тот же инспектор.

RequestAtPoint переехал в tgu-requests/RequestDetailsPanel (нужен вкладке «Заявки»).
2026-06-10 15:58:55 +03:00
Дмитрий Соловьев bdbc874f41 feat(tgu-ui): тепловая карта приоритетов и инспектор объектов на вкладке «Комплексный план»
Чекбокс «Тепловая карта» — фоновый слой-заливка ячеек сетки заданий по важности
(cool→hot), источник GET /api/pcp-request/v1/cells/priority-map (cellsApi + drawHeatmap).
Heatmap — полноценный слой MapPolygon (layer "heatmap", importance/cellNum), участвует
в spatial-индексе и chooser, рисуется под контурами плана/заявок.

Клик по объекту открывает правый инспектор ComplexInfoPanel (по аналогии с редактором):
карточки ячейки приоритета, включения комплексного плана и заявки; при наложении —
список объектов под точкой клика с раскрытием. При включённой тепловой карте ячейка
всегда идёт первой в списке и раскрыта по умолчанию.

Бэклог #44 отмечен сделанным.
2026-06-10 15:47:18 +03:00
Дмитрий Соловьев 11380fced5 fix(tgu-ui): гасить «Создать черновик» для стартовавшего плана (replace→422)
Кнопка предлагала replace-черновик для уже стартовавшего плана, хотя бэк
(CreateDraftUseCase.createReplaceDraft) возвращает 422 «окно выдачи заморожено».
Гард canCreateDraftFromPlan теперь требует startInFuture (зеркалит редактор);
для стартовавших eligible-планов вместо кнопки — amber-подсказка про fork-forward.
2026-06-10 15:46:57 +03:00
Дмитрий Соловьев 3765efb4fe feat(ui): перевести фронт с pcp-ui-service на источники, снять gateway catch-all
Запросы tguApi.ts (platforms/plans/decision/dismiss/restore/confirm-layin)
и flight-line переведены с прокси /api/tgu-planning через умирающий
pcp-ui-service на прямые вызовы pcp-tgu-service (/api/pcp-tgu, decision и
confirm-layin — на тест-контроллер /test/tgu/*) и pcp-ballistics-service.
flight-line перенесён в ballisticsApi.ts. editorApi.ts modes переведён с
/api/current-plans на /api/pcp-mission. UX-перевод ошибок решения уже жил во
фронте (errorMessage в tguApi.ts), серверная обвязка ui-service дублировала.

Из config-repo/pcp-gateway-service.yaml снят маршрут ui-catch-all: не-матчнутый
/api/** теперь отдаёт 404 на gateway, а не уходит в pcp-ui-service.

Шаг 8 (вывод сервиса из эксплуатации: compose/helm/CI/реестр + удаление кода)
отложен до проверки репойнта на живом стенде; сервис пока задеплоен без
маршрутов. См. docs/план-перевода-с-pcp-ui-service.md и задачу #40 бэклога.
2026-06-10 14:47:05 +03:00
Дмитрий Соловьев ab3a787da5 feat(gateway): сервис pcp-gateway-service + сворачивание маршрутизации фронта на него
- новый Spring Cloud Gateway (WebFlux): доменные маршруты /api/pcp-<x>/**
  со StripPrefix=2, /api/stations без среза пути, catch-all /api/** → ui-service;
  опциональная JWT-валидация на edge (gateway.security.jwt-enabled, по умолчанию off)
- config-repo: pcp-gateway-service.yaml (маршруты) + порт/адрес gateway в реестрах
  application-{local,docker-local,dev}
- build: репозитории переведены на mavenCentral (nstart-proxy закомментирован),
  включены mavenLocal/gradlePluginPortal; settings: include модуля
- pcp-tgu-ui-service: vite-proxy и nginx.conf свёрнуты на единый /api → gateway
  (вместо набора per-service правил)
- deploy: сервис gateway в docker-compose; helm-чарт pcp-gateway-service
- CI: .gitlab/ci/pcp-gateway-service.yml + проводка в .gitlab-ci.yml
2026-06-10 13:34:16 +03:00
Дмитрий Соловьев 505bf1f31c Новый сервис pcp-tgu-ui-service: ТГУ-фронт на headless-auth nstart + платформенный CI/деплой 2026-06-09 14:00:24 +03:00