# Tài liệu Thiết kế Giải pháp theo Use Cases (HLD - Use Cases Mapping) ## Hệ thống Event-Driven Loyalty & Rewards Dựa trên phân tích yêu cầu nghiệp vụ (Use Cases Analysis), tài liệu này mô tả chi tiết phương án kỹ thuật để đáp ứng từng Use Case, đảm bảo hệ thống mở rộng tốt, không bị nghẽn cổ chai và duy trì tính toàn vẹn dữ liệu cho các giao dịch tài chính. --- ### 1. Bảng Ánh xạ Nghiệp vụ - Kỹ thuật (UC-to-Solution Mapping Table) Bảng dưới đây giúp đội ngũ BA và Developer nắm bắt nhanh mối quan hệ 1-1 giữa yêu cầu nghiệp vụ và giải pháp kỹ thuật tương ứng. | Mã UC / Tên Use Case | Giải pháp Kỹ thuật tương ứng | Thành phần liên quan (Components) | | :--- | :--- | :--- | | **UC-01** - First Login
*(Đăng nhập lần đầu)* | Gán cờ `first_login_flag` bằng lệnh `SET_TRUE_ONCE`. Thành công sẽ kích hoạt event `First_Login_Reward` để hệ thống cộng điểm và đẩy thông báo realtime. | `attribute-service`, `transaction-service`, Kafka (`tracking-topic`, `events-topic`), PostgreSQL (Attr DB) | | **UC-02** - Daily Login Tracking
*(Điểm danh hàng ngày)* | Cập nhật bộ đếm `current_streak` và `last_login_date`. Bỏ qua các sự kiện trùng lặp trong ngày (Idempotency). Khi đủ 7/30 ngày, trigger event trả thưởng. | `attribute-service`, `transaction-service`, Kafka (`tracking-topic`, `events-topic`) | | **UC-03** - View Item
*(Xem chi tiết quà)* | Cập nhật `item_view_count`, lưu lịch sử `recently_viewed` vào Cache. Cộng `weekly_view_count`, đủ 10 views sẽ trigger event cộng điểm. | `attribute-service`, Redis (Cache), Kafka (`tracking-topic`), PostgreSQL (Attr DB) | | **UC-04** - Transfer Balance
*(Chuyển điểm)* | Xử lý giao dịch trừ tiền người gửi, cộng tiền người nhận trong cùng 1 ACID Transaction. Bắn push notification cho cả hai bên. | `transaction-service`, `notification-service`, Kafka (`events-topic`), PostgreSQL (Txn DB) | | **UC-05** - Inactive Account Login
*(Login sau thời gian ngủ đông)*| Kèm cấu hình `CHECK_AND_UPDATE_TIMER` vào event Login. Nếu GAP >= 90 ngày, trigger event `Account_Reactivated` để đổi trạng thái và gửi noti Welcome Back. | `attribute-service`, `transaction-service`, Kafka (`tracking-topic`, `events-topic`) | | **UC-06** - Welcome Offer
*(Mở thẻ mới)* | Hệ thống phát hành thẻ (External) bắn event. `transaction-service` kiểm tra khóa bảo vệ (Idempotency) để đảm bảo chỉ thưởng 1 lần. | Hệ thống phát hành thẻ, `transaction-service`, Kafka (`events-topic`) | | **UC-07** - Update Profile
*(Hoàn tất hồ sơ)* | `profile-service` tự đánh giá độ hoàn thiện và bắn event. Core engine kiểm tra mốc thời gian (trước 30/09) để quyết định cộng điểm. | `profile-service`, `transaction-service`, Kafka (`events-topic`) | | **UC-08** - Survey
*(Hoàn thành khảo sát)* | Bắn 1 event nhưng định tuyến song song 2 luồng: (1) Cấp voucher và (2) Cập nhật cờ `survey_completed = true` để không hiển thị lại popup. | `transaction-service`, `attribute-service`, Kafka (`events-topic`, `tracking-topic`) | | **UC-09** - Redeem Item
*(Đổi quà)* | Kiểm tra số dư, trừ điểm và khóa tồn kho (reserve item) trong 1 giao dịch cơ sở dữ liệu nguyên tử (ACID DB Transaction). | `transaction-service`, `notification-service`, PostgreSQL (Txn DB) | | **UC-10** - Merchant Scan
*(Quét mã voucher)* | API Đồng bộ (Synchronous). Đổi trạng thái voucher sang USED (ACID). Thành công sẽ đẩy noti realtime cho người dùng qua Kafka. | Merchant App, `transaction-service`, API Gateway, PostgreSQL (Txn DB) | | **UC-11** - Retention
*(Mật khẩu sắp hết hạn)* | Scheduler chạy hằng ngày quét DB lọc danh sách `password_expiry_date`. Bắn thẳng thông báo vào Kafka mà không cần đi qua Core engine. | `marketing-service`, `notification-service`, Kafka (`noti-topic`) | | **UC-12** - Most Redeem Item
*(Sản phẩm đổi nhiều nhất)* | Event Processor sao chép luồng sự kiện đổi quà sang `tracking-topic` để cập nhật counter `total_redeem_count` trên thuộc tính sản phẩm (Thuần Tracking). | Event Processor, `attribute-service`, Kafka (`tracking-topic`), PostgreSQL (Attr DB) | | **UC-13** - Retention
*(User Dormant 3 tháng)* | Scheduler chạy hằng ngày lọc user có `last_user_txn_date` >= 90 ngày. Bắn event vào Core engine để thực thi cấp ưu đãi riêng và push noti. | `marketing-service`, `transaction-service`, PostgreSQL (Txn DB & Marketing DB) | --- ### 2. Cấu trúc chi tiết giải pháp theo từng UC (High-Level Technical Details) #### Nhóm 1: Hệ thống đếm và Theo dõi (Tracking & Counters) *Bao gồm: UC-01, UC-02, UC-03, UC-05, UC-12* - **Luồng dữ liệu (Data Flow):** Client -> `event-processor-service` -> `tracking-topic` -> `attribute-service`. - **Cơ chế xử lý đặc biệt:** - **Pattern "Accumulate & Trigger":** `attribute-service` hoạt động như một "Dumb Executor" tích lũy các event có tần suất cao (như Login, ViewItem). Nó xử lý các quy tắc lũy kế, khi đạt ngưỡng (Threshold) hoặc điều kiện trạng thái, nó mới sản sinh một event "có giá trị tài chính" (ví dụ: `View_10_Items_Reward`) đẩy vào `events-topic` để `transaction-service` trả thưởng. Cách này bảo vệ Core Engine không bị quá tải. - **Caching:** Dùng Redis để lưu trữ thuộc tính `recently_viewed` (UC-03) nhằm đáp ứng nhu cầu truy vấn hiển thị liên tục ở trang chủ với độ trễ cực thấp (<10ms). - **Idempotency (Tính luỹ đẳng):** Bộ đếm tự động lọc bỏ các hành động lặp lại không hợp lệ, ví dụ login nhiều lần trong 1 ngày (UC-02) hoặc kiểm tra cờ (UC-01) để tránh cộng thưởng nhầm. #### Nhóm 2: Giao dịch Tài chính & Quản lý Kho (Financial & Inventory) *Bao gồm: UC-04, UC-09, UC-10* - **Luồng dữ liệu (Data Flow):** - (UC-04, UC-09): Client -> `event-processor-service` -> `events-topic` -> `transaction-service`. - (UC-10): Merchant App -> HTTP Sync API -> `transaction-service`. - **Cơ chế xử lý đặc biệt:** - **ACID Transactions / Rollback:** Việc trừ điểm người gửi & cộng điểm người nhận (UC-04) hoặc trừ điểm & khóa tồn kho (UC-09) bắt buộc nằm chung trong 1 Database Transaction nguyên tử. Nếu 1 trong 2 thao tác lỗi, toàn bộ giao dịch bị rollback, đảm bảo không bao giờ có chuyện "trừ điểm nhưng chưa có quà". - **Cơ chế gọi Đồng bộ (Sync API):** Ở UC-10, thay vì gửi qua Kafka, giao dịch quét voucher được thực thi trực tiếp qua Restful API để trả về kết quả thành công/thất bại ngay lập tức trên máy Pos của Merchant. #### Nhóm 3: Tương tác Hệ thống Ngoài & Luồng Song song *Bao gồm: UC-06, UC-07, UC-08* - **Luồng dữ liệu (Data Flow):** External Systems / App -> `event-processor-service` -> `events-topic` -> `transaction-service`. - **Cơ chế xử lý đặc biệt:** - **Dual Publishing (Định tuyến song song):** Trong UC-08 (Hoàn thành khảo sát), Event Processor sao chép sự kiện thành 2 luồng độc lập: một vào `events-topic` để lấy voucher, một vào `tracking-topic` để ẩn màn hình khảo sát. Việc này giảm liên kết cứng (decouple) giữa UI State và Financial Ledger. #### Nhóm 4: Cronjob, Batch Processing & Retention *Bao gồm: UC-11, UC-13* - **Luồng dữ liệu (Data Flow):** `marketing-service` (Cronjob) -> Query Database -> Kafka -> Các Service liên quan. - **Cơ chế xử lý đặc biệt:** - **Off-peak Processing:** Chạy các job quét CSDL vào giờ thấp điểm (đêm khuya) để lấy danh sách người dùng ngủ đông hoặc mật khẩu sắp hết hạn. Tránh chiếm dụng connection của DB chính. - **Phân luồng:** UC-11 chỉ gửi tin nhắn nên đẩy thẳng vào `noti-topic`. UC-13 liên quan đến tặng quà nên định tuyến về `events-topic` để thực thi qua Core. --- ### 3. Sơ đồ Luồng Xử lý Kỹ thuật Tổng quát (System Flow Diagram) Sơ đồ dưới đây trình bày cấu trúc định tuyến thông minh (Smart Router) và cách các thành phần lõi trao đổi với nhau nhằm đáp ứng chuỗi sự kiện. ```mermaid graph TD %% Clients MA[Member App / Web] MRA[Merchant App] EXT[External Systems: Card Issuance / Profile] %% Gateway subgraph Smart Event Gateway EP{event-processor-service
Validate & Router} end %% Kafka Topics subgraph Message Broker K_ET([events-topic
Direct Financial]) K_TT([tracking-topic
Tracking & State]) K_NT([noti-topic
Notifications]) end %% Core Services subgraph Core Services ATTR[attribute-service
EAV & Accumulator] TP[transaction-service
Ledger & Rule Engine] NS[notification-service
Push/SMS/Email] MKT[marketing-service
Cron & Scheduler] end %% Databases DB_ATTR[(PostgreSQL: Attribute)] REDIS[(Redis: Cache)] DB_TP[(PostgreSQL: Transaction)] %% Connections MA -- "Login, ViewItem, Redeem, Transfer" --> EP EXT -- "WelcomeOffer, ProfileCompleted" --> EP MRA -- "Sync API: Scan Voucher" --> TP EP -- "Tracking/State Events" --> K_TT EP -- "Financial/Reward Events" --> K_ET K_TT --> ATTR K_ET --> TP ATTR -- "Read/Write" --> DB_ATTR ATTR -- "Fast Read" --> REDIS TP -- "ACID Txn" --> DB_TP ATTR -. "Trigger Reward
(Threshold Reached)" .-> K_ET TP -- "Result Noti" --> K_NT MKT -- "Retention Noti" --> K_NT MKT -- "Dormant Reward" --> K_ET K_NT --> NS NS -- "Firebase Push" --> MA ``` --- ### 4. Đánh giá Mức độ Khả thi & Rủi ro (Technical Risk Assessment) Trong 13 Use Cases, có những thách thức kỹ thuật cần đặc biệt lưu tâm và áp dụng chiến lược phòng vệ: **1. Rủi ro phức tạp nhất: Đổi quà (UC-09 - Redeem Item)** - **Vấn đề:** Rất dễ xảy ra lỗi tranh chấp dữ liệu (Race Condition) khi nhiều người dùng cùng đổi 1 món quà đang "hot" có số lượng giới hạn, hoặc timeout giao dịch DB khiến hệ thống "trừ điểm nhưng kho không trừ". - **Phương án dự phòng (Fallback & Mitigation):** - Áp dụng cơ chế **Pessimistic Locking** (`SELECT FOR UPDATE`) ở bảng Inventory để đảm bảo nhất quán dữ liệu. - Kết hợp sử dụng **Redis Decrement** để cấp phát số lượng kho tạm thời trên memory trước khi thực hiện giao dịch xuống Database (Pre-deduction), giảm tải I/O cho PostgreSQL. **2. Nghẽn cổ chai luồng sự kiện (Bottleneck in High-Frequency Events)** - **Vấn đề:** Các sự kiện như `View_Item` hay `Login` có lượng truy cập khổng lồ, nếu đẩy dồn dập có thể làm chậm trễ các sự kiện quan trọng như `Transfer_Balance` trên hạ tầng Kafka. - **Phương án dự phòng (Fallback & Mitigation):** - Tách bạch hoàn toàn `tracking-topic` (Volume lớn, độ ưu tiên thấp) và `events-topic` (Volume vừa, độ ưu tiên cao). - Tăng số lượng Phân vùng (Partitions) trên `tracking-topic` và chạy nhiều Instance (Consumer Group) của `attribute-service` để tiêu thụ dữ liệu song song (Horizontal Scale). **3. Cơ chế phục hồi sự cố (Fault Tolerance & Dead Letter Queue)** - **Vấn đề:** Khi `transaction-service` dính ngoại lệ logic (VD: Khách hàng bị khóa tài khoản ngay lúc event trả điểm tới) khiến việc consume báo lỗi liên tục. - **Phương án dự phòng (Fallback & Mitigation):** - Cấu hình **Dead Letter Queue (DLQ)** trên Kafka. Nếu một sự kiện xử lý thất bại sau số lần retry quy định (VD: 3 lần), hệ thống sẽ gắp nó bỏ qua DLQ để tránh làm nghẽn dòng thông tin (Head-of-line blocking). Đội vận hành sẽ tái xử lý (replay) các sự kiện DLQ này sau khi khắc phục xong lỗi dữ liệu hoặc rule kinh doanh.