Theo dõi mức độ sử dụng CRM & Callbot theo khách hàng

I. Tổng quan

1. Vấn đề

  • Team CS và team Sale hiện thiếu một điểm nhìn tập trung để biết khách hàng doanh nghiệp có đang thực sự sử dụng CRM hay không.
  • Ngoài CRM, nội bộ cũng cần biết khách hàng có đang vận hành Callbot hay không, chạy với tần suất nào, mức độ sử dụng ra sao và ví còn đủ tiền để tiếp tục chạy hay không.
  • Việc đánh giá khách hàng “có dùng hệ thống” thường đang dựa vào cảm nhận, hỏi thủ công hoặc kiểm tra rời rạc ở nhiều màn hình khác nhau như đăng nhập, object CRM, lịch sử hoạt động.
  • Khi khách hàng ngừng sử dụng, nội bộ thường phát hiện muộn, dẫn tới chậm chăm sóc lại, khó kéo khách hàng quay lại quy trình làm việc trên CRM, và làm tăng rủi ro churn/gia hạn thấp.
  • Hệ thống hiện chưa có một định nghĩa nghiệp vụ thống nhất cho các trạng thái sử dụng CRM, trạng thái chạy Callbot, mức độ sử dụng và tình trạng ví.

2. Giải pháp

  • Xây dựng tính năng báo cáo nội bộ Theo dõi mức độ sử dụng CRM & Callbot theo khách hàng trong nhóm tính năng Internal, không thuộc dashboard dành cho khách hàng.
  • Tính năng tổng hợp tín hiệu sử dụng sản phẩm ở cấp khách hàng doanh nghiệp, hiển thị theo danh sách và chi tiết từng khách hàng.
  • Hệ thống tự phân loại trạng thái sử dụng dựa trên bộ chỉ số thống nhất cho cả CRM và Callbot: đăng nhập gần nhất, số user hoạt động, số thao tác CRM lõi, trạng thái Callbot, tần suất chạy, mức độ sử dụng, số dư ví và lịch sử follow-up.
  • Team CS và Sale có thể lọc nhanh các khách hàng đang có nguy cơ hoặc đã không sử dụng để chủ động nhắc, tạo task chăm sóc, hoặc chuyển escalate nội bộ khi cần.

3. Đối tượng

  • CS
  • Sale/Account Manager
  • CS Lead
  • Sales Manager
  • Admin nội bộ

4. Tầm nhìn/insight

  • Phiên bản đầu tập trung vào báo cáo nội bộ và tác vụ follow-up thủ công có hỗ trợ dữ liệu.
  • Giai đoạn sau có thể mở rộng:
    • Cho phép cấu hình ngưỡng usage theo gói dịch vụ, phân khúc khách hàng hoặc giai đoạn vòng đời.
    • Hợp nhất thêm dữ liệu các sản phẩm khác ngoài CRM và Callbot vào cùng một monitor khách hàng.
    • Sinh cảnh báo tự động qua notification/email/Zalo nội bộ.
    • Đề xuất playbook chăm sóc theo lý do giảm usage.
    • Kết hợp thêm dữ liệu hợp đồng, onboarding, ticket hỗ trợ và kết quả gia hạn để tính Customer Health Score.

II. Yêu cầu chức năng

1. Danh sách tính năng

  • Dashboard nội bộ tổng quan usage CRM + Callbot theo tập khách hàng đang quản lý.
  • Danh sách khách hàng với trạng thái CRM, trạng thái Callbot, tình trạng ví và lý do cảnh báo.
  • Bộ lọc theo owner, team, gói dịch vụ, segment, trạng thái usage CRM, trạng thái Callbot, tình trạng ví, khoảng thời gian không hoạt động.
  • Chi tiết usage của từng khách hàng theo 7 ngày, 30 ngày và xu hướng cho cả CRM và Callbot.
  • Timeline hoạt động gần nhất của khách hàng.
  • Ghi nhận và quản lý follow-up nội bộ.
  • Tạo task chăm sóc trực tiếp từ màn hình usage monitoring.
  • Export danh sách khách hàng cần follow-up.
  • Bắn webhook đồng bộ trạng thái usage sang bảng thông tin khách hàng đang được quản lý trên stag.app.ucall.vn.

2. Đặc tả chi tiết

  • User story 1: Là một CS, tôi muốn xem nhanh khách hàng nào đang không sử dụng CRM để chủ động chăm sóc lại kịp thời.
Tên Use Case [UC-01] Xem danh sách khách hàng theo trạng thái sử dụng CRM
Actor (Người dùng) CS, Sale/Account Manager, CS Lead, Sales Manager
Pre-condition (Tiền ĐK) User đã đăng nhập hệ thống nội bộ và có quyền xem báo cáo nội bộ usage CRM.
Main Flow (Luồng chính) 1. User mở menu Internal hoặc CS Tools và chọn báo cáo Customer Product Monitoring.
2. Hệ thống hiển thị các thẻ tổng quan và bảng danh sách khách hàng.
3. User chọn bộ lọc Trạng thái CRM = Không sử dụng hoặc Có nguy cơ không sử dụng.
4. Hệ thống trả về danh sách khách hàng phù hợp cùng các cột chỉ số usage.
5. User click 1 dòng khách hàng để xem chi tiết usage.
Alternate/Exception Flow (Luồng rẽ nhánh/Ngoại lệ) 3a. Không có dữ liệu phù hợp bộ lọc: hiển thị empty state và số lượng bằng 0.
4a. Dữ liệu usage đang được tổng hợp chưa xong: hiển thị trạng thái Đang cập nhật dữ liệu và thời điểm cập nhật gần nhất.
Post-condition (Hậu ĐK) User nhìn thấy danh sách khách hàng cần follow-up và có thể đi tiếp sang màn hình chi tiết.
  • User story 2: Là một Sale hoặc CS, tôi muốn xem lý do vì sao khách hàng bị đánh dấu không sử dụng để chọn đúng cách tiếp cận.
Tên Use Case [UC-02] Xem chi tiết usage của một khách hàng
Actor (Người dùng) CS, Sale/Account Manager, CS Lead, Sales Manager
Pre-condition (Tiền ĐK) Khách hàng đã tồn tại trong hệ thống CRM và user có quyền xem khách hàng đó.
Main Flow (Luồng chính) 1. User click vào 1 khách hàng trong bảng danh sách.
2. Hệ thống mở màn hình chi tiết hoặc drawer chi tiết.
3. Hệ thống hiển thị trạng thái usage hiện tại, lý do cảnh báo, lần đăng nhập cuối, lần thao tác CRM lõi cuối, số user active 7 ngày/30 ngày, top object được sử dụng, biểu đồ xu hướng theo ngày.
4. User xem timeline hoạt động và lịch sử follow-up nội bộ gần nhất.
5. User chọn hành động tiếp theo: tạo task, ghi chú follow-up hoặc đổi người phụ trách.
Alternate/Exception Flow (Luồng rẽ nhánh/Ngoại lệ) 3a. Khách hàng chưa phát sinh dữ liệu sử dụng nào: hiển thị trạng thái Chưa bắt đầu sử dụng nếu còn trong thời gian onboarding, hoặc Không sử dụng nếu đã qua onboarding.
5a. User không có quyền tạo task: ẩn action tương ứng.
Post-condition (Hậu ĐK) User nắm được nguyên nhân giảm usage và có thể tạo hoạt động follow-up ngay trên cùng flow.
  • User story 3: Là một CS Lead, tôi muốn hệ thống lưu lịch sử follow-up để tránh việc một khách hàng bị bỏ quên hoặc bị gọi trùng nhiều lần.
Tên Use Case [UC-03] Ghi nhận follow-up từ báo cáo usage
Actor (Người dùng) CS, Sale/Account Manager, CS Lead
Pre-condition (Tiền ĐK) User đang xem 1 khách hàng trong báo cáo usage và có quyền tạo follow-up hoặc task.
Main Flow (Luồng chính) 1. User bấm Tạo follow-up hoặc Tạo task chăm sóc.
2. Hệ thống mở popup nhập nội dung, deadline, người phụ trách, kết quả dự kiến.
3. User lưu thông tin.
4. Hệ thống tạo record follow-up và/hoặc task tương ứng.
5. Hệ thống cập nhật cột Lần follow-up gần nhất, Người follow-up gần nhất, Trạng thái follow-up.
Alternate/Exception Flow (Luồng rẽ nhánh/Ngoại lệ) 2a. Nếu khách hàng đã có follow-up mở chưa hoàn tất trong 3 ngày gần nhất, hệ thống cảnh báo để tránh tạo trùng.
3a. Nếu user nhập deadline nhỏ hơn thời điểm hiện tại, hệ thống báo lỗi validate.
Post-condition (Hậu ĐK) Hệ thống lưu được lịch sử chăm sóc và hỗ trợ điều phối nội bộ tốt hơn.
  • User story 4: Là một hệ thống nội bộ, tôi muốn bắn webhook usage sang bảng thông tin khách hàng trên stag.app.ucall.vn để dữ liệu chăm sóc khách hàng được đồng bộ về cùng một nơi quản lý.
Tên Use Case [UC-04] Đồng bộ usage CRM sang bảng thông tin khách hàng qua webhook
Actor (Người dùng) System, Integration service, hệ thống stag.app.ucall.vn
Pre-condition (Tiền ĐK) Job aggregate usage chạy thành công và khách hàng có khóa định danh để mapping sang record khách hàng ở stag.app.ucall.vn.
Main Flow (Luồng chính) 1. Job aggregate tính lại trạng thái usage của khách hàng.
2. Hệ thống tạo payload đồng bộ gồm thông tin khách hàng, trạng thái usage, chỉ số chính và thời điểm tổng hợp.
3. Hệ thống gọi webhook outbound tới endpoint nhận dữ liệu trên stag.app.ucall.vn.
4. Hệ thống đích xác thực chữ ký/request và cập nhật bảng thông tin khách hàng tương ứng.
5. Hệ thống nguồn lưu trạng thái đồng bộ success cùng thời gian đồng bộ cuối.
Alternate/Exception Flow (Luồng rẽ nhánh/Ngoại lệ) 2a. Không tìm thấy khóa mapping khách hàng ở hệ thống đích: bỏ qua đồng bộ và ghi log lỗi có thể xử lý lại.
3a. Endpoint đích timeout hoặc trả lỗi 5xx: hệ thống đưa event vào hàng đợi retry.
4a. Webhook không hợp lệ chữ ký hoặc sai schema: hệ thống đích từ chối cập nhật và trả lỗi 4xx.
Post-condition (Hậu ĐK) Bảng thông tin khách hàng trên stag.app.ucall.vn nhận được trạng thái usage mới nhất hoặc có log retry nếu đồng bộ lỗi.

3. Danh sách nghiệp vụ

  • Đơn vị theo dõi là Khách hàng doanh nghiệp/tài khoản khách hàng, không phải từng user lẻ.
  • Mỗi khách hàng có một trạng thái usage hiện tại tại thời điểm hệ thống tổng hợp dữ liệu.
  • Việc đánh giá usage phải xét đồng thời theo 2 lớp:
    • Trạng thái hoạt động hiện tại: phản ánh khách hàng có còn phát sinh usage gần đây hay không.
    • Độ phủ sử dụng license: phản ánh số user active so với số license/tài khoản đã mua.
  • Phiên bản đầu đề xuất 3 trạng thái:
    • Không sử dụng (inactive): Không có login nào trong 7 ngày gần nhất HOẶC không có hành động CRM lõi nào trong 7 ngày gần nhất.
    • Có nguy cơ không sử dụng (at_risk): Vẫn có tương tác trong 7 ngày gần nhất, nhưng tỷ lệ phủ sử dụng license thấp (< 30% với KH có >= 5 license), hoặc số user active giảm mạnh.
    • Đang sử dụng (active): Khách hàng có tương tác (đăng nhập và hành động CRM lõi) trong 7 ngày gần nhất, VÀ mức độ phủ sử dụng license đạt ngưỡng tối thiểu (>= 30% với KH có >= 5 license, hoặc có ít nhất 1 user active với KH < 5 license).
  • Định nghĩa thêm chỉ số Tỷ lệ phủ sử dụng license 7 ngày:
    • license_usage_rate_7d = active_users_7d / licensed_users
    • Nếu licensed_users = 0 thì tỷ lệ được ghi nhận là 0 và cần gắn cờ dữ liệu bất thường để kiểm tra lại hợp đồng/cấp quyền.
  • Định nghĩa Độ phủ sử dụng để phục vụ vận hành:
    • Tốt: license_usage_rate_7d >= 0.5
    • Trung bình: 0.3 <= license_usage_rate_7d < 0.5
    • Thấp: 0 < license_usage_rate_7d < 0.3
    • Không có: license_usage_rate_7d = 0
  • Rule áp trạng thái theo độ phủ:
    • Với khách hàng có từ 5 license trở lên, nếu license_usage_rate_7d < 0.3 thì không được xếp Đang sử dụng, mà phải đưa vào Có nguy cơ không sử dụng với lý do Độ phủ sử dụng thấp.
    • Với khách hàng có dưới 5 license, có thể xét theo số tuyệt đối; nếu có ít nhất 1 user active và có hành động CRM lõi thì vẫn có thể xếp Đang sử dụng.
    • Trường hợp ví dụ khách hàng mua 20 tài khoản nhưng chỉ có 1-2 tài khoản active trong 7 ngày gần nhất thì license_usage_rate_7d = 5%-10%, phải xếp Có nguy cơ không sử dụng, không xếp Đang sử dụng.
  • Hành động CRM lõi là các thao tác do người dùng thực hiện và có tạo ra giá trị sử dụng hệ thống, bao gồm ít nhất một trong các nhóm:
    • Tạo/sửa record Contact, Enterprise, Deal, Task, Meeting, Ticket, Order.
    • Ghi nhận Call activity.
    • Hoàn tất hoặc cập nhật Task/Meeting.
  • Các hành động sau không được tính là usage lõi:
    • Chỉ mở màn hình/list/detail mà không phát sinh thay đổi dữ liệu.
    • Tác vụ sinh bởi automation, cronjob hoặc integration server nếu không xác định được người dùng cuối.
    • Hoạt động của user đã bị khóa hoặc bị xóa.
  • Dữ liệu usage cần hỗ trợ ít nhất 3 khung nhìn thời gian: Hôm nay, 7 ngày, 30 ngày.
  • Mỗi khách hàng cần lưu các chỉ số tối thiểu:
    • Tổng số license được cấp.
    • Số user đã kích hoạt.
    • Số user active trong 7 ngày.
    • Số user active trong 30 ngày.
    • Tỷ lệ phủ sử dụng license trong 7 ngày.
    • Mức độ phủ sử dụng license (Tốt/Trung bình/Thấp/Không có).
    • Lần login gần nhất.
    • Lần phát sinh hành động CRM lõi gần nhất.
    • Tổng số hành động CRM lõi trong 7 ngày và 30 ngày.
    • Top object được sử dụng nhiều nhất trong 30 ngày.
    • Lý do gán trạng thái hiện tại.
  • Ngoài CRM, hệ thống cần theo dõi thêm trạng thái sử dụng Callbot theo từng khách hàng.
  • Callbot service status là trạng thái vận hành hiện tại của dịch vụ Callbot tại thời điểm aggregate. Đề xuất các option:
    • not_purchased: Khách hàng chưa mua hoặc chưa được cấp quyền dùng Callbot.
    • not_configured: Đã có gói/quyền nhưng chưa cấu hình campaign/scenario đủ để chạy.
    • ready: Đã cấu hình đủ điều kiện chạy nhưng hiện chưa có campaign đang chạy.
    • running: Có campaign/công việc Callbot đang chạy hoặc vừa chạy gần đây trong khung thời gian theo dõi.
    • paused: Callbot bị tạm dừng bởi người dùng nội bộ hoặc khách hàng.
    • completed: Đợt chạy gần nhất đã kết thúc và hiện không còn lịch chạy kế tiếp.
    • wallet_blocked: Không chạy được vì ví không đủ tiền.
    • error: Không chạy được do lỗi cấu hình, lỗi gateway hoặc lỗi hệ thống.
  • Callbot run frequency là tần suất vận hành được cấu hình hoặc được suy luận từ dữ liệu chạy gần nhất. Đề xuất các option:
    • none: Không có lịch chạy hoặc chưa từng chạy.
    • ad_hoc: Chạy thủ công, không theo lịch cố định.
    • daily: Chạy hằng ngày.
    • weekdays: Chạy theo ngày làm việc.
    • weekly: Chạy hằng tuần.
    • monthly: Chạy hằng tháng.
  • Callbot usage level là mức độ sử dụng Callbot trong kỳ theo dõi, phản ánh cường độ vận hành thực tế so với mức kỳ vọng. Đề xuất các option:
    • high: Có chạy đều, số lần chạy đạt từ 80% trở lên so với tần suất kỳ vọng trong 7 ngày hoặc 30 ngày gần nhất.
    • medium: Đạt từ 30% đến dưới 80% tần suất kỳ vọng.
    • low: Có chạy nhưng dưới 30% tần suất kỳ vọng.
    • none: Không có lần chạy nào trong kỳ theo dõi.
  • Nếu chưa có tần suất kỳ vọng được cấu hình, hệ thống được phép suy luận tạm từ lịch chạy/campaign hiện có; nếu vẫn không đủ dữ liệu thì gán run_frequency = ad_hocusage_level dựa trên số lần chạy tuyệt đối.
  • Mỗi khách hàng dùng Callbot cần lưu tối thiểu các chỉ số:
    • Trạng thái dịch vụ Callbot hiện tại.
    • Tần suất chạy Callbot.
    • Mức độ sử dụng Callbot.
    • Lần chạy Callbot gần nhất.
    • Số campaign Callbot active.
    • Số lần chạy trong 7 ngày và 30 ngày.
    • Tổng số cuộc gọi/attempt Callbot trong 7 ngày và 30 ngày.
    • Tỷ lệ thành công kết nối hoặc tỷ lệ hoàn thành nếu hệ thống đã có metric này.
  • Hệ thống cần theo dõi trạng thái ví để biết khách hàng còn khả năng tiếp tục chạy Callbot hay không.
  • Wallet balance status là trạng thái số dư ví tại thời điểm aggregate. Đề xuất các option:
    • sufficient: Số dư đủ an toàn cho nhu cầu chạy hiện tại.
    • warning: Số dư còn nhưng đang xuống ngưỡng cảnh báo, cần theo dõi.
    • low: Số dư thấp, có nguy cơ dừng Callbot sớm.
    • exhausted: Ví đã hết hoặc không đủ để chạy thêm.
    • unknown: Chưa lấy được dữ liệu ví hoặc chưa xác định được ngưỡng.
  • Ở phiên bản đầu, nên hiển thị đồng thời số dư ví thực tếwallet_status; không nên chỉ hiển thị màu trạng thái mà thiếu số tiền cụ thể.
  • Nếu hệ thống tính được mức tiêu hao trung bình, nên bổ sung:
    • avg_wallet_burn_per_day_7d
    • estimated_wallet_days_left
  • Rule cảnh báo kết hợp:
    • Nếu callbot_status = active nhưng wallet_status = low hoặc exhausted thì gắn cờ Cần nạp ví.
    • Nếu callbot_status = ready kéo dài quá 7 ngày sau ngày bật dịch vụ thì gắn cờ Chưa rollout Callbot.
    • Nếu monitor crmat_risk/inactive và monitor callbotusage_level = low/none thì mức ưu tiên follow-up phải cao hơn chỉ một sản phẩm giảm dùng.
  • Hệ thống nên tính thêm overall_status ở mức khách hàng để CS/Sale lọc nhanh:
    • healthy: Các sản phẩm chính đang dùng ổn, ví ở trạng thái an toàn hoặc không áp dụng.
    • attention: Có ít nhất một tín hiệu cảnh báo nhưng chưa tới mức nghiêm trọng.
    • critical: Có sản phẩm không còn dùng, bị chặn bởi ví/lỗi, hoặc nhiều tín hiệu xấu cùng lúc.
  • Sau mỗi lần aggregate usage thành công, hệ thống cần bắn webhook đồng bộ sang bảng thông tin khách hàng trên stag.app.ucall.vn.
  • Webhook đồng bộ không được phụ thuộc vào việc user có mở màn hình báo cáo hay không; đây là luồng backend bất đồng bộ sau khi aggregate.
  • Chỉ bắn webhook với khách hàng có khóa mapping giữa CRM nội bộ và record khách hàng đang được quản lý trên stag.app.ucall.vn.
  • Mỗi event đồng bộ cần có event_id hoặc khóa idempotent tương đương để hệ thống đích tránh cập nhật trùng khi retry.
  • Điều kiện nên bắn webhook:
    • Khi trạng thái usage thay đổi.
    • Khi lý do cảnh báo thay đổi.
    • Khi các chỉ số tổng hợp được refresh theo chu kỳ và nghiệp vụ yêu cầu hệ thống đích luôn giữ snapshot mới nhất.
  • Nếu webhook đồng bộ lỗi, trạng thái báo cáo nội bộ vẫn được cập nhật thành công; lỗi sync không được rollback kết quả aggregate usage.
  • Cần lưu tối thiểu các thông tin sync:
    • sync_status
    • last_synced_at
    • last_sync_error
    • last_sync_event_id
  • Nếu khách hàng ở trạng thái Không sử dụng liên tiếp từ 14 ngày trở lên, hệ thống gắn thêm tag Mức ưu tiên cao.
  • Nếu khách hàng đã có follow-up mở chưa hoàn tất thì cột trạng thái follow-up phải hiển thị ngay tại danh sách.
  • Phân quyền:
    • CSSale/Account Manager chỉ xem được tập khách hàng mình phụ trách hoặc được chia sẻ quyền.
    • CS Lead, Sales Manager, Admin có thể xem theo team hoặc toàn bộ dữ liệu tùy cấu hình permission.

4. Giao diện

  • Đề xuất đặt tại menu: Internal hoặc CS Tools > Customer Product Monitoring.
  • Màn hình danh sách gồm:
    • Nhóm thẻ tổng quan: Ổn định, Cần chú ý, Nguy cấp.
    • Nhóm thẻ ví: Đủ tiền, Cảnh báo, Số dư thấp, Hết tiền.
    • Bộ lọc nhanh: owner, team, sản phẩm đang dùng, trạng thái tổng hợp, trạng thái ví, có follow-up mở/không.
    • Ô tìm kiếm theo tên khách hàng, mã khách hàng, số điện thoại, domain/email doanh nghiệp.
    • Bảng dữ liệu với các cột đề xuất:
      • Khách hàng
      • Owner
      • Trạng thái tổng hợp
      • CRM
      • Callbot
      • Lý do
      • Action
  • Action tại từng dòng:
    • Xem chi tiết
    • Tạo follow-up
    • Tạo task
    • Export dòng này
  • Màn hình chi tiết hoặc drawer gồm:
    • Header với tên khách hàng, trạng thái tổng hợp, owner CS/Sale.
    • 5 field monitor chính: overall_status, crm_status, callbot_status, wallet_status, overall_reason.
    • Timeline hoạt động và timeline follow-up nội bộ.
    • Khối Đề xuất xử lý theo rule đơn giản, ví dụ:
      • Không login 7 ngày: đề xuất CS gọi xác nhận lý do ngừng dùng.
      • Có login nhưng không thao tác CRM: đề xuất training lại quy trình nhập liệu.
      • Chỉ 1 user active trong account có nhiều license: đề xuất kiểm tra rollout nội bộ phía khách hàng.
      • Callbot đang wallet_blocked: đề xuất liên hệ khách hàng nạp ví ngay.
      • Callbot ở not_configured nhưng đã mua gói: đề xuất hướng dẫn setup hoặc book lại onboarding.
  • UI ưu tiên list-first để team vận hành xử lý hàng loạt; chi tiết mở nhanh dưới dạng drawer là phù hợp hơn page sâu ở phiên bản đầu.

5. Đề xuất 5 trường monitor chính

Không tính các cột định danh như customer_name, owner, products_enabled.

Tên trường Kiểu dữ liệu Option/Format Định nghĩa
overall_status enum healthy, attention, critical Trạng thái tổng hợp quan trọng nhất để nội bộ ưu tiên xử lý nhanh.
crm_status enum active, at_risk, inactive Trạng thái sử dụng CRM hiện tại.
callbot_status enum not_enabled, ready, active, at_risk, paused, blocked, inactive, error Trạng thái vận hành Callbot hiện tại.
wallet_status enum na, sufficient, warning, low, exhausted Trạng thái ví ở mức vận hành.
overall_reason string Chuỗi ngắn Lý do ngắn gọn, dễ hiểu nhất để biết phải xử lý gì ngay.

Định nghĩa option

  • overall_status:
    • healthy: Khách hàng đang dùng ổn, chưa cần can thiệp.
    • attention: Có dấu hiệu giảm dùng hoặc sắp có vấn đề, cần theo dõi.
    • critical: Đã ngừng dùng, bị chặn dịch vụ hoặc rủi ro cao, cần xử lý ngay.
  • crm_status:
    • inactive: Không còn sử dụng CRM (không tương tác/thao tác lõi trong 7 ngày gần nhất).
    • at_risk: Vẫn có tương tác nhưng tỷ lệ phủ license quá thấp (< 30%).
    • active: Đang sử dụng CRM ổn định (có tương tác 7 ngày và phần trăm độ phủ tốt).
  • callbot_status:
    • not_enabled: Không dùng Callbot.
    • ready: Đã setup cơ bản nhưng chưa chạy đáng kể.
    • active: Đang chạy ổn định.
    • at_risk: Vẫn chạy nhưng tần suất/mức dùng giảm.
    • paused: Tạm dừng chủ động.
    • blocked: Không chạy được, thường do ví hoặc điều kiện vận hành.
    • inactive: Không còn sử dụng.
    • error: Lỗi cấu hình hoặc lỗi hệ thống.
  • wallet_status:
    • na: Không áp dụng vì khách hàng không dùng dịch vụ cần ví.
    • sufficient: Ví đủ an toàn.
    • warning: Ví còn nhưng đã xuống ngưỡng cảnh báo.
    • low: Ví thấp, có nguy cơ dừng dịch vụ.
    • exhausted: Ví hết hoặc không đủ để chạy tiếp.

5.1. Các chỉ số đánh giá CRM Status

1. Tương tác với hệ thống (trong 7 ngày gần nhất)

  • crm_last_login_at (Lần đăng nhập gần nhất): Kiểm tra xem khách hàng có đăng nhập vào hệ thống trong 7 ngày qua hay không.
  • crm_last_core_action_at (Lần phát sinh hành động CRM lõi gần nhất): Kiểm tra xem người dùng có thực hiện các hành động tạo ra giá trị trong 7 ngày qua hay không.
    • Hành động CRM lõi bao gồm: Tạo/sửa record (Contact, Enterprise, Deal, Task, Meeting, Ticket, Order), ghi nhận Call activity, hoặc hoàn tất/cập nhật Task/Meeting.

2. Mức độ sử dụng (Adoption rate / Độ phủ sử dụng license)

  • crm_licensed_users: Tổng số license (tài khoản) đã mua / được cấp.
  • crm_active_users_7d: Số user có hoạt động (active) trong 7 ngày gần nhất.
  • Tỷ lệ phủ sử dụng license 7 ngày (crm_adoption_rate = crm_active_users_7d / crm_licensed_users): Dùng để đánh giá mức độ sử dụng của toàn doanh nghiệp (Tốt: >50%, Trung bình: 30-50%, Thấp: <30%). Đi kèm với điều kiện doanh nghiệp phải có từ 5 license trở lên (nếu dưới 5 license thì chỉ cần 1 user active là được ghi nhận).

5.2. Thuật toán cơ bản để tính 5 field

  • crm_status (Dựa trên 2 nhóm chỉ số: Tương tác 7 ngày và Độ phủ license)
    • inactive: nếu không có login trong 7 ngày HOẶC không có hành động CRM lõi trong 7 ngày (Dựa vào chỉ số Tương tác).
    • at_risk: nếu không rơi vào inactive (tức là có tương tác), NHƯNG tỷ lệ phủ sử dụng license thấp (< 30% đối với KH >= 5 license) (Dựa vào chỉ số Mức độ sử dụng).
    • active: các trường hợp còn lại (Có tương tác VÀ có độ phủ sử dụng đạt yêu cầu).
  • callbot_status
    • not_enabled: không có gói/quyền Callbot
    • blocked: có gói nhưng không chạy được vì ví không đủ tiền
    • error: có lỗi cấu hình hoặc lỗi hệ thống
    • paused: bị tạm dừng chủ động
    • inactive: không có run trong 30 ngày
    • at_risk: có run nhưng thấp hơn ngưỡng kỳ vọng
    • ready: đã setup cơ bản nhưng chưa có run đáng kể
    • active: các trường hợp còn lại
  • wallet_status
    • na: không dùng dịch vụ cần ví
    • exhausted: số dư <= 0 hoặc không đủ cho lần chạy tiếp theo
    • low: số ngày ước tính còn chạy <= 7
    • warning: số ngày ước tính còn chạy > 7<= 14
    • sufficient: các trường hợp còn lại
  • overall_status
    • critical: nếu crm_status = inactive hoặc callbot_status thuộc blocked/error/inactive hoặc wallet_status = exhausted
    • attention: nếu không phải critical nhưng có ít nhất một trạng thái cảnh báo như crm_status = at_risk, callbot_status = at_risk/ready/paused, wallet_status = warning/low
    • healthy: các trường hợp còn lại
  • overall_reason
    • Lấy lý do có độ ưu tiên cao nhất trong các rule đang trigger
    • Thứ tự ưu tiên đề xuất:
      • Callbot blocked by wallet
      • CRM inactive
      • Callbot error
      • Wallet low
      • Low CRM adoption
      • Callbot usage below expected
      • New customer onboarding

5.3. Pseudocode tính cụ thể

INPUT
  customer
  now
  go_live_date
  has_callbot_package
  crm_last_login_at
  crm_last_core_action_at
  crm_licensed_users
  crm_active_users_7d
  callbot_last_run_at
  callbot_is_paused
  callbot_has_system_error
  callbot_is_ready
  callbot_expected_runs_7d
  callbot_actual_runs_7d
  wallet_balance
  wallet_next_run_cost
  estimated_wallet_days_left

CONSTANTS
  ONBOARDING_DAYS = 14
  CRM_INACTIVE_DAYS = 7
  CRM_LOW_ADOPTION_RATE = 0.3
  CRM_MIN_LICENSE_FOR_ADOPTION_CHECK = 5
  CALLBOT_INACTIVE_DAYS = 30
  CALLBOT_AT_RISK_RATE = 0.3
  WALLET_LOW_DAYS = 7
  WALLET_WARNING_DAYS = 14
FUNCTION days_between(a, b):
  return floor(abs(a - b) in days)

FUNCTION safe_ratio(numerator, denominator):
  if denominator is null or denominator <= 0:
    return null
  return numerator / denominator
FUNCTION calc_crm_status():
  go_live_days = days_between(now, go_live_date)
  crm_inactive_by_login = (
    crm_last_login_at is null
    or days_between(now, crm_last_login_at) >= CRM_INACTIVE_DAYS
  )
  crm_inactive_by_action = (
    crm_last_core_action_at is null
    or days_between(now, crm_last_core_action_at) >= CRM_INACTIVE_DAYS
  )
  crm_adoption_rate = safe_ratio(crm_active_users_7d, crm_licensed_users)
  crm_low_adoption = (
    crm_licensed_users >= CRM_MIN_LICENSE_FOR_ADOPTION_CHECK
    and crm_adoption_rate is not null
    and crm_adoption_rate < CRM_LOW_ADOPTION_RATE
  )

  if go_live_days <= ONBOARDING_DAYS:
    return "onboarding"

  if crm_inactive_by_login or crm_inactive_by_action:
    return "inactive"

  if crm_low_adoption:
    return "at_risk"

  return "active"
FUNCTION calc_callbot_status():
  if not has_callbot_package:
    return "not_enabled"

  if wallet_balance is not null and wallet_next_run_cost is not null and wallet_balance < wallet_next_run_cost:
    return "blocked"

  if callbot_has_system_error:
    return "error"

  if callbot_is_paused:
    return "paused"

  if callbot_last_run_at is null:
    if callbot_is_ready:
      return "ready"
    return "inactive"

  if days_between(now, callbot_last_run_at) >= CALLBOT_INACTIVE_DAYS:
    return "inactive"

  if callbot_expected_runs_7d is not null and callbot_expected_runs_7d > 0:
    callbot_run_rate = callbot_actual_runs_7d / callbot_expected_runs_7d
    if callbot_run_rate < CALLBOT_AT_RISK_RATE:
      return "at_risk"

  if callbot_actual_runs_7d <= 0 and callbot_is_ready:
    return "ready"

  return "active"
FUNCTION calc_wallet_status():
  if not has_callbot_package:
    return "na"

  if wallet_balance is null:
    return "warning"

  if wallet_balance <= 0:
    return "exhausted"

  if wallet_next_run_cost is not null and wallet_balance < wallet_next_run_cost:
    return "exhausted"

  if estimated_wallet_days_left is not null:
    if estimated_wallet_days_left <= WALLET_LOW_DAYS:
      return "low"
    if estimated_wallet_days_left <= WALLET_WARNING_DAYS:
      return "warning"

  return "sufficient"
FUNCTION calc_overall_status(crm_status, callbot_status, wallet_status):
  if crm_status == "inactive":
    return "critical"

  if callbot_status in ["blocked", "error", "inactive"]:
    return "critical"

  if wallet_status == "exhausted":
    return "critical"

  if crm_status == "at_risk":
    return "attention"

  if callbot_status in ["at_risk", "ready", "paused"]:
    return "attention"

  if wallet_status in ["warning", "low"]:
    return "attention"

  return "healthy"
FUNCTION calc_overall_reason(crm_status, callbot_status, wallet_status):
  if callbot_status == "blocked":
    return "Callbot blocked by wallet"

  if crm_status == "inactive":
    return "CRM inactive"

  if callbot_status == "error":
    return "Callbot error"

  if wallet_status in ["warning", "low", "exhausted"]:
    return "Wallet low"

  if crm_status == "at_risk":
    return "Low CRM adoption"

  if callbot_status == "at_risk":
    return "Callbot usage below expected"

  if crm_status == "onboarding":
    return "New customer onboarding"

  if callbot_status == "ready":
    return "Callbot ready but not running"

  return "Operating normally"
MAIN
  crm_status = calc_crm_status()
  wallet_status = calc_wallet_status()
  callbot_status = calc_callbot_status()
  overall_status = calc_overall_status(crm_status, callbot_status, wallet_status)
  overall_reason = calc_overall_reason(crm_status, callbot_status, wallet_status)

III. Yêu cầu phi chức năng

  • Dữ liệu usage trên dashboard cần được cập nhật định kỳ tối thiểu mỗi 1 giờ; ở phiên bản đầu không yêu cầu realtime tuyệt đối.
  • Thời gian tải màn danh sách với bộ lọc phổ biến và trang đầu tiên không quá 3 giây.
  • Các chỉ số tổng hợp phải có hiển thị thời điểm cập nhật dữ liệu gần nhất.
  • Mọi thao tác tạo follow-up, export, đổi owner hoặc mở chi tiết phải được ghi log audit.
  • Dữ liệu phải tuân thủ phân quyền theo phạm vi khách hàng và vai trò nội bộ.
  • Hệ thống phải hỗ trợ phân trang và lọc trên tập dữ liệu lớn.
  • Với các job tổng hợp usage, cần có cơ chế retry và monitoring để tránh làm sai trạng thái usage hàng loạt.
  • Webhook outbound sang stag.app.ucall.vn cần có timeout, retry policy, dead-letter hoặc cơ chế requeue để xử lý lỗi tạm thời.
  • Request webhook cần có cơ chế xác thực tối thiểu như HMAC signature, shared secret hoặc token riêng cho môi trường staging.
  • Cần tách log aggregate usage và log sync webhook để dễ vận hành và đối soát.

IV. Dependency (Liên quan & phụ thuộc)

  • Module CRM Objects để lấy dữ liệu thao tác trên Contact, Enterprise, Deal, Task, Meeting, Ticket, Order.
  • Module Activities để lấy lịch sử Call/Task/Meeting.
  • Module Customer hoặc object đại diện doanh nghiệp để gom usage theo account khách hàng.
  • Module Permission để giới hạn dữ liệu theo owner/team.
  • Module Task/Calendar nếu cho phép tạo task follow-up trực tiếp từ báo cáo.
  • Hệ thống tracking/audit log hoặc event log để tính login gần nhất, thao tác gần nhất và tổng hợp theo user.
  • Nếu sản phẩm chưa có bảng tổng hợp usage, backend cần bổ sung job ETL/aggregation riêng để tránh query trực tiếp trên log thô cho mỗi lần mở báo cáo.
  • Outbound webhook/integration service để gửi dữ liệu sang stag.app.ucall.vn.
  • Mapping giữa customer_id nội bộ và khóa record của bảng thông tin khách hàng trên stag.app.ucall.vn.
  • API/endpoint nhận webhook ở môi trường staging để cập nhật bảng thông tin khách hàng.

V. API Contract (Dev viết)

API 1: Lấy danh sách khách hàng theo trạng thái monitor

  • Method & Endpoint: GET /api/v1/internal/customer-usage/customers
  • Query Params (đề xuất):
    • page
    • page_size
    • keyword
    • owner_id
    • team_id
    • product_code
    • overall_status
    • wallet_status
    • sort_by
    • sort_direction
  • Response 200 (Thành công):
    {
      "meta": {
        "page": 1,
        "page_size": 20,
        "total": 125,
        "last_aggregated_at": "2026-03-26T09:00:00Z"
      },
      "summary": {
        "healthy": 61,
        "attention": 43,
        "critical": 21
      },
      "items": [
        {
          "customer_id": 1001,
          "customer_name": "ABC Holdings",
          "owner_cs_name": "Nguyen Van A",
          "owner_sale_name": "Tran Thi B",
          "overall_status": "attention",
          "crm_status": "at_risk",
          "callbot_status": "active",
          "wallet_status": "warning",
          "overall_reason": "CRM adoption is low and wallet is close to threshold"
        }
      ]
    }
    

API 2: Lấy chi tiết monitor của một khách hàng

  • Method & Endpoint: GET /api/v1/internal/customer-usage/customers/{customer_id}
  • Response 200 (Thành công):
    {
      "customer": {
        "id": 1001,
        "name": "ABC Holdings",
        "owner_cs_name": "Nguyen Van A",
        "owner_sale_name": "Tran Thi B",
        "overall_status": "attention",
        "crm_status": "at_risk",
        "callbot_status": "active",
        "wallet_status": "warning",
        "overall_reason": "CRM adoption is low and wallet is close to threshold"
      },
      "sync_status": "success",
      "last_aggregated_at": "2026-03-26T09:00:00Z"
    }
    

API 3: Lấy timeline usage và follow-up

  • Method & Endpoint: GET /api/v1/internal/customer-usage/customers/{customer_id}/timeline
  • Query Params (đề xuất):
    • from_date
    • to_date
    • type (usage, follow_up, all)
  • Response 200 (Thành công):
    {
      "items": [
        {
          "time": "2026-03-25T03:00:00Z",
          "type": "follow_up",
          "title": "CS called customer",
          "description": "Customer reported internal sales team is not entering data regularly",
          "actor_name": "Nguyen Van A"
        },
        {
          "time": "2026-03-22T08:15:00Z",
          "type": "usage",
          "title": "Updated Deal",
          "description": "User Pham Van C updated Deal DH-10023",
          "actor_name": "Pham Van C"
        }
      ]
    }
    

API 4: Tạo follow-up từ báo cáo usage

  • Method & Endpoint: POST /api/v1/internal/customer-usage/follow-ups
  • Request Body Payload:
    {
      "customer_id": 1001,
      "assignee_id": 11,
      "due_at": "2026-03-27T09:00:00Z",
      "note": "Call customer to verify why team stopped updating CRM",
      "create_task": true
    }
    
  • Response 200 (Thành công):
    {
      "follow_up_id": 9001,
      "task_id": 7001,
      "message": "Tạo follow-up thành công"
    }
    

API 5: Cập nhật cấu hình ngưỡng usage

  • Method & Endpoint: PUT /api/v1/internal/customer-usage/settings
  • Mục đích: Cho phép Admin nội bộ thay đổi ngưỡng mặc định theo toàn hệ thống hoặc theo segment khách hàng.
  • Request Body Payload (đề xuất):
    {
      "default_onboarding_days": 14,
      "product_usage_high_threshold": 0.8,
      "product_usage_medium_threshold": 0.3,
      "wallet_warning_days_left": 14,
      "wallet_low_days_left": 7
    }
    

Webhook 1: Đồng bộ customer monitor sang bảng thông tin khách hàng trên stag.app.ucall.vn

  • Method & Endpoint (đề xuất phía hệ thống đích): POST https://stag.app.ucall.vn/api/v1/internal/customer-usage/webhook
  • Mục đích: Cập nhật trạng thái monitor tổng hợp của khách hàng vào bảng thông tin khách hàng đang được quản lý trên bản staging.
  • Headers (đề xuất):
    • Content-Type: application/json
    • X-Webhook-Event: customer_monitor_updated
    • X-Webhook-Event-Id: evt_20260326_1001_001
    • X-Webhook-Signature: sha256=...
  • Request Body Payload (đề xuất):
    {
      "event_id": "evt_20260326_1001_001",
      "event_type": "customer_monitor_updated",
      "sent_at": "2026-03-26T09:05:00Z",
      "source": "crm_internal",
      "customer": {
        "customer_id": 1001,
        "customer_name": "ABC Holdings",
        "owner_cs_name": "Nguyen Van A",
        "owner_sale_name": "Tran Thi B"
      },
      "overall_monitor": {
        "overall_status": "attention",
        "crm_status": "at_risk",
        "callbot_status": "active",
        "wallet_status": "warning",
        "overall_reason": "CRM adoption is low and wallet is close to threshold"
      }
    }
    
  • Response 200 (Thành công):
    {
      "message": "Webhook received",
      "event_id": "evt_20260326_1001_001",
      "updated": true
    }
    
  • Response 400/401 (Lỗi validate/xác thực):
    {
      "message": "Invalid signature or payload"
    }
    
  • Lưu ý triển khai:
    • Endpoint/path thực tế phía stag.app.ucall.vn cần được chốt với team quản lý staging.
    • Hệ thống đích nên update theo external_customer_key hoặc khóa mapping ổn định, không nên phụ thuộc duy nhất vào tên khách hàng.
    • Nếu hệ thống đích chỉ cần cập nhật một số cột trong bảng thông tin khách hàng, có thể giới hạn payload ở phiên bản đầu để giảm coupling.

VI. Test case (BA hoặc Tester viết)

  • TC1 - Tính đúng crm_status: Khách hàng không có login hoặc không có hành động CRM lõi trong 7 ngày -> crm_status = inactive.
  • TC2 - Tính đúng crm_status mức cảnh báo: Khách hàng vẫn có login nhưng độ phủ dùng thấp -> crm_status = at_risk.
  • TC3 - Tính đúng callbot_status: Khách hàng có Callbot đang chạy bình thường -> callbot_status = active.
  • TC4 - Tính đúng callbot_status bị chặn: Khách hàng có Callbot nhưng ví không đủ tiền -> callbot_status = blocked.
  • TC5 - Tính đúng wallet_status: Ví còn dưới ngưỡng cảnh báo nhưng chưa hết -> wallet_status = warning hoặc low theo rule cấu hình.
  • TC6 - Tính đúng overall_status: Nếu crm_status = inactive hoặc callbot_status = blocked -> overall_status = critical.
  • TC7 - Tính đúng overall_reason: Khi nhiều rule cùng đúng, hệ thống chọn đúng lý do có ưu tiên cao nhất.
  • TC8 - Phân quyền theo owner/team: User CS chỉ nhìn thấy các khách hàng thuộc phạm vi mình phụ trách; manager nhìn thấy toàn team.
  • TC9 - Webhook đồng bộ đúng 5 field monitor: Payload gửi sang stag.app.ucall.vn chứa đúng overall_status, crm_status, callbot_status, wallet_status, overall_reason.
  • TC10 - Retry webhook khi timeout: Endpoint staging timeout hoặc trả 5xx -> event được đưa vào retry queue, không làm fail aggregate job.