diff --git a/config-repo/pcp-gateway-service.yaml b/config-repo/pcp-gateway-service.yaml index af1d5ac..33c0611 100644 --- a/config-repo/pcp-gateway-service.yaml +++ b/config-repo/pcp-gateway-service.yaml @@ -62,12 +62,10 @@ spring: uri: ${pcp.services.stations} predicates: - Path=/api/stations/** - # --- Общий catch-all /api/** -> ui-service. Матчится ПОСЛЕДНИМ (order выше). - - id: ui-catch-all - uri: ${pcp.services.ui} - predicates: - - Path=/api/** - order: 1 + # Catch-all /api/** -> pcp-ui-service СНЯТ: фронт переведён на источники напрямую + # (tgu/баллистика/mission), ui-service выводится из эксплуатации. См. + # docs/план-перевода-с-pcp-ui-service.md и задачу #40 бэклога. Любой не-матчнутый + # /api/** теперь честно отдаёт 404 на gateway, а не молча уходит в умирающий сервис. # Валидация JWT на edge. По умолчанию ВЫКЛЮЧЕНА (anonymous, как сейчас работает фронт). # Для закрытого контура: GATEWAY_JWT_ENABLED=true И задать issuer через env diff --git a/docs/бэклог-pcp-tgu-ops-ui.md b/docs/бэклог-pcp-tgu-ops-ui.md index 4bef3cf..9fcaf4f 100644 --- a/docs/бэклог-pcp-tgu-ops-ui.md +++ b/docs/бэклог-pcp-tgu-ops-ui.md @@ -13,7 +13,7 @@ > Задачи #12–#25 заведены по результатам аудита. Подробности, обоснование и рекомендации > по каждой — в [аудит-проекта-2026-06-06.md](аудит-проекта-2026-06-06.md) (ссылки на коды находок B/F/R/C). -_Обновлено: 2026-06-08_ +_Обновлено: 2026-06-10_ --- @@ -43,6 +43,16 @@ _Обновлено: 2026-06-08_ - [ ] **#27** — Проверить сервис получения паспорта маршрута по отдельности. - [ ] **#28** — Проверить связь сервиса заданий и сервиса получения паспорта маршрута между собой. +### Бэкенд / вывод pcp-ui-service из эксплуатации +- [~] **#40** — Перевести все запросы фронта с `pcp-ui-service` на источники и вывести сервис из эксплуатации. `pcp-ui-service` — наследие старого server-rendered UI; новый фронт ходит к доменным сервисам через gateway, и `pcp-ui-service` остаётся в маршрутизации только как **catch-all** для двух поверхностей: `tguApi.ts` → `/api/tgu-planning/*` (+ flight-line) и `editorApi.ts` → `/api/current-plans/missions/{id}/modes`. Карта запросов, источники, реальные пути и пошаговый план — в [план-перевода-с-pcp-ui-service.md](план-перевода-с-pcp-ui-service.md). Ключевые моменты: (1) перенести во фронт UX-перевод ошибок решения по плану (сейчас живёт в `TguPlanningService`); (2) `decision`/`confirm-layin` идут в тест-контроллер tgu (`/test/tgu/*`, гейт `tgu.test-controller.enabled`) — поведение не меняем; (3) DTO проксируются как есть, схема фронта не ломается; (4) внешних потребителей у сервиса нет (проверено grep), но перед удалением кода свериться по мёртвым поверхностям (bookings/catalog/rva/com-plan/…). После переезда — снять `ui-catch-all` из `config-repo/pcp-gateway-service.yaml`, убрать сервис из docker-compose/helm/CI/config-repo. + - [x] Шаги 1–7: репойнт фронта на источники (`tguApi.ts` → `/api/pcp-tgu` + `/test/tgu/*`; flight-line → `ballisticsApi.ts`; `editorApi.ts` modes → `/api/pcp-mission`) и снятие `ui-catch-all` из gateway. Перевод ошибок уже жил во фронте (`errorMessage` в `tguApi.ts`). Typecheck чист. + - [ ] Шаг 8: вывод сервиса из эксплуатации (compose/helm/CI/config-repo/реестр `pcp.services.ui`) и удаление кода — **отложено** до проверки репойнта на живом стенде. Пока сервис задеплоен, но без маршрутов. + +### Слоты (вкладка «Заявка» и «Редактор») +- [ ] **#41** — Запрос слотового покрытия по заявке. На вкладке «Заявка» (и в «Редакторе») запрашивать у slots-service слотовое покрытие заявки — какие слоты КА покрывают AOI заявки на её интервале. Источник — slots-service (минуя умирающий `pcp-ui-service`, ср. #40). Уточнить контракт ответа (слоты + связь с ячейками/покрытием заявки) и где он отрисовывается. +- [ ] **#42** — Бронирование слотов по заявке. С вкладки «Заявка» (и/или «Редактор») бронировать выбранные слоты под заявку через slots-service. Связано с показом забронированных слотов (#3) и пересчётом комплексного плана при бронировании (#6). Уточнить: единичное/пакетное бронирование, идемпотентность, что возвращается после брони. +- [ ] **#43** — Уточнение статуса слота. На вкладке «Заявка» (и «Редактор») показывать/обновлять актуальный статус слота (свободен / забронирован / занят по заложенному плану). Учитывать, что слоты занимаются по `LAID_IN`, а не по `ACCEPT` (ср. #10). Источник статусов — slots-service; согласовать с #41/#42. + ### Баги - [ ] **#8** — Ошибка при попытке принять план на вкладке «Планы». - [ ] **#39** — Авторасчёт плана выдаёт нереализуемые маршруты съёмки с креном > 45° (напр. `survey-211`, Emissio 1, крен 46.8°). Такой маршрут нельзя построить вручную: фронт зажимает `MAX_ROUTE_ROLL_DEG = 45` (`TguEditorTab.tsx`), а баллистика/геометрия маршрута и фильтр видимости (МПЛ, `abs(kren) <= 45°`) определены только до 45°. _Диагностика (2026-06-08): корень — данные каталога, не логика. slots-service строит крен слота как центр угловой полосы из каталога (`SlotService.kt:903-905`, `gamma=(begin+end)/2`) и предел 45° не учитывает; полосы берутся напрямую из `satellite_slot_angle`. В сиде каталога (`pcp-satellite-catalog-service/.../V1__initial.sql`) у **оптических** Emissio (id 1-6, 22) собственный профиль полос уходит до 50.42°, и полоса №17 [46.08°, 47.51°] даёт центр ровно 46.8°. Версия «посчитали по логике локации» проверена и НЕ подтвердилась: в slots-service нет ветвления по типу КА (оптика/локация) — все КА строятся одним `TestSatelliteImpl`, солвер выбирается стратегией запроса (GREEDY/CONTINUOUS), `type_code` не используется. Reflexio (локация) наоборот имеет узкие полосы ~17-25°. Решение (вернуться позже): либо обрезать/убрать в каталоге оптические полосы за 45° (поз. №16-20 у Emissio), либо добавить в slots-service зажим/отсев слотов по рабочему пределу крена КА. Истинный предел Emissio подтвердить у владельца каталога/баллистиков перед правкой._ diff --git a/docs/план-перевода-с-pcp-ui-service.md b/docs/план-перевода-с-pcp-ui-service.md new file mode 100644 index 0000000..6497b6c --- /dev/null +++ b/docs/план-перевода-с-pcp-ui-service.md @@ -0,0 +1,116 @@ +# План перевода запросов с pcp-ui-service на источники + +_Составлено: 2026-06-10. Связано с задачей #40 бэклога [бэклог-pcp-tgu-ops-ui.md](бэклог-pcp-tgu-ops-ui.md)._ + +## Зачем + +`pcp-ui-service` — наследие старого server-rendered UI (Thymeleaf-страницы + REST-прокси-обвязка +над доменными сервисами). Новый фронт `pcp-tgu-ui-service` ходит к бэкендам через +`pcp-gateway-service`, и большинство его клиентов уже бьют в доменные сервисы напрямую +(`/api/pcp-tgu`, `/api/pcp-mission`, `/api/pcp-ballistics`, `/api/pcp-complex`, +`/api/pcp-request`). `pcp-ui-service` остаётся в маршрутизации только как **catch-all** +(`ui-catch-all`, `order:1` в `config-repo/pcp-gateway-service.yaml`) для двух поверхностей. +Цель — увести эти две поверхности на источники и вывести `pcp-ui-service` из эксплуатации. + +## Кто ещё зависит от pcp-ui-service + +Проверено (grep по `config-repo/`, `services/`, `libs/`): **никто, кроме фронта и catch-all +gateway.** Остальные ссылки — это самопрописка сервиса в Spring Boot Admin +(`config-repo/pcp-ui-service.yaml`) и комментарии в `pcp-types-lib` про то, что обогащение +DTO «исторически делалось в ui-service». Восток-запад (межсервис) сервис не вызывает никто. + +## Карта запросов фронта, идущих через pcp-ui-service + +Через catch-all `pcp-ui-service` сейчас проходят запросы только из **двух** файлов фронта. +Всё остальное (`ballisticsApi`, `complexPlanApi`, `missionPlanningApi`, `requestApi`, +`tguPlanApi`, `stationsApi`) уже ходит мимо ui-service. + +### 1. `src/api/tguApi.ts` → `/api/tgu-planning/*` (+ flight-line) + +Контроллер `TguPlanningRestController` (`services/pcp-ui-service/.../controller/TguPlanningController.kt`) +проксирует через `TguPlanningService`/`BallisticsService`. Источники и реальные пути: + +| Запрос фронта (через ui-service) | HTTP | Реальный источник | Путь на источнике | +|--------------------------------------------------------------|------|------------------------------|----------------------------------------------------| +| `/api/tgu-planning/platforms` | GET | pcp-tgu-service | `/api/platforms` | +| `/api/tgu-planning/plans?historyDays` | GET | pcp-tgu-service | `/api/plans?historyDays` | +| `/api/tgu-planning/spacecraft/{id}/plans?historyDays` | GET | pcp-tgu-service | `/api/plans/{spacecraftId}?historyDays` | +| `/api/tgu-planning/plans/{planId}/decision?decision&reason` | POST | pcp-tgu-service (**TEST**) | `/test/tgu/plans/{planId}/decision` | +| `/api/tgu-planning/plans/{planId}/dismiss` | POST | pcp-tgu-service | `/api/plans/{planId}/dismiss` | +| `/api/tgu-planning/plans/{planId}/restore` | POST | pcp-tgu-service | `/api/plans/{planId}/restore` | +| `/api/tgu-planning/plans/{planId}/confirm-layin?reason` | POST | pcp-tgu-service (**TEST**) | `/test/tgu/plans/{planId}/confirm-layin` | +| `/api/tgu-planning/spacecraft/{noradId}/flight-line` | GET | pcp-ballistics-service | `/api/satellites/{noradId}/flight-line` (+интервал)| + +**Что ui-service делает поверх прокси (нельзя потерять при переезде):** +- **Перевод ошибок в человекочитаемые сообщения** для решения по плану (`decision`): + 404 → «План не найден.» / «Test controller недоступен или отключён.»; 409 → «План не + является активным планом, ожидающим решения…»; 5xx → «Test controller недоступен…». + Сетевые сбои (`WebClientRequestException`) → 503 «Test controller недоступен…». + При переезде эту UX-обвязку нужно перенести во фронт (`tguApi.ts`/общий `http.ts`, см. #17), + иначе оператор увидит сырой 4xx/5xx. +- `decision` и `confirm-layin` идут в **тест-контроллер** tgu (`/test/tgu/...`), гейтится + `tgu.test-controller.enabled` в `config-repo/pcp-tgu-service.yaml`. Это MVP-канал + подтверждений (ср. #13). При переезде поведение не меняется — но прод-канал решений + остаётся отдельным вопросом. +- DTO (`TguPlanResponse`, `TguPlatformResponse`) проксируются **как есть** (`bodyToFlux` + того же типа) — форма ответа источника и ui-service идентична, фронт не сломается по схеме. + +### 2. `src/features/tgu-editor/editorApi.ts` → `/api/current-plans/missions/{planId}/modes` + +| Запрос фронта (через ui-service) | HTTP | Реальный источник | Путь на источнике | +|---------------------------------------------------|------|-----------------------------|------------------------------------| +| `/api/current-plans/missions/{planId}/modes` | GET | pcp-mission-planing-service | `/api/missions/{missionId}/modes` | + +`CurrentPlansController.modes` → `MissionService.modesByMission` → `${settings.mission-service}` +(= `pcp.services.mission` = pcp-mission-planing-service), прямой проброс `List`. +Фронтовый `missionPlanningApi.ts` уже ходит в этот же сервис через `/api/pcp-mission` — endpoint +переезжает туда же. + +## План перевода (порядок шагов) + +> **Статус (2026-06-10): шаги 1–7 выполнены** — фронт ходит в источники напрямую, catch-all +> снят. Шаг 8 (вывод сервиса из эксплуатации) отложен до проверки репойнта на живом стенде; +> до этого pcp-ui-service остаётся задеплоен, но без маршрутов (безвреден). Перевод ошибок +> решения уже жил во фронте (`errorMessage` в `tguApi.ts`) — серверная обвязка ui-service +> дублировала его, при прямом обращении к tgu ничего не потеряно. + +1. **flight-line → `/api/pcp-ballistics`.** Перенести `fetchFlightLine` в `ballisticsApi.ts` + (там уже `BASE=/api/pcp-ballistics`), путь `/api/satellites/{noradId}/flight-line` + интервал + `time_start`/`time_stop`. Сверить формат точек `FlightLinePoint` с тем, что отдаёт + баллистика напрямую (ui-service отдавал `collectList().block()` того же flux — форма та же). +2. **platforms / plans / spacecraft-plans → `/api/pcp-tgu`.** Перепривязать GET-методы + `tguApi.ts` на `/api/pcp-tgu` + `/api/platforms`, `/api/plans`, `/api/plans/{id}`. + `tguPlanApi.ts` уже использует этот префикс — переиспользовать его конвенции/`fetchJson`. +3. **dismiss / restore → `/api/pcp-tgu`** на `/api/plans/{id}/dismiss|restore` (реальный API). +4. **decision / confirm-layin → `/api/pcp-tgu`** на `/test/tgu/plans/{id}/decision|confirm-layin`. + **Одновременно** перенести во фронт перевод ошибок (карта статусов → сообщения выше). + Учесть зависимость от `tgu.test-controller.enabled`. +5. **modes → `/api/pcp-mission`.** В `editorApi.ts` заменить + `/api/current-plans/missions/{id}/modes` на `/api/pcp-mission/api/missions/{id}/modes` + (через общий клиент/`apiFetch`). Свериться с `missionPlanningApi.ts`. +6. **Vite/nginx.** Проверить, что `/api/pcp-*` и `/api/pcp-mission` уже проксируются на gateway + (да — единый `/api` → gateway). Спец-обработка `/api/tgu-planning`/`/api/current-plans` + не нужна. +7. **Снять catch-all.** Удалить маршрут `ui-catch-all` из `config-repo/pcp-gateway-service.yaml` + (после того как фронт перестал слать `/api/tgu-planning` и `/api/current-plans`). Проверить, + что никакой `/api/**` больше не должен попадать в ui-service. +8. **Вывод сервиса из эксплуатации.** Убрать `pcp-ui-service` из gateway-реестра-потребителей, + `docker-compose`/helm/CI (`.gitlab/ci/pcp-ui-service.yml`, include в `.gitlab-ci.yml`, + `changes:`-списки), `config-repo/pcp-ui-service.yaml`, Spring Boot Admin. Код сервиса — + архивировать/удалить отдельным шагом после стабилизации. + +## Риски и на что смотреть + +- **Потеря UX-перевода ошибок решения** — главный функциональный риск. Перенести в фронт + вместе с шагом 4, не откладывать. +- **Тест-контроллер как канал решений** — `decision`/`confirm-layin` остаются на `/test/tgu/*`. + Это сознательный MVP-срез; прод-канал — отдельная задача (ср. #13). +- **Мёртвые поверхности ui-service.** Контроллеры `bookings`, `catalog`, `rva`, `dynamic-plan`, + `tle-analysis`, `tle-comparison`, `com-plan`, `requests`, `map`, `satellites/pdcm`, + `RvaController` и server-rendered страницы новый фронт **не вызывает** — они умирают вместе + с сервисом. Перед удалением кода ещё раз убедиться, что у них нет внешних потребителей + (геопортал и т.п.). +- **Обогащение DTO в ui-service** (`BookedSlotDetailsDTO`: имя/тип КА добавлялись в ui-service). + Если такая обогащённая поверхность понадобится новому фронту — она должна переехать в + источник или во фронт, а не остаться «висеть» в умирающем сервисе. Сейчас новый фронт её + не использует. diff --git a/services/pcp-tgu-ui-service/src/api/ballisticsApi.ts b/services/pcp-tgu-ui-service/src/api/ballisticsApi.ts index 32cb524..e574081 100644 --- a/services/pcp-tgu-ui-service/src/api/ballisticsApi.ts +++ b/services/pcp-tgu-ui-service/src/api/ballisticsApi.ts @@ -4,6 +4,64 @@ import { apiFetch } from './apiFetch' const BASE = '/api/pcp-ballistics' +export type FlightLinePoint = { + time: string + revolution: number + lat: number + long: number + latLeft: number + longLeft: number + latInnerLeft: number + longInnerLeft: number + latInnerRight: number + longInnerRight: number + latRight: number + longRight: number + revSign: 'ASC' | 'DESC' +} + +/** + * Трасса полёта КА (flight-line) на интервале для отрисовки на карте/таймлайне из + * pcp-ballistics-service (GET /api/satellites/{norad}/flight-line). Шаг трассы 60 с. + * @param noradId NORAD-идентификатор КА. + * @param fromMs Начало интервала, мс от эпохи. + * @param toMs Конец интервала, мс от эпохи. + * + * @returns Точки трассы полёта на интервале. + */ +export async function fetchFlightLine( + noradId: string, + fromMs: number, + toMs: number, +): Promise { + const params = new URLSearchParams({ + time_start: toLocalDateTime(fromMs), + time_stop: toLocalDateTime(toMs), + }) + const url = `${BASE}/api/satellites/${encodeURIComponent(noradId)}/flight-line?${params.toString()}` + + let response: Response + try { + response = await apiFetch(url, { headers: { Accept: 'application/json' } }) + } catch { + throw new TguApiError('Не удалось подключиться к сервису баллистики.', 'network') + } + + const text = await response.text() + if (!response.ok) { + throw new TguApiError( + extractErrorText(text) || 'Ошибка сервиса баллистики.', + 'http', + response.status, + ) + } + if (!text.trim()) { + return [] + } + + return JSON.parse(text) as FlightLinePoint[] +} + export type PointVisibilityParam = { /** NORAD-идентификатор КА. */ noradId: number diff --git a/services/pcp-tgu-ui-service/src/api/tguApi.ts b/services/pcp-tgu-ui-service/src/api/tguApi.ts index 8579549..eec39b1 100644 --- a/services/pcp-tgu-ui-service/src/api/tguApi.ts +++ b/services/pcp-tgu-ui-service/src/api/tguApi.ts @@ -5,53 +5,21 @@ import { type TguPlanDecisionMessage, type TguPlatform, } from '../model/tguTypes' -import { toLocalIso } from '../utils/localTime' import { apiFetch } from './apiFetch' -export type FlightLinePoint = { - time: string - revolution: number - lat: number - long: number - latLeft: number - longLeft: number - latInnerLeft: number - longInnerLeft: number - latInnerRight: number - longInnerRight: number - latRight: number - longRight: number - revSign: 'ASC' | 'DESC' -} - /** - * Трасса полёта КА (flight-line) на интервале для отрисовки на карте/таймлайне. - * @param noradId NORAD-идентификатор КА. - * @param fromMs Начало интервала, мс от эпохи. - * @param toMs Конец интервала, мс от эпохи. - * - * @returns Точки трассы полёта на интервале. + * Запросы планирования ТГУ идут напрямую в pcp-tgu-service через gateway (`/api/pcp-tgu` → + * :7011), как и остальные tgu-вызовы (см. tguPlanApi.ts). Решение/подтверждение закладки — + * на тест-контроллере ТГУ (`/test/tgu/*`, гейт `tgu.test-controller.enabled`, MVP-канал). */ -export async function fetchFlightLine( - noradId: string, - fromMs: number, - toMs: number, -): Promise { - const query = new URLSearchParams({ - time_start: toLocalIso(fromMs), - time_stop: toLocalIso(toMs), - }) - return fetchJson( - `/api/tgu-planning/spacecraft/${encodeURIComponent(noradId)}/flight-line?${query}`, - ) -} +const BASE = '/api/pcp-tgu' /** * Список платформ (КА) ТГУ. * @returns Платформы планирования ТГУ. */ export async function fetchPlatforms(): Promise { - return fetchJson('/api/tgu-planning/platforms') + return fetchJson(`${BASE}/api/platforms`) } /** @@ -64,8 +32,8 @@ export async function fetchPlatforms(): Promise { export async function fetchPlans(historyDays: number, spacecraftId?: string): Promise { const query = new URLSearchParams({ historyDays: String(historyDays) }) const path = spacecraftId - ? `/api/tgu-planning/spacecraft/${encodeURIComponent(spacecraftId)}/plans?${query}` - : `/api/tgu-planning/plans?${query}` + ? `${BASE}/api/plans/${encodeURIComponent(spacecraftId)}?${query}` + : `${BASE}/api/plans?${query}` return fetchJson(path) } @@ -89,7 +57,7 @@ export async function sendPlanDecision( } return fetchJson( - `/api/tgu-planning/plans/${encodeURIComponent(planId)}/decision?${query}`, + `${BASE}/test/tgu/plans/${encodeURIComponent(planId)}/decision?${query}`, { method: 'POST' }, true, ) @@ -101,7 +69,7 @@ export async function sendPlanDecision( * @param planId Идентификатор плана. */ export async function dismissPlan(planId: string): Promise { - await fetchJson(`/api/tgu-planning/plans/${encodeURIComponent(planId)}/dismiss`, { + await fetchJson(`${BASE}/api/plans/${encodeURIComponent(planId)}/dismiss`, { method: 'POST', }) } @@ -111,7 +79,7 @@ export async function dismissPlan(planId: string): Promise { * @param planId Идентификатор плана. */ export async function restorePlan(planId: string): Promise { - await fetchJson(`/api/tgu-planning/plans/${encodeURIComponent(planId)}/restore`, { + await fetchJson(`${BASE}/api/plans/${encodeURIComponent(planId)}/restore`, { method: 'POST', }) } @@ -122,7 +90,7 @@ export async function restorePlan(planId: string): Promise { * @param planId Идентификатор плана. */ export async function confirmPlanLayin(planId: string): Promise { - await fetchJson(`/api/tgu-planning/plans/${encodeURIComponent(planId)}/confirm-layin`, { + await fetchJson(`${BASE}/test/tgu/plans/${encodeURIComponent(planId)}/confirm-layin`, { method: 'POST', }) } diff --git a/services/pcp-tgu-ui-service/src/features/constellation/realData.ts b/services/pcp-tgu-ui-service/src/features/constellation/realData.ts index 3558a0e..a6e2034 100644 --- a/services/pcp-tgu-ui-service/src/features/constellation/realData.ts +++ b/services/pcp-tgu-ui-service/src/features/constellation/realData.ts @@ -10,10 +10,10 @@ Возвращает { env, domain, sched } в том же виде, что buildEnv() прототипа, так что ConstellationDashboard рендерит реальные данные без изменений разметки. ============================================================ */ -import { fetchPlatforms, fetchFlightLine, fetchPlans, type FlightLinePoint } from "../../api/tguApi"; +import { fetchPlatforms, fetchPlans } from "../../api/tguApi"; import { fetchStations, type StationDto } from "../../api/stationsApi"; import { fetchRequestsForMap } from "../../api/requestApi"; -import { fetchSatelliteRva } from "../../api/ballisticsApi"; +import { fetchSatelliteRva, fetchFlightLine, type FlightLinePoint } from "../../api/ballisticsApi"; import { fetchPlanModes, type PlanMode } from "../tgu-editor/editorApi"; import type { TguPlatform, TguPlan } from "../../model/tguTypes"; import type { RequestMapItem } from "../../model/requestTypes"; diff --git a/services/pcp-tgu-ui-service/src/features/tgu-editor/TguEditorTab.tsx b/services/pcp-tgu-ui-service/src/features/tgu-editor/TguEditorTab.tsx index a4335e6..3b6dc34 100644 --- a/services/pcp-tgu-ui-service/src/features/tgu-editor/TguEditorTab.tsx +++ b/services/pcp-tgu-ui-service/src/features/tgu-editor/TguEditorTab.tsx @@ -1,10 +1,9 @@ import { useEffect, useMemo, useRef, useState, useCallback, type MutableRefObject } from "react"; import { fetchRequestsForMap } from "../../api/requestApi"; import { fetchStations, type StationDto } from "../../api/stationsApi"; -import { fetchFlightLine, type FlightLinePoint } from "../../api/tguApi"; import type { RequestMapItem } from "../../model/requestTypes"; import { stationPasses, type OrbitPassInfo, type PassRange } from "../tgu-map-2d/geometry/passes"; -import { fetchPointVisibility, fetchSatelliteRva, type PointVisibilityParam, type RvaZone } from "../../api/ballisticsApi"; +import { fetchPointVisibility, fetchSatelliteRva, fetchFlightLine, type FlightLinePoint, type PointVisibilityParam, type RvaZone } from "../../api/ballisticsApi"; import { buildSurveyRoute, calculateDrops, diff --git a/services/pcp-tgu-ui-service/src/features/tgu-editor/editorApi.ts b/services/pcp-tgu-ui-service/src/features/tgu-editor/editorApi.ts index ceab45e..4e6b852 100644 --- a/services/pcp-tgu-ui-service/src/features/tgu-editor/editorApi.ts +++ b/services/pcp-tgu-ui-service/src/features/tgu-editor/editorApi.ts @@ -1,3 +1,5 @@ +import { apiFetch } from "../../api/apiFetch"; + export type PlanSurveyMode = { id: number; planId: number; @@ -30,9 +32,10 @@ export type PlanDropMode = { export type PlanMode = PlanSurveyMode | PlanDropMode; export async function fetchPlanModes(planId: string): Promise { - const response = await fetch(`/api/current-plans/missions/${encodeURIComponent(planId)}/modes`, { - headers: { Accept: "application/json" } - }); + const response = await apiFetch( + `/api/pcp-mission/api/missions/${encodeURIComponent(planId)}/modes`, + { headers: { Accept: "application/json" } } + ); if (!response.ok) { throw new Error(`Ошибка загрузки включений плана: ${response.status}`); }