Skip to content

PRD: Tín hiệu & thông báo thiết bị

ModuleThiết bị (CORE-04)PRD IDPRD-MON-001
StatusIn-progressOwnerĐội Device / Signal
Date2026-05-21Versionv0.1
Packages@nx/signal · @nx/outreach · @nx/coreURDMON

TL;DR

Mang đến cho KICKO một nền tảng activity-notification phía server: một Kafka consumer thu nhận các sự kiện hoạt động, một worker xác định đúng những người dùng nhận trong scope organizer/merchant, lưu một bản ghi notification, rồi đẩy trực tiếp tới các client đang kết nối qua WebSocket. Kết quả - quản trị viên thấy hoạt động thiết bị và nền tảng hiển thị gần như tức thời thay vì phải polling, và use case trực tiếp đầu tiên (inquiry-submitted) chạy thông suốt từ đầu đến cuối.

1. Context & Problem

Định danh & Giám sát Tình trạng Thiết bị (MON) cần nền tảng ghi nhận hoạt động và hiển thị cho quản trị viên gần như tức thời. Hiện chưa có nền tảng thông báo phía server: sự kiện xảy ra ở commerce/outreach nhưng không có gì phát chúng tới đúng người dùng hay đẩy lên giao diện trực tiếp, nên quản trị viên không thể theo dõi hoạt động ngay khi nó diễn ra.

Increment này xây dựng nền tảng đó trong @nx/signal - một pipeline activity-notification trọn vẹn (Kafka consumer → worker → bản ghi được lưu → WebSocket emit) - cùng với việc xác định người nhận theo scope organizer/merchant và một WebSocket transport ổn định. Đây là kênh truyền thời gian thực mà việc giám sát và hiển thị hoạt động dựa vào; phần báo cáo heartbeat/tình trạng (URD-MON-001/002) và các thao tác thiết bị từ xa (URD-MON-004/005) được theo dõi riêng.

2. Goals & Non-Goals

Goals

  • Một pipeline activity-notification chạy bằng Kafka trong @nx/signal: consumer → worker → bản ghi được lưu → WebSocket emit.
  • Xác định người nhận - thông báo được phát tới đúng người dùng trong scope organizer/merchant.
  • Một WebSocket transport ổn định (room + topic + socket-event service) với cách đặt tên room/topic cố định (signal/notification, NOTIFICATION_CREATED).
  • Trạng thái đã đọc của notification: các endpoint REST để lấy notification và đánh dấu đã đọc.
  • Use case thời gian thực đầu tiên trọn vẹn: thông báo WebSocket inquiry-submitted trong @nx/outreach.

Non-Goals

  • Phát heartbeat và ngưỡng offline 15 phút (URD-MON-001/002).
  • Hủy kích hoạt từ xa / xóa dữ liệu từ xa (URD-MON-004/005).
  • Giao diện dashboard tình trạng theo từng thiết bị (bề mặt client tiêu thụ).
  • Tách bộ công cụ notification khỏi @nx/signal sang một package dùng chung.

3. Success Metrics

MetricTarget / signal
Độ trễ phátSự kiện hoạt động → WebSocket emit tới client gần như tức thời (dưới một giây ở tải thông thường)
Độ chính xác người nhậnThông báo tới đúng người dùng trong scope organizer/merchant; không rò rỉ chéo tenant
Độ bềnMọi notification được phát đều có bản ghi được lưu; trạng thái đã đọc tồn tại qua lần kết nối lại
Phạm viĐường đi trực tiếp đầu tiên (inquiry-submitted) được kiểm chứng trọn vẹn; pipeline tái dùng cho các loại sự kiện sau

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
Quản trị viên / Chủ sở hữuThấy hoạt động nền tảng & thiết bị hiển thị trực tiếp không cần polling
Client đang kết nối (web/app)Nhận thông báo qua WebSocket trực tiếp và phản ánh trạng thái đã đọc
Người xử lý outreachĐược báo ngay khi có inquiry được gửi

Core scenarios: một sự kiện hoạt động đến Kafka → worker xác định người nhận trong scope organizer/merchant và lưu một notification → bản ghi được đẩy qua WebSocket tới các client đang kết nối → một client lấy notification của mình và đánh dấu đã đọc; việc gửi inquiry phát một thông báo WebSocket trực tiếp qua cùng transport này.

5. User Stories

  • Là một quản trị viên, tôi muốn hoạt động xuất hiện trên giao diện ngay khi nó diễn ra, để tôi giám sát nền tảng mà không cần làm mới.
  • Là một client đang kết nối, tôi muốn nhận thông báo qua WebSocket trực tiếp, để thấy cập nhật ngay khoảnh khắc nó xảy ra.
  • Là một client đang kết nối, tôi muốn lấy notification của mình và đánh dấu đã đọc, để trạng thái đã đọc nhất quán qua các phiên.
  • Là một người xử lý outreach, tôi muốn có thông báo trực tiếp khi một inquiry được gửi, để tôi phản hồi kịp thời.
  • nền tảng, tôi muốn thông báo chỉ phát tới người dùng trong đúng scope organizer/merchant, để không tenant nào thấy hoạt động của tenant khác.

6. Functional Requirements

#RequirementURD ref
FR-1Một Kafka consumer thu nhận các sự kiện hoạt động vào pipeline notificationURD-MON-003
FR-2Một worker xác định các user ID người nhận trong scope organizer/merchantURD-MON-003
FR-3Mỗi notification được lưu thành một bản ghi activity-notification trong @nx/coreURD-MON-003
FR-4Một WebSocket transport (room + topic + socket-event service) đẩy notification tới các client đang kết nối trực tiếp, trên room signal/notification / topic NOTIFICATION_CREATEDURD-MON-003
FR-5Các endpoint REST lấy notification của một người dùng và đánh dấu đã đọcURD-MON-003
FR-6Việc gửi inquiry trong @nx/outreach phát một thông báo WebSocket tới các client quan tâmURD-MON-003

Toàn bộ nội dung requirement và tiêu chí nghiệm thu nằm trong Device URD. PRD này tham chiếu chúng thay vì lặp lại.

7. Non-Functional Requirements

AreaRequirement
Tenancy & authzViệc xác định người nhận theo scope organizer/merchant; thông báo không bao giờ vượt ranh giới tenant
Độ bềnMọi WebSocket emit đều được bảo chứng bằng một bản ghi notification được lưu; trạng thái đã đọc lấy lại được sau khi kết nối lại
Performance / scaleKafka tách rời việc thu nhận khỏi việc phát; worker xử lý các đợt dồn dập mà không chặn producer
Độ ổn định transportCách đặt tên room/topic cố định (signal/notification, NOTIFICATION_CREATED) để client đăng ký theo một hợp đồng ổn định
i18nNhãn notification hiển thị cho người dùng dùng song ngữ ({ en, vi }) khi xuất hiện

8. UX & Flows

Các bề mặt chính: notification component nằm trong @nx/signal (components/notification - consumer, worker, socket-event service, rooms, topics) với REST trong controllers/activity-notifications; đường đi inquiry nằm trong @nx/outreach (components/websocket, controllers/inquiry). Giao diện dashboard tiêu thụ nằm ngoài phạm vi của increment này.

9. Data & Domain

EntityVai trò
activity-notificationBản ghi notification được lưu (người nhận, payload, trạng thái đã đọc) trong @nx/core
Notification componentKafka consumer, worker, socket-event service, rooms, topics của @nx/signal
WebSocket room / topicRoom signal/notification và topic NOTIFICATION_CREATED - kênh phát trực tiếp
Xác định người nhậnTra cứu của PolicyDefinitionRepository các user ID trong một organizer/merchant

Chỉ ở mức khái niệm - schema đầy đủ nằm trong developer domain model.

10. Dependencies & Assumptions

Depends on

  • @nx/core - sở hữu schema/model/repository activity-notification, Kafka topic + types, và việc xác định người nhận qua PolicyDefinitionRepository.
  • Kafka - đường nối thu nhận giữa các nguồn hoạt động và notification worker.
  • WebSocket transport - kênh phát trực tiếp tới các client đang kết nối.
  • @nx/outreach - producer sự kiện đầu tiên (gửi inquiry).

Assumptions

  • Các nguồn hoạt động đẩy sự kiện lên Kafka topic đã thống nhất.
  • Dữ liệu thành viên organizer/merchant sẵn sàng cho việc xác định người nhận.
  • Client duy trì một kết nối WebSocket và đăng ký room signal/notification.

11. Risks & Open Questions

Risk / questionMitigation / status
Việc xác định người nhận có thể rò rỉ chéo tenantViệc xác định theo scope organizer/merchant; kiểm chứng dựa trên tra cứu thành viên
Mất kết nối WebSocket có thể làm rơi thông báo trực tiếpMọi emit đều được bảo chứng bằng một bản ghi được lưu; client lấy lại trạng thái đã đọc khi kết nối lại
Tên room/topic lệch nhau giữa producer và clientTên được cố định thành signal/notification / NOTIFICATION_CREATED như một hợp đồng ổn định
Bộ công cụ notification nằm trong @nx/signal, chưa dùng chungChấp nhận cho increment này; việc tách sang package dùng chung là một cân nhắc tương lai
Heartbeat/tình trạng của MON vẫn còn chờNgoài phạm vi tại đây; increment này chỉ giao transport (xem §2)

12. Release Plan & Launch Criteria

AspectPlan
PhaseP2 (MON là một tính năng P2, In-progress)
RolloutTất cả merchant; không feature flag
MigrationEntity activity-notification mới; không cần migration dữ liệu
Launch criteriaSự kiện hoạt động → xác định người nhận → bản ghi được lưu → WebSocket emit được kiểm chứng trọn vẹn; đường đi inquiry-submitted được kiểm chứng; trạng thái đã đọc tồn tại qua kết nối lại
MonitoringLượng notification, độ trễ phát, tình trạng kết nối WebSocket, độ đúng của việc xác định người nhận

13. FAQ

Cái này có giao heartbeat / tình trạng thiết bị không? Không - increment này giao kênh truyền thông báo thời gian thực mà việc giám sát dựa vào. Phát heartbeat và ngưỡng offline (URD-MON-001/002) được theo dõi riêng.

Người nhận được chọn thế nào? Worker xác định các user ID trong scope organizer/merchant liên quan qua PolicyDefinitionRepository; thông báo không bao giờ vượt ranh giới tenant.

Điều gì xảy ra nếu một client bị mất kết nối khi sự kiện xảy ra? Notification vẫn được lưu; client lấy lại notification và trạng thái đã đọc qua REST khi kết nối lại.

Client đăng ký room/topic nào? Room signal/notification, topic NOTIFICATION_CREATED - một hợp đồng cố định, ổn định.

Vì sao đường đi inquiry-submitted nằm ở đây? Đây là use case thời gian thực đầu tiên chứng minh transport trọn vẹn, phát từ @nx/outreach qua cùng nền tảng WebSocket.

References

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