Lịch sử & Quan sát (History & Observability)
Có hai loại "lịch sử" dễ nhầm nhau. Trang này tách bạch chúng và chỉ ra tra cứu/quan sát ở đâu — rất quan trọng cho support và debug.
Hai loại lịch sử — đừng nhầm
| Entity audit history | Notification-run history | |
|---|---|---|
| Trả lời | "Cái gì đã thay đổi trên một entity?" | "Một thông báo đã được lên lịch / gửi / skip / delivered ra sao?" |
| Lưu ở | EntityHistory (registry + HistoryEventKey + upsert) | NotificationJob / AutomationScheduler / OutgoingMessage … |
| Bản chất | Projection lịch sử state của entity | Bản ghi lần chạy của một thông báo/automation |
| Trang | Kiến trúc Platform — phần History | Trang này |
⚠️
NotificationJoblà bản ghi notification-run, không phải bản ghi entity audit. Đừng mởNotificationJobđể tra "entity đổi gì" — đó là việc củaEntityHistory.
Tra cứu theo câu hỏi (nguồn nào trả lời gì)
| Câu hỏi | Nguồn |
|---|---|
| Automation run status / trace | AutomationScheduler (+ InputHash, DispatchResultJson, TraceBlobName) |
| Trace mirror | AutomationJob (Azure Table) |
| Notification event (run) | NotificationJob — PartitionKey = EventKey (GUID ngẫu nhiên ở đường direct; entity-event:... tất định ở đường event-derived — không phải Entity.Guid) |
| Entity audit (state change) | EntityHistory — PartitionKey = Entity.Guid, HistoryEventKey tất định |
| In-app / user state | UserMessage — PartitionKey = user:{User.Id} / employee:{Employee.Guid} |
| Provider delivery | OutgoingMessage — PartitionKey = NotificationJob.PartitionKey/EventKey (transactional) hoặc MessagingJob.Guid (campaign) |
| Report/campaign run | MessagingJob (SQL + blob payload) |
| Việc bị skip/deactivate/UI-only | AutomationScheduler (support lookup) |
Lưu ý re-key: thay đổi
notification-historyđổi khóa các transactional message theo nguồn (vdinvoice:{guid},account:{guid}) để mở lịch sử đúng nơi người dùng mong đợi.
Chiến lược "hybrid-light"
Không xây bảng link nguồn rộng, không có AutomationOutcomeIndex trong MVP:
- Lịch sử entity chính tra qua Azure key policy (PartitionKey = entity người dùng mở).
- Các outcome skipped / deactivated / UI-only tra qua support views trên
AutomationScheduler.
Quan sát (Observability)
| Tín hiệu | Nguồn | Trạng thái |
|---|---|---|
| Log tạo job event-derived | EntityEventNotificationPostProcessor log 1 dòng có cấu trúc (EventTypeId/EventKey/BusinessUnitId) | ✅ Đã có — đủ để đếm "loại nào, bao nhiêu, qua worker". |
| Trace automation chi tiết | AutomationScheduler.TraceBlobName (blob private, stream qua API có authorize) | ✅ Khi support cần. |
| Kết quả dispatch | AutomationScheduler.DispatchResultJson (SkippedReasonCode/ConflictReasonCode/Summary) | ✅ Nhỏ, merge khi retry, không xóa. |
| Metric/dashboard tổng hợp | — | ⏳ Follow-up (cần hệ metrics riêng). |
Unit test delivery layer (SendXxxNotification) | — | ⏳ Nợ test (không có harness sẵn). |
"Vì sao việc này không gửi?" — checklist nhanh
- Có row
AutomationSchedulerkhông? Trạng thái gì (Deactivated/Skipped/Failed/IsOnSupportHold)? DispatchResultJsoncóSkippedReasonCode/ConflictReasonCodegì?- Notification Settings của BU: loại đó đã seed
NotificationOption+ có subscriber chưa? OutgoingMessagecó dòng không, ở trạng thái nào (Created/Sending/FailedFinal)?- Cần trace sâu → đọc
TraceBlobName.
Liên quan
- Kiến trúc Platform — cách
EntityHistoryđược sinh (audit). - Automation & Reminders — vòng đời
AutomationScheduler. - Communication — Case thường gặp — skip/deactivate.