Ticket & State Machine
The ticket is the central entity of @nx/helpdesk. Each ticket has a lifecycle managed by an XState v5 state machine with 10 statuses, a full event audit trail, and asynchronous context enrichment.
Ticket Statuses
| Status | Code | Description |
|---|---|---|
| Open | OPEN | Newly created ticket, not yet assigned |
| Assigned | ASSIGNED | Assigned to a specific agent |
| In Progress | IN_PROGRESS | Agent is actively working on it |
| Waiting for User | WAITING_USER | Requires a response from the reporter |
| Waiting Internal | WAITING_INTERNAL | Depends on another team or department |
| Escalated | ESCALATED | Escalated to a higher tier |
| Resolved | RESOLVED | Agent marked as resolved, awaiting confirmation |
| Closed | CLOSED | Customer confirmed — fully complete |
| Reopened | REOPENED | Customer reopened after closure |
| Waiting Agent | WAITING_AGENT | Waiting for an agent to be assigned |
| Pending | PENDING | Holding / not-yet-categorized |
| Assignment Failed | ASSIGNMENT_FAILED | Auto-assignment found no eligible agent |
Authoritative enum:
TicketStatusesinpackages/core/src/models/schemas/helpdesk/ticket/schema.ts(12 values).
State Machine (XState v5)
Data Model
Ticket
| Column | Type | Description |
|---|---|---|
id | bigint | Snowflake ID |
merchantId | bigint | Tenant scope |
reporterId | bigint | Reporter (userId or agentId) |
reporterType | enum | USER / AGENT |
category | bigint | FK → TicketCategory |
priority | smallint | 100 LOW / 200 NORMAL / 300 HIGH / 400 URGENT |
status | enum | 10 statuses (see table above) |
subject | varchar | Short title |
description | text | Detailed description |
context | jsonb | Rich context data (order, product, …) |
deletedAt | timestamp | Soft delete |
TicketMessage
| Column | Type | Description |
|---|---|---|
id | bigint | Snowflake ID |
ticketId | bigint | FK → Ticket |
senderId | bigint | Sender ID |
senderType | enum | USER / AGENT / SYSTEM |
messageType | enum | TEXT / IMAGE / FILE / SYSTEM_NOTE |
content | text | Message body |
attachments | jsonb | List of attached files |
isInternal | boolean | Internal note (hidden from customer) |
TicketEvent (Event Sourcing)
Every action on a ticket is written to TicketEvent, building a complete audit trail:
| Event | Description |
|---|---|
TICKET_CREATED | Ticket was created |
STATUS_CHANGED | Status transition |
ASSIGNED | Agent assigned |
MESSAGE_ADDED | New message |
TAG_ADDED / TAG_REMOVED | Tag change |
SLA_WARNING / SLA_BREACHED | SLA events |
ESCALATED | Escalation triggered |
RESOLVED / CLOSED | End of lifecycle |
REST API
Tickets (/tickets), including messages, status transitions, assignment, resolution confirmation, tags, and attachments — full endpoint reference rendered live from /v1/api/helpdesk/doc/openapi.json. Endpoint tables are intentionally not hand-maintained.
Use Cases
Ticket
| Use Case | Description |
|---|---|
CreateTicketUseCase | Creates ticket, emits TICKET_CREATED event |
ListTicketsUseCase | Search and paginate tickets |
GetTicketUseCase | Fetch a single ticket's details |
UpdateTicketStatusUseCase | Transition status via the state machine |
AssignTicketUseCase | Assign ticket to an agent |
AddMessageUseCase | Add a message to a ticket |
GetTicketMessagesUseCase | Cursor-based message pagination |
ConfirmResolutionUseCase | Confirm resolution → transition to CLOSED |
EnrichTicketContextUseCase | Enrich context (order, product) asynchronously |
AddAttachmentsToMessageUseCase | Attach files to a message |
Context Enrichment Worker
When a ticket is created, context-enrichment.worker runs asynchronously to populate the context JSONB column:
Data is fetched from ProductRepository and SaleOrderRepository (both from @nx/core) and stored in the context column so agents have full context without querying other services.
Event-Driven Flow on Ticket Creation
Related Pages
- Helpdesk Service — service overview
- Architecture — Ticket state machine
- Domain Model
- API Events