EFKO Kernel: обзор проекта
Назначение
efko-kernel — Nx-монорепозиторий с несколькими NestJS-сервисами, разделенными по доменам:
gateway— публичная HTTP-точка входа и оркестратор запросов.auth-service— идентификация, аутентификация, refresh-сессии и жизненный цикл пользователей.personnel— кадровый домен: подразделения, должности, сотрудники, шаблоны смен.production— производственный домен: продукты, заказы, выпуск, качество, остатки, продажи, датчики, KPI.etl— прием данных из внешних систем, нормализация, трансформация и доставка во внутренние домены.
Кроме сервисов, в репозитории есть общие библиотеки с контрактами, интерфейсами и инфраструктурными NestJS-утилитами.
Структура монорепозитория
apps/*— deployable-сервисы.libs/contracts— общие команды, queries и события для межсервисного взаимодействия.libs/interfaces— общие TypeScript-интерфейсы, enum-ы и RPC-структуры.libs/nest-utils— переиспользуемая инфраструктура: auth guards/decorators, HTTP logging и exception filters, RPC helper-ы, RabbitMQ event emitter и shared transactional outbox.
Все сервисы оформлены как Nx applications с локальными project.json. Сборка идет через webpack-cli, а на уровне workspace подключены Nx plugins для webpack, ESLint и Jest.
Топология рантайма
Внешние точки входа
gatewayподнимает HTTP API под/apiи публикует Swagger.auth-serviceтоже поднимает HTTP API и Swagger, поэтому может использоваться как напрямую, так и за gateway.personnel,productionиetlтакже стартуют как Nest HTTP-приложения, но их основная прикладная интеграция построена вокруг сервисных вызовов и очередей.
Шина интеграции
Основной межсервисный транспорт — RabbitMQ.
auth-serviceиспользуетefko.auth.commands,efko.auth.queries,efko.auth.events.personnelиспользуетefko.personnel.commands,efko.personnel.queries,efko.personnel.events.productionиспользуетefko.production.commands,efko.production.queries,efko.production.events.etlопределяетefko.etl.commandsиefko.etl.events.gatewayвыступает RPC-клиентом для доменных сервисов и проксирует туда команды и queries.
Очереди объявляются явно и используют quorum queue options.
Важно: в коде gateway есть proxy для production-service, но текущий getRMQConfig() явно декларирует только auth и personnel exchanges/queues. Это стоит рассматривать как текущую архитектурную несогласованность между wiring и ожидаемым поведением.
Роли сервисов
Gateway
gateway агрегирует HTTP-модули для auth, personnel, production и ETL. На краю системы он применяет request ID middleware, логирование, обработку ошибок, cache и rate limiting. Дальше запросы отправляются в RabbitMQ command/query exchanges или, в случае ETL, проксируются в HTTP API ETL-сервиса.
Auth Service
auth-service отвечает за регистрацию, логин, выпуск и refresh токенов, чтение/обновление пользователя и деактивацию. Хранение реализовано через Prisma, а доменные события публикуются в RabbitMQ.
Personnel
personnel владеет кадровыми агрегатами и использует Prisma-репозитории плюс shared outbox для надежной публикации доменных событий после записи состояния.
Production
production владеет операционными производственными данными. Feature-модули покрывают продукты, заказы, выпуск, продажи, остатки, качество, датчики и KPI. Для событийного взаимодействия используется shared outbox поверх Prisma.
ETL
etl — интеграционная граница для внешних систем вроде 1C:ZUP, 1C:ERP, MES, SCADA, LIMS. Его pipeline разделен на:
ingestion— прием данных, auth/role checks, парсинг файлов и первичная валидация;transform— source-specific transformer-ы и mapper-ы в канонические payload-ы;imports— хранение raw imports и transformation logs;dispatch— доставка во внутренние сервисы по HTTP/RabbitMQ.
Хранилища данных
Проект использует polyglot persistence.
auth-serviceиспользует Prisma с моделямиUserиRefreshToken.personnelиспользует Prisma с моделямиDepartment,Position,Employee,ShiftScheduleTemplate,OutboxMessage.productionиспользует Prisma с моделямиProduct,ProductionOrder,ProductionOutput,Sale,Inventory,QualityResult,SensorReading,OutboxMessage.etlиспользует MongoDB через Mongoose как минимум дляRawImportиTransformationLog, а также GridFS-подобное файловое хранение для импортируемых файлов.
Prisma-сервисы получают datasource URLs из env через prisma.config.ts.
Общие архитектурные паттерны
Contracts-first границы
libs/contracts задает команды, queries и события для gateway и доменных сервисов. За счет этого proxy-слой и обработчики внутри сервисов опираются на одни и те же message shapes и topic names.
Корреляция запросов и логирование
Во всем workspace стандартизировано structured logging через nestjs-pino. Для трассировки используются RequestIdMiddleware, HTTP logging interceptors и service-specific exception filters либо shared HTTP filters.
Валидация на границах
Контроллеры и bootstrap-слои активно используют Nest ValidationPipe с transform, whitelist и forbidNonWhitelisted. Это показывает намерение отсекать невалидные payload еще до входа в application use case.
Transactional outbox
libs/nest-utils содержит общий outbox module, repository abstraction, Prisma-backed implementation и periodic publisher. personnel и production подключают этот модуль, чтобы сохранять события транзакционно и публиковать их асинхронно.
Разделение commands, queries и events
Именование exchange-ей и структура контроллеров отражают CQRS-подобный подход:
- commands меняют состояние;
- queries читают данные;
- events уведомляют другие сервисы о завершившихся доменных изменениях.
Этот подход виден и в раскладке shared contracts, и в RabbitMQ wiring.
Сквозной поток данных
Упрощенно система работает так:
- Клиент приходит в
gatewayпо HTTP, либо внешние данные заходят черезetl. gatewayвалидирует запрос и пересылает его в доменный сервис через RabbitMQ commands/queries.- Доменные сервисы исполняют use case-ы поверх Prisma-репозиториев и доменных сущностей.
- Для событийных сценариев
personnelиproductionсохраняют outbox records и публикуют события асинхронно. etlпринимает внешние записи, превращает их в canonical payload-ы и отправляет в downstream-домены.
Карта документации
Подробная документация по сервисам лежит в:
docs/gateway.mddocs/auth-service.mddocs/personnel.mddocs/production.mddocs/etl.md
Этот файл описывает систему на уровне композиции и сквозных механизмов, а service-level файлы фиксируют конкретные API, модули, обработчики и операционные детали.
Допущения и ограничения
- Обзор собран по структуре репозитория, Nest-модулям, контрактам, схемам и инфраструктурному коду, без доступа к deployment manifests и runtime-окружениям.
- В репозитории видны HTTP bootstrap-ы всех сервисов, но основная интеграционная модель доменных сервисов выглядит как RabbitMQ RPC + event publishing.
- Секреты, реальные env-значения и внутренние URL сознательно не включались в документацию.