Events Catalog
Полный каталог всех доменных событий в системе EFKO Kernel.
Обзор
Система использует событийную архитектуру для асинхронной коммуникации между сервисами. События публикуются в RabbitMQ exchanges и потребляются downstream сервисами.
Exchanges событий
efko.auth.events— события auth-serviceefko.personnel.events— события personnel-serviceefko.production.events— события production-serviceefko.etl.events— события etl-service
Envelope Event
Все события в системе упаковываются в Envelope Event — стандартизированную обертку, которая обеспечивает единый формат для всех доменных событий. Это позволяет downstream сервисам корректно обрабатывать события независимо от их типа.
Структура Envelope Event
{
event_id: string; // UUID события (генерируется при публикации)
event_type: string; // Тип события (например, "auth.user.created.event")
timestamp: string; // Время публикации события (ISO datetime)
source_service: string; // Сервис-источник события (например, "auth-service")
correlation_id: string; // ID для трассировки запроса
version: string; // Версия схемы события (например, "1.0.0")
payload: unknown; // Payload доменного события (специфичен для типа)
}
Пример Envelope Event
{
"event_id": "evt-123e4567-e89b-12d3-a456-426614174000",
"event_type": "auth.user.created.event",
"timestamp": "2025-01-15T10:30:00Z",
"source_service": "auth-service",
"correlation_id": "req-abc123",
"version": "1.0.0",
"payload": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "ivan@example.com",
"fullName": "Иванов Иван",
"role": "admin",
"isActive": true,
"employeeId": null
}
}
Поля Envelope
| Поле | Тип | Описание |
|---|---|---|
event_id |
string | Уникальный идентификатор события (UUID v4) |
event_type |
string | Тип события (соответствует routing key) |
timestamp |
string | Время публикации события в формате ISO 8601 |
source_service |
string | Сервис, который опубликовал событие |
correlation_id |
string | ID для трассировки распределенных запросов |
version |
string | Версия схемы события (например, "1.0.0") |
payload |
unknown | Payload доменного события (структура зависит от типа) |
Использование в коде
// Публикация события с envelope
await this.eventEmitter.emit('auth.user.created.event', {
event_id: randomUUID(),
event_type: 'auth.user.created.event',
timestamp: new Date().toISOString(),
source_service: 'auth-service',
correlation_id: correlationId,
version: '1.0.0',
payload: userCreatedEventPayload,
});
// Потребление события
@RabbitSubscribe({
exchange: 'efko.auth.events',
routingKey: 'auth.user.created.event',
queue: 'auth.user.created',
})
async handleUserCreated(envelope: IRabbitEvent<AuthUserCreatedEvent>) {
const { event_id, event_type, timestamp, source_service, correlation_id, payload } = envelope;
// Обработка события
}
Best Practices для Envelope
- Всегда используйте envelope — не публикуйте "сырые" события напрямую
- Генерируйте event_id — используйте UUID v4 для уникальности
- Указывайте timestamp — время публикации, а не время доменного события
- Используйте correlation_id — для трассировки распределенных запросов
- Указывайте version — для управления версионностью схемы события
- Валидируйте envelope — downstream сервисы должны проверять структуру envelope перед обработкой payload
Публикация событий
События публикуются двумя способами:
- Transactional Outbox — для personnel и production сервисов
- Событие записывается в таблицу
outbox_messagesв той же транзакции с доменными данными - Периодический publisher (
OutboxPeriodicPublisher) читает PENDING события и публикует в RabbitMQ - Статус обновляется на SENT при успешной публикации
-
Повторная публикация при ошибках (retry)
-
Direct Publish — для auth-service и некоторых сценариев
- Событие публикуется сразу через
RmqEventEmitterService - Используется для критически важных событий, требующих немедленной доставки
Потребление событий
Downstream сервисы подписываются на соответствующие exchanges и обрабатывают события: - Для синхронизации данных - Для триггера бизнес-процессов - Для уведомлений и аналитики
Auth Events
События аутентификации и управления пользователями.
AuthUserCreatedEvent
Публикуется при регистрации нового пользователя.
Exchange: efko.auth.events
Routing Key: auth.user.created.event
Когда публикуется: После успешной регистрации пользователя в RegisterUserUseCase
Payload
{
userId: string; // UUID пользователя
email: string; // Email пользователя
fullName: string; // Полное имя
role: UserRole; // Роль пользователя
isActive: boolean; // Статус активности
employeeId: string | null; // ID сотрудника (если привязан)
createdAt: Date; // Дата создания
updatedAt: Date; // Дата обновления
}
Пример
{
"userId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "ivan@example.com",
"fullName": "Иванов Иван",
"role": "admin",
"isActive": true,
"employeeId": null,
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:30:00.000Z"
}
Кто может потреблять
- Personnel Service — для синхронизации с кадровыми данными
- Analytics Service — для аналитики по пользователям
AuthUserDeactivatedEvent
Публикуется при деактивации пользователя.
Exchange: efko.auth.events
Routing Key: auth.user.deactivated.event
Когда публикуется: После успешной деактивации в DeactivateUserUseCase
Payload
Пример
Кто может потреблять
- Personnel Service — для увольнения сотрудника
- Production Service — для отзыва прав доступа
- Gateway — для инвалидации сессий в кэше
Personnel Events
События кадрового домена: подразделения, должности, сотрудники, смены.
PersonnelEmployeeCreatedEvent
Публикуется при приеме сотрудника на работу.
Exchange: efko.personnel.events
Routing Key: personnel.employee.created.event
Когда публикуется: После успешного создания в CreateEmployeeUseCase
Payload
{
id: string; // UUID сотрудника
personnelNumber: string; // Табельный номер
fullName: string; // Полное имя
departmentId: string; // UUID подразделения
positionId: string; // UUID должности
status: EmployeeStatus; // Статус сотрудника
}
Пример
{
"id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"personnelNumber": "EMP-0001",
"fullName": "Иванов Иван Иванович",
"departmentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"positionId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"status": "active"
}
Кто может потреблять
- Auth Service — для создания учетной записи сотрудника
- Access Control Service — для выдачи прав доступа
PersonnelEmployeeUpdatedEvent
Публикуется при обновлении данных сотрудника.
Exchange: efko.personnel.events
Routing Key: personnel.employee.updated.event
Когда публикуется: После успешного обновления в UpdateEmployeeUseCase
Payload
{
id: string; // UUID сотрудника
fullName: string; // Полное имя
departmentId: string; // UUID подразделения
positionId: string; // UUID должности
employmentType: EmploymentType; // Тип занятости
status: EmployeeStatus; // Статус сотрудника
}
Пример
{
"id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"fullName": "Иванов Иван Петрович",
"departmentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"positionId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"employmentType": "main",
"status": "active"
}
Кто может потреблять
- Auth Service — для обновления профиля пользователя
- Access Control Service — для обновления прав доступа
PersonnelEmployeeTerminatedEvent
Публикуется при увольнении сотрудника.
Exchange: efko.personnel.events
Routing Key: personnel.employee.terminated.event
Когда публикуется: После успешного увольнения в TerminateEmployeeUseCase
Payload
{
id: string; // UUID сотрудника
terminationDate: string; // Дата увольнения (ISO date)
status: EmployeeStatus; // Статус (TERMINATED)
}
Пример
{
"id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"terminationDate": "2025-06-30",
"status": "terminated"
}
Кто может потреблять
- Auth Service — для деактивации учетной записи
- Production Service — для отзыва прав доступа
- Access Control Service — для отзыва всех разрешений
PersonnelDepartmentCreatedEvent
Публикуется при создании подразделения.
Exchange: efko.personnel.events
Routing Key: personnel.department.created.event
Когда публикуется: После успешного создания в CreateDepartmentUseCase
Payload
{
id: string; // UUID подразделения
name: string; // Название подразделения
code: string; // Код подразделения
type: DepartmentType; // Тип подразделения
parentId: string | null | undefined; // UUID родительского подразделения
}
Пример
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Производственный цех №1",
"code": "PROD-001",
"type": "division",
"parentId": null
}
Кто может потреблять
- Analytics Service — для аналитики по оргструктуре
- Reporting Service — для отчетов по подразделениям
PersonnelDepartmentUpdatedEvent
Публикуется при обновлении подразделения.
Exchange: efko.personnel.events
Routing Key: personnel.department.updated.event
Когда публикуется: После успешного обновления в UpdateDepartmentUseCase
Payload
{
id: string; // UUID подразделения
name: string; // Название подразделения
code: string; // Код подразделения
type: DepartmentType; // Тип подразделения
headEmployeeId: string | null | undefined; // UUID руководителя
}
Пример
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Производственный цех №2",
"code": "PROD-001",
"type": "division",
"headEmployeeId": "d4e5f6a7-b8c9-0123-defa-234567890123"
}
Кто может потреблять
- Analytics Service — для обновления аналитики
- Reporting Service — для обновления отчетов
PersonnelPositionCreatedEvent
Публикуется при создании должности.
Exchange: efko.personnel.events
Routing Key: personnel.position.created.event
Когда публикуется: После успешного создания в CreatePositionUseCase
Payload
{
id: string; // UUID должности
title: string; // Название должности
code: string; // Код должности
departmentId: string; // UUID подразделения
}
Пример
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"title": "Оператор станка",
"code": "OP-001",
"departmentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Кто может потреблять
- Analytics Service — для аналитики по должностям
- Access Control Service — для создания ролей по должностям
PersonnelPositionUpdatedEvent
Публикуется при обновлении должности.
Exchange: efko.personnel.events
Routing Key: personnel.position.updated.event
Когда публикуется: После успешного обновления в UpdatePositionUseCase
Payload
{
id: string; // UUID должности
title: string; // Название должности
code: string; // Код должности
departmentId: string; // UUID подразделения
}
Пример
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"title": "Старший оператор станка",
"code": "OP-001",
"departmentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Кто может потреблять
- Analytics Service — для обновления аналитики
- Access Control Service — для обновления ролей
PersonnelShiftTemplateCreatedEvent
Публикуется при создании шаблона смены.
Exchange: efko.personnel.events
Routing Key: personnel.shift-template.created.event
Когда публикуется: После успешного создания в CreateShiftTemplateUseCase
Payload
{
id: string; // UUID шаблона
name: string; // Название шаблона
shiftType: ShiftType; // Тип смены
startTime: string; // Время начала (HH:MM)
endTime: string; // Время окончания (HH:MM)
workDaysPattern: string; // Паттерн рабочих дней (бинарная строка)
}
Пример
{
"id": "e5f6a7b8-c9d0-1234-efab-345678901234",
"name": "Дневная смена",
"shiftType": "day_shift",
"startTime": "08:00",
"endTime": "20:00",
"workDaysPattern": "1111100"
}
Кто может потреблять
- Shift Service — для создания графиков смен
- Production Service — для планирования производства
PersonnelShiftTemplateUpdatedEvent
Публикуется при обновлении шаблона смены.
Exchange: efko.personnel.events
Routing Key: personnel.shift-template.updated.event
Когда публикуется: После успешного обновления в UpdateShiftTemplateUseCase
Payload
{
id: string; // UUID шаблона
name: string; // Название шаблона
shiftType: ShiftType; // Тип смены
startTime: string; // Время начала (HH:MM)
endTime: string; // Время окончания (HH:MM)
workDaysPattern: string; // Паттерн рабочих дней
}
Пример
{
"id": "e5f6a7b8-c9d0-1234-efab-345678901234",
"name": "Ночная смена",
"shiftType": "night_shift",
"startTime": "20:00",
"endTime": "08:00",
"workDaysPattern": "1111100"
}
Кто может потреблять
- Shift Service — для обновления графиков смен
- Production Service — для обновления планирования
PersonnelShiftAssignedEvent
Публикуется при назначении сотрудника на смену.
Exchange: efko.personnel.events
Routing Key: personnel.shift.assigned.event
Когда публикуется: При назначении сотрудника на конкретную смену
Payload
{
assignmentId: string; // UUID назначения
employeeId: string; // UUID сотрудника
personnelNumber: string; // Табельный номер
shiftTemplateId: string; // UUID шаблона смены
shiftType: ShiftType; // Тип смены
shiftDate: string; // Дата смены (ISO date)
startTime: string; // Время начала (ISO datetime)
endTime: string; // Время окончания (ISO datetime)
assignedAt: string; // Время назначения (ISO datetime)
assignedByUserId?: string; // UUID пользователя, назначившего смену
}
Пример
{
"assignmentId": "f6a7b8c9-d0e1-2345-fabc-456789012345",
"employeeId": "d4e5f6a7-b8c9-0123-defa-234567890123",
"personnelNumber": "EMP-0001",
"shiftTemplateId": "e5f6a7b8-c9d0-1234-efab-345678901234",
"shiftType": "day_shift",
"shiftDate": "2025-01-20",
"startTime": "2025-01-20T08:00:00Z",
"endTime": "2025-01-20T20:00:00Z",
"assignedAt": "2025-01-15T10:00:00Z",
"assignedByUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Кто может потреблять
- Access Service — для выдачи пропусков в определенные периоды
- Production Service — для планирования персонала на линиях
Production Events
События производственного домена: продукты, заказы, выпуск, качество, датчики.
ProductionProductCreatedEvent
Публикуется при создании продукта.
Exchange: efko.production.events
Routing Key: production.product.created.event
Когда публикуется: После успешного создания в CreateProductUseCase
Payload
{
id: string; // UUID продукта
code: string; // Код продукта
name: string; // Название продукта
category: ProductCategory; // Категория продукта
}
Пример
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"code": "PROD-001",
"name": "Творог 5%",
"category": "finished_product"
}
Кто может потреблять
- ETL Service — для синхронизации с внешними системами
- Analytics Service — для аналитики по продуктам
ProductionProductUpdatedEvent
Публикуется при обновлении продукта.
Exchange: efko.production.events
Routing Key: production.product.updated.event
Когда публикуется: После успешного обновления продукта
Payload
{
id: string; // UUID продукта
code: string; // Код продукта
name: string; // Название продукта
category: ProductCategory; // Категория продукта
}
Пример
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"code": "PROD-001",
"name": "Творог 5% (обновленный)",
"category": "finished_product"
}
Кто может потреблять
- ETL Service — для синхронизации с внешними системами
- Analytics Service — для обновления аналитики
ProductionOrderCreatedEvent
Публикуется при создании производственного заказа.
Exchange: efko.production.events
Routing Key: production.order.created.event
Когда публикуется: После успешного создания в CreateOrderUseCase
Payload
{
id: string; // UUID заказа
externalOrderId: string; // Внешний номер заказа
productId: string; // UUID продукта
status: OrderStatus; // Статус заказа
}
Пример
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"externalOrderId": "EXT-ORDER-001",
"productId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "planned"
}
Кто может потреблять
- Personnel Service — для планирования персонала
- Analytics Service — для аналитики по заказам
ProductionOrderStatusUpdatedEvent
Публикуется при обновлении статуса заказа.
Exchange: efko.production.events
Routing Key: production.order.status-updated.event
Когда публикуется: После успешного обновления статуса в UpdateOrderStatusUseCase
Payload
{
id: string; // UUID заказа
status: OrderStatus; // Новый статус
actualQuantity: number | null; // Фактическое количество
actualStart: string | null; // Фактическое начало (ISO datetime)
actualEnd: string | null; // Фактическое окончание (ISO datetime)
}
Пример
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "completed",
"actualQuantity": 950,
"actualStart": "2025-01-02T06:00:00Z",
"actualEnd": "2025-01-09T18:00:00Z"
}
Кто может потреблять
- Personnel Service — для освобождения/назначения персонала
- Analytics Service — для аналитики выполнения заказов
- Inventory Service — для обновления остатков
ProductionOutputRecordedEvent
Публикуется при регистрации выпуска продукции.
Exchange: efko.production.events
Routing Key: production.output.recorded.event
Когда публикуется: После успешной записи в RecordOutputUseCase
Payload
{
id: string; // UUID выпуска
orderId: string; // UUID заказа
lotNumber: string; // Номер партии
quantity: number; // Количество
}
Пример
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"orderId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"lotNumber": "LOT-2025-001",
"quantity": 500
}
Кто может потреблять
- Quality Service — для инициирования контроля качества
- Inventory Service — для обновления остатков
- Analytics Service — для аналитики выпуска
ProductionSaleRecordedEvent
Публикуется при регистрации продажи.
Exchange: efko.production.events
Routing Key: production.sale.recorded.event
Когда публикуется: После успешной записи в RecordSaleUseCase
Payload
{
id: string; // UUID продажи
externalId: string; // Внешний ID продажи
productId: string; // UUID продукта
amount: number; // Сумма продажи
channel: SaleChannel; // Канал продаж
}
Пример
{
"id": "d4e5f6a7-b8c9-0123-defa-234567890123",
"externalId": "SALE-001",
"productId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amount": 50000,
"channel": "retail"
}
Кто может потреблять
- Inventory Service — для обновления остатков
- Analytics Service — для аналитики продаж
- Finance Service — для финансового учета
ProductionInventoryUpdatedEvent
Публикуется при обновлении остатков на складе.
Exchange: efko.production.events
Routing Key: production.inventory.updated.event
Когда публикуется: После успешного upsert в UpsertInventoryUseCase
Payload
{
id: string; // UUID остатка
productId: string; // UUID продукта
warehouseCode: string; // Код склада
quantity: number; // Количество
}
Пример
{
"id": "e5f6a7b8-c9d0-1234-efab-345678901234",
"productId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"warehouseCode": "WH-01",
"quantity": 200
}
Кто может потреблять
- Analytics Service — для аналитики остатков
- Alert Service — для уведомлений о низких остатках
ProductionQualityResultRecordedEvent
Публикуется при регистрации результата контроля качества.
Exchange: efko.production.events
Routing Key: production.quality-result.recorded.event
Когда публикуется: После успешной записи в RecordQualityResultUseCase
Payload
{
id: string; // UUID результата
lotNumber: string; // Номер партии
productId: string; // UUID продукта
inSpec: boolean; // Соответствует норме
decision: QualityDecision; // Решение
}
Пример
{
"id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
"lotNumber": "LOT-2025-001",
"productId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"inSpec": true,
"decision": "approved"
}
Кто может потреблять
- Analytics Service — для аналитики качества
- Alert Service — для уведомлений о браке
- Production Service — для блокировки выпуска бракованной продукции
ProductionSensorReadingRecordedEvent
Публикуется при записи показания датчика.
Exchange: efko.production.events
Routing Key: production.sensor-reading.recorded.event
Когда публикуется: После успешной записи в RecordSensorReadingUseCase
Payload
{
id: string; // UUID показания
deviceId: string; // ID устройства
productionLine: string; // Производственная линия
parameterName: string; // Название параметра
quality: SensorQuality; // Качество сигнала
}
Пример
{
"id": "a7b8c9d0-e1f2-3456-abcd-567890123456",
"deviceId": "SENSOR-01",
"productionLine": "Line-1",
"parameterName": "temperature",
"quality": "good"
}
Кто может потреблять
- Analytics Service — для аналитики показаний
- Alert Service — для уведомлений об отклонениях
ProductionSensorAnomalyDetectedEvent
Публикуется при обнаружении аномалии в показаниях датчика.
Exchange: efko.production.events
Routing Key: production.sensor.anomaly.event
Когда публикуется: При детекции аномалии в SensorAnomalyDetector
Payload
{
readingId: string; // UUID показания
deviceId: string; // ID устройства
productionLine: string; // Производственная линия
parameterName: string; // Название параметра
value: number; // Значение
unit: string; // Единица измерения
quality: SensorQuality; // Качество сигнала
anomalyType: SensorAnomalyType; // Тип аномалии
severity: SensorAnomalySeverity; // Тяжесть аномалии
reason: string; // Причина
lowerLimit?: number; // Нижний предел
upperLimit?: number; // Верхний предел
detectedAt: string; // Время обнаружения (ISO datetime)
}
Пример
{
"readingId": "a7b8c9d0-e1f2-3456-abcd-567890123456",
"deviceId": "SENSOR-01",
"productionLine": "Line-1",
"parameterName": "temperature",
"value": 95.5,
"unit": "°C",
"quality": "good",
"anomalyType": "VALUE_OUT_OF_RANGE",
"severity": "HIGH",
"reason": "Temperature exceeds upper limit of 85°C",
"lowerLimit": 60,
"upperLimit": 85,
"detectedAt": "2025-01-05T10:30:00Z"
}
Кто может потреблять
- Alert Service — для немедленных уведомлений
- Analytics Service — для анализа аномалий
- Production Service — для автоматической остановки линии
SensorAnomalyType
VALUE_OUT_OF_RANGE— Значение вне допустимого диапазонаBAD_QUALITY— Плохое качество сигналаMISSING_DATA— Отсутствующие данныеDEVIATION_SPIKE— Резкое отклонение
SensorAnomalySeverity
LOW— НизкаяMEDIUM— СредняяHIGH— ВысокаяCRITICAL— Критическая
ETL Events
События интеграции с внешними системами.
EtlImportCompletedEvent
Публикуется при успешном завершении импорта.
Exchange: efko.etl.events
Routing Key: etl.import.completed.event
Когда публикуется: После успешного завершения ETL pipeline
Payload
{
importId: string; // ID импорта (MongoDB ObjectId)
sourceSystem: string; // Источник системы
importType: string; // Тип импорта
status: string; // Статус (completed)
recordsCount: number; // Количество записей
successCount: number; // Количество успешных
errorCount: number; // Количество ошибок
timestamp: string; // Время завершения (ISO datetime)
}
Пример
{
"importId": "507f1f77bcf86cd799439011",
"sourceSystem": "1c_zup",
"importType": "employees",
"status": "completed",
"recordsCount": 150,
"successCount": 145,
"errorCount": 5,
"timestamp": "2025-01-15T14:30:00Z"
}
Кто может потреблять
- Analytics Service — для аналитики импортов
- Notification Service — для уведомлений об успешном импорте
EtlImportFailedEvent
Публикуется при неудачном завершении импорта.
Exchange: efko.etl.events
Routing Key: etl.import.failed.event
Когда публикуется: После неудачного завершения ETL pipeline
Payload
{
importId: string; // ID импорта (MongoDB ObjectId)
sourceSystem: string; // Источник системы
importType: string; // Тип импорта
errorMessage: string; // Сообщение об ошибке
timestamp: string; // Время неудачи (ISO datetime)
}
Пример
{
"importId": "507f1f77bcf86cd799439011",
"sourceSystem": "1c_zup",
"importType": "employees",
"errorMessage": "Failed to dispatch to personnel-service: timeout",
"timestamp": "2025-01-15T14:30:00Z"
}
Кто может потреблять
- Alert Service — для немедленных уведомлений
- Analytics Service — для анализа проблем импорта
- Notification Service — для уведомлений об ошибке
Потребление событий
Подписка на события
Для потребления событий из RabbitMQ:
@RabbitSubscribe({
exchange: 'efko.personnel.events',
routingKey: 'personnel.employee.created.event',
queue: 'my-service.personnel.events.queue',
})
async handleEmployeeCreatedEvent(payload: PersonnelEmployeeCreatedEvent) {
// Обработка события
}
Обработка ошибок
При ошибке обработки события:
- Сообщение возвращается в очередь с reject(false) для повторной попытки
- После N неудачных попыток сообщение перемещается в DLQ
- Статус outbox записи обновляется на FAILED
Корреляция
Все события содержат метаданные для корреляции:
- correlationId — связывает с исходным запросом
- timestamp — время публикации
- sourceService — сервис-источник
Мониторинг событий
RabbitMQ Management UI
Отслеживайте события через RabbitMQ Management UI: - Проверьте наличие сообщений в очередях - Мониторьте rate публикации - Проверьте DLQ (Dead Letter Queue) для неудачных сообщений
Outbox таблица
Мониторинг через SQL:
Логи
ETL и domain сервисы логируют: - Публикацию событий - Ошибки публикации - Retry попытки