TicketManagement.Sdk
1.0.17
dotnet add package TicketManagement.Sdk --version 1.0.17
NuGet\Install-Package TicketManagement.Sdk -Version 1.0.17
<PackageReference Include="TicketManagement.Sdk" Version="1.0.17" />
<PackageVersion Include="TicketManagement.Sdk" Version="1.0.17" />
<PackageReference Include="TicketManagement.Sdk" />
paket add TicketManagement.Sdk --version 1.0.17
#r "nuget: TicketManagement.Sdk, 1.0.17"
#:package TicketManagement.Sdk@1.0.17
#addin nuget:?package=TicketManagement.Sdk&version=1.0.17
#tool nuget:?package=TicketManagement.Sdk&version=1.0.17
TicketManagement.Sdk
TicketManagement.Sdk là client .NET chính thức giúp các hệ thống con (source systems) tích hợp với Ticket Management API. Thư viện này phản ánh đầy đủ nghiệp vụ quy trình xử lý ticket (workflow) và các nguyên tắc miền (domain invariants) được định nghĩa trong aggregate root Ticket.
Tổng quan nghiệp vụ (Business Domain Overview)
Ticket là gì?
Ticket là một yêu cầu nghiệp vụ (request) được gửi từ hệ thống con lên hệ thống Ticket Management để xử lý theo một quy trình luồng (workflow). Mỗi ticket có:
- Thông tin nguồn:
SourceSystemId(hệ thống con),SourceTicketId(ID gốc),DeepLinkUrl(URL quay lại hệ thống con). - Phân loại:
TicketTypeId,TicketTypeName,Title,Summary,Priority(Low, Medium, High, Critical). - Người tạo yêu cầu (requester):
RequesterHdCode,RequesterName,RequesterEmail,RequesterBranchId. - Trạng thái nghiệp vụ:
BusinessStatus— xem chi tiết bên dưới. - Các bước xử lý (steps): Một hoặc nhiều bước, mỗi bước có thể có nhiều người xử lý (multi-assignee).
- Lịch sử thay đổi (histories): Ghi lại toàn bộ hành động kèm snapshot trước/sau.
- Reminder: Cấu hình nhắc nhở xử lý ticket.
- Detail Properties: Thông tin mở rộng dạng key-value.
Trạng thái nghiệp vụ (BusinessStatus)
| Trạng thại | Giá trị | Ý nghĩa |
|---|---|---|
Open |
0 | Ticket vừa tạo ở dạng nháp, chưa gửi đi. |
PendingReview |
1 | Đang được xử lý / xem xét bởi assignee. |
Forwarded |
2 | Đã chuyển đến bước/cấp xử lý tiếp theo. |
Completed |
3 | Đã hoàn thành (trạng thái kết thúc). |
Cancelled |
4 | Đã bị hủy (trạng thái kết thúc). |
Rejected |
5 | Bị từ chối (trạng thái kết thúc). |
⚠️ Quy tắc chuyển trạng thái:
- Không thể chuyển từ trạng thái kết thúc (
Completed/Cancelled/Rejected) sang trạng thái khác.- Không thể chuyển lùi sang trạng thái có thứ tự thấp hơn (ngoại lệ:
RevoketừPendingReview→Open).- Thứ tự:
Open(0) →PendingReview(1) →Forwarded(2) →Completed(3).
Trạng thái bước xử lý (StepStatus)
| Trạng thái | Ý nghĩa |
|---|---|
Pending |
Chờ xử lý |
Completed |
Đã hoàn thành |
Approved |
Đã phê duyệt |
Skipped |
Bị bỏ qua |
Rejected |
Bị từ chối |
ReturnedForRevision |
Bị trả lại để chỉnh sửa |
Cancelled |
Bị hủy |
Hành động trên bước (StepAction)
| Hành động | Ý nghĩa |
|---|---|
Approve |
Phê duyệt |
Reject |
Từ chối |
Forward |
Chuyển đi |
Complete |
Hoàn thành |
SendBack |
Trả về bước trước |
Cancel |
Hủy ticket tại bước hiện tại |
Vòng đời ticket (Ticket Lifecycle)
┌──────────────────────────────────────────────┐
│ Tạo ticket (Create) │
│ CreateDraft → Open ─── CreateAndSend ──┐ │
│ │ │ │
└──────────────────────┼───────────────────┘ │
│ │
┌────────────┴────────────┐ │
│ Open (Draft) │ │
│ - Chỉ requester thấy │ │
│ - Chưa có assignee │ │
└────────────┬────────────┘ │
│ │
│ Send (do requester) │
│ │
┌────────────┴────────────┐ │
│ PendingReview │◄────────────┘
│ - Assignee xem xét │
│ - Có thể: │
│ • Approve → Completed │
│ • ApproveAndMoveNext │
│ → Forwarded │
│ • Reject → Rejected │
│ • SendBack → step cũ │
│ • Cancel → Cancelled │
│ • Revoke → Open │
└────────────┬────────────┘
│
┌────────────┴────────────┐
│ Forwarded │
│ - Bước mới, assignee mới│
│ - Các hành động tương tự│
└────────────┬────────────┘
│
┌────────────┴────────────┐
│ Completed / Cancelled /│
│ Rejected │
│ (Terminal) │
└─────────────────────────┘
Quy tắc nghiệp vụ (Business Rules)
Ai được làm gì?
| Hành động | Ai thực hiện | Điều kiện |
|---|---|---|
| Tạo draft | Hệ thống con (qua SDK) | Source system active + ticket type allowed |
| Send (gửi xử lý) | Requester | Ticket ở Open, có step, có assignee |
| Approve | Assignee hiện tại | Step ở Pending, ticket đang xử lý |
| ApproveAndMoveNext | Assignee hiện tại | Step ở Pending/Approved |
| Reject | Assignee hiện tại | Step ở Pending |
| SendBack | Assignee hiện tại | Step ở Pending, có step trước đó |
| Cancel | Requester | Ticket đang xử lý |
| Close | Bất kỳ actor | Step đã Approved |
| Revoke | Requester | Step chưa xử lý (ActedAt == null) |
Các ràng buộc khác
- Mỗi step có thể có nhiều assignees — hỗ trợ multi-approval, parallel assignment.
- Draft ticket chỉ có 1 step — không thể Send nếu đã có nhiều hơn 1 step.
- Không thể Revoke nếu step đã được xử lý (thời gian
ActedAtđã được ghi nhận). - Khi ticket vào trạng thái kết thúc (
Completed/Cancelled/Rejected), reminder tự động tắt. - Mỗi hành động workflow đều ghi snapshot trước/sau — phục vụ audit và trace.
- Business status không thể chuyển lùi (trừ Revoke là ngoại lệ có chủ đích).
SDK API & Domain Mapping
Mỗi method trong SDK tương ứng với một domain method trên entity Ticket:
| SDK Method | Domain Method (Ticket.cs) | Chuyển trạng thái | Ghi chú |
|---|---|---|---|
CreateDraftAsync |
Constructor + SetCurrentStep |
→ Open |
Step ở StepOrder=0, Action=null |
CreateAndSendAsync |
Constructor + Send() |
Open → PendingReview |
Tạo + gửi luôn |
SendAsync |
Send() |
Open → PendingReview |
Gửi draft đi xử lý |
ApproveAsync |
ApproveCurrentStep() |
→ Completed |
Phê duyệt và kết thúc |
ApproveAndMoveNextAsync |
ApproveCurrentStepAndMoveNext() |
→ Forwarded |
Phê duyệt và chuyển bước tiếp |
RejectAsync |
RejectCurrentStep() |
→ Rejected |
Từ chối yêu cầu |
SendBackAsync |
SendBackToPreviousStep() |
→ PendingReview (trên step cũ) |
Trả về bước trước |
CancelAsync |
CancelCurrentStep() |
→ Cancelled |
Hủy ticket |
CloseAsync |
Close() |
→ Completed |
Đóng ticket đã được approved |
RevokeAsync |
Revoke() |
→ Open |
Rút lại về draft |
Quick Start — Luồng nghiệp vụ điển hình
1. Khởi tạo client
using TicketManagement.Sdk.Builder;
using TicketManagement.Sdk.Implementation;
using TicketManagement.Sdk.Models.Common;
using TicketManagement.Sdk.Models.Enums;
using TicketManagement.Sdk.Models.Requests;
var client = TicketManagementClient
.CreateBuilder()
.WithBaseUrl("https://your-ticket-management-host/")
.WithSourceSystemId("YOUR_SOURCE_SYSTEM")
.WithSecret("YOUR_SHARED_SECRET")
.Build();
2. Tạo ticket và gửi xử lý (luồng 2 bước)
// Requester tạo step đầu tiên
var stepBuilder = TicketStep
.CreateBuilder()
.WithStepCode("SUBMIT")
.WithStepName("Trình ký")
.WithStepOrder(1)
.WithAssignees(new List<TicketAssignee>
{
new() { HdCode = "HD0002", Name = "Trưởng bộ phận", Email = "truongbp@bank.com", BranchId = "BR001" }
});
var requestBuilder = CreateTicketRequest
.CreateBuilder()
.WithTicketTypeId("LOAN")
.WithTicketTypeName("Giải ngân vay")
.WithSourceTicketId("EXT-001")
.WithTitle("Giải ngân cho khách hàng XYZ")
.WithPriority(TicketPriority.High)
.WithRequesterHdCode("HD0001")
.WithRequesterName("Nguyễn Văn A")
.WithRequesterEmail("a.nguyen@bank.com")
.WithRequesterBranchId("BR001")
.WithStep(stepBuilder);
// Tạo và tự động Send — ticket vào PendingReview ngay
var result = await client.CreateAndSendAsync(requestBuilder);
3. Xử lý ticket — phê duyệt và kết thúc
// Assignee (HD0002) phê duyệt — ticket kết thúc
var approveResult = await client.ApproveAsync(
result.TicketId,
TicketApproveRequest.CreateBuilder()
.WithApproverHdCode("HD0002")
.WithApproverName("Trưởng bộ phận")
.WithComments("Đã kiểm tra và phê duyệt")
);
// BusinessStatus → Completed
4. Xử lý ticket — phê duyệt và chuyển tiếp
// Assignee phê duyệt và tạo step mới cho cấp trên
var nextStep = TicketStep
.CreateBuilder()
.WithStepCode("DIRECTOR_APPROVE")
.WithStepName("Giám đốc duyệt")
.WithStepOrder(2)
.WithAssignees(new List<TicketAssignee>
{
new() { HdCode = "HD0003", Name = "Giám đốc", Email = "gd@bank.com", BranchId = "BR001" }
});
var nextResult = await client.ApproveAndMoveNextAsync(
result.TicketId,
TicketApproveAndMoveNextRequest.CreateBuilder()
.WithApproverHdCode("HD0002")
.WithApproverName("Trưởng bộ phận")
.WithComments("Trình giám đốc duyệt")
.WithNextStep(nextStep)
);
// BusinessStatus → Forwarded, step DIRECTOR_APPROVE được tạo
5. Các hành động khác
// Từ chối — chỉ assignee hiện tại mới được reject
await client.RejectAsync(
ticketId,
TicketRejectRequest.CreateBuilder()
.WithRejecterHdcode("HD0002")
.WithRejectionReason("Hồ sơ chưa đầy đủ")
);
// BusinessStatus → Rejected
// Trả về bước trước
await client.SendBackAsync(
ticketId,
TicketSendBackRequest.CreateBuilder()
.WithApprovalManagerHdcode("HD0002")
.WithComments("Vui lòng chỉnh sửa thông tin")
);
// BusinessStatus → PendingReview, current step trở về step trước
// Hủy — chỉ requester mới được cancel
await client.CancelAsync(
ticketId,
TicketCancelRequest.CreateBuilder()
.WithCancellerHdcode("HD0001")
.WithCancellationReason("Không còn nhu cầu")
);
// BusinessStatus → Cancelled
// Đóng — step hiện tại phải đang Approved
await client.CloseAsync(
ticketId,
TicketCloseRequest.CreateBuilder()
.WithCloserHdcode("HD0002")
.WithCloseReason("Hoàn thành")
);
// BusinessStatus → Completed
// Rút lại — chỉ requester, step chưa xử lý
await client.RevokeAsync(
ticketId,
TicketRevokeRequest.CreateBuilder()
.WithRevokerHdcode("HD0001")
.WithRevocationReason("Tạo nhầm, cần chỉnh sửa")
);
// BusinessStatus → Open
Request Models & Builders
Mỗi request model có private constructor — không thể dùng new. Phải dùng fluent builder (truy cập qua CreateBuilder()), builder sẽ validate các field bắt buộc khi Build() được gọi nội bộ.
| Request Model | Fluent Builder Interface | Builder Entry Point |
|---|---|---|
CreateTicketRequest |
ICreateTicketRequestBuilder |
CreateTicketRequest.CreateBuilder() |
TicketSendRequest |
ITicketSendRequestBuilder |
TicketSendRequest.CreateBuilder() |
TicketApproveRequest |
ITicketApproveRequestBuilder |
TicketApproveRequest.CreateBuilder() |
TicketApproveAndMoveNextRequest |
ITicketApproveAndMoveNextRequestBuilder |
TicketApproveAndMoveNextRequest.CreateBuilder() |
TicketRejectRequest |
ITicketRejectRequestBuilder |
TicketRejectRequest.CreateBuilder() |
TicketSendBackRequest |
ITicketSendBackRequestBuilder |
TicketSendBackRequest.CreateBuilder() |
TicketCancelRequest |
ITicketCancelRequestBuilder |
TicketCancelRequest.CreateBuilder() |
TicketCloseRequest |
ITicketCloseRequestBuilder |
TicketCloseRequest.CreateBuilder() |
TicketRevokeRequest |
ITicketRevokeRequestBuilder |
TicketRevokeRequest.CreateBuilder() |
Mỗi SDK method nhận builder interface (không phải request đã build) và gọi Build() nội bộ trước khi gửi.
Response Models
| Response Model | Trả về từ | Nội dung chính |
|---|---|---|
TicketInitResponse |
CreateDraftAsync, CreateAndSendAsync |
TicketId, Ticket (chi tiết), CreationTime, LastModifiedTime |
TicketDetailResponse |
Tất cả workflow actions | Toàn bộ state: BusinessStatus, CurrentStepCode, Steps, Assignees... |
ErrorResponse |
Lỗi API | Code, Message, Errors, ValidationErrors |
Models
| Model | Cách tạo | Properties |
|---|---|---|
TicketStep |
TicketStep.CreateBuilder() |
StepCode, StepName, StepOrder, StepStatus, Action, Comment, Assignees |
TicketAssignee |
new trực tiếp |
HdCode, Name, Email, BranchId |
TicketReminder |
new trực tiếp |
IsEnabled, IntervalUnit, IntervalValue, StartRemindAt, StopRemindAfter, MaxReminderCount |
Xử lý lỗi (Error Handling)
Tất cả exception kế thừa từ TicketClientException với thuộc tính ErrorCode.
| HTTP Status | Exception | ErrorCode |
|---|---|---|
| 400 | ValidationException |
ValidationError |
| 401 | UnauthorizedException |
Unauthorized |
| 403 | ForbiddenException |
Forbidden |
| 404 | TicketNotFoundException |
TicketNotFound |
| 409 | InvalidStateTransitionException |
InvalidStateTransition |
| Other | ApiCommunicationException |
ApiCommunicationError |
Các exception không phải HTTP:
| Exception | Khi nào xảy ra |
|---|---|
InvalidConfigurationException |
Thiếu hoặc sai thông tin cấu hình client |
InvalidRequestException |
Thiếu field bắt buộc trong request (validation SDK) |
InvalidResponseException |
Response rỗng hoặc không thể parse JSON |
Cấu hình client
var client = TicketManagementClient
.CreateBuilder()
.WithBaseUrl("https://api.example.com/") // Required
.WithSourceSystemId("MY_SYSTEM") // Required
.WithSecret("shared-secret") // Required
.WithSchemaVersion("1.0") // Optional, default "1.0"
.WithTimeout(TimeSpan.FromSeconds(60)) // Optional, default 30s
.WithRetryPolicy(maxRetries: 5, initialDelayMs: 200) // Optional, default 3/100ms
.WithLogger(msg => Console.WriteLine(msg)) // Optional
.WithMessageId(Guid.NewGuid()) // Optional
.Build();
Authentication Headers
| Header | Nguồn | Mục đích |
|---|---|---|
X-Source-System-Id |
WithSourceSystemId() |
Định danh hệ thống con |
X-Secret |
WithSecret() |
Xác thực yêu cầu |
X-Schema-Version |
WithSchemaVersion() |
Phiên bản schema |
X-Message-Id |
WithMessageId() / per-call |
Idempotency key (optional) |
x-message-timestamp |
Tự động sinh | Thời gian gửi request (UTC) |
Idempotency
Mỗi request có thể gửi kèm header X-Message-Id (GUID) để đảm bảo xử lý một lần. Nếu message trùng, API trả về kết quả của lần xử lý trước — không tạo ticket mới.
// Gán mặc định cho tất cả request
client = clientBuilder.WithMessageId(Guid.NewGuid()).Build();
// Hoặc gán riêng cho từng request
var result = await client.CreateAndSendAsync(requestBuilder, messageId: Guid.NewGuid());
Retry Policy
SDK tự động retry trên transient failures với exponential backoff:
- Transient status codes: 408 (RequestTimeout), 429 (TooManyRequests), 500, 502, 503, 504
- Transport errors:
HttpRequestException - Mặc định: 3 retries, 100ms initial delay (nhân đôi mỗi lần)
- Custom:
WithRetryPolicy(maxRetries, initialDelayMs)
Cấu trúc thư mục
TicketManagement.Sdk/
├── Builder/ # Fluent builders
├── Contracts/
│ └── ITicketClient.cs # Public SDK contract
├── Exceptions/ # Exception hierarchy
├── Implementation/
│ ├── TicketManagementClient.cs # Core SDK implementation
│ └── SdkClientOptions.cs
├── Models/
│ ├── Common/ # TicketStep, TicketAssignee, TicketReminder
│ ├── Enums/ # Business/step enums
│ ├── Requests/ # Request models (builder pattern)
│ └── Responses/ # Response models
└── README.md
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.17 | 105 | 5/6/2026 |
| 1.0.16 | 92 | 5/6/2026 |
| 1.0.15 | 102 | 4/21/2026 |
| 1.0.14 | 99 | 4/21/2026 |
| 1.0.13 | 105 | 4/21/2026 |
| 1.0.12 | 100 | 4/19/2026 |
| 1.0.11 | 94 | 4/18/2026 |
| 1.0.10 | 99 | 4/16/2026 |
| 1.0.9 | 92 | 4/16/2026 |
| 1.0.8 | 90 | 4/16/2026 |
| 1.0.7 | 103 | 4/16/2026 |
| 1.0.6 | 98 | 4/16/2026 |
| 1.0.5 | 92 | 4/16/2026 |
| 1.0.4 | 113 | 4/16/2026 |
| 1.0.3 | 103 | 4/16/2026 |
| 1.0.2 | 100 | 4/16/2026 |
| 1.0.1 | 107 | 4/16/2026 |
| 1.0.0 | 98 | 4/16/2026 |
SDK for integrating with Ticket Management API. Supports ticket creation
(draft/auto-send), workflow actions (approve, reject, send, send-back, revoke, cancel, close),
fluent builders, automatic retries with exponential backoff, idempotency via message ID, and
comprehensive error handling.