Commit Graph

169 Commits

Author SHA1 Message Date
Дмитрий Соловьев c07fce093e config-server: git-репозиторий и деплой на observatio-terrae (ветка dev, deploy-token-5) 2026-06-09 17:19:51 +03:00
Дмитрий Соловьев ccbb77787f config-server(dev): переключение на репозиторий observatio-terrae, ветка dev 2026-06-09 17:08:40 +03:00
Дмитрий Соловьев c2a847fc2e ci: рубильник RUN_ALL для прогона всех gradle-сервисов (кроме pcp-tgu-ui-service)
Run pipeline + RUN_ALL=true прогоняет test/build/package всех бэкендов
независимо от changes; deploy:dev остаётся ручным. Обычный пуш по-прежнему
собирает только изменившийся сервис. pcp-tgu-ui-service source-guard-нут
(только push), чтобы не попадать в RUN_ALL/web-пайплайны.
2026-06-09 14:55:04 +03:00
Дмитрий Соловьев f11e143a9c ci: триггер ребилда всех gradle-сервисов (кроме pcp-tgu-ui-service) 2026-06-09 14:08:09 +03:00
Дмитрий Соловьев e51c7965ec config(pcp-request-service): вернуть env-плейсхолдеры datasource в shared-профиль
Merge 0ec8c30 затёр ${SPRING_DATASOURCE_URL/USERNAME/PASSWORD} на конкретный
postgres в shared-профиле, из-за чего падал тест RequestServiceConfigTest
(shared datasource keeps environment placeholders) и красился CI.
Плейсхолдеры восстановлены; local-профиль остаётся с конкретным postgres.
2026-06-09 14:00:24 +03:00
Дмитрий Соловьев cb439319c5 pcp-tgu-ui-service в группе сервисов pcp: регистрация в CI + per-service Node-пайплайн + helm-чарт 2026-06-09 14:00:24 +03:00
Дмитрий Соловьев f292291e04 Удаление старого pcp-tgu-ops-ui: заменён на pcp-tgu-ui-service 2026-06-09 14:00:24 +03:00
Дмитрий Соловьев 505bf1f31c Новый сервис pcp-tgu-ui-service: ТГУ-фронт на headless-auth nstart + платформенный CI/деплой 2026-06-09 14:00:24 +03:00
emelianov 0b617594fd Merge remote-tracking branch 'origin/dev' into dev 2026-06-09 13:41:54 +03:00
emelianov e6822b6caf ПУУД с постоянным азимутом 2026-06-09 13:41:50 +03:00
Дмитрий Соловьев a5c6b66826 CI: перевод сборки на gradle jdk21-ubi10 2026-06-09 12:43:35 +03:00
Дмитрий Соловьев 060bcce9f2 Edit pcp-ballistics-service.yml перевод на java 21 2026-06-09 09:33:18 +00:00
emelianov faf88eaf94 ПУУД с постоянным азимутом 2026-06-09 12:31:53 +03:00
emelianov e1e96b1ff0 Merge remote-tracking branch 'origin/dev' into dev 2026-06-08 18:43:11 +03:00
emelianov 69f2d6ad4f ПУУД с постоянной ориентацией 2026-06-08 18:43:05 +03:00
Дмитрий Соловьев 2a04a81bc0 Merge branch 'tgu-ops-ui' into 'dev'
Сервис pgu-ops-ui

See merge request 2-6/2-6-4/missionis/observatio-terrae!2
2026-06-08 11:58:27 +00:00
Дмитрий Соловьев 8ac4afa195 config: адреса инфраструктуры на localhost (application-dev/docker-local, create_pcp_databases) 2026-06-08 14:45:50 +03:00
Дмитрий Соловьев 1a0348cdeb merge: влить dev (ПУУД, angular-motion-lib, fix requests) в tgu-ops-ui 2026-06-08 14:25:29 +03:00
Дмитрий Соловьев 5fa3ceaac9 feat(группировка): реальная съёмка/сброс/связь и заполнение борта
Дашборд «Группировка» наполняется из плана: режимы SURVEY/DROP → интервалы
съёмки и сброса с контуром и станцией, окна ЗРВ выделены в отдельную «связь»
(раньше показывались как сброс). Заполнение бортового накопителя считается
из объёмов маршрутов (volumeMb) с модельной ёмкостью 500 ГБ
(ONBOARD_CAPACITY_MB) — memAt по таймлайну, подсветка контура/линии сброса
на карте.
2026-06-08 14:00:03 +03:00
Дмитрий Соловьев 2c8b317c42 fix(editor): зажим крена маршрута к ±45°
Бэкенд считает геометрию видимости/маршрута только в |крен| ≤ 45°,
поэтому предел снижен с 89° до 45°. Введён общий clampRoll (зажим +
округление до 0.1°), применён при ручной правке крена (кнопки ±,
прямой ввод) и при загрузке сохранённого маршрута в окно построения
(легаси-маршрут вне ±45° зажимается).
2026-06-08 13:59:53 +03:00
Дмитрий Соловьев ff0b2639c9 feat(editor-map): отдельный цвет линии сброса на карте
Сброс рисуется приглушённо-малиновым (rgba(214,96,138,0.82), ширина 5)
поверх трассы: контрастно к бирюзовым виткам, не сливается с заявками
и контурами съёмки.
2026-06-08 13:59:46 +03:00
Дмитрий Соловьев c74327011a docs(бэклог): #39 — авторасчёт выдаёт маршруты с креном >45° (slots/каталог)
Зафиксирована диагностика: корень — оптические полосы Emissio в каталоге
(satellite_slot_angle) уходят до 50.42°, slots-service берёт центр полосы
без зажима по 45°. Версия «логика локации» проверена и отклонена.
2026-06-08 13:55:01 +03:00
Дмитрий Соловьев c1259c3105 pcp-request-service: аудит-фиксы RS1/RS3/RS6/RS7
RS1 (#29): планировщик истечения заявок — RequestExpiryService
(@Scheduled + FOR UPDATE SKIP LOCKED, мультиинстанс-safe), refreshStatus
вызывается и при создании заявки.
RS7 (#35): единый топик pcp.request.status.v1 → geoportal (COMPLETED/EXPIRED
в payload), замена orphan pcp.request.completed.v1; эмиссия из matching и
expiry через тот же outbox; backoff/next_attempt_at/cap для outbox FAILED.
RS3 (#31): DefaultErrorHandler + DeadLetterPublishingRecoverer
(DLQ pcp.route.georeference-dlq.v1), bounded retry, контрактные ошибки в DLQ.
RS6 (#34): проброс coverageRequiredPercent из API, разведение терминов
покрытие/важность.

Доки: бэклог, аудит сервиса заданий, карты взаимодействий.
RS2 (#30) отложено до #28, RS5 (#33) — до роста требований к точности.
2026-06-06 23:47:19 +03:00
Дмитрий Соловьев 2499aebf2d routes: объём маршрута (volumeMb) — расчёт, хранение в БД и отображение
Объём режима = скорость × длительность, Мбайт: съёмка 120 Мбайт/с (12 ГБ / 100 с), сброс — канал 1200 Мбит/с ÷ 8. Единый источник — ModeDataRates в pcp-types-lib. Хранится колонкой volume_mb (Flyway V10 mission-planing, V9 complex-mission, бэкфилл из duration), заполняется на всех путях построения через @PrePersist/@PreUpdate. DTO отдают вычисляемое read-only поле (та же формула). Фронт pcp-tgu-ops-ui показывает объём в редакторе (инспектор, построенный маршрут) и в сводке комплексного плана.
2026-06-06 18:34:29 +03:00
Дмитрий Соловьев 316e0ee552 pcp-tgu: эндпоинт /test/tgu/platforms/load-manual принимает JSON
Тестовый эндпоинт загрузки платформ принимает root-array НСИ в теле запроса (@RequestBody List<NsiPlatformDto>) вместо пути к файлу; маршрут load-from-file переименован в load-manual.
2026-06-06 18:33:47 +03:00
Дмитрий Соловьев a06dfcac4e docs: карта kafka/http/camunda взаимодействий сервисов 2026-06-06 00:12:27 +03:00
Дмитрий Соловьев 45fd6e8da9 docs: бэклог и бриф pcp-tgu-ops-ui, ui-прототипы tgu-ops
Добавлены docs/бэклог-pcp-tgu-ops-ui.md, бриф дашборда состояния группировки
и прототипы docs/ui-prototypes/tgu-ops/; удалён устаревший
docs/задачи для pcp-tgu-ops-ui.txt.
2026-06-06 00:04:36 +03:00
Дмитрий Соловьев 3239e7d26c pcp-tgu-ops-ui: правки API-клиентов, вкладок и стилей
complexPlanApi/missionPlanningApi, TguComplexPlanTab, TguEditorTab,
стили tgu-editor.css/tgu-planning.css.
2026-06-06 00:04:25 +03:00
Дмитрий Соловьев 1d07588690 backend: правки complex-mission/mission-planing/request + тестовые паспорта
ComplexPlanRunOrchestrationService, MissionController, MissionPlaningService,
KafkaProducerConfig; обновлены тестовые JSON-паспорта route-processing.
2026-06-06 00:04:17 +03:00
Дмитрий Соловьев b454c01c09 config: адреса config-server и окружения на localhost
application.yaml/yml всех сервисов и config-repo переведены с 192.168.60.x
на localhost (дефолты CONFIG_SERVER_URI и пр.); обновлены примеры в
changeIpInCurrentFolder.sh и create_pcp_databases.sh.
2026-06-06 00:04:09 +03:00
Дмитрий Соловьев 26bd1f111d build: Java 21 для всех модулей + чистка мёртвого versions.camunda
versions.java 17→21 (toolchain и Kotlin jvmTarget везде завязаны на это свойство;
рантайм-образы liberica-openjre 21 уже совпадают). pcp-tgu-service переведён с
хардкода of(21) на общее свойство. Удалён неиспользуемый versions.camunda=8.4.15
(оба потребителя Camunda уже на camunda-spring-boot-4-starter:8.8.10).
2026-06-05 23:53:30 +03:00
Дмитрий Соловьев 821de2b0c0 pcp-tgu-ops-ui: вкладка «Группировка» (состояние группировки) на реальных данных
Встраивание дизайн-хэндоффа constellation dashboard отдельной вкладкой рядом с
Планы/Карта/Комплексный план/Редактор/Заявки.

- модуль src/features/constellation/ (прототип на JSX + realData.ts/ConstellationTab.tsx)
- реальные данные вместо симуляции: платформы (OPERATIONAL), станции, заявки→ROI (WKT),
  трасса flight-line как эфемерида (сэмплер позиции через env.subSat), ЗРВ→сброс,
  съёмка по пролёту над ROI; оптика/локация — по имени КА из НСИ
- d3-geo + topojson-client; карта world-atlas локально (без CDN)
- изоляция стилей на .cdash (конфликт --line с theme.css), высота .app=100%
- локальное время в часах и оси таймлайна (конвенция проекта)
- allowJs:true в tsconfig.app.json под JSX-модуль
2026-06-05 23:37:47 +03:00
Дмитрий Соловьев ea207088bc pcp-tgu-ops-ui: правка включения через окно построения + обновление состава плана
Редактор: инспектор включения теперь только просмотр (время с десятыми долями
секунды), кнопки «Редактировать»→«Удалить». «Редактировать» открывает окно
построения, предзаполненное параметрами, и при сохранении заменяет маршрут.
Прицеливание опорной точки — явный режим: активно, пока не выбран проход.

Планы: состав включений выбранного плана перечитывается при возврате на вкладку
«Планы», иначе счётчик маршрутов оставался прежним после правок в редакторе.
2026-06-05 16:13:33 +03:00
Дмитрий Соловьев 995396da3b pcp-tgu-ops-ui: вкладка «Комплексный план» + слой карты
Новая вкладка планирования «Комплексный план» (TguComplexPlanTab) и
одноимённый слой на 2D-карте, выключенный по умолчанию.

- TguComplexPlanTab + complexPlanApi (через прокси /api/pcp-complex,
  добавлен в vite.config.ts) — данные из pcp-complex-mission-service;
- слой complexPlan: тип в mapLayerTypes/mapTypes/mapSelectionTypes,
  отрисовка drawComplexPlan, тоггл и подписи в Tgu2DMapTab/Tgu2DMapView;
- вкладка complex в TguActiveTab, кнопка в TguToolbar, рендер в
  TguPlanningPage; complexPlan: false в дефолтах слоёв и в редакторе/
  заявках/тесте интервала.
2026-06-05 14:51:59 +03:00
Дмитрий Соловьев 69dfd8025d pcp-tgu: слоты по факту закладки, запрет ранней закладки, шире рейл редактора
- слоты (acceptedPlanSlotsUpdate) занимаются на LAID_IN, а не на ACCEPT —
  до закладки план ещё может быть вытеснен коррекцией
- «Подтвердить закладку» недоступно, пока начало плана в будущем
- левая панель редактора 15.5rem → 17rem (цифры статистики у границы)
2026-06-04 21:15:13 +03:00
Дмитрий Соловьев bd2bc9d583 pcp-tgu: редактор — расчёт плана съёмки+сброса одной операцией, очистка плана, удаление включений
Вкладка «Редактор»:
- Кнопка «Рассчитать план» — запускает surveys/calculate → drops/calculate
  одной операцией на черновике (ensureDraft), затем перечитывает включения.
  Источник комплексного плана (snapshot этапа 4) выбирает бэкенд по интервалу.
  Вызовы идут напрямую в pcp-mission-planing-service (/api/pcp-mission).
  Ручные маршруты съёмки (source=MANUAL) сохраняются при пересчёте.
- Кнопка «Очистить план» — новый эндпоинт DELETE /api/missions/{id}/modes
  (clearPlan) сносит ВСЕ включения, включая ручные, с бронями и связями.
- Удаление маршрута съёмки / сброса в правой панели с подтверждением:
  WorkInspector.canDelete показывает кнопку удаления и для рассчитанных
  (read-only) включений, когда есть черновик; удаление через deleteMode.
2026-06-04 21:03:44 +03:00
Дмитрий Соловьев 9f1756a9f9 pcp-tgu-ops-ui: снятие плана с учёта + индикатор КА = нерешённый отказ
Индикатор «проблема КА» теперь означает НЕразрешённый отказ, а не «есть
хоть один REJECTED»: unresolvedProblemSpacecraftIds не красит КА, если
проблемный план снят с учёта (dismissedAt) либо цепочка уже продвинулась
за него (advanced-план со стартом не раньше). Исправленные и снятые
отказы гаснут сами.

- кнопка «Снять с учёта» / «Вернуть на учёт» в деталях плана для
  терминально-негативных статусов + бейдж «снят с учёта»;
- dismissPlan/restorePlan (через BFF), поле dismissedAt в модели;
- снятый план приглушён и штрихуется на таймлайне;
- тесты на unresolvedProblemSpacecraftIds.
2026-06-04 16:59:28 +03:00
Дмитрий Соловьев e6f1219c9c pcp-tgu: «снять с учёта» терминально-негативный план (dismissed_at)
Оператор деактивирует отменённый/неудавшийся план, чтобы он не считался
проблемой и не красил индикатор КА. Косметико-статистический флаг
dismissed_at: статус плана и состояние цепочки не трогает, обратим.

- planned_plan.dismissed_at (V14) + поле в сущности и PlanResponse;
- DismissPlanUseCase.dismiss/restore с гардом на терминально-негативные
  статусы (REJECTED, START_AMBIGUOUS, LAYIN_FAILED, NOT_ACCEPTED,
  SUPERSEDED), идемпотентно; эндпоинты POST /api/plans/{id}/dismiss|restore;
- BFF (pcp-ui-service): проброс dismissedAt в TguPlanResponse и
  /api/tgu-planning/plans/{id}/dismiss|restore;
- тест DismissPlanUseCaseTest; починен предсуществующий TguPlanningServiceTest
  (мок-JSON не отдавал projected — WebClient падал на null→boolean).
2026-06-04 16:59:13 +03:00
Дмитрий Соловьев fae57e957e pcp-tgu-ops-ui: «Создать план» берёт план в фокусе как базу-предысторию
Диалог получает initialBasePlanId — выбранный (в фокусе) план; селект
«Базовое состояние» предзаполняется им, если он годится в базу (тот же КА,
не PLANNED/DRAFT), иначе остаётся «без истории». Оператор может сменить
базу вручную.
2026-06-04 16:32:49 +03:00
Дмитрий Соловьев faadc63028 pcp-tgu-ops-ui: тест-кнопка закладки, статус SUPERSEDED, подсветка цепочки
- Тест-кнопка «Подтвердить закладку» в деталях плана для AWAITING_LAYIN
  (под подписью «ТЕСТОВЫЙ ФУНКЦИОНАЛ», с подтверждением). Гасится, если по
  КА уже заложен план со стартом в пределах ±10 мин (дублирует бэкенд-гард).
- Статус SUPERSEDED: стиль/подпись/легенда.
- Поиск уже созданного черновика — по слоту (КА + окно исходного плана),
  т.к. basePlanId черновика теперь = предшественник, а не исходный план.
- Таймлайн: при выборе плана непричастные планы гаснут, а текущий/прошлый/
  следующий обводятся яркими рамками (current #2563EB, prev #94A3B8,
  next #F59E0B). Асимметрия: prev (явная база выбранного) показывается
  всегда, даже REJECTED/SUPERSEDED; next (обратная ссылка) не подсвечивает
  мёртвые статусы — иначе вытесненная коррекция ложно числилась бы
  «следующей» у заложенного плана.
2026-06-04 16:13:13 +03:00
Дмитрий Соловьев 87905311b1 pcp-tgu: якорь цепочки на LAID_IN, параллельные выдачи, SUPERSEDED
Базой цепочки план становится на ЗАКЛАДКЕ (LAID_IN), а не на приёмке.
После принятого плана можно отправить коррекцию — она тоже примется;
несколько выдач «в полёте» по одному КА теперь норма, а не конфликт.

- ACCEPT больше не двигает currentBasePlanId/chainVersion и не запирает
  слот — только переводит план в AWAITING_LAYIN.
- Новый позитивный топик layin-confirmed + LayinConfirmedConsumer →
  handleLayinConfirmed: AWAITING_LAYIN → LAID_IN, план становится базой
  (chainVersion++), конкуренты на пересекающемся окне гасятся в новый
  терминальный статус SUPERSEDED. Гард ±10 мин (LAYIN_MIN_SEPARATION_MINUTES):
  нельзя заложить план со стартом в пределах 10 мин от уже заложенного (409).
- «В полёте» считается из статусов планов (ISSUING/WAITING_DECISION), а не
  из единственного active-слота; снят гард «идёт выдача другого плана».
  IssueDuePlanWorker гейтится hasBlockingInFlight, базу нового плана берёт
  как latestCommittedPlanId; grace больше не двигает базу.
- PlanProjectionService якорит по самому дальнему committed-окну
  {ISSUING, WAITING_DECISION, AWAITING_LAYIN, LAID_IN}.
- REJECT ставит паузу только если по КА не осталось живых кандидатов.
- CreateDraftUseCase: replace-черновик наследует ПРЕДШЕСТВЕННИКА исходного
  плана (base.basePlanId), а не сам план — коррекция занимает тот же слот;
  fork-forward по-прежнему ссылается на базу. Идемпотентность черновиков —
  по слоту (КА + окно), а не по basePlanId.
- Тест-контроллер: POST /test/tgu/plans/{id}/confirm-layin (через BFF
  pcp-ui-service) — имитация события «план заложен».
- Док PCP_TGU_PLAN_STATUS_LIFECYCLE обновлён (LAID_IN-переход, SUPERSEDED).
2026-06-04 16:13:02 +03:00
Дмитрий Соловьев 5235142fa6 pcp-tgu: редактор — таймлайн зум/драг/секундная шкала, подтверждения в деталях плана, без авто-кнопок
- детали плана: подтверждение (confirm) на «Отправить» и «Удалить» черновика
- редактор: убраны кнопки «Применить»/«Отмена», undo/redo и сдвиг ◀▶ из тулбара
- окно: предел отдаления план±1ч, дефолт тоже план±1ч; зум кнопками и колесом мыши (центр — курсор)
- таймлайн: drag по горизонтали как карту; минимум окна ~10с
- ось времени: адаптивные деления от секунд до недель, секунды в подписи при мелком масштабе
2026-06-04 14:20:01 +03:00
Дмитрий Соловьев 9e7cae4a56 docs: актуализация списка задач pcp-tgu-ops-ui (закрытые пункты, витки/полосы обзора) 2026-06-04 13:30:21 +03:00
Дмитрий Соловьев f0e56b6e2a pcp-tgu: редактор — стабильные витки, плейсхолдер без плана, черновик без авто-перехода
Вкладка «Планы»:
- «Создать черновик на основе плана» больше не перекидывает в редактор: черновик
  создаётся, выбирается на схеме (тумблер «Черновики» вкл.) и показывается подсказка —
  оператор сам переходит в «Редактор».

Редактор:
- Витки больше не пропадают «иногда»: жизненный цикл flightLineData теперь полностью
  внутри fetch-эффекта на [noradId, mapRange] (сброс + перезагрузка атомарны). Раньше
  трассу сбрасывал общий reset по ссылке selectedPlan, а перезагружал отдельный эффект —
  фоновый loadData пересобирал selectedPlan с тем же окном, mapRange по значению не менялся,
  фетч не перезапускался, витки молча исчезали.
- Явный индикатор вместо немой пустоты: «Загрузка трассы…» / «Нет данных трассы на это окно».
- После удаления открытого черновика редактор не «всплывал» обратно: guard загрузки включений
  не тянет режимы по устаревшему draftPlanId, когда план не выбран.
- Редактор включений гейтится на наличие плана (план == миссия): без плана — плейсхолдер
  «Выберите КА и план…». Иначе после удаления черновика вкладка оставалась активной по КА
  (витки, режим съёмки), хотя редактировать нечего.
2026-06-04 13:30:12 +03:00
emelianov b62a7cf8ef ПУУД 2026-06-04 13:22:48 +03:00
Дмитрий Соловьев 9e5460d646 pcp-tgu: редактор/карта — выбор объекта (линии/сбросы) и проброс текста ошибок
- Карта 2D: клик по линии (трасса КА / сеанс сброса) выбирает объект — общий
  инспектор с таймлайном; MapLine.name, тип selection "line" (kind track/drop),
  связь с работой через modeId; spatialIndex учитывает линии.
- Редактор (TguEditorTab/EditorPanels): единый WorkInspector для клика по карте
  и по таймлайну, подсветка соответствующего включения, стили tgu-editor.css.
- config-repo: server.error.include-message=always для pcp-tgu-service и
  pcp-mission-planing-service — UI показывает причину 4xx (reason/exception),
  а не только HTTP-фразу.
2026-06-04 13:08:08 +03:00
Дмитрий Соловьев d9f8260120 pcp-tgu: вкладка «Планы» — черновик на основе плана + правки UX
- Кнопка «Создать черновик на основе плана» в деталях плана: создаёт
  replace-черновик (окно 1:1, все включения клонируются) и открывает редактор.
  Путь «сделать исправленный план» вместо повторной отправки. Доступна для
  персистентных правимых баз; DRAFT/PLANNED/LAID_IN исключены (для LAID_IN
  replace 1:1 запрещён). Если черновик по базе уже есть — открываем его.
- Диалог создания плана цепочки: вместо списка будущих планов и «Отправить
  вручную» — кнопка «Редактировать» (сразу в редактор черновика).
- Сайдбар: повторный клик по выбранному КА снимает выбор (показать все КА).
2026-06-04 13:07:09 +03:00
Дмитрий Соловьев fd3603a086 pcp-tgu: статусы плана — актуальная легенда с тултипами + док жизненного цикла
- STATUS_STYLES в порядке жизненного цикла: убран легаси ACCEPTED, добавлены
  LAID_IN/NOT_ACCEPTED/LAYIN_FAILED, у каждого статуса человеческое описание.
- Легенда вкладки «Планы»: тултипы по наведению (title=description), убрана
  устаревшая приписка про стрелки.
- TimelineStatusStyle: добавлено обязательное поле description.
- HandlePlanDecisionUseCase: TODO(layin-confirmed) — обработчик приёма события
  «план заложен» (AWAITING_LAYIN → LAID_IN) ещё не реализован.
- docs/architect/PCP_TGU_PLAN_STATUS_LIFECYCLE.md: справочник по каждому статусу
  (когда наступает / что значит / какой переход), диаграмма, зарезервированный ACCEPTED.
2026-06-04 13:06:58 +03:00
Дмитрий Соловьев a5a1cdfa64 pcp-tgu: связь планов на таймлайне по basePlanId вместо стрелок/нумерации по времени
Стрелки и бейджи-цифры цепочки строились по ВРЕМЕНИ (соседние по времени
планы КА) и ложно сцепляли два черновика с одной предысторией как «один —
предок другого». Убираем эту логику целиком (buildSequentialLinks,
buildPlanChains, CHAIN_COLORS/chainColor, тип TimelineLink) и показываем
связь только по реальному basePlanId:

- В деталях плана — строка basePlanId (рендерится, если задан).
- При выборе плана на таймлайне подсвечиваем гало два соседних звена по
  basePlanId: предыдущий (planId == basePlanId выбранного) — тёплый янтарь,
  следующий (basePlanId == выбранный) — бирюза. Следующих может быть
  несколько (черновики с одной предысторией) — подсвечиваются все.

Бэкенд: basePlanId/projected проброшены через PlanResponse (pcp-tgu-service)
и TguPlanResponse (pcp-ui-service — прокси /api/tgu-planning/plans, иначе
Jackson срезал бы неизвестные поля). Требует рестарт обоих сервисов.

Заодно: очистка нотиса деталей при смене фокуса (план/ЗРВ) и блок
«Включения» (счётчики съёмок/сбросов) в правой панели.
2026-06-04 11:44:28 +03:00
Дмитрий Соловьев 294b17757d pcp: время — сквозной naive LocalDateTime как локальное настенное время (без UTC)
Отказ от остаточной UTC-семантики: naive LocalDateTime трактуется как
локальное время единой зоны всех сервисов.

Backend (границы внешних систем):
- VisibilityPayloadParser, SyncSpacecraftFromNsiUseCase: ZoneOffset.UTC →
  ZoneId.systemDefault() для проекции внешних Instant/ISO-с-Z в naive.
- тесты границ перевёрнуты на systemDefault (под Europe/Moscow ждут +3).
- чистка UTC-формулировок в DTO-комментариях, мёртвых ссылок на
  docs/standards/DATETIME_UTC.md.

Frontend (pcp-tgu-ops-ui):
- utils/utcTime.ts → utils/localTime.ts: parseLocal/formatLocal*/toLocalIso/
  toLocalInputValue с локальной семантикой (без дописывания Z и timeZone:UTC).
- замена getUTC*/Date.UTC/toISOString-сериализации на локальные аналоги.
- убраны пользовательские подписи «UTC» в редакторе/таймлайне.
- удалён utcTime.guard.test.ts (форсил обратный UTC-инвариант); тест-фикстуры
  сделаны зоно-независимыми. tsc + vitest зелёные под TZ=UTC и TZ=Europe/Moscow.

Включает также прочие незакоммиченные правки рабочего дерева.
2026-06-04 09:50:39 +03:00