Domain Model
Tất cả schema Drizzle nằm trong
@nx/coredướipackages/core/src/models/schemas/helpdesk/(30 thư mục bảng). Helpdesk chỉ khai báo lớp repository. Schema PostgreSQLhelpdeskđược định nghĩa bởiPostgresSchemas.HELPDESK = 'helpdesk'.
1. ERD đầy đủ
2. Thực thể
Một block cho mỗi bảng chính. Gốc nguồn schema:
packages/core/src/models/schemas/helpdesk/. Cột chung (id,createdAt,updatedAt,deletedAt,metadata) đến từgenerateCommonColumnDefs().
Ticket
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.Ticket |
| Nguồn | helpdesk/ticket/schema.ts |
| Soft-delete | có |
| Cột Owner ID | merchantId (+ organizerId) |
Trường:
| Trường | Type | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
id | text | ✓ | Snowflake | PK |
organizerId | text | ✓ | — | Phạm vi organizer |
merchantId | text | ✓ | — | Phạm vi tenant |
reporterId | text | ✓ | — | Ai mở ticket |
reporterType | text (TActorTypes) | ✓ | USER | USER / AGENT / SYSTEM |
category | text | ✓ | — | Ref TicketCategory (soft ref) |
priority | integer (TTicketPriorities) | ✓ | MEDIUM | LOW/MEDIUM/HIGH/URGENT/CRITICAL |
status | text (TTicketStatuses) | ✓ | OPEN | Xem enum bên dưới |
subject | i18n jsonb | ✓ | — | { en, vi } |
description | i18n jsonb | ✓ | — | { en, vi } |
context | jsonb | ✓ | {} | Context order/product được enrich |
assignedToAgentId | text | — | — | Agent hiện tại |
assignedToUserId | text | — | — | User id của agent |
assignedAt | timestamptz | — | — | — |
resolvedAt / resolvedBy / resolutionNote | timestamptz / text / i18n | — | — | Dữ liệu giải quyết |
closedAt / closedBy | timestamptz / text | — | — | Dữ liệu đóng |
sessionId | text | — | — | Session khởi tạo |
metadata | jsonb | ✓ | {} | Cờ linh tinh (ví dụ categorySkills, tagIds) |
Enum Status (TicketStatuses):
| Giá trị | Mô tả |
|---|---|
OPEN | Mới, chưa được phân công |
ASSIGNED | Đã phân công cho một agent |
IN_PROGRESS | Đang được xử lý |
WAITING_USER | Chờ người báo cáo trả lời |
WAITING_AGENT | Chờ một agent |
WAITING_INTERNAL | Chờ một team khác |
PENDING | Giữ chỗ / chưa phân loại |
ASSIGNMENT_FAILED | Auto-assign không tìm thấy agent |
ESCALATED | Escalate lên tier cao hơn |
RESOLVED | Agent đã giải quyết, chờ xác nhận |
CLOSED | Xác nhận hoàn thành |
REOPENED | Mở lại sau khi giải quyết/đóng |
Tập helper:
ACTIVE_SET = {OPEN, IN_PROGRESS, REOPENED},RESOLVED_SET = {RESOLVED, CLOSED}.
Indexes: IDX_Ticket_merchant_status_created_at, IDX_Ticket_assigned_to_status, IDX_Ticket_reporter_created_at, IDX_Ticket_category_priority_status, IDX_Ticket_status, IDX_Ticket_priority, IDX_Ticket_created_at.
TicketMessage
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.TicketMessage |
| Nguồn | helpdesk/ticket-message/schema.ts |
| Soft-delete | có |
| Trường | Type | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
ticketId | text | ✓ | — | Ticket cha |
authorId (col sender_id) | text | ✓ | — | Tác giả |
authorType (col sender_type) | text (TActorTypes) | ✓ | — | USER/AGENT/SYSTEM |
type (col message_type) | text (TTicketMessageTypes) | ✓ | — | Xem enum |
content | i18n jsonb | ✓ | — | Nội dung { en, vi } |
isInternal | boolean | ✓ | false | Ẩn khỏi người báo cáo |
attachmentIds | text[] | ✓ | {} | Ref attachment |
Loại message (TicketMessageTypes): COMMENT, USER_REPLY, AGENT_REPLY, INTERNAL_NOTE, SYSTEM_MESSAGE, AUTO_REPLY.
TicketEvent (audit / event sourcing)
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.TicketEvent |
| Nguồn | helpdesk/ticket-event/schema.ts |
| Trường | Type | Bắt buộc | Mô tả |
|---|---|---|---|
ticketId | text | ✓ | Cha |
eventType | text (TTicketEventTypes) | ✓ | Xem enum |
actorId / actorType | text | — | Ai thực hiện |
oldValue / newValue | text | — | Diff status/value |
changes | jsonb | — | Diff có cấu trúc |
reason | text | — | Lý do tùy chọn |
Loại event (TicketEventTypes, giá trị chuỗi có dấu chấm, ví dụ ticket.created): TICKET_CREATED, TICKET_UPDATED, TICKET_ASSIGNED, TICKET_ASSIGNMENT_FAILED, TICKET_REASSIGNED, TICKET_STATUS_CHANGED, TICKET_PRIORITY_CHANGED, TICKET_RESOLVED, TICKET_CLOSED, TICKET_REOPENED, TICKET_ESCALATED, MESSAGE_CREATED, MESSAGE_UPDATED, SLA_WARNING, SLA_BREACHED, SLA_CRITICAL_BREACH.
SlaPolicy
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.SlaPolicy |
| Nguồn | helpdesk/sla-policy/schema.ts |
| Soft-delete | có |
Deadline response/resolution theo từng priority, ngưỡng cảnh báo, rule escalation, và cờ business-hours. Mặc định: xem SLA & Escalation.
SlaTracker
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.SlaTracker |
| Nguồn | helpdesk/sla-tracker/schema.ts |
| Cardinality | 1:1 theo ticket (UQ_SlaTracker_ticket_id) |
| Trường | Type | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
ticketId | text | ✓ | — | Ticket (unique) |
policyId (col sla_policy_id) | text | ✓ | — | SlaPolicy |
priority | integer | ✓ | 200 | Snapshot priority |
firstResponseDeadline | timestamptz | ✓ | — | Deadline response |
resolutionDeadline | timestamptz | ✓ | — | Deadline resolution |
firstResponseAt / resolvedAt | timestamptz | — | — | Thực tế |
firstResponseStatus | text (TSlaStatuses) | ✓ | OK | OK/WARNING/BREACHED |
resolutionStatus | text (TSlaStatuses) | ✓ | OK | OK/WARNING/BREACHED |
timeToFirstResponse / timeToResolution | integer | — | — | Phút |
breachedAt / breachMinutes / breachReason | timestamptz / integer / text | — | 0 | Theo dõi vi phạm |
escalationLevel | integer | ✓ | 0 | Level escalation hiện tại |
warningsSent | jsonb[] | ✓ | [] | Cảnh báo đã gửi |
lastCheckedAt | timestamptz | — | — | Lần monitor cuối |
Enum status SLA (SlaStatuses): OK, WARNING, BREACHED.
SlaEscalation
| Thuộc tính | Giá trị |
|---|---|
| Bảng | helpdesk.SlaEscalation |
| Nguồn | helpdesk/sla-escalation/schema.ts |
| Trường | Type | Bắt buộc | Mô tả |
|---|---|---|---|
ticketId | text | ✓ | Ticket |
escalationType | text (TSlaEscalationTypes) | ✓ | SLA_BREACH / MANUAL / CUSTOMER_REQUEST / HIGH_IMPACT / INCIDENT_REPORT |
escalationLevel | smallint (TSlaEscalationLevel) | ✓ | 1 / 2 / 3 |
previousPriority / newPriority | smallint | — | Thay đổi priority |
escalatedBy / escalatedById | text | ✓ / — | Actor |
reason | text | ✓ | Vì sao |
actions | jsonb[] | ✓ | Hành động đã thực hiện |
escalatedAt / resolvedAt | timestamptz | ✓ / — | Mốc thời gian |
Thực thể hỗ trợ
| Bảng | Nguồn | Mục đích |
|---|---|---|
TicketAssignment | helpdesk/ticket-assignment/ | Lịch sử phân công theo ticket |
TicketCategory | helpdesk/ticket-category/ | Category với số đếm ticket |
TicketTag / TicketTagMapping | helpdesk/ticket-tag*/ | Tag + ánh xạ M:N, số đếm sử dụng |
Agent / AgentGroup / AgentGroupMember | helpdesk/agent*/ | Agent, group, thành viên |
AssignmentRule | helpdesk/assignment-rule/ | Rule routing → group/agent |
Article / ArticleCategory / ArticleView / ArticleFeedback | helpdesk/article*/ | Knowledge base |
Survey / SurveyQuestion / SurveyResponse | helpdesk/survey*/ | Khảo sát CSAT |
FeatureRequest / FeatureVote | helpdesk/feature-*/ | Vote feature |
Notification / NotificationTemplate / NotificationPreference / NotificationDeliveryLog / NotificationBatch | helpdesk/notification*/ | Engine thông báo |
Compensation | helpdesk/compensation/ | Bản ghi đền bù vi phạm SLA |
JobExecutionLog | helpdesk/job-execution-log/ | Idempotency / audit worker |
3. Bất biến xuyên thực thể
| Bất biến | Thực thi |
|---|---|
Đúng một SlaTracker cho mỗi ticket | Index unique UQ_SlaTracker_ticket_id |
| Chuyển đổi status ticket theo máy trạng thái | UpdateTicketStatusUseCase (XState) |
Mỗi thay đổi status ghi một TicketEvent | Use-case ghi event trong cùng thao tác |
TicketCategory.ticketCount phản ánh tickets | TicketCreatedListener.incrementTicketCount() |
TicketTag.usageCount phản ánh ánh xạ | TicketCreatedListener.incrementUsageCount() |
escalationLevel tăng đơn điệu | SLA monitor + escalation worker |
4. Hành vi Soft-delete
| Hành vi | Chi tiết |
|---|---|
| Đọc mặc định | deletedAt IS NULL (qua generateCommonColumnDefs()) |
| Hard-delete | Không phải mặc định; soft-delete qua timestamp deletedAt |
| Restore | Xóa deletedAt |