The Tickets module provides a full support ticket system with lifecycle management, agent assignment, threaded comments, file attachments, and role-based access control.
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/tickets | POST | Open new ticket |
/api/tickets | GET | List tickets (paginated, filterable) |
/api/tickets/{id} | GET | Get ticket details |
/api/tickets/{id}/assign | POST | Assign to agent |
/api/tickets/{id}/comments | POST | Add comment |
/api/tickets/{id}/files | POST | Attach file |
/api/tickets/{id}/status | PATCH | Change status |
Architecture
TicketEndpoints (Minimal API) │ ▼TicketService │ ├── ITicketRepository → SqlSugarTicketRepository ├── TicketAuthorizationService (role + data scope checks) ├── ITicketAttachmentAccessService → FileAssetTicketAttachmentAccessService ├── ITicketEventPublisher → NullTicketEventPublisher └── ITicketAuditSink → NullTicketAuditSinkTicket entity
public class TicketEntity : TenantSoftDeleteEntityBase{ public string Title { get; set; } public string Description { get; set; } public string Status { get; set; } // Open, InProgress, Resolved, Closed public string Priority { get; set; } // Low, Normal, High, Critical public string? AssignedToId { get; set; } public string CreatedById { get; set; }}Lifecycle states
Open → InProgress → Resolved → Closed ↑ │ │ └───────┘ │ (reopened) │ ▼ Closed (terminal)Authorization model
TicketAuthorizationService enforces role-based access:
| Role | Permissions |
|---|---|
| Creator | View own, add comments, reopen |
| Agent | View assigned, change status, assign |
| Admin | Full access across tenant |
| System | Cross-tenant read (audit) |
public static class TicketPermissions{ public const string TicketCreate = "ticket.create"; public const string TicketView = "ticket.view"; public const string TicketAssign = "ticket.assign"; public const string TicketStatusChange = "ticket.status.change"; public const string TicketComment = "ticket.comment"; public const string TicketManage = "ticket.manage";}Ticket roles
public static class TicketRoleNames{ public const string Creator = "ticket.creator"; public const string Agent = "ticket.agent"; public const string Admin = "ticket.admin";}Pagination and filtering
public class TicketPage{ public IReadOnlyList<Ticket> Items { get; } public int TotalCount { get; } public bool HasMore { get; }}
public class TicketQuery{ public string? Status { get; set; } public string? Priority { get; set; } public string? AssignedToId { get; set; } public string? Search { get; set; } public int Page { get; set; } public int PageSize { get; set; }}See also
- Files module — Ticket attachment support
- Notifications module — Ticket status notifications
- Webhooks module — Ticket event delivery