Customer Service — Events

(Добавлено в BR 3.1)

Публикует

customer.created

Публикуется при создании клиента (любым способом: admin / POS / merge / import в будущем).

Topic: customer.created

{
  "event_id": "uuid",
  "timestamp": "datetime",
  "version": 1,
  "payload": {
    "customer_id": "uuid",
    "franchise_id": "uuid",
    "phone": "+79991234567",
    "email": "user@example.com | null",
    "first_name": "string",
    "last_name": "string | null",
    "registration_source": "pos | web | mobile | admin | import",
    "registered_by_employee_id": "uuid | null",
    "registered_at": "datetime"
  }
}

Консьюмеры:

  • Customer Service (self) — триггерит точечный пересчёт dynamic групп для нового клиента (некоторые правила типа registration_source срабатывают сразу)
  • Loyalty Service (в будущем, BR 3.2+) — начисление welcome bonus

customer.updated

Публикуется при редактировании клиента через PATCH /customers/{id}. Изменения адресов публикуются через это же событие с пометкой в changed_fields.

Payload changed_fields — planned

Текущая реализация CustomerEventPublisher.publishUpdated() включает customer_id, franchise_id, phone, email, first_name, last_name, но массив changed_fields пока не формируется. Потребители могут сверять значения с предыдущим известным состоянием (event sourcing).

Topic: customer.updated

{
  "event_id": "uuid",
  "timestamp": "datetime",
  "version": 1,
  "payload": {
    "customer_id": "uuid",
    "franchise_id": "uuid",
    "changed_fields": ["phone", "birthday", "addresses"],
    "updated_at": "datetime"
  }
}

Консьюмеры:

  • Customer Service (self) — точечный пересчёт dynamic групп для клиента. Некоторые поля (birthday, city, delivery_zone) меняют принадлежность к группам

customer.deleted

Публикуется при soft delete клиента. PII уже обезличены на момент события.

Topic: customer.deleted

{
  "event_id": "uuid",
  "timestamp": "datetime",
  "version": 1,
  "payload": {
    "customer_id": "uuid",
    "franchise_id": "uuid",
    "deleted_at": "datetime"
  }
}

Консьюмеры:

  • Loyalty Service (в будущем) — обнуление балансов, снятие с промо-кампаний
  • Notification Service (в будущем) — отписка от рассылок

customer-group.member-changed

Публикуется при добавлении или удалении клиента из группы (любым механизмом: ручное для static, пересчёт для dynamic).

Topic: customer-group.member-changed

{
  "event_id": "uuid",
  "timestamp": "datetime",
  "version": 1,
  "payload": {
    "group_id": "uuid",
    "customer_id": "uuid",
    "franchise_id": "uuid",
    "group_name": "string",
    "group_type": "static | dynamic",
    "action": "added | removed",
    "changed_at": "datetime"
  }
}

Консьюмеры:

  • Notification Service (в будущем) — «Клиент получил статус VIP» push/email
  • Loyalty Service (в будущем) — активация/деактивация привилегий привязанных к группе

В MVP BR 3.1 консьюмеров нет

Событие публикуется сразу — это дёшево. Будущие сервисы подключаются без правок Customer Service.


Потребляет

order.completed

Источник: Order Service. Публикуется при завершении заказа (статус closed, выдан клиенту).

Consumer group: customer-service-group

Формат (обогащён в BR 3.1):

{
  "event_id": "uuid",
  "timestamp": "datetime",
  "version": 1,
  "payload": {
    "order_id": "uuid",
    "store_id": "uuid",
    "franchise_id": "uuid",
    "order_number": "string",
    "total": "decimal",
    "status": "closed",
    "customer_id": "uuid | null"
  }
}

Обработка:

  • Если customer_id IS NULL → событие игнорируется (анонимный заказ)
  • Если customer_id IS NOT NULL → вызов POST /internal/customer-groups/recompute-for-customer { customer_id } (локальный self-call через внутреннюю шину, без HTTP). Пересчитывает все dynamic группы для этого клиента — некоторые правила становятся применимыми (например, «LTV > 50 000 ₽» после нового заказа)

Полный пересчёт как fallback

Даже если consumer пропустит событие (например, сбой Kafka), scheduler раз в сутки в 03:00 МСК делает полный пересчёт всех dynamic групп всех франшиз. Значит группы к утру в корректном состоянии.


Топик-конвенция

  • Topics в одном namespace customer.* (kebab через точку)
  • Consumer group в Customer Service — customer-service-group
  • При смене payload — увеличивается version; старые consumers продолжают работать с новыми payloads (новые поля игнорируются)

Ссылки