Store Service — Events
Публикует
store.table.upserted
Публикуется при любом изменении состояния стола: create / update / soft-delete / occupy / release / reserve / cancel-reservation / waiter assignment. Используется pos-bff для realtime-инвалидации плана зала на POS-терминалах (Kafka → SSE → EventSource в pos-desktop).
Topic: store.table.upserted
Ключ Kafka: store_id
Доставка: fire-and-forget без outbox. Для UI-инвалидации потеря единичного события приемлема — на POS есть 10с polling fallback. При недоступности Kafka в момент изменения транзакция всё равно коммитится (KafkaTemplate возвращает CompletableFuture, exception логируется но не пробрасывается).
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"franchise_id": "uuid",
"store_id": "uuid",
"table_id": "uuid",
"number": "integer",
"status": "free | occupied | reserved",
"current_order_id": "uuid | null",
"current_waiter_id": "uuid | null",
"change_type": "created | updated | deleted | occupied | released | reserved | waiter_assigned",
"deleted_at": "datetime | null"
}
}Консьюмеры:
- pos-bff (group
pos-bff-sse-${HOSTNAME}) — broadcastToStore(store_id,table.invalidate) → POS Desktop вызываетtablesStore.reload()
marketing.slide.changed
(BR 6.1)
Публикуется при любом CRUD-изменении маркетинговых слайдов: create / update / soft-delete / reorder / активация-деактивация. Используется pos-bff для realtime-обновления standby-карусели на POS Desktop (Kafka → SSE → EventSource в pos-desktop).
Topic: marketing.slide.changed
Ключ Kafka: store_id (партиционирование по ТТ — все события одной ТТ идут в одну партицию, упорядоченно)
Доставка: через outbox (как store.table.upserted? — нет, table — fire-and-forget; здесь — outbox для гарантии at-least-once, потому что reorder влияет на порядок отображения; потеря единичного события создаст рассинхрон между админкой и кассой). Запись в outbox-таблицу в той же транзакции что и marketing_slides, отдельный publisher-poller вычитывает и публикует, по успешной публикации помечает processed_at.
{
"event_id": "uuid",
"timestamp": "datetime",
"version": 1,
"payload": {
"franchise_id": "uuid",
"store_id": "uuid",
"slide_id": "uuid | null — null для action=reordered (затронуты все слайды ТТ)",
"action": "created | updated | deleted | reordered | activated | deactivated"
}
}Минимальный payload
Не кладём
image_url,title,order— потребитель (pos-bff) использует событие только как trigger для broadcast. POS Desktop по SSE event дёргаетGET /pos/api/v1/marketing/activeи забирает свежий список.
Консьюмеры:
- pos-bff (group
pos-bff-sse-${HOSTNAME}) — broadcastToStore(store_id,marketing.invalidate) → POS Desktop в standby-режиме перезагружает активные слайды
Потребляет
| Event | Topic | Consumer group | Зачем |
|---|---|---|---|
order.status.changed | order.status.changed | store-service-tables | OrderStatusConsumer синхронизирует статус столов zal_tables с жизненным циклом заказа (освобождение стола при закрытии/отмене) |
Side-эффекты приостановки ЮЛ — синхронно
Приостановка ЮЛ → снятие ТТ с публикации реализована через синхронный вызов User Service → Store Service
POST /internal/stores/unpublish-by-legal-entity. Kafka не используется.
Будущие события (Phase 2)
| Event | Описание | Когда понадобится |
|---|---|---|
store.created | ТТ создана | Customer BFF (обновление каталога) |
store.published | ТТ опубликована | Customer BFF, Order Service |
store.unpublished | ТТ снята с публикации | Customer BFF, Order Service |
store.updated | ТТ обновлена (адрес, график) | Customer BFF |
store.deleted | ТТ удалена | Customer BFF, Order Service |
Ссылки
- Event Bus — общая шина и SSE-мост admin → POS
Переход на Kafka
При появлении нескольких консьюмеров (Customer BFF, Order Service) — переводим side-эффекты на Kafka, убираем синхронные вызовы.