Appearance
Type Deep Dive — Call Center And Hotline Touchpoints
1. Vai trò của lớp này
Call center trong CRM không chỉ là tiện ích gọi điện. Nó đang chạm trực tiếp vào:
- tạo/sync call logs,
- binding cuộc gọi với ticket,
- runtime capability của agent qua extension mapping,
- danh sách missed ticket và hotline follow-up.
2. Runtime Surface ở FE
2.1 Ticket list
Tickets.tsx có 3 dấu hiệu cho thấy hotline là first-class runtime:
- check extension bằng
localStoragequacheckLocalStorageExtension()(Tickets.tsx:107-119), - gọi
useSipCall().initiateCall, - hiển thị source tooltip giải thích origin của ticket.
Nếu extension mapping hoặc local storage không hợp lệ, user có quyền vẫn có thể mất khả năng call ngay trên UI.
2.2 Ticket create / bind call
TicketCreate.tsx đọc newCallObj từ localStorage khi mount. Sau khi create/update thành công, nếu object này tồn tại thì page gọi updateIncallCall để set ticket_id cho cuộc gọi vừa diễn ra (TicketCreate.tsx:210-220).
Nghĩa là ticket có thể được sinh sau cuộc gọi, rồi bind ngược lại vào log đã tồn tại.
3. Metadata Contracts
3.1 Actions
actions.graphql hiện expose:
callcenterCallData(...)callcenterCallOutEvent(...)secureIncall(data: SecureIncallInput!)
secureIncall nhận contact_id và source, trả message + call_id (actions.graphql:786-799).
3.2 REST endpoints
Metadata cũng expose REST endpoint cho callcenterCallData và callcenterCallOutEvent, nên call runtime có thể đi qua ngoài GraphQL UI path.
4. Backend Runtime
| File | Vai trò |
|---|---|
crm-api/action/secure_incall.go | Secure/initiate contract |
crm-api/action/callcenter_calldata.go | Nhận event cuộc gọi, upsert log |
crm-api/action/callcenter_callout.go | Ghi event call out |
crm-api/action/action.go | Register các call actions |
Từ log debug trong callcenter_calldata.go có thể thấy runtime này đang:
- normalize status,
- query log theo
call_id + extension, - update hoặc insert
incall_call_log, - ghi khá nhiều debug statement.
5. Extension Mapping Surface
CRM module có riêng:
MappingAcc.tsxMappingAccCreate.tsx
Các page này thao tác với incall_extension để map hotline extension với account nội bộ. Đây là prerequisite runtime, không phải admin convenience page.
6. Boundary Với Module Khác
| Boundary | Vai trò |
|---|---|
notification | Call events và reminders có thể tạo inbox/push surfaces liên quan |
webhook | incall.go trong webhook vẫn là external ingress boundary của một phần phone integration |
user | Staff display, user select, account mapping |
crm ticket | Ticket là object đích để gắn cuộc gọi và missed follow-up |
7. QA Focus
- Agent chưa có extension mapping nhưng có quyền CRM/callcenter.
- Tạo cuộc gọi mới, sau đó tạo ticket từ popup/form để xác minh
incall_call.ticket_id. - Cuộc gọi outbound và inbound có cùng
call_idnhưng event khác nhau. - Kiểm tra missed/answered normalization trong
callcenterCallData. - Xác minh REST endpoint path và GraphQL action path đều ghi đúng log.
8. Rủi ro / Findings kỹ thuật
| ID | Mức | Finding |
|---|---|---|
| CC-F01 | P1 | Runtime call capability phụ thuộc localStorage extension data, nên đây là hidden operational dependency của FE. |
| CC-F02 | P1 | Ticket-call binding diễn ra hậu create/update, nên nếu mutation phụ fail có thể sinh ticket nhưng không gắn được call log. |
| CC-F03 | P2 | Hotline runtime đang phân tán qua GraphQL action, REST endpoint, FE local state và webhook boundary, nên debug production incident sẽ cần nhìn nhiều lớp cùng lúc. |