Capture current PCP architecture notes, service-map prototypes, TGU operations UI/map work, local configuration updates, database helper scripts, and request/sample JSON artifacts.
pcp-route-processing-service
Назначение сервиса
pcp-route-processing-service принимает route passport из Kafka, парсит входной JSON, нормализует GeoJSON geometry в WKT, сохраняет паспорт маршрута в БД и создаёт downstream events в outbox.
Публикация downstream events выполняется не из Kafka listener, а через scheduled outbox worker:
RoutePassportMessageListenerчитает input Kafka record.RoutePassportJsonParserServiceвалидирует и парсит payload.RoutePassportIngestionServiceв одной DB transaction сохраняетroute_passportsи создаётroute_passport_outbox.- Listener подтверждает offset только после успешного ingestion.
RoutePassportOutboxWorkerclaim'ит due outbox rows и публикует их черезRoutePassportKafkaPublisherService.
Kafka topics
Input topic:
pcp.request.survey-georeference.v1
DLQ topic:
pcp.request.survey-georeference-dlq.v1
Output topics:
pcp.route.in.v1- событие для mission-planning flow.pcp.route.georeference.v1- событие для request-service matching flow.
DB tables
route_passports- сохранённые паспорта маршрутов и source metadata входного Kafka record.route_passport_outbox- pending/published/failed downstream events для Kafka publication.
Horizontal scaling
Несколько pod'ов сервиса могут безопасно запускать outbox worker одновременно.
Outbox claim использует DB-level concurrency:
SELECT ... FOR UPDATE SKIP LOCKEDвыбирает duePENDINGrows.lockedUntilвыставляется в той же transaction, что и claim.- После commit другие instances не claim'ят row, пока
lockedUntilв будущем. - Если instance умер после claim, abandoned row снова станет доступна после истечения
lockedUntil. - In-memory locks, leader election и single-instance assumptions не используются.
Delivery semantics
Delivery semantics: at-least-once.
Exactly-once не обещается. Kafka transactions не используются. Downstream consumers должны быть идемпотентны к повторной доставке одного и того же события.
Error handling
Input Kafka flow:
- contract/parsing errors не подтверждают offset и обрабатываются configured retry/DLQ policy;
- после исчерпания retry record публикуется в
pcp.request.survey-georeference-dlq.v1; - временные ошибки ingestion retry'ятся bounded policy.
Output Kafka flow:
- downstream events сначала сохраняются в
route_passport_outbox; - output Kafka errors не теряются, а переводят row обратно в
PENDINGс bounded exponential backoff; - после исчерпания
maxAttemptsиз outbox row событие получает статусFAILED.
Observability
Логи содержат operational identifiers без полного payload:
- source topic, partition, offset, key и payload size для input ingestion;
routeId,routeNameFull,traceId,correlationId;- outbox id, event type, target topic, message key, attempts, status,
nextAttemptAt,lockedUntil,publishedAt; - exception class/message для failure path.
Доступные Micrometer counters:
route_passport_ingest_success_totalroute_passport_ingest_failure_totalroute_passport_outbox_published_totalroute_passport_outbox_retry_totalroute_passport_outbox_failed_total
Operational notes
Test controller is disabled by default and must not be exposed in production unless explicitly enabled with:
app:
route-processing:
test-controller:
enabled: true
Current business limitations
routeStatusсейчас остаётсяPROCESSED.- Сервис не делает request matching.
- Сервис не считает coverage.
- Сервис не вызывает request-service или mission-service по HTTP.