# Observatio Terrae (pcp) — карта сервисов, взаимодействие и контракты > Базовый справочный документ для доработки системы планирования ДЗЗ. > Составлен из исходного кода (контроллеры, Kafka listeners/publishers, HTTP-клиенты) и `config-repo`. > Помечено явно, что **проверено по коду**, а что **требует уточнения** (`⚠`). Стек: Kotlin + Spring Boot, Spring Cloud Config, Spring Boot Admin, Camunda 8 / Zeebe (оркестрация), Kafka (события), PostgreSQL (БД на сервис, Flyway), Helm + GitLab CI. --- ## 1. Карта сервисов — кто за что отвечает ### Доменные сервисы | Сервис | Зона ответственности | REST base | Хранит | Kafka (in / out) | Зрелость* | |---|---|---|---|---|---| | **pcp-request-service** | Приём и жизненный цикл заявок на съёмку; сетка Земли (earth-grid), геопривязка ячеек, сопоставление маршрутов с заявками | `/v1/requests`, `/v1/cells`, `/v1/grid` | заявки, ячейки сетки, outbox | in: `pcp.route.georeference.v1` · out: `pcp.request.completed.v1` (outbox) | 🟢 высокая | | **pcp-route-processing-service** | Приём «паспортов маршрутов», нормализация/геопривязка, ретрансляция дальше; собственный outbox + DLQ | `/api/route-processing` (test) | outbox маршрутов | in: `pcp.request.survey-georeference.v1` · out: `pcp.route.georeference.v1`, `pcp.route.in.v1`, DLQ | 🟢 высокая | | **pcp-satellite-catalog-service** | Каталог КА (источник истины): спутники, группы, observation/slot-профили | `/api/satellites`, `/api/satellite-groups` | каталог КА, профили | out: `pcp.satellites` (`SatelliteDeletedEvent`) | 🟡 средняя (мало тестов) | | **pcp-ballistics-service** | Баллистика: орбиты, ЗРВ/RVA, узлы, трассы, time-extract по TLE | `/api/satellites`, `/api/obj-view`, `/api/tle`, `/api/rva` | орбитальные данные | in: `pcp.tle` (IC/ICRV/TLE фильтры), `pcp.satellites` | 🟡 средняя | | **tle-monitoring-service** | Подтяжка TLE (CelesTrak), мониторинг каталога | — | TLE-история | in: `pcp.satellites` · out: `pcp.tle` ⚠ | 🟡 средняя | | **pcp-coverage-scheme-service** | Расчёт схемы покрытия (coverage scheme) | `/api/coverage-schemes` | результаты схем | in: `pcp.satellites` | 🟡 средняя | | **slots-service** | Слоты сброса/ресурсы: расчёт, бронирование, статусы слотов | (см. контроллеры) | слоты, брони | in/out: `pcp.slots.status.v1` (`BookedSlotsStatusChangedEvent`); in: `pcp.satellites` | 🟢 высокая (лучшее покрытие тестами) | | **pcp-complex-mission-service** | Комплексный план по тепловой карте методом слотов; снапшоты планов | `/api/satellites`, `/api/com-plan` | комплексные планы, снапшоты | in: `pcp.satellites` | 🟢 высокая | | **pcp-mission-planing-service** | План по конкретному КА: съёмка / сброс / стирание; **хост Zeebe-воркеров** оркестрации | `/api/missions` | миссии, режимы | in: `pcp.slots.status.v1`, `pcp.route.in.v1`, `pcp.satellites` | 🔴 низкая (есть заглушки в `FlowService`) | | **pcp-dynamic-plan-service** | Динамический/текущий план (greedy-математика, расчёт по интервалам) | `/v1/main/calcPlan` | прогоны (runs), результаты | in: `pcp.satellites` | 🟡 средняя | | **pcp-tgu-service** | Операторская оркестрация (ТГУ/Mission Ops): окна видимости, выдача планов, решения по планам; **деплой и запуск BPMN** | `/api/plans`, `/api/platforms`, `/test/tgu` | планы КА, dedup-таблицы | in: `pcp.tgu.satellite-plan-decision.v1` · out: `pcp.tgu.visibility-windows-changed.v1` | 🟢 высокая | | **pcp-stations-service** | Каталог наземных станций приёма | `/api/stations` | станции | — | 🟡 средняя | | **pcp-ui-service** | BFF/агрегатор для веб-UI и 3D-глобуса (CZML/Cesium); проксирует во все сервисы | `/requests`, `/map`, `/api/*` | — (stateless) | — | 🟡 средняя | \* Зрелость = оценка по соотношению тестов, наличию idempotency/outbox, чистоте слоёв и отсутствию заглушек (см. предыдущий разбор). ### Инфраструктурные модули | Модуль | Роль | |---|---| | **spring-cloud-config-server** | Раздаёт конфигурацию из `config-repo` всем сервисам | | **pcp-srpring-boot-admin-server** | Spring Boot Admin — мониторинг/health всех сервисов (опечатка в имени: `srpring`) | | **pcp-tgu-ops-ui** | Отдельная SPA Mission Ops/TGU; карта возможностей и источников данных: [`PCP_TGU_OPS_UI_CAPABILITY_MAP.md`](PCP_TGU_OPS_UI_CAPABILITY_MAP.md) | | **libs/pcp-types-lib** | Общие DTO и конверт `KafkaMessage`, перечисление `PcpKafkaEvent` | | **libs/ballistics-lib** | Общие баллистические расчёты | --- ## 2. Диаграммы взаимодействия ### 2.1. Синхронные зависимости (REST) — кто кого вызывает Рёбра восстановлены из ключей `*-service*` base-url в `config-repo` и имён HTTP-клиентов в коде. ```mermaid flowchart TD UI[pcp-ui-service
BFF / агрегатор] REQ[pcp-request-service
заявки + earth-grid] CAT[pcp-satellite-catalog-service
каталог КА] BAL[pcp-ballistics-service] CM[pcp-complex-mission-service] MP[pcp-mission-planing-service] SL[slots-service] CS[pcp-coverage-scheme-service] DP[pcp-dynamic-plan-service] TGU[pcp-tgu-service] ST[pcp-stations-service] TLE[tle-monitoring-service] UI --> REQ & CM & DP & TGU & CAT & BAL & ST & SL & MP & CS CM --> BAL & REQ & CAT & ST & SL & CS MP --> BAL & CM & CAT & ST SL --> REQ & CAT DP --> REQ & BAL & CAT CS --> BAL & CM & CAT TLE --> CM & CAT TGU --> BAL TLE -.внешний.-> CTRAK[(CelesTrak)] TGU -.внешний.-> ORD[(ordinis.nstart.cloud
классификатор платформ + external points)] ``` Наблюдения по графу: - `pcp-satellite-catalog-service` и `pcp-ballistics-service` — самые востребованные (почти все зовут их). Кандидаты на повышенные требования к SLA/надёжности. - `pcp-ui-service` — точка агрегации (BFF), завязан на всё. - ⚠ Есть взаимный вызов `complex-mission ⇄ coverage-scheme` (CM зовёт CS на расчёт, CS в конфиге знает про CM) — проверить, нет ли циклической зависимости в рантайме. ### 2.2. Событийный слой (Kafka) — потоки данных ```mermaid flowchart LR EXT[Внешний источник / UI ⚠] -->|pcp.request.survey-georeference.v1| RP[route-processing] RP -->|pcp.route.georeference.v1| REQ[request-service] RP -->|pcp.route.in.v1| MP[mission-planing] REQ -->|pcp.request.completed.v1 ⚠ потребитель| Q1{{?}} CAT[satellite-catalog] -->|pcp.satellites / SatelliteDeletedEvent| BAL[ballistics] CAT --> TLEM[tle-monitoring] CAT --> SL[slots] CAT --> MP CAT --> CM[complex-mission] CAT --> DP[dynamic-plan] TLEM -->|pcp.tle| BAL SL -->|pcp.slots.status.v1 / BookedSlotsStatusChanged| MP SL -->|pcp.slots.status.v1| SL MissionOps[Mission Ops / КА ⚠] -->|pcp.tgu.satellite-plan-decision.v1| TGU[tgu-service] TGU -->|pcp.tgu.visibility-windows-changed.v1| TGU ``` ### 2.3. Сквозной сценарий планирования (sequence) Упрощённый happy-path от заявки до выдачи задания на КА. ```mermaid sequenceDiagram participant U as UI participant RQ as request-service participant RP as route-processing participant CM as complex-mission participant SL as slots-service participant TGU as tgu-service (Camunda) participant MP as mission-planing (Zeebe workers) U->>RQ: POST заявка на съёмку RP-->>RQ: pcp.route.georeference.v1 (геопривязанные маршруты) RQ->>RQ: сопоставление маршрут↔заявка, RequestCompleted (outbox) U->>CM: POST /api/com-plan/process (комплексный план) CM->>SL: расчёт/бронирование слотов CM->>CM: снапшот комплексного плана U->>TGU: POST /test/tgu/plans/{id}/issue TGU->>TGU: start BPMN createSatelliteMission Note over TGU,MP: Zeebe job dispatch по jobType TGU-->>MP: calculateSatelliteSurveyMissions MP->>MP: план съёмки TGU-->>MP: calculateSatelliteDropMissions MP->>MP: план сброса TGU-->>MP: sendSatellitePlan MP-->>TGU: Message_SatellitePlanAccepted ⚠ (сейчас имитация) MissionOps-->>TGU: pcp.tgu.satellite-plan-decision.v1 (ACCEPTED/REJECTED) TGU->>TGU: updateAcceptedPlanSlots BPMN → updateSlotsStatus ``` --- ## 3. Контракты между сервисами ### 3.1. Оркестрация Camunda 8 / Zeebe **Деплой BPMN:** `pcp-tgu-service` через `@Deployment` при старте грузит: `classpath:BPMN/createSatelliteMission.bpmn`, `classpath:BPMN/updateAcceptedPlanSlots.bpmn`. **Zeebe job workers** (реализованы в `pcp-mission-planing-service/FlowService`): | jobType | Назначение | Вход (process variables) | Выход | Примечание | |---|---|---|---|---| | `calculateSatelliteSurveyMissions` | План съёмки | `satellitePlanId`, `spacecraftId`, `planStartTime`, `planEndTime` | `modes: Int` | `autoComplete=false` | | `calculateSatelliteDropMissions` | План сброса | `satellitePlanId` | `modes: Int` | — | | `sendSatellitePlan` | Отправка плана на КА | `satellitePlanId` | — | ⚠ сейчас `Thread.sleep` + имитация подтверждения | | `updateSlotsStatus` | Подтверждение, обновление слотов | `satellitePlanId` | `slots: List` | используется в `updateAcceptedPlanSlots` | **Camunda message:** `Message_SatellitePlanAccepted`, `correlationKey = satellitePlanId`. > ⚠ `schemes/pcp_v1.bpmn` — большой концептуальный процесс (шлюзы, параллельные ветки, подпроцессы), **не задеплоен** и без jobType. Реально работает только минимальный `createSatelliteMission.bpmn` (start → 3 service task → end, без обработки ошибок). ### 3.2. Kafka-топики (реестр) Конверт по умолчанию — `KafkaMessage` из `pcp-types-lib`: поля `type`, `data`, `traceId`, `correlationId`, `id`, `source`, `time`. Тип события — enum `PcpKafkaEvent`. | Топик | Producer | Consumer(s) | Тип события / payload | Ключ | |---|---|---|---|---| | `pcp.satellites` | satellite-catalog | ballistics, tle-monitoring, slots, mission-planing, complex-mission, dynamic-plan | `SatelliteDeletedEvent` (`satelliteId`, `noradId`) | `satelliteId` | | `pcp.tle` | tle-monitoring / catalog ⚠ | ballistics (фильтры IC/ICRV/TLE) | TLE / `ICPlacedEvent` / `ICRVPlacedEvent` / `ICUpdatedEvent` | ⚠ | | `pcp.request.survey-georeference.v1` | внешний / UI ⚠ | route-processing | RoutePassport (сырой) | ⚠ | | `pcp.request.survey-georeference-dlq.v1` | route-processing | (DLQ) | — | — | | `pcp.route.georeference.v1` | route-processing | request-service | `RoutePassportDto` (геопривязанный) | ⚠ | | `pcp.route.in.v1` | route-processing | mission-planing (`ModeStatusChangedEvent`) | processed route / mode-status | ⚠ | | `pcp.request.in.v1` | request-service / UI ⚠ | ⚠ требует уточнения | `RequestPlacedEvent` | ⚠ | | `pcp.request.completed.v1` | request-service (outbox) | ⚠ требует уточнения | RequestCompleted | `aggregateId` (UUID заявки) | | `pcp.slots.status.v1` | slots-service | mission-planing, slots-service (self) | `BookedSlotsStatusChangedEvent` | ⚠ | | `pcp.tgu.satellite-plan-decision.v1` | Mission Ops / КА ⚠ | tgu-service | `PlanDecisionMessage` (ACCEPTED/REJECTED, `attemptId`) | ⚠ | | `pcp.tgu.visibility-windows-changed.v1` | tgu-service | tgu-service | `VisibilityWindowsChangedMessage` | ⚠ | > ⚠ Реализация консьюмеров неоднородна: одни читают типизированный `KafkaMessage`, другие парсят сырое дерево и ждут поле `data`; используются обе версии Jackson (2 и 3). Это первый кандидат на унификацию контракта. ### 3.3. REST-эндпоинты (контракты API по сервисам) **request-service** (`/v1`) ``` GET /v1/requests/{id} GET /v1/requests/{requestId}/with-cells DELETE /v1/requests/{id} GET /v1/cells/with-requests GET /v1/grid/settings PUT /v1/grid/settings POST /v1/grid/rebuild ``` **satellite-catalog-service** (`/api/satellites`, `/api/satellite-groups`) ``` GET/PUT/DELETE /api/satellites/{satellite_id} GET /api/satellites/by-norad/{norad_id} GET/POST/PUT/DELETE /api/satellites/{satellite_id}/observation-profile GET/POST/PUT/DELETE /api/satellites/{satellite_id}/slot-profile POST /api/satellites/batch GET/PUT/DELETE /api/satellite-groups/{group_id} ``` **ballistics-service** (`/api`) ``` POST /api/satellites/{satellite_id}/extract-time POST /api/satellites/{satellite_id}/clear GET /api/satellites/{norad_id}/orbit | /asc-node | /flight-line | /rva GET /api/satellites/orbit/availability[/{id}] POST /api/obj-view/mpl-square | /mpl-point GET /api/obj-view/cell-coverage/{number} POST /api/tle/parse | /api/tle/rva ``` **complex-mission-service** (`/api`) ``` POST /api/com-plan/process | /clear GET/DELETE /api/com-plan/runs/{id} GET /api/com-plan/runs | /runs/{id}/modes | /cell-with-mars/{cell_number} GET /api/satellites/{satellite_id}[/mission|/modes|/snapshots|/mission/statistics|/mission-for-paint] GET /api/satellites/snapshots[/{snapshot_id}[/modes]] | /modes POST /api/satellites/prepare ``` **mission-planing-service** (`/api/missions`) ``` GET /api/missions/{mission_id}[/modes] GET /api/missions/modes/satellite POST /api/missions/{mission_id}/drops/calculate POST /api/missions/{mission_id}/surveys/calculate POST /api/missions/{mission_id}/confirm PUT /api/missions/survey-modes/{mode_id}/status PUT/DELETE /api/missions/{mission_id} ``` **slots-service / coverage-scheme / dynamic-plan / stations / tgu** ``` coverage-scheme : POST /api/coverage-schemes/calculate dynamic-plan : POST /v1/main/calcPlan ; GET /v1/main/calcPlan/runs|/{runId}[/result|/routes|/intervals] stations : GET /api/stations[/{station_id}] ; POST /api/stations ; DELETE /api/stations/{station_id} tgu : GET /api/plans/{spacecraftId} ; /api/platforms ; POST /test/tgu/plans/{planId}/issue|/decision ; /spacecraft/{id}/refresh-visibility|/rebuild-plans ``` **ui-service** — BFF, агрегирует вызовы: `/requests/*`, `/map`, `/api/requests`, `/api/slots/booking/request`, `/api/com-plan/*`, `/api/tgu-planning/*`, `/api/current-plans/*`, `/api/dynamic-plan/*`, `/api/stations/*`. ### 3.4. Внешние интеграции | Откуда | Куда | Назначение | |---|---|---| | tle-monitoring-service | CelesTrak | загрузка TLE | | tgu-service | `https://ordinis.nstart.cloud/api/v1/spacecraft/records` | классификатор платформ (фильтр `OPERATIONAL`), кэш 15m | | tgu-service | external points API (`pcp.services.ballistics`) | внешние точки (lookahead 3 дня) | --- ## 4. Открытые вопросы для уточнения перед доработкой Эти пункты помечены `⚠` выше — их стоит зафиксировать до изменений: 1. Producer топиков `pcp.request.survey-georeference.v1` и `pcp.request.in.v1` (внешняя система или UI?). 2. Consumer `pcp.request.completed.v1` — кто слушает завершённые заявки (предположительно complex-mission/планирование). 3. Producer `pcp.tgu.satellite-plan-decision.v1` — реальный Mission Ops/КА vs текущая имитация в `FlowService`. 4. Точные DTO payload для `pcp.tle`, `pcp.route.in.v1`, `pcp.slots.status.v1` — зафиксировать схемы. 5. Возможная циклическая зависимость `complex-mission ⇄ coverage-scheme` в рантайме. 6. Расхождение задеплоенного `createSatelliteMission.bpmn` и концептуального `schemes/pcp_v1.bpmn` — какой считать целевым. --- *Документ описывает текущее состояние «как есть». При доработке обновлять разделы 2–3 синхронно с изменениями контроллеров, listener'ов и `config-repo`.*