Commit Graph

188 Commits

Author SHA1 Message Date
Дмитрий Соловьев 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
emelianov faedd21f43 расчет ПУУД 2026-06-04 09:39:27 +03:00
Дмитрий Соловьев 5049395911 pcp-tgu: пауза цепочки после REJECTED + режим «Черновики» + UI цепочек/ЗРВ
Бэкенд (pcp-tgu-service):
- REJECTED трактуется как «план неправильный»: авто-перевыдача больше НЕ
  взводится, цепочка встаёт на паузу (новый флаг
  SpacecraftPlanningStateEntity.pausedAfterReject, миграция V13). Технические
  негативы («не заложен»/«не принят») по-прежнему дают срочную перевыдачу.
- Пауза централизована в PlanProjectionService.project(): для отклонённой
  цепочки проекция пустая, воркер выдачи ничего не материализует. Флаг
  снимается при ручной выдаче/промоуте черновика/приёмке (оператор вмешался).
- Режим «Черновики»: GET /plans/drafts (опц. ?spacecraftId) -> только DRAFT.
- Гард дублей черновиков: (КА + начало + конец) уникальны среди DRAFT,
  повторное создание окна -> 409.
- ZrvWindowMatcher: сравнение по истинной abs-длительности Duration (<=1с),
  устойчиво к усечению ISO на фронте до целых секунд.

Фронт (pcp-tgu-ops-ui): вкладка «Планы» — таймлайн цепочек, детали плана,
панель ЗРВ (TguZrvPanel), диалог создания цепочки, режим черновиков.

Удалён устаревший docs/tasks/TASK_tgu-plan-versioning-manual-reissue.md.
2026-06-04 00:04:47 +03:00
Дмитрий Соловьев 3638afdb85 pcp: откат UTC-слоя — сквозной naive LocalDateTime без зоны на проводе
Возврат к модели «настенных часов»: одна ISO-строка без зоны
("2026-05-29T01:00:00") от БД до экрана, никто не привязывает её к
часовому поясу, сдвигаться нечему.

Бэкенд — снять зону с границы API:
- DTO OffsetDateTime/Instant -> LocalDateTime и убрана конвертация
  atOffset(ZoneOffset.UTC)/toUtcOffset() в фабриках и мапперах:
  tgu PlanResponse/NewChainDTOs/TguPlanningDTO, request RequestApiDtos,
  complex ComplexPlanRun*DTO, dynamic ObservationParametersDebugDTO.
- Удалён толерантный Jackson-слой: PcpTimeModule(+autoconfig, ServiceLoader,
  imports), PcpTimeModuleV3, LocalDateTimeTimeZoneSerializer; снята их
  регистрация в Camunda/Rest/dynamic JacksonConfig. Штатный JSR-310
  (JavaTimeModule + WRITE_DATES_AS_TIMESTAMPS=false) оставлен.
- Kafka-конверт KafkaMessage.time сериализуется ISO без офсета.
- mission-planing Mode/SurveyMode/DropMode entity и репозитории/сервис
  переведены на LocalDateTime; колонки БД остаются timestamptz (Hibernate
  мапит на naive без миграции — прецедент MissionEntity/PlanEntity).
- RequestServiceClient (dynamic) синхронизирован по типу с request-service.

Анти-регрессия: LocalDateTime.now(ZoneOffset.UTC) для серверных штампов
оставлен (выбор настенных часов UTC, не зона на проводе).

Фронт — снять офсет с egress: toUtcIso/фильтры отдают naive без Z
(после удаления толерантного десериализатора штатный парсер падал бы на Z).
Дисплейные хелперы (показ «как пришло», без сдвига) сохранены.

Тесты: контрактные ждут naive ISO; удалены UTC-артефакты (нормализация
офсетов) и тесты прослоек. Удалён docs/standards/DATETIME_UTC.md.

Операционно перед выкатом: сервисы катить согласованно; Kafka-топики с
ранее опубликованным офсетом +00:00 дренировать/проиграть.
2026-06-04 00:03:52 +03:00
Дмитрий Соловьев 0e534c5bd5 docs: удалить неактуальные TASK-доки (datetime-utc, tgu-editor-integration, plan-on-demand-redesign) 2026-06-03 16:26:03 +03:00
Дмитрий Соловьев 9c2d8516bc pcp: создание плана новой цепочки из вкладки «Планы» (база/без истории, окно из двух ЗРВ)
Оператор берёт за основу прошлый план (предыстория) или начинает цепочку с нуля,
набирает окно из двух реальных ЗРВ и создаёт план-кандидат; сразу показывается прогноз
будущей цепочки от него. Рабочим (якорем) план становится после ручной отправки (promote)
и приёмки — отдельного механизма якорения не вводим.

pcp-tgu-service:
- сырые ЗРВ: PlanCalculationService.rawWindows + PlanProjectionService.rawZrvWindows,
  GET /api/plans/{spacecraftId}/zrv (исходные окна снапшота, не cooked-проекция);
- CreateChainPlanUseCase + POST /api/plans/new-chain: опциональная база (клон включений
  в окно) либо пустая миссия без истории; прогноз цепочки через projectAfterWindow;
- ZrvWindowMatcher (старт+КПП одной зоны, конец — другой); assertDraftSlotStillValid
  переведён на него — единая проверка для replace/fork-forward и окна из двух ЗРВ;
- тесты: CreateChainPlanUseCaseTest (8), ZrvWindowMatcherTest (7), правки promote-тестов.

pcp-mission-planing-service:
- POST /api/missions/blank — пустая миссия для сценария «без истории» (+ 2 теста).

pcp-tgu-ops-ui:
- API fetchZrvWindows/createChainPlan; диалог «Создать план» во вкладке «Планы»
  (выбор базы, стартовой и конечной ЗРВ) с показом спрогнозированной цепочки и ручной
  отправкой; подсветка ЗРВ выбранного КА на таймлайне;
- «Целевая ЗРВ» убрана из редактора (он остаётся под replace-правку); удалён ставший
  мёртвым editorForkForward; createChainWindows + тесты.
2026-06-03 16:25:46 +03:00
Дмитрий Соловьев 057452f19d pcp-tgu-ops-ui: fork-forward в редакторе — выбор будущей ЗРВ для перевыдачи невозвратного плана
Селектор «Целевая ЗРВ» в EditorToolbar: текущий слот (replace, по умолчанию)
либо будущая ЗРВ из проекции pcp-tgu-service (fetchSpacecraftPlans →
GET /api/plans/{spacecraftId}, фильтр futureZrvWindows: PLANNED строго в
будущем, кроме базы — та же проекция, что валидирует бэк). Выбор окна
переводит обзор редактора и заставляет ensureDraft слать mode=fork-forward
(naive-UTC окно + kpp); селектор блокируется после создания DRAFT.
2026-06-03 14:12:21 +03:00
Дмитрий Соловьев 2a841fc7b3 tgu: DELETE /plans/{draftPlanId} — отказ от черновика (бэкенд + кнопка «Отмена» и авто-отмена в редакторе) 2026-06-03 13:59:52 +03:00
Дмитрий Соловьев ec67d9d83d pcp-tgu-ops-ui: Ф6 ядро — draft/validate/promote в редакторе (replace), прямой прокси /api/pcp-tgu 2026-06-03 13:53:24 +03:00
Дмитрий Соловьев ae7effe1fa pcp-tgu-service: Ф5 — promote черновика с оптимистичным локом базы (POST /plans/{id}/promote) 2026-06-03 13:36:59 +03:00
Дмитрий Соловьев 8133a5144f pcp-mission-planing: Ф4 — валидация-заглушка POST /missions/{id}/validate (контракт конфликтов, пустой diff) 2026-06-03 13:27:31 +03:00
Дмитрий Соловьев f5211fa5a0 pcp-mission-planing: Ф3 — правки контента в черновик (PATCH съёмки, DELETE включения, без авто-создания живой миссии) 2026-06-03 13:20:54 +03:00
Дмитрий Соловьев 85ce238f52 pcp: Ф2 — доработки по ревью (валидация ошибок клона, идемпотентность DRAFT, тесты)
- MissionPlaningClient: маппинг ошибок mission-planing (4xx как есть, 5xx → 502) + таймаут 30с
- CreateDraftUseCase: гард идемпотентности — второй открытый DRAFT на тот же план → 409
- cloneMission: явная валидация mode (неизвестный → 400 вместо тихого полного клона)
- константы DraftMode/CloneMode вместо строковых литералов
- kdoc: семантика fork-forward (границы-слот vs времена включений; съёмка без сброса)
- тесты: CreateDraftUseCaseTest (13 кейсов), MissionCloneTest (+съёмка без сброса)
2026-06-03 13:09:52 +03:00
Дмитрий Соловьев 0d69617420 pcp: Ф2 — черновик-клон миссии (replace + fork-forward)
mission-planing: POST /api/missions/{id}/clone — полный клон (replace)
или по перекрытию с окном (fork-forward, [start,stop) открытый правый конец);
пустые drop-mode (все съёмки вне окна) не клонируются

tgu-service: PlannedPlanStatus.DRAFT; POST /api/plans/{planId}/draft
(CreateDraftUseCase: guard replace/fork-forward, clone mission → planId=newMissionId,
компенсация при сбое); DRAFT отфильтрован из PlanQueryService read-пути;
MissionPlaningClient + MissionPlaningProperties + mission-planing.base-url в yaml

тесты: MissionCloneTest (6 граничных кейсов предиката перекрытия),
PlanQueryServiceTest (DRAFT не видна в ответе)
2026-06-03 12:53:57 +03:00
Дмитрий Соловьев 80e281dd6d pcp-tgu-ops-ui: панель «Параметры включения» в инспекторе маршрута
- WorkInspector показывает аппарат, виток, крен, угол захвата, центр контура (съёмка)
  и станцию/сбрасываемые съёмки (сброс)
- planModesToWorks/addShoot прокидывают planModeId, revolution, rollDeg, captureAngleDeg,
  centerLat/Lon, surveyIds в модель включения
- место под перечень заданий маршрута (привязка — позже)
- секция «Станция приёма» рендерится только в режиме правки
2026-06-03 12:40:53 +03:00
Дмитрий Соловьев e060e13b85 pcp-tgu-service: боевой POST /api/plans/{planId}/issue + гард точки невозврата
- ручная выдача вынесена из TestTguController в PlanController
- assertReissuableInSlot: 422 при LAID_IN и заморозке (now >= start - layinFreezeMinutes),
  409 при активной выдаче другого плана КА; перевыдача того же плана поверх своей
  in-flight attempt разрешена (новая attemptNo++ замещает летящую)
- REISSUABLE_STATUSES удалён — гард по времени/статусу его заместил
- layinFreezeMinutes (деф. 10) в PlanningProperties + config-repo/application yaml
- граничные тесты в IssueDuePlanWorkerOnDemandTest, переписан PlanIssueAndDecisionFlowTest
- дизайн-док версионирования (фаза 1 отмечена сделанной)
2026-06-03 12:40:03 +03:00
Дмитрий Соловьев c32e13e09c pcp-tgu-ops-ui: гасить кнопки решения по истечении grace-окна WAITING_DECISION 2026-06-03 10:00:44 +03:00
Дмитрий Соловьев 9a2ba655e1 pcp-ui-service: удалить мёртвый реактивный CorsFilterComponent (сервлет-стек его не вызывает) 2026-06-03 09:45:24 +03:00
Дмитрий Соловьев 938248d150 pcp-tgu-ops-ui: крен маршрута — один знак после запятой 2026-06-03 09:43:10 +03:00
Дмитрий Соловьев 17b8679e44 pcp-ui-service: CORS allowedOriginPatterns — фикс Invalid CORS request на POST решения плана 2026-06-03 09:43:10 +03:00
Дмитрий Соловьев b61be0afb8 pcp-tgu-ops-ui: маска ввода времени — невозможные значения недопустимы
Time24Field принимал любой текст (99:99 и т.п.), валидным он был только при
коммите/блюре. Добавлена маска maskTime: на каждый ввод оставляет цифры,
расставляет двоеточия и зажимает сегменты (часы 0-23, мин/сек 0-59) с авто-
дополнением первого разряда, поэтому набрать невозможное время нельзя.
Покрыто юнит-тестами (timeFields.test.ts).
2026-06-03 09:12:16 +03:00
Дмитрий Соловьев 51fd8a446b pcp-tgu-ops-ui: надёжный 24ч ввод времени (своё текстовое поле вместо нативного)
Нативные input type=time/datetime-local рендерят время по локали браузера/ОС
(AM/PM) и игнорируют атрибут lang в Chrome — поэтому lang=ru-RU не помогал.
Заменено на собственные контролы (components/timeFields.tsx):
- Time24Field — текстовый ввод ЧЧ:ММ[:СС] с валидацией, детерминированный 24ч;
- DateTime24Field — нативный календарь для даты + Time24Field для времени.
Подключено в окне маршрута редактора и во всех datetime-local фильтрах
(Планы, заявки на карте, создание/фильтр заявок).
2026-06-03 09:02:27 +03:00
Дмитрий Соловьев f0e16aa4e8 pcp-tgu-ops-ui: одно перекрестие опорной точки + 24ч формат времени
- Редактор: убрано накопление целей съёмки — на карте только одно
  перекрестие текущей точки (pickTarget заменяется при каждом клике),
  с перекрестия убрана подпись. Правая панель переименована в
  «Опорная точка прицеливания» с координатами.
- 24-часовой формат: lang="ru-RU" на всех datetime-local инпутах
  (Планы, фильтры заявок на карте, создание/фильтр заявок), иначе
  браузер рендерил их по локали ОС в AM/PM.
2026-06-02 23:33:41 +03:00
Дмитрий Соловьев e68c17e792 pcp-tgu-service: миграция с WebFlux на servlet/MVC
WebFlux в tgu был фиктивным: блокирующая JPA, контроллеры оборачивали
блокирующие вызовы в Mono.fromCallable{}.subscribeOn(boundedElastic()),
WebClient .block()-ался сразу. Единственный WebFlux-only сервис флота.

- build: подключён pcp-types-lib (тянет starter-web → servlet), springdoc
  webflux-ui → webmvc-ui; starter-webflux оставлен только ради WebClient
- контроллеры возвращают значения напрямую (без Mono-обёрток)
- удалено локальное Jackson-2 зеркало PcpTimeModule.kt → модуль из либы
  в CamundaJacksonConfig; Jackson-3 зеркало остаётся (Boot 4 держит
  Jackson 3 на HTTP-границе и для MVC), WebFluxJacksonConfig → RestJacksonConfig
2026-06-02 23:14:12 +03:00
Дмитрий Соловьев cde4ffa9b6 pcp-tgu-service: толерантность времени на Jackson-3 пути (REST-кодеки WebFlux) 2026-06-02 22:57:49 +03:00
Дмитрий Соловьев 84e70350b9 pcp-types-lib: Kafka-конверт time в UTC (фикс сдвига пояса)
KafkaMessage.time: LocalDateTime.now() -> now(ZoneOffset.UTC);
LocalDateTimeTimeZoneSerializer: atZone(systemDefault()) -> atOffset(UTC).

Было: локальное now() + systemDefault давали на проводе "...+03:00", и
потребитель (паттерн ...SSS[xxx] в LocalDateTime) дропал зону -> сдвиг на пояс.
Стало: "...+00:00" — инстант тот же, но стенные часы совпадают с UTC, сдвиг ушёл.

Тест LocalDateTimeTimeZoneSerializerTest: UTC-офсет без сдвига + round-trip.
DATETIME_UTC.md: баг перенесён в «Исправленные».
2026-06-02 22:48:13 +03:00
Дмитрий Соловьев 405f02aa86 pcp: слой толерантности времени — читать naive(=UTC) и Z во всём флоте
PcpTimeModule (libs/pcp-types-lib): толерантные Jackson-десериализаторы
LocalDateTime/OffsetDateTime/Instant — любой потребитель читает оба формата
на проводе и нормализует к UTC. Только чтение, формат записи не меняется.

Подключение фронтом по флоту:
- Spring Boot auto-configuration + AutoConfiguration.imports — Boot-маппер
  всех 12 сервисов на pcp-types-lib (без правок в сервисах);
- Jackson SPI (META-INF/services) — ручные мапперы с findAndRegisterModules();
- точечно: dynamic-plan/JacksonConfig (ручной ObjectMapper);
- tgu (WebFlux, не зависит от либы) — локальное зеркало модуля в
  CamundaJacksonConfig (Jackson-2 путь).

Зачем: микросервисы деплоятся независимо; с толерантностью продюсера можно
флипать LocalDateTime -> OffsetDateTime (Z) в любом порядке без синхронного
деплоя — потребитель не падает на парсинге офсета.

Тесты: PcpTimeModuleTest (оба формата -> один UTC-момент + авто-подхват SPI).
Доки: DATETIME_UTC.md (раздел 2bis + найденные баги формата), CHECKLIST.md.
2026-06-02 22:35:50 +03:00
Дмитрий Соловьев 240e12f442 pcp-tgu-ops-ui: вкладка Редактор — шаг времени маршрута и формат длительности
- RouteTimeStepper и доработки EditorPanels/TguEditorTab по вводу времени;
- formatDuration: секунды/минуты для коротких интервалов;
- стили tgu-editor.css.
2026-06-02 22:06:06 +03:00
Дмитрий Соловьев c2e2b2922f pcp: миграция времени плана ТГУ на явный Z (OffsetDateTime)
PlanResponse (pcp-tgu-service) и зависящий от него TguPlanResponse (pcp-ui-service)
переведены с naive LocalDateTime на OffsetDateTime в UTC → на проводе явная зона Z.
Домен/БД (PlannedPlanEntity/CalculatedPlan) остаются naive LocalDateTime (= UTC);
конвертация только на границе API (atOffset(ZoneOffset.UTC)). Потребитель один
(ui-service.TguPlanningService), обновлён синхронно; фронт parseUtc совместим с Z.

- контрактные тесты обновлены на Z (PlanResponseContractTest, TguPlanningDtoContractTest);
- тестовые фикстуры/ассерты приведены к OffsetDateTime/Z (PlanQueryServiceTest,
  CatalogControllerTest, TguPlanningServiceTest);
- docs/standards/DATETIME_UTC.md: отражена миграция и обновлена таблица сервисов.
2026-06-02 22:02:13 +03:00
Дмитрий Соловьев 260583b134 pcp: единообразие времени (UTC) по группе сервисов
Фронт (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).
2026-06-02 21:51:38 +03:00
Дмитрий Соловьев ac2220d063 pcp-tgu-ops-ui: вкладка Редактор — план, включения, нижняя панель
- Слева выводим даты начала/конца плана и корректные счётчики
  съёмки/сброса (из plan modes, а не из заглушки-черновика).
- На таймлайне показываем реальные включения плана (read-only): убран
  фейковый «сброс на весь интервал»; вместо линии «сейчас» — маркеры
  начала и конца плана; клик по включению открывает его инфо справа.
- Включения съёмки и сброса разнесены на два ряда (верх/низ) и различаются
  цветом, слева — подписи рядов.
- Нижняя панель: активная дорожка резиновая — примыкает к низу и не
  пустует, при подъёме панели ряды расширяются; высота бара ограничена
  потолком и центрируется в ряду, чтобы узкие включения не вытягивались.
- Время в редакторе парсится/форматируется через utils/utcTime.
2026-06-02 16:54:01 +03:00
Дмитрий Соловьев fb0332a030 pcp-tgu-ops-ui: единый UTC во времени; дефолтный диапазон Планы
Время бэка (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 на единообразие времени.
2026-06-02 16:53:48 +03:00