- Редактор: убрано накопление целей съёмки — на карте только одно
перекрестие текущей точки (pickTarget заменяется при каждом клике),
с перекрестия убрана подпись. Правая панель переименована в
«Опорная точка прицеливания» с координатами.
- 24-часовой формат: lang="ru-RU" на всех datetime-local инпутах
(Планы, фильтры заявок на карте, создание/фильтр заявок), иначе
браузер рендерил их по локали ОС в AM/PM.
Фронт (pcp-tgu-ops-ui):
- тест-страж utcTime.guard.test.ts: запрещает Date.parse / new Date(string) /
toLocale* без timeZone вне utils/utcTime; тестовые фикстуры переведены на parseUtc.
Бэкенд:
- UTC-now: LocalDateTime.now() -> LocalDateTime.now(ZoneOffset.UTC) по всем сервисам
(entity-дефолты, воркеры, use case'ы) и в тестовых фикстурах.
- Конвертации к UTC (баги на не-UTC JVM, каждая с регресс-тестом в не-UTC поясе):
- tgu: VisibilityPayloadParser, SyncSpacecraftFromNsiUseCase (Instant -> UTC LocalDateTime);
- mission-planing: MissionPlaningService (OffsetDateTime -> UTC через toUtcLocalDateTime);
- dynamic-plan: RequestServiceClient (OffsetDateTime -> UTC);
- slots: SlotRepositoryImpl (getObject(LocalDateTime) вместо getTimestamp().toLocalDateTime()).
- Контрактные сериализационные тесты формата на проводе (naive без зоны / Z):
PlanResponse (tgu), RequestResponseDto (request, эталон), TguPlanning DTO (ui).
- KDoc-инвариант «=UTC» на UI-facing DTO (tgu PlanResponse, ui-service DTO вкладки ТГУ).
Документация: docs/standards/DATETIME_UTC.md (соглашение, таблица сервисов, под-задачи на миграцию к Z),
docs/standards/CHECKLIST.md (пункт про UTC на API).
- Слева выводим даты начала/конца плана и корректные счётчики
съёмки/сброса (из plan modes, а не из заглушки-черновика).
- На таймлайне показываем реальные включения плана (read-only): убран
фейковый «сброс на весь интервал»; вместо линии «сейчас» — маркеры
начала и конца плана; клик по включению открывает его инфо справа.
- Включения съёмки и сброса разнесены на два ряда (верх/низ) и различаются
цветом, слева — подписи рядов.
- Нижняя панель: активная дорожка резиновая — примыкает к низу и не
пустует, при подъёме панели ряды расширяются; высота бара ограничена
потолком и центрируется в ряду, чтобы узкие включения не вытягивались.
- Время в редакторе парсится/форматируется через utils/utcTime.
Время бэка (naive LocalDateTime и OffsetDateTime) разбиралось через
new Date(string)/Date.parse, из-за чего naive-строки трактовались как
локальное время браузера: вкладки расходились по времени, а путь создания
заявки сдвигал введённое время на офсет. Ввёл единую точку utils/utcTime
(parseUtc/formatUtc*/toUtcInputValue/toUtcIso) и перевёл на неё вкладки
«Планы», «Заявки», «Карта 2D» — чтение, пикеры диапазона, создание заявки.
Плюс на вкладке «Планы» график по умолчанию открывается на интервал
сейчас−30 мин … сейчас+3 дня.
docs/tasks/TASK_datetime-utc-consistency.md — ТЗ на сверку всей группы
сервисов pcp на единообразие времени.
drawPlanWorks проецировал точки напрямую и проверял видимость по одной
копии мира: полигон, пересекающий 180°, рисовался через всю карту, а слой
мигал «то есть, то нет» при зуме/панораме. Перенёс паттерн из
drawRequests/drawSwath: unwrapX (склейка контура через шов) + отрисовка в
трёх копиях мира с culling по каждой.
С остальными КА мы не работаем, поэтому отсекаем их сразу на входе в
loadData: фильтруем платформы по статусу и оставляем планы только для
эксплуатируемых КА (по norad-id), иначе неoperational-аппарат вернулся бы
fallback-строкой по плану в buildPlatformsForInterval.
Статусы SUPERSEDED/EXPIRED удалены из модели tgu-service, поэтому чистим их и
во фронте, чтобы не описывать несуществующие состояния.
- tguTypes: убраны EXPIRED/SUPERSEDED из union TguPlanStatus.
- tguStatus: удалены их стили; заодно снят осиротевший фильтр
isActivePlanStatus/ACTIVE_PLAN_STATUSES (после удаления чекбокса не нужен).
- tguTimelineMapper: EXPIRED убран из PROBLEM_STATUSES.
- tgu-planning.css: удалены классы .status-superseded/.status-expired и
осиротевший блок .tgu-timeline-controls.
- TguPlanningPage: убран тумблер «Показать историю версий» вместе со стейтом
showHistory и фильтром timelinePlans — таймлайн рендерит все планы из API
напрямую (перестали скрываться AWAITING_LAYIN/REJECTED/LAYIN_FAILED/NOT_ACCEPTED).
EXPIRED в requestTypes (статус заявок) — отдельный домен, не тронут.
Раньше таймлайн рисовал планы всех статусов, включая историю версий
(SUPERSEDED/EXPIRED/REJECTED), из-за чего активная цепочка тонула в
наложении старых планов. Теперь по умолчанию показываются только
актуальные планы (PLANNED/ISSUING/WAITING_DECISION/ACCEPTED), а историю
версий можно включить чекбоксом над таймлайном.
Новая вкладка «Заявки»: показ заявок за интервал на 2D-карте,
создание заявки рисованием полигона на карте с формой параметров
(Оптика/РСА) и удаление выбранной заявки (createRequest/deleteRequest,
RequestCreatePanel/RequestDetailsPanel, polygonToWkt). В Tgu2DMapView
добавлен изолированный режим рисования полигона.
2D-карта: панели информации о станции и о заявках, слой станций
(stationsApi), поддержка выбора объектов через спатиальный индекс.
Список слоёв упрощён — трасса/полоса/маркеры КА убраны из переключателя,
по умолчанию включены работы плана, станции и заявки.
Режим «Сброс» теперь рабочий: загружает ЗРВ станций
(ballisticsApi.fetchSatelliteRva), даёт оператору выбрать зону, затем
показывает съёмки плана, заканчивающиеся строго до начала зоны, и
сохраняет сброс в плане (missionPlanningApi.saveDropRoute → DropPanel).
Старый фейковый DownlinkPanel на stationPasses убран из потока.
Режим «Съёмка» сохраняет маршрут через saveSurveyRoute.
Времена ЗРВ приходят как LocalDateTime без зоны и трактуются как UTC
(helper localDateTimeMs), чтобы сравнивать с временами съёмок.
В vite-прокси добавлены pcp-ballistics, pcp-mission и stations.
Polygons crossing the antimeridian were rendered with a large visual jump.
Now each polygon is drawn three times (dx = 0, ±worldSize) after unwrapping
X-coordinates, with viewport culling to skip invisible copies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tgu-editor.css: add .map-pass-selector styles — floating panel with
semi-transparent background, range slider track, fill, tick marks, draggable
thumbs, and per-handle labels showing orbit number + UTC time.
docs: update PCP_ARCHITECTURE.md to reflect pcp-tgu-ops-ui is now a real SPA
(not a placeholder); add PCP_TGU_OPS_UI_CAPABILITY_MAP.md describing feature
areas and data sources for the TGU ops frontend.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
drawTracks: detect antimeridian crossing by comparing consecutive screen X
positions against worldSize/2; use moveTo instead of lineTo on large jumps
so tracks don't draw a horizontal line across the globe.
Tgu2DMapView: replace the heuristic lon-range check (> 300°) with an exact
condition — skip bbox culling when the canvas is wider than the world tile
(entire globe visible) or when topLeft.lon >= bottomRight.lon (viewport
straddles the antimeridian). Both cases previously produced a nonsensical
bbox that hid polygons near ±180°.
drawRequests: remove per-polygon screen-space culling; viewport filtering is
already handled upstream by visiblePolygons, so the redundant check was
incorrectly hiding requests at high zoom levels near canvas edges.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace synthetic orbit calculation (Kepler + spacecraft ID hash) with real
data from pcp-ballistics-service via a new proxy endpoint in pcp-ui-service.
Backend:
- TguPlanningController: add GET /api/tgu-planning/spacecraft/{noradId}/flight-line
that proxies FlightLineDTO[] from BallisticsService for a given time interval
Frontend:
- Fetch FlightLineDTO[] (revolution, time, lat/long, swath boundaries) using
the spacecraft's noradId for the current 24h map window
- Group points by real revolution number to build OrbitPassInfo[] with actual
orbit numbers and UTC times instead of synthetic Kepler-based estimates
- Build ground track MapLines and swath MapPolygons from real coordinates;
swath polygon = outer-left edge forward + outer-right edge reversed
- Enable swath layer in the editor map; draw with teal fill/stroke matching
the track colour
- MapPassSelector now shows real revolution numbers in header and handle labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
На вкладке Редактор 2D-карта теперь показывает включения выбранного плана
и новые съёмки, добавленные в текущей сессии.
- editorApi: типы PlanSurveyMode/PlanDropMode/PlanMode и fetchPlanModes —
вызывает GET /api/current-plans/missions/{planId}/modes на pcp-mission-planing-service,
где planId TGU совпадает с missionId (выяснено по Camunda-процессу)
- TguEditorTab: загружает включения при выборе плана, строит MapPolygon[]
из SURVEY-режимов через parseWktPolygon(contourWkt), включён слой planWorks
- Tgu2DMapView: разделены pending-маркер (оранжевый, выбор точки)
и confirmed-маркеры (бирюзовые, подтверждённые съёмки из драфта);
клик на маркер съёмки открывает WorkInspector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch the 2D map sidebar from single-spacecraft selection to per-spacecraft visibility toggles, add a show-all action, and update map tab labels and styles for the all-spacecraft view.
Port the TGU editor prototype into pcp-tgu-ops-ui as a new editor tab, add draft/conflict/pass logic with tests, extend the 2D map picking API, and include editor styles/theme aliases and task/prototype docs.
Validation: npm run test; npm run build in services/pcp-tgu-ops-ui.