Skip to content

Kiến trúc Sự kiện

Các service BANA được tách rời qua bốn seam. Redis không phải một trong số đó - nó chỉ là cache, fan-out WebSocket giữa các instance, và storage cho BullMQ.

SeamMang gìNguồn-sự-thật
Kafka event / command (nx.bana.evt.* · nx.bana.cmd.*)sự kiện ứng dụng liên-servicepackages/core/src/common/kafka/registry.ts (ServiceTopicDefs)
Debezium CDC (nx.bana.cdc.<schema>.<Table>)thay đổi dòng → read-model (Typesense, projection)cùng registry (CDC_TABLE_SCHEMA, CDCTopicDefs)
HTTP webhookhai chặng service-to-service (payment→sale, commerce→invoice)cấu hình webhook từng service
WebSocket (ws:…)đẩy real-time tới client (fan-out giữa instance qua Redis)websocket.ts từng service

Code cũ / chết - không phải xương sống messaging

IEventBus + RedisPubSubAdapter của @nx/core và các hằng PaymentEventChannels / CommerceEventChannels không bao giờ được khởi tạo cho eventing liên-service. Seam payment thật là topic Kafka nx.bana.evt.payment.succeeded, không phải chuỗi payment.order.success. Redis pub/sub chuyển frame WebSocket giữa các replica - nó không chuyển sự kiện ứng dụng giữa các service.

Kafka event & command

Quy ước tên topic: nx.bana.<evt|cmd>.<domain>[.<entity>].<event> - chữ thường, ngăn bằng ., dùng - cho từ ghép, quá khứ cho evt, mệnh lệnh cho cmd. Registry ServiceTopicDefs là danh sách đầy đủ:

TopicLoạiProducerConsumer
nx.bana.evt.payment.succeededevtsalefinance, inventory, invoice
nx.bana.evt.inventory.purchase-order.receivedevtinventoryfinance
nx.bana.evt.inventory.stock.issued-for-saleevtinventoryfinance
nx.bana.evt.inventory.stock.adjustedevtinventoryfinance
nx.bana.evt.kitchen.ticket-item.status-changedevtsaleinventory
nx.bana.evt.inventory.material.transferredevtinventoryinventory (chuyển kho)
nx.bana.evt.inventory.material.stock-changedevtinventory(chưa có consumer)
nx.bana.evt.signal.activity.notifiedevt(chưa có producer)signal → WebSocket
nx.bana.cmd.ledger.generatecmdledgerledger (queue → worker nội bộ)

Các hằng KafkaTopics.* phân giải ra các tên trên. signal.activity.notified đã có consumer nhưng chưa có producer trong repo; material.stock-changed được phát nhưng hiện chưa có consumer - cả hai đã đấu nối sẵn cho việc sắp tới. cmd.ledger.generatenội bộ ledger (tách queue→worker), không phải seam liên-service.

Consumer group

ServiceSubscribe
financepayment.succeeded, inventory.purchase-order.received, inventory.stock.issued-for-sale, inventory.stock.adjusted, CDC public.Merchant
inventorypayment.succeeded, kitchen.ticket-item.status-changed, inventory.material.transferred, CDC public.Merchant, CDC public.ProductVariant
invoicepayment.succeeded, CDC public.Merchant
signalsignal.activity.notified
searchtoàn bộ 27 CDC topic
ledgercmd.ledger.generate (nội bộ)

Debezium CDC

Connector Debezium đặt topic.prefix = nx.bana.cdc, phát nx.bana.cdc.<schema>.<Table> đúng nguyên theo từng bảng Postgres (CDC_TABLE_SCHEMA, đồng bộ với table.include.list của connector). 27 bảng được capture và đưa vào read-model:

ConsumerCDC topicProjection
searchtoàn bộ 27 (SearchCollections.ALL_CDC_TOPICS)collection Typesense (products, merchants, categories, organizers, devices, sale-channels)
invoicenx.bana.cdc.public.MerchantTaxInfo (hồ sơ thuế merchant chuẩn)
financenx.bana.cdc.public.Merchantví Cash mặc định khi có merchant mới
inventorynx.bana.cdc.public.Merchant, …public.ProductVariantseed InventoryItem

Bảng capture theo schema: public (Organizer, Merchant, Category, Device, SaleChannel, Product, ProductInfo, ProductVariant, ProductCategory, ProductIdentifier, MetaLink, ProductBundler, ProductOption, ProductOptionValue, ProductVariantOption), pricing (FareSet, Fare), sale (SaleOrder), inventory (InventoryStock, InventoryItem, InventoryLocation, InventoryIdentifier, Material), identity (User, UserProfile, UserIdentifier, PolicyDefinition).

Topic nội bộ connector (không phải dữ liệu ứng dụng): nx_bana_connect_configs / _offsets / _statuses, __debezium-heartbeat.nx.bana.cdc, nx.bana.cdc.public.debezium_signal, và các topic DLQ.

WebSocket topic

Topic WebSocket theo ws:{namespace}.{domain}.{entity}; room theo wr:{namespace}/{path}. Dựng bởi WebSocketTopics / WebSocketRooms trong packages/core/src/common/events/websocket-events.ts. Giao giữa các instance được fan-out qua Redis (signal, sale, payment, helpdesk, outreach gắn một Redis emitter adapter).

Sale (packages/sale/src/common/websocket.ts):

TopicMục đích
ws:observation.sale.sale-orderĐơn được tạo/cập nhật
ws:observation.sale.sale-order-itemThay đổi mục đơn hàng
ws:observation.sale.sale-checkThay đổi trạng thái check
ws:observation.sale.kitchen-ticketPhiếu bếp được gửi
ws:observation.sale.kitchen-ticket-itemCập nhật mục phiếu bếp
ws:observation.allocation.allocation-usageThay đổi sử dụng chỗ/allocation

Payment (packages/payment/src/common/websocket.ts):

TopicMục đích
ws:observation.payment.transactionCập nhật trạng thái giao dịch thanh toán
ws:observation.payment.payment-attemptSự kiện từng lần thử thanh toán

Outreach (packages/outreach/src/components/websocket/topics.ts):

TopicMục đích
ws:observation.outreach.inquiry.submittedCó inquiry mới (thông báo admin real-time)

HTTP webhook

payment → sale

Service sale nhận sự kiện thanh toán từ MQ-Pay qua HTTP, định tuyến theo header X-Webhook-Event-Type (packages/sale/src/common/webhook-types.ts):

Event typeMục đích
mq-pay:attempt.successLần thử thanh toán thành công
mq-pay:attempt.failedLần thử thanh toán thất bại
mq-pay:attempt.expiredLần thử thanh toán hết hạn
mq-pay:attempt.cancelledNgười dùng hủy lần thử
mq-pay:transaction.settledGiao dịch tất toán (đã trả hết)
mq-pay:transaction.cancelledGiao dịch bị hủy

Khi đơn tất toán, sale phát topic Kafka nx.bana.evt.payment.succeeded. Bên trong thư viện MQ-Pay các sự kiện này trước hết phát trên một EventEmitter của Node.js (mq-pay:transaction.*, mq-pay:attempt.*, mq-pay:refund.*) và được bắc cầu sang sale qua MQPaySaleEventAdapter → SaleEventMapperService → SalePaymentEventHandlerService.

commerce → invoice

commerce phát commerce:organizer.hq_changed như một HTTP webhook (WebhookDispatcherService + WebhookConfig); invoice nhận qua CommerceWebhookService.handleEvent để làm mới hồ sơ phát hành.

Luồng

Onboarding merchant mới (qua CDC)

Thanh toán

Thay đổi sản phẩm → read-model (CDC)

Trang Liên quan

TrangMô tả
Kiến trúcDanh mục dịch vụ, chuỗi phụ thuộc, ma trận component
Platform FactsTóm tắt messaging seam, số liệu chuẩn
Hạ tầng - KafkaThiết lập cluster Kafka KRaft
Hạ tầng - CDCCấu hình pipeline Debezium CDC

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.