Skip to content

ADR-0002. Activity notification do Kafka cấp, lưu trong core, rồi push

TrườngGiá trị
StatusAccepted
Date2026-05-20
Deciderssignal-team
Supersedes

Bối cảnh

  • Sự kiện domain (vd thanh toán thành công) cần trở thành notification bền vững, theo từng user hiển thị trong UI "chuông" một gợi ý WS live.
  • Producer biết điều gì xảy ra và một phạm vi người nhận (org / merchant / users rõ ràng) nhưng không biết danh sách người nhận cụ thể.
  • Signal đã sở hữu edge WebSocket nhưng không có schema; bảng ActivityNotification tập trung trong @nx/core.
  • Notification phải sống sót qua một socket lỡ — client có thể offline khi sự kiện bắn.

Quyết định

Chúng ta sẽ cấp activity notification cho Signal qua Kafka (signal.activity-notification), và để worker giải → lưu → push:

  1. Consume TActivityNotificationMessage; từ chối eventType lạ.
  2. Giải người nhận phía server — org/merchant qua PolicyDefinitionRepository, users qua recipientIds rõ ràng (fallback [actorId]).
  3. Dựng content + html từ một markdown decorator, lưu một hàng ActivityNotification mỗi người nhận qua createAll.
  4. Push observation/signal/notification/created tới mỗi room signal/notification/{recipientId}.

Consumer chạy với autocommit: false, commit theo từng message sau khi handler return, và fallbackMode: latest.

Hệ quả

ƯuNhược
Notification bền vững (DB) và live (WS)Re-delivery tạo hàng trùng — không dedup hôm nay
Producer giữ chỉ-scope; Signal sở hữu giải người nhậnGiải người nhận là một lần hit DB đồng bộ mỗi message
Tái dùng schema/repo tập trung @nx/coreLỗi handler được log nhưng không retry/DLQ
Commit thủ công cho an toàn at-least-onceHiện chỉ hiện thực nội dung PAYMENT_SUCCESS

Phương án đã cân nhắc

Phương ánƯuNhượcVì sao loại
Chỉ push WS (không lưu)Đơn giản nhấtMất nếu client offline; không lịch sửUI chuông cần lịch sử bền vững
Producer giải người nhận + ghi hàngSignal giữ nguMỗi producer lặp giải + kiến thức schemaTập trung trong Signal DRY hơn
Autocommit + idempotency keyÍt code thủ côngCần store dedup; chưa xâyHoãn; commit thủ công là an toàn tạm

Tham chiếu

  • signal/src/components/notification/component.ts (config consumer)
  • signal/src/services/activity-notification-worker.service.ts (giải/lưu/push)
  • core/src/common/kafka/types.ts (TActivityNotificationMessage)
  • API Events — idempotency

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