Files
dc-observatio/docs/аудит-проекта-2026-06-06.md
T
Дмитрий Соловьев 345529cde0 chore: сохранение текущих изменений (deploy local-bundle/local-jar, request-service, slots UI markedObjectIds)
Безопасный коммит незакоммиченной работы перед реализацией бронирования слотов.
Вне коммита оставлены: package-lock.json (пустой, мусор), requests.json (scratch-данные).
2026-06-11 14:00:12 +03:00

174 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Аудит проекта observatio-terrae
Дата: 2026-06-06. Автор: Claude (Opus 4.8).
Охват: фронтенд `pcp-tgu-ops-ui` + бэкенд-сервисы. Сервис `tle-monitoring-service` по
указанию исключён из анализа.
Метод: статический разбор кода, прогон сборки/тестов фронта, выборочное чтение бэкенд-сервисов
(акцент на недавно дорабатываемых: tgu, mission-planing, complex-mission, request), проверка
конфигов, CORS, обработки ошибок и гигиены репозитория.
## Сводка по состоянию
Базовое здоровье — хорошее. Фронтенд проходит строгую типизацию (`tsc -b`, exit 0) и все
тесты (53 теста в 12 файлах, зелёные); в исходниках нет `console.*`, `any`, `@ts-ignore`.
Бэкенд использует общий `GlobalExceptionHandler` из `pcp-types-lib`, нет `printStackTrace`,
нет `@Disabled`/`@Ignore` тестов. Найденные проблемы — это в основном технический долг,
копипаст-артефакты и один реальный риск надёжности в Camunda-воркерах.
Приоритеты: **B1** (надёжность), **R1/C1** (гигиена/конфиги), затем рефакторинг-долг.
---
## Бэкенд
### B1 (высокий). Camunda job-воркеры молча проглатывают исключения
Файл: [FlowService.kt](../services/pcp-mission-planing-service/src/main/kotlin/space/nstart/pcp/pcp_mission_planing_service/service/FlowService.kt)
Все воркеры объявлены с `autoComplete = false` и обёрнуты в:
```kotlin
catch (ex : Exception) { logger.warn(ex.message) }
```
Если исключение возникает до `client.newCompleteCommand(...).send()`, задача **не завершается и
не падает**: воркер «съел» ошибку. Camunda не получает ни complete, ни fail/incident — BPMN-процесс
зависает молча до таймаута активации, без видимого инцидента и без явной диагностики. Плюс
`logger.warn(ex.message)` теряет stack trace, а `ex.message` может быть `null`.
Рекомендация: в catch завершать задачу через `client.newFailCommand(job.key)` (с retries) либо
бросать исключение наверх, чтобы Camunda создала incident; логировать как `logger.error(msg, ex)`
со стек-трейсом. Это касается `surveyPlan`, `surveyDrop`, `sendPlan`, `confirmPlan` и прочих
воркеров файла.
### B2 (средний). Симуляционная заглушка `Thread.sleep(5000)` в проде-пути
Файл: [FlowService.kt:97](../services/pcp-mission-planing-service/src/main/kotlin/space/nstart/pcp/pcp_mission_planing_service/service/FlowService.kt#L97)
В `sendPlan` стоит `Thread.sleep(5000)` с комментарием «Иммитация сообщения о получении
подтверждения» — синхронно блокирует поток job-воркера на 5 с и эмулирует приём подтверждения
плана. Для MVP-демо допустимо (см. практику осознанных заглушек), но это нужно снять при
интеграции с реальной шиной подтверждений; пока имитация маскирует отсутствие реального канала и
держит поток пула воркеров.
### B3 (средний). Несогласованные пакеты — копипаст-артефакты
Базовые пакеты ряда сервисов не соответствуют их имени (видимо, форки шаблона):
| Сервис | Пакет | Проблема |
|---|---|---|
| pcp-ballistics-service | `space.nstart.pcp.pcp_request_service` | пакет от request-сервиса |
| pcp-complex-mission-service | `space.nstart.pcp.pcp_satellites_service` | чужое имя |
| pcp-ui-service | `space.nstart.pcp.slots_service` | совпадает со slots-service |
| slots-service | `space.nstart.pcp.slots_service` | тот же пакет, что у ui-service |
| pcp-tgu-service | `space.nstart.pcp_tgu_service` | пропущен сегмент `.pcp.` |
| pcp-request-service | `org.nstart.dep265.requestservice` | другой корень (`org` вместо `space`) |
Последствия: grep/навигация по пакету выводит на «не тот» сервис, IDE-импорты обманчивы,
ui-service и slots-service неотличимы по пакету. Переименование пакетов затрагивает много файлов —
делать осознанно, отдельной задачей; новые сервисы заводить уже с корректным пакетом.
### B4 (низкий). Опечатка «srpring» растиражирована
`pcp-srpring-boot-admin-server` — опечатка в имени каталога и пакета, продублированная в
`settings.gradle.kts`, `build.gradle.kts`, `.gitlab-ci.yml`, `deploy/local-bundle/docker-compose.yml`,
`config-repo/application-docker-local.yaml`. Косметика, но фиксируется во всей инфраструктуре, потому
исправлять дорого — оставить как известный долг или чинить вместе с B3.
### B5 (низкий). Потеря stack trace при логировании
~9 мест вида `logger.warn(ex.message)` / `logger.error(ex.message)` логируют только текст без
исключения. Для диагностики предпочтительно `logger.error("...", ex)`.
### B6 (инфо). Опечатки в лог-сообщениях
Напр. «Утверждение поана» (план), «Иммитация» (имитация) в FlowService.
---
## Фронтенд (pcp-tgu-ops-ui)
### F1 (средний). Дублирование HTTP-/error-обвязки в API-клиентах
`extractErrorText` скопирован в 5 файлах: `tguApi.ts`, `ballisticsApi.ts`, `missionPlanningApi.ts`,
`complexPlanApi.ts`, `tguPlanApi.ts`. Шаблон `try { fetch } catch { TguApiError("network") }` +
разбор `!response.ok` повторяется ~22 раза (7 в missionPlanningApi, 5 в tguPlanApi и т.д.).
В `tguApi.ts` уже есть аккуратный `fetchJson<T>()` — остальные клиенты переписывают то же руками.
Рекомендация: вынести единый `src/api/http.ts` (обёртка `fetchJson` + `extractErrorText` +
маппинг ошибок) и переиспользовать. Сократит ~150 строк и устранит расхождения (см. F5).
### F2 (низкий). Островок нетипизированного JS во вкладке «Группировка»
`features/constellation/*` — это `.jsx`/`.js` (`ConstellationDashboard.jsx`, `sim.js`, `data.js`,
`MapView.jsx`, `Panels.jsx`, `Timeline.jsx`, `util.js`), включён через `allowJs`. Остальное
приложение — строгий TS. Прототипный код подключён в прод через `ConstellationTab.tsx` (обёртка с
`as ComponentType`). Типы в нём фактически `any` — провал строгой типизации в этой ветке UI.
Долг: постепенно перевести на `.tsx` или хотя бы добавить декларации типов на границе.
### F3 (низкий). Мёртвый barrel `constellation/index.js`
`features/constellation/index.js` (реэкспорт `SIM`, `SATELLITES`, `STATIONS`, ...) нигде не
импортируется — можно удалить.
### F4 (низкий). God-компонент `TguEditorTab.tsx` (1727 строк)
Самый крупный файл фронта; держит десятки `useState`/`useRef`, режимы правой панели, построение
маршрутов, валидацию, undo/redo. Хорошо закомментирован, но монолитен. Кандидат на декомпозицию
(вынос хуков `useDraftHistory`, `useRouteBuilder`, разнесение панелей) для снижения связности.
### F5 (инфо). Расхождение приоритета полей ошибки
В `tguApi.extractErrorText` порядок полей `reason, message, error, detail`, а в
`missionPlanningApi.extractErrorText``message, error, reason, detail`. При едином ответе бэка
пользователь увидит разный текст из разных клиентов. Устранится при выносе общей обвязки (F1).
---
## Гигиена репозитория
### R1 (средний). Крупные дампы данных в корне репозитория (в git)
Отслеживаются git и лежат в корне:
- `pcp_requests_converted_create_requests.json` (~228 КБ)
- `response_заданияКубернетс.json` (~157 КБ)
- `response_заданияЕмельянов.json` (~66 КБ)
Это тестовые выгрузки, засоряющие корень и историю. Перенести в `docs/`/`*/src/test/resources`
или убрать из git (оставив в `.gitignore`).
### R2 (низкий). Посторонние артефакты в корне (не в git)
- `node_modules/` в корне + пустой `package-lock.json` (`"packages": {}`, 0 зависимостей) —
корневого Node-проекта нет, фронт живёт в `services/pcp-tgu-ops-ui`. Мусор от случайного
`npm install` в корне; удалить, при желании добавить `/package-lock.json` в `.gitignore`.
- `obj_terra.zip` (~1.5 МБ) в корне — не в git, но захламляет дерево.
### R3 (низкий). 26 устаревших каталогов `bin/` на диске
Скомпилированные `bin/main/...` (gitignored) задваивают исходники: любой `grep` по `services`
выдаёт каждый файл дважды (src + bin) — шум при навигации. Прогнать `./gradlew clean` /
удалить `bin/` каталоги.
---
## Конфигурация и безопасность
### C1 (средний). Несогласованное задание паролей БД в config-repo
В большинстве сервисов пароль зашит как `password: password`, и только
[pcp-tgu-service.yaml](../config-repo/pcp-tgu-service.yaml) использует переопределяемый паттерн
`password: ${DB_PASSWORD:password}`. Для локалки риск низкий, но шаблон важен: привести все
сервисы к `${DB_PASSWORD:...}` (и прочие креды — к env-переменным), чтобы прод/стенды
переопределялись без правки config-repo.
### C2 (низкий). CORS: широкий в ui-service, отсутствует в остальных
[WebConfig.kt](../services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/configuration/WebConfig.kt)
задаёт `allowedOriginPatterns("*")` + `allowCredentials=true` — широко; для прода имеет смысл
сузить origin до конкретных хостов. Остальные сервисы, которые фронт зовёт напрямую (tgu,
mission, request, ballistics, complex, stations), CORS-конфига не имеют — сейчас работает только
потому, что обращение идёт через Vite-прокси/nginx (same-origin). Прямые кросс-доменные вызовы к
ним из браузера упадут — это ограничение стоит держать в курсе при изменении схемы доступа.
---
## Что в порядке (намеренно не правим)
- Заглушки/тест-контроллеры/пустой контракт валидации миссии — осознанные MVP-срезы, не дефекты.
- Прямые вызовы микросервисов из фронта через прокси (без BFF) — принятое решение этапа.
- Naive `LocalDateTime` как локальное настенное время — намеренная договорённость проекта.
## Рекомендованный порядок работ
1. **B1** — починить обработку ошибок в Camunda-воркерах (надёжность процессов).
2. **R1, C1** — убрать дампы из корня; унифицировать env-пароли.
3. **F1** — общий `http.ts`, заодно закрыть F5.
4. **B2** — снять `Thread.sleep`-имитацию при появлении реального канала подтверждений.
5. Фоном: **R2/R3** (чистка), **F2/F4** (типизация constellation, декомпозиция редактора),
**B3/B4** (пакеты/опечатки) — отдельными задачами из-за широкого охвата.