Kiến trúc
1. Bối cảnh hệ thống (C4 L1)
Helpdesk là một VerifierApplication — nó xác thực JWT với JWKS của identity issuer nhưng không bao giờ phát token. Nó không có cuộc gọi outbound đồng bộ tới các microservice chị em; dữ liệu cross-domain (products, sale orders) được đọc qua repository do
@nx/coreship.
2. Góc nhìn Container (C4 L2)
| Process | RUN_MODE | Chạy |
|---|---|---|
| API | startup (mặc định) | Hono server, controllers, EventBus, queue producers |
| Worker | worker | Worker BullMQ tiêu thụ 6 hàng đợi |
| Migration | migrate | Process migration Drizzle một lần |
3. Góc nhìn Component (C4 L3) — Phân lớp nội bộ
| Lớp | Trách nhiệm |
|---|---|
| Controllers | Cổng merchant-access (assertMerchantAccess() + useRequestContext()), ánh xạ DTO; ủy thác cho use-case. Không có decorator @authenticate |
| Use-Cases | Thao tác nghiệp vụ single-responsibility, đăng ký làm service DI; phát event / dispatch job |
| Listeners | Đăng ký sự kiện in-process, fan out tới job BullMQ / side effect |
| Workers | Tiêu thụ hàng đợi BullMQ; chạy use-case cho công việc async (assignment, SLA, escalation, notification, enrichment, survey) |
| Repositories | Truy vấn Drizzle; schema tập trung trong @nx/core |
| Components | Xuyên suốt: EventBus, Queue, Worker, Mail, WebSocket, Redis cache |
4. Chỉ mục Máy trạng thái
| Thực thể | Trạng thái | Sơ đồ |
|---|---|---|
Ticket | OPEN, ASSIGNED, IN_PROGRESS, WAITING_USER, WAITING_AGENT, WAITING_INTERNAL, PENDING, ASSIGNMENT_FAILED, ESCALATED, RESOLVED, CLOSED, REOPENED | → nhảy |
SlaTracker | ON_TRACK → WARNING → BREACHED → CRITICAL | → SLA & Escalation |
Ticket (XState v5)
Nguồn TicketStatuses: packages/core/src/models/schemas/helpdesk/ticket/schema.ts. 12 trạng thái; chuyển đổi được thực thi bởi UpdateTicketStatusUseCase.
PENDINGlà trạng thái giữ chỗ được định nghĩa trongTicketStatusescho công việc chưa được phân loại. Bảng chuyển đổi chi tiết: Ticket System → Vòng đời.
5. Kịch bản Runtime
5.1 Tạo ticket → enrichment + assignment
| Bước | Chi tiết |
|---|---|
| 3 | Ticket + audit TicketEvent được ghi trong một đơn vị công việc |
| 4 | Emit in-process — không bao giờ chặn response HTTP |
| 7-8 | Listener fan out tới BullMQ; worker (worker process) nhận chúng |
5.2 Vi phạm SLA → escalation → notification
| Bước | Chi tiết |
|---|---|
| 1 | Cron được đăng ký bởi QueueComponent.scheduleSlaMonitoring() (WORKER_CONFIG.SLA_MONITOR_INTERVAL) |
| 4-5 | Ngưỡng cảnh báo từ SLA_WARNING_THRESHOLDS (75 / 90 / 100 / 150) |
| reassign | Tái phân công Level-2+ cho senior agent hiện bị tắt trong code (xem Vận hành → Vấn đề đã biết) |
5.3 Ticket resolved → trigger survey
6. Mối quan tâm xuyên suốt
| Mối quan tâm | Dịch vụ này xử lý như thế nào |
|---|---|
| AuthN | JWT được xác thực với JWKS của identity (VerifierApplication). Không phát hành |
| AuthZ | Truy cập theo merchant qua assertMerchantAccess() + useRequestContext() từ @nx/core; không có decorator @authenticate theo route. PermissionService cho kiểm tra riêng helpdesk |
| i18n | Cột jsonb, hình dạng { en, vi } (helper cột i18n()) — ví dụ subject, description ticket, name chính sách SLA |
| Logging | console.log/console.error có tiền tố phạm vi [Component] (không có logger có cấu trúc đấu nối trong worker/listener) |
| Tracing | Không đấu nối |
| Idempotency | Job BullMQ dùng helper idempotency (worker-idempotency.helper.ts, idempotent-worker-deps.factory.ts); cron SLA dùng jobId: 'sla-monitor-cron' cố định để ngăn trùng lặp |
| Soft-delete | deletedAt qua generateCommonColumnDefs() tập trung; đọc mặc định loại trừ hàng đã xóa |
| IDs | Snowflake qua IdGenerator, worker node 12 |
| DLQ | HandleDeadLetterUseCase + dlq.helper.ts cho job thất bại |