c1259c3105
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) — до роста требований к точности.
15 KiB
15 KiB
Бэклог pcp-tgu-ops-ui
Список задач по сервису pcp-tgu-ops-ui (и связанным бэкендам). Ведётся вручную и с помощью Claude: по просьбе — отмечаем выполненное и добавляем новые задачи.
Обозначения статуса:
[ ]— не начато[~]— в работе[x]— выполнено (переносится в раздел «Выполнено» с пометкой)
У каждой задачи есть стабильный номер #N — он не меняется при правках списка, на него удобно ссылаться. Новые задачи получают следующий свободный номер.
Задачи #12–#25 заведены по результатам аудита. Подробности, обоснование и рекомендации по каждой — в аудит-проекта-2026-06-06.md (ссылки на коды находок B/F/R/C).
Обновлено: 2026-06-06
Активные задачи
Карта и отображение
- #1 — Отображать трассы полос исходя из возможности съёмки КА. Для оптики показывать только участки, попадающие в допустимый угол Солнца.
- #2 — При клике в область, где пересекается несколько полос обзора, выводить список этих объектов на правой панели; при выборе элемента — выделять соответствующий объект на карте.
- #3 — Показ забронированных слотов на вкладках «Карта» и «Редактор». На вкладке «Редактор» они должны быть другого цвета и выделяться.
Редактор
- #4 — Показывать на вкладке «Редактор» только те заявки, которые может удовлетворить аппарат (например, для оптики не показывать заявку, для которой доступна только локация).
- #5 — Дать возможность превратить план в статусе
PLANNED(построенный цепочкой от последнегоLAID_IN) в черновик и вручную наполнить его включениями — до того, как он будет автоматически выдан по таймеру.
Комплексный план
- #6 — Пересчитывать комплексный план при бронировании новых слотов или при поступлении новой заявки.
Бэкенд / инфраструктура
- #7 — Перевести сервис станций на ordinis (по примеру получения аппаратов в сервисе tgu).
Проверка сервисов
- #27 — Проверить сервис получения паспорта маршрута по отдельности.
- #28 — Проверить связь сервиса заданий и сервиса получения паспорта маршрута между собой.
Баги
- #8 — Ошибка при попытке принять план на вкладке «Планы».
Аудит — надёжность и бэкенд
Источник и рекомендации: аудит-проекта-2026-06-06.md.
- #12 — (B1, высокий) Camunda job-воркеры в
FlowServiceмолча глотают исключения (catch { logger.warn(ex.message) }) приautoComplete=false: задача не завершается и не падает, BPMN-процесс зависает без инцидента. Завершать черезnewFailCommand/проброс наверх, логироватьerror(msg, ex). - #13 — (B2, средний) Снять симуляционную заглушку
Thread.sleep(5000)(«имитация подтверждения плана») вFlowService.sendPlanпри появлении реального канала подтверждений. - #14 — (B3, средний) Привести в порядок несогласованные пакеты-копипасты (ballistics→
pcp_request_service, complex-mission→pcp_satellites_service, ui-service и slots-service делятslots_service, request→org.nstart.dep265, tgu→без.pcp.). Отдельной задачей из-за широкого охвата. - #15 — (B4, низкий) Опечатка «srpring» в
pcp-srpring-boot-admin-serverрастиражирована по каталогу, пакету, CI, docker-compose, gradle. Чинить вместе с #14. - #16 — (B5, низкий) ~9 мест
logger.warn/error(ex.message)теряют stack trace — заменить наlogger.error("...", ex).
Аудит — фронтенд
Источник и рекомендации: аудит-проекта-2026-06-06.md.
- #17 — (F1, средний) Вынести общий
src/api/http.ts(fetchJson+extractErrorText+ маппинг ошибок):extractErrorTextпродублирован в 5 клиентах, fetch-обвязка повторяется ~22 раза. Заодно устранить расхождение приоритета полей ошибки (F5). - #18 — (F2, низкий) Перевести нетипизированный островок
features/constellation/*(.jsx/.js,allowJs) на TS или добавить декларации типов на границе. - #19 — (F3, низкий) Удалить мёртвый barrel
features/constellation/index.js(нигде не импортируется). - #20 — (F4, низкий) Декомпозировать God-компонент
TguEditorTab.tsx(1727 строк): вынести хуки (useDraftHistory,useRouteBuilder), разнести панели.
Аудит — гигиена репозитория и конфиги
Источник и рекомендации: аудит-проекта-2026-06-06.md.
- #21 — (R1, средний) Убрать из git крупные дампы в корне (
pcp_requests_converted_create_requests.json~228 КБ,response_заданияКубернетс.json~157 КБ,response_заданияЕмельянов.json~66 КБ) — перенести вsrc/test/resources/docsили удалить с добавлением в.gitignore. - #22 — (R2, низкий) Удалить посторонние артефакты в корне:
node_modules/+ пустойpackage-lock.json,obj_terra.zip; при желании добавить/package-lock.jsonв.gitignore. - #23 — (R3, низкий) Прогнать
./gradlew clean/ удалить 26 устаревших каталоговbin/(задваивают исходники, шумят при grep). - #24 — (C1, средний) Унифицировать креды БД в config-repo: привести все сервисы к переопределяемому
password: ${DB_PASSWORD:...}(как в tgu-service), убрать зашитыеpassword: password. - #25 — (C2, низкий) Сузить CORS для прода в
pcp-ui-service(allowedOriginPatterns("*")+allowCredentials) до конкретных origin; держать в курсе отсутствие CORS у напрямую вызываемых сервисов (работает только через прокси/nginx).
Аудит — сервис заданий (pcp-request-service)
Источник и рекомендации: аудит-сервис-заданий.md (коды находок RS1–RS7).
- #30 — (RS2, высокий) Матчинг засчитывает покрытие по любому геометрическому пересечению, игнорируя совместимость аппарата (
survey_type, крен, разрешение, угол Солнца). Добавить фильтр совместимости маршрут↔заявка перед зачётом покрытия; тип сенсора в паспорте маршрута согласовать в рамках #28. Отложено до #28 (решение, 2026-06-06):RoutePassportDtoне несёт явныйsurveyType— контракт фиксируется в рамках аудита связи сервисов #28, тогда же делаем фильтр. - #33 — (RS5, низкий) Площади считаются планарно в градусах (JTS
areaна EPSG:4326) — искажение для крупных/высокоширотных заявок. Перейти на геодезию (ST_Area(geography)или равновеликая проекция), когда вырастут требования к точности. Отложено по решению аудита: покрытие считается отношением площадей (планар ≈ геодезия для обычных AOI), а переключениеarea()затрагивает matching и точечные ассерты тестов — вводим при росте требований к точности.
Выполнено
- #34 — (RS6) Проброс требуемого процента покрытия из API + разведение терминов. Готово: в
CreateRequestDtoдобавлено опциональное полеcoverageRequiredPercent(0 < x ≤ 100, по умолчанию 100), оно пробрасывается в сущность и используется как порог COMPLETED; захардкоженная константа убрана. В KDoc/коде разведены «прогресс покрытия» (coverageRequiredPercent) и «важность заявки» (importance, карта приоритетов ячеек). Тесты:RequestServiceTest,RequestApiDtoContractTest. - #31 — (RS3) DLQ и error-handler для Kafka-листенера маршрутов. Готово:
KafkaConsumerConfig—DefaultErrorHandler+DeadLetterPublishingRecovererв топикpcp.route.georeference-dlq.v1, экспоненциальный bounded retry, контрактные ошибки (JsonProcessingException/ConstraintViolationException) → DLQ без ретраев, диагностические заголовки. Настройкиapp.kafka.consumer.route.*, активируется при заданномspring.kafka.bootstrap-servers. ТестKafkaConsumerConfigTest. - #35 — (RS7) Уведомление geoportal о финале заявки. Готово: единый топик
pcp.request.status.v1(заменил orphanpcp.request.completed.v1) с терминальным статусом в payload (COMPLETED/EXPIRED). Эмиссия из двух мест через тот же transactional outbox:RouteMatchingService(по покрытию) иRequestExpiryService(по сроку, #29). СервисRequestCompletedOutboxService→RequestStatusOutboxService, eventTypeREQUEST_TERMINAL_STATUS. Outbox получил backoff: колонкиattempts/next_attempt_at, удвоениеinitial→max, пределmax-attempts(терминальный FAILED). Конфигpcp.outbox.*. Тесты:OutboxPublisherServiceTest,OutboxEventRepositoryJpaTest,RequestStatusOutboxServiceTest,RequestExpiryServiceTest,RouteMatchingServiceTest. Док: интеракции обновлены. Известный мелкий зазор: заявка, созданная уже просроченной, события не шлёт (вырожденный кейс). - #29 — (RS1) Планировщик истечения заявок. Готово:
RequestExpiryService(@Scheduled,FOR UPDATE SKIP LOCKED, батчи с верхним лимитом) переводит просроченныеACCEPTED/ACTIVEвEXPIRED; несколько инстансов безопасны.refreshStatusтеперь вызывается и при создании заявки — статус приёма отражает окно (ACCEPTED/ACTIVE/EXPIRED), а не всегдаACCEPTED. Конфигpcp.request.expiry.*в config-repo. Тесты:RequestExpiryServiceTest(юнит) +RequestRepositoryJpaTest(H2). Разблокирует EXPIRED-эмиссию в #35. - #32 — (RS4) Удалить мёртвый конфиг сервиса заданий. Готово: из
config-repo/pcp-request-service.yamlубраныapp.request.cleanup-cron/cleanup-retention-daysи неиспользуемый топикapp.kafka.topics.request(pcp.request.in.v1); кода под ними не было,@Value-привязок нет. - #26 — Проверить сервис заданий (
pcp-request-service) по отдельности. Готово: аудит в аудит-сервис-заданий.md — карта взаимодействий, учёт покрытия, жизненный цикл, мультиинстанс; находки RS1–RS7 (RS1/RS2 — высокий приоритет). - #9 — Расширить вправо левую панель информации на вкладке «Редактор» (цифры у границы смотрелись плохо). Готово: commit
69dfd80, рейл 15.5rem → 17rem. - #10 — Проставлять статусы слотов только после того, как план заложен на КА. Готово: commit
69dfd80, слоты занимаются поLAID_IN, а не поACCEPT. - #11 — Запретить нажимать «Подтвердить закладку», пока начало закладки в будущем. Готово: commit
69dfd80.