Status: Accepted
Date: 2026-04-18
Переписываем crcm-protocol-service с нуля. Исходный сервис страдает циклическими зависимостями (ProtocolService ↔ ExtractService), god-классами (ProtocolService — 839 строк), прямым обращением к JPA-репозиториям соседних модулей.
Архитектурный вопрос: как модули protocol, extract, signature, integration взаимодействуют без циклов и без tight coupling.
Hexagonal architecture (Ports & Adapters):
protocol, extract, signature) объявляют порты (интерфейсы) — что им нужно.integration, либо другой бизнес-модуль).DIP для sibling-модулей: когда protocol нуждается в данных от extract, порт живёт в protocol/port/, адаптер в extract/adapter/. Это значит extract зависит от protocol на уровне source-imports, но поток данных — обратный (extract отдаёт данные protocol).
Правило "port owned by consumer": порт формулирует потребитель, в своих терминах (ISP). Если двум модулям нужно одно и то же от внешнего источника — каждый объявляет свой порт, пусть даже с одинаковыми сигнатурами.
Positive:
protocol → document → core, а extract → protocol → document → core (extract "ниже", потому что зависим).protocol тестируется с мок-портами, без Spring-контекста и Feign.Negative:
core/port/ (shared module): отвергнуто — core превратится в помойку контрактов бизнес-модулей, теряется use-case-фокус портов (ISP violation).contracts/ для межмодульных портов: избыточно для проекта размера 7 модулей; даст смысл при 15+.protocol → extract через публичные сервисные классы: возвращает tight coupling, нет абстракции для тестов.