Appearance
Type Deep Dive — Ticket Lifecycle And Results
1. Mục tiêu của flow này
Flow ticket lifecycle xử lý 3 việc khác nhau nhưng đang đi chung một runtime:
- create/update dữ liệu ticket,
- đổi status theo assignee hoặc kết quả,
- sinh ticket kế tiếp nếu complete dẫn sang follow-up mới.
Điểm quan trọng: FE orchestrate nhiều mutation, nhưng backend mới là nơi quyết định transition hợp lệ và việc có duplicate ticket hay không.
2. Create / Update Orchestration ở FE
2.1 Save flow thực tế
TicketCreate.tsx đang chạy theo chuỗi sau (TicketCreate.tsx:184-340):
text
Submit form
-> createTicket hoặc updateTicket
-> nếu có newCallObj thì update incall_call.ticket_id
-> nếu có assignee và status hiện tại là new -> changeStatusTicket(assigned)
-> nếu bỏ assignee và status hiện tại là assigned -> changeStatusTicket(new)
-> nếu có result -> changeStatusTicket(completed)
-> nếu backend trả new_ticket_id và result cho phép -> route sang ticket mới
-> insert ticket log2.2 Rule ngầm trong FE
| Rule | Nguồn |
|---|---|
make_consultant_appointment và move_consultant_appointment bắt buộc có callBackDate + appointmentDate | TicketCreate.tsx:185-194 |
Save với assignee trên ticket new sẽ auto chuyển sang assigned | TicketCreate.tsx:223-243 |
Save bỏ assignee trên ticket assigned sẽ auto chuyển về new | TicketCreate.tsx:244-264 |
Save với result sẽ luôn gọi changeStatusTicket sang completed | TicketCreate.tsx:266-285 |
3. Transition Engine ở Backend
3.1 Contract
changeStatusTicket nhận:
ticket_idstatus_idnotedue_dateappointment_start_at
Backend load ticket hiện tại, gọi ticket.ValidateNewStatus(...), rồi mới xử lý transition (change_status_ticket.go:21-46).
3.2 Hai nhánh xử lý
| Nhánh | Hành vi |
|---|---|
status != completed | update_ticket_by_pk với status_id và output_note |
status == completed | gọi ticket.Duplicate(...) và trả new_ticket_id nếu có |
Nghĩa là completed ở đây không phải "đóng ticket cũ rồi xong", mà là điểm vào của chain engine.
4. Result Và Sinh Ticket Mới
4.1 Result không sinh ticket mới
FE đang chặn redirect sang ticket mới với các result:
cancel_consultant_appointmentcancel_servicewrong_numberwrong_informationcompleted
Đây là whitelist ở UI để coi kết quả là terminal outcome (TicketCreate.tsx:174-181).
4.2 Result có thể sinh ticket mới
Nếu changeStatusTicket trả new_ticket_id và result không nằm trong nhóm trên:
- popup mode: emit
refresh(new_ticket_id)rồi đóng popup, - full page mode: route sang
ROUTE_TICKET_UPDATEhoặcROUTE_TICKET_DETAILcủa ticket mới.
Hệ quả:
- FE state sau submit có thể nhảy sang ticket khác,
- QA phải xác minh cả ticket cũ lẫn ticket mới,
- analytics nếu chỉ đếm một ticket hoàn tất có thể miss chain length.
5. Event Side Effects
5.1 Ticket insert
ticket_insert.go đang làm thêm các side effects sau khi row mới được tạo:
- refresh service groups qua
UpdateTicketServiceGroups, - ghi KPI log
MetricTicketCreated, - ghép
keywordscủa ticket với keywords của address, - thêm assignee/in-charge vào
account.related_peoplenếu có.
5.2 Ticket update
ticket_update.go đang làm:
- nếu
output_notecó dữ liệu và status chuyển sang completed thì tạocustomer_note, - refresh
keywords, - cập nhật
account.related_peoplekhi assignee/in-charge thay đổi.
Như vậy history thực tế không chỉ nằm ở ticket_history_log, mà còn kéo side effects sang customer note và account relation.
6. Appointment Và Due Date
| Field | Vai trò trong lifecycle |
|---|---|
due_date | Callback / follow-up deadline cho ticket hiện tại hoặc ticket kế tiếp |
appointment_start_at | Mốc lịch hẹn dùng trong completed/duplicate path |
appointment_id | Khi tạo từ appointment hoặc gắn với appointment |
remind_ticket_tomorrow không query ticket theo due date. Nó query appointment ngày mai trước, rồi map ngược ra ticket qua appointment_id. Đây là rule khác hẳn với remind_ticket_today.
7. QA Focus
- Tạo ticket có assignee từ đầu để xác minh auto
new -> assigned. - Sửa ticket assigned rồi bỏ assignee để xác minh
assigned -> new. - Chốt result thuộc nhóm terminal để xác minh không redirect sang ticket mới.
- Chốt result thuộc nhóm follow-up để xác minh backend trả
new_ticket_idvà UI chuyển sang ticket kế tiếp. - Xác minh
output_notekhi completed có sinhcustomer_note. - Xác minh tạo ticket từ call runtime có update
incall_call.ticket_id.
8. Rủi ro / Findings kỹ thuật
| ID | Mức | Finding |
|---|---|---|
| LC-F01 | P1 | FE đang chồng nhiều mutation trong một submit flow, nên retry/error handling có thể rơi vào trạng thái partial success. |
| LC-F02 | P1 | changeStatusTicket trả new_ticket_id nhưng UI decision lại phụ thuộc thêm vào whitelist result phía FE; đây là dual-control dễ drift. |
| LC-F03 | P2 | note trong action contract và output_note ở update path rất gần nghĩa nhưng không hoàn toàn đồng nhất, dễ gây nhầm khi map form fields. |