Tài liệu Phân tích Nghiệp vụ (BA)
Tích hợp toàn hệ thống — Cơ sở đào tạo pha chế

dotB (CRM) · Dataverse (kho gốc) · Power Automate (trục điều phối) · Haravan · VoIP24H · App Exam · Power BI

Phiên bản0.9 — Bản thảo làm việc với khách hàng
Ngày06/07/2026
NguồnĐặc tả tích hợp v1.0 (Dactar_tich_hop.pdf)
Trạng tháiChờ khách hàng xác nhận các mục 14–15

1.Giới thiệu & phạm vi

1.1 Mục đích tài liệu

Tài liệu này tường minh hóa bản đặc tả tích hợp sơ khởi của khách hàng thành tài liệu phân tích nghiệp vụ đầy đủ: luồng dữ liệu, hợp đồng tích hợp (webhook/API), mô hình lưu trữ, quy tắc nghiệp vụ, báo cáo, yêu cầu phi chức năng. Mỗi điểm chưa rõ được gắn mã Q-xx (câu hỏi mở), A-xx (giả định) hoặc R-xx (rủi ro) để rà soát cùng khách hàng trong buổi làm việc tiếp theo.

1.2 Mục tiêu nghiệp vụ

  • Một khách hàng — một hồ sơ duy nhất xuyên suốt mọi kênh (web, mạng xã hội, walk-in, cửa hàng online, tổng đài, thi cử).
  • Sale mở hồ sơ khách trên dotB thấy được toàn cảnh 360°: tổng chi tiêu, hạng khách, lịch sử gọi, tình trạng thi — mà không bao giờ nhìn thấy PII đầy đủ (SĐT, email được che).
  • Không phụ thuộc nhà cung cấp: dữ liệu gốc luôn nằm ở Dataverse do khách hàng sở hữu; thay bất kỳ hệ vệ tinh nào cũng không mất dữ liệu.
  • Báo cáo quản trị (Power BI) lấy từ một nguồn số liệu duy nhất, nhất quán giữa mọi báo cáo.

1.3 Phạm vi

Trong phạm vi (In-scope)
  • Thiết kế Identity Model (CusID / phone / email) & quy trình sinh CusID.
  • 5 luồng tích hợp: lead intake, đơn hàng Haravan, cuộc gọi VoIP24H, kết quả thi App Exam, đồng bộ hiển thị về dotB.
  • Khớp trùng (identity resolution), hợp nhất hồ sơ, Merge_Audit.
  • Onboarding dữ liệu cũ (Legacy_Records) — mức yêu cầu; spec nhập liệu chi tiết là tài liệu riêng.
  • Masking PII & phân quyền trên dotB.
  • Báo cáo Power BI (read-only trên Dataverse) & job đối soát đêm.
Ngoài phạm vi (Out-of-scope)
  • Nghiệp vụ nội bộ của từng hệ vệ tinh (quy trình bán hàng trên dotB, vận hành kho Haravan, ra đề thi App Exam…).
  • SLA engine chấm điểm Sale (đã xây riêng — chỉ dùng chung nguồn Call_Log).
  • Chiến dịch marketing automation, chăm sóc tự động (giai đoạn sau).
  • Chi tiết UX/UI màn hình dotB (phụ thuộc khả năng tùy biến của dotB — xem Q-01).

2.Bối cảnh & kiến trúc tổng thể

Nguyên tắc tối cao (khách hàng đã chốt) Dataverse là System of Record (SoR) duy nhất. Mọi hệ khác (dotB, Haravan, VoIP24H, App Exam) là vệ tinh, đọc/ghi bắt buộc qua Power Automate. Không hệ vệ tinh nào giữ bản gốc PII đầy đủ. Mọi hệ vệ tinh có thể thay thế mà không mất dữ liệu.
Web formlanding page Facebook / Zalo / TikToklead ads, chat Walk-inSale nhập tại quầy POWER AUTOMATE — trục tiếp nhận & điều phối (mục 2.2) nhận webhook mọi kênh · chuẩn hóa phone/email · gọi resolveIdentity validate checksum CusID · masking PII trước khi đẩy dotB retry khi lỗi · job đối soát đêm · cảnh báo IT — KHÔNG hệ nào nối thẳng dotB DATAVERSE — System of Record (kho gốc, PII đầy đủ) Customer · Lead · Order · Call_Log · Exam_Result · Course_History Legacy_Records · Merge_Audit · rollup: total_spend, tier dotB (CRM)chỉ HIỂN THỊ, masked Haravanđơn hàng online VoIP24Htổng đài App Examthi cử Power BIread-only đẩy hiển thị (masked) webhook ghi vào (qua Power Automate) báo cáo ghi: lead / order / call / exam đọc: hồ sơ + chỉ số (masked)

2.1 Chiều dữ liệu

ChiềuDữ liệuNguồn → ĐíchCơ chếTần suất
Vào Dataverse (ghi)Lead (web form, social)Kênh số → Power Automate → DataverseConnector / webhookNear-real-time
Đơn hàngHaravan → Power Automate → Dataverse (Order)Webhook order.created / order.paidNear-real-time + đối soát đêm
Cuộc gọiVoIP24H → Power Automate → Dataverse (Call_Log)Webhook call.endedNear-real-time
Kết quả thiApp Exam → Power Automate → Dataverse (Exam_Result)Webhook exam.completedNear-real-time
Ra khỏi Dataverse (đọc, đã masked)Hồ sơ khách + total_spend + tier + lịch sử gọi + trạng thái thiDataverse → Power Automate → dotBPush cập nhật trường tùy chỉnh / activity timelineNear-real-time sau mỗi thay đổi
Báo cáoToàn bộ chỉ số mục 10Dataverse → Power BIDirect connect, read-onlyTheo lịch refresh (đề xuất 1–4 giờ/lần — Q-14)
Ràng buộc kiến trúc quan trọng dotB không là nơi tổng hợp — chỉ hiển thị dữ liệu Dataverse đẩy sang. Mọi phép tính (tổng chi tiêu, xếp hạng) thực hiện tại Dataverse. Nếu dotB có tính năng "1-click integration" nối thẳng Haravan/VoIP, phải tắt để ép mọi dữ liệu đi qua Power Automate (Q-02).

2.2 Power Automate làm gì — trách nhiệm & danh sách flow cần xây

Power Automate không lưu dữ liệu — nó là tầng điều phối (orchestration). Mọi flow đều theo cùng một khung xử lý 6 bước:

1
Tiếp nhận: nhận webhook / form submission từ hệ nguồn; xác thực chữ ký webhook (HMAC/secret — Q-37).
2
Chuẩn hóa & validate: chuẩn hóa phone (bỏ +84, khoảng trắng, về 10 số), email lowercase, datetime về múi giờ Asia/Ho_Chi_Minh; kiểm tra payload đủ trường bắt buộc; validate checksum nếu payload có CusID (sai → từ chối + cờ fraud).
3
Định danh: gọi resolveIdentity (mục 7) để tìm/tạo CusID, hoặc đẩy vào review queue.
4
Ghi Dataverse: ghi vào bảng tương ứng (Lead/Order/Call_Log/Exam_Result) theo nguyên tắc idempotent — trùng ID nguồn thì bỏ qua, không ghi đúp.
5
Đẩy hiển thị: sau khi Dataverse tính lại rollup, mask PII rồi đẩy trường tùy chỉnh / activity timeline sang dotB.
6
Xử lý lỗi: retry có backoff; lỗi lặp lại → dead-letter queue + cảnh báo IT (Q-46); toàn bộ run có log để truy vết.

Danh mục flow đề xuất (bám theo các luồng L1–L6, mục 5)

FlowTriggerNhiệm vụ chínhĐích ghiĐẩy sang dotBPhục vụ
PA-01 Lead intake WebForm web submitChuẩn hóa → resolveIdentity → tạo/gắn LeadLead / CustomerHồ sơ masked + gán Sale (Q-22)L1, UC-1
PA-02 Lead intake SocialLead ads FB/Zalo/TikTok (connector)Như PA-01, thêm map trường theo kênh (Q-21)Lead / CustomerHồ sơ maskedL1
PA-03 Walk-in / cập nhật phoneSale thao tác trên dotBBlind overwrite → resolveIdentity → cờ PHONE_MISMATCH_REVIEW → gửi OTP → merge → ghi Merge_Audit (4 số cuối)Customer, Merge_AuditCảnh báo 4 số cuối, kết quả xác nhậnUC-1
PA-04 Order HaravanWebhook order.created/paidresolveIdentity → ghi Order → chờ rollup total_spend/tierOrder{total_spend, tier}L2, UC-2
PA-05 Call log VoIPWebhook call.endedresolveIdentity → ghi Call_Log (immutable)Call_LogTimeline: số cuộc, thời điểm, thời lượng, kết quảL3, UC-3
PA-06 Exam resultWebhook exam.completedKhớp theo CusID (nếu có) hoặc resolveIdentity → ghi Exam_ResultExam_Resultexam_status + điểm + ngày + lần thiL4, UC-4
PA-07 Ghi danh → App ExamGhi danh khóa họcĐẩy CusID xuống App Exam để khớp 1-1 (Q-08)Course_HistoryL4
PA-08 Đối soát đêmLịch (hằng đêm)So tổng Haravan vs Order Dataverse; lệch → backfill qua API + báo cáo chênh lệch (mở rộng VoIP/Exam — Q-45)Order (bù)Cập nhật lại chỉ số nếu có bùMục 11
PA-09 Review queueCó bản ghi nghi trùng (B3)Tạo việc cho Sale, nhắc SLA, escalate QL khi quá hạn (Q-33)Review queueThông báo trên dotBMục 7

Lưu ý triển khai: danh mục trên là mức đề xuất để ước lượng khối lượng — số flow thực tế có thể gộp/tách khi thiết kế chi tiết. Các connector (Haravan, VoIP24H, App Exam, dotB) đều đứng tên tenant của khách hàng (mục 9). Chi phí license premium connector tính theo danh mục này — Q-15.

3.Các bên liên quan & hệ thống

3.1 Vai trò con người

Vai tròTrách nhiệm trong hệ thốngQuyền dữ liệu
Sale / Tư vấnTiếp nhận lead, tư vấn, ghi nhận walk-in, xử lý cảnh báo trùng, xem hồ sơ 360°Chỉ hồ sơ được gán; PII luôn masked; chỉ số (chi tiêu/hạng/thi) chỉ đọc; được cập nhật phone theo cơ chế "sửa không cần thấy"
Quản lý (QL) SaleDuyệt sửa hàng loạt, giám sát hàng chờ review khớp trùng, xem báo cáo độiNhư Sale + duyệt thao tác nhạy cảm; phạm vi hồ sơ rộng hơn (Q-12)
Quản trị hệ thống / ITQuản trị Dataverse, Power Automate, connector, phân quyền, giám sát lỗi đồng bộToàn quyền backend (cần quy định ai được xem PII đầy đủ — Q-13)
Đội nhập liệu (onboarding)Số hóa dữ liệu 3 năm cũ vào Legacy_Records trước go-liveGhi Legacy_Records; theo spec riêng "Số hóa dữ liệu cũ"
Ban giám đốc / Kế toánXem báo cáo Power BI, quyết định chính sách chi tiêu cũ (mục 8.5)Power BI read-only
Khách hàng / Học viênĐể lại lead, mua hàng, gọi điện, thi; tự xác thực số điện thoại qua OTP/ZaloChỉ thấy dữ liệu của chính mình (OTP)

3.2 Hệ thống

Hệ thốngVai tròGhi vào DataverseNhận từ DataverseĐiểm cần xác minh
DataverseSoR — kho gốc, nơi duy nhất giữ PII đầy đủ, nơi tính toán rollupLicense/capacity (Q-15)
Power AutomateTrục điều phối: tiếp nhận mọi kênh, resolveIdentity, đẩy hiển thị, đối soátConnector đứng tên khách hàng, không đứng tên dotB
dotBCRM cho Sale — màn hình làm việc, CHỈ hiển thị dữ liệu maskedWalk-in / thao tác Sale (qua PA)Hồ sơ masked, total_spend, tier, call timeline, exam_statusQ-01, Q-02, Q-03
HaravanBán hàng online (nguyên liệu, dụng cụ…)Order (webhook)CusID tham chiếu (tùy chọn — Q-05)Q-04
VoIP24HTổng đài gọi ra/vàoCall_Log (webhook)Q-06, Q-07
App ExamThi cuối khóaExam_Result (webhook)CusID lúc ghi danh (khuyến nghị)Q-08
Power BIBáo cáo quản trịĐọc trực tiếp (read-only)Q-14

4.Mô hình định danh khách hàng (Identity Model)

Đây là nền móng của toàn bộ tích hợp: mọi bảng dữ liệu, mọi luồng, mọi kịch bản kiểm tra đều quy về mô hình khóa 3 lớp.

4.1 Ba lớp khóa

KhóaVai tròTính chấtAi sinhHệ quả thiết kế
CusIDKhóa chính kỹ thuật (Primary Key)Bất biến, vô nghĩa, có checksumDataverseMọi hệ vệ tinh trỏ vào CusID; sửa phone/email không phá liên kết Order/Call/Exam
phoneKhóa nghiệp vụ chính (Business Key 1)Sửa được; dùng khớp trùng; uniqueNgười nhập / kháchChuẩn hóa trước khi so (bỏ +84, khoảng trắng, về 10 số)
emailKhóa nghiệp vụ phụ (Business Key 2)Sửa được; khớp trùng dự phòngNgười nhập / kháchSo sánh lowercase; "cứu" các ca nhập sai SĐT

4.2 Định dạng CusID

CUST-<sequence>-<checksum>        ví dụ: CUST-1001-M

sequence : số tăng dần do Dataverse cấp
checksum : ≥1 ký tự = f(sequence + SecretSalt), thuật toán GIỮ KÍN
           → checksum hiển thị công khai, thuật toán + salt bảo mật
           → record từ hệ vệ tinh về SAI checksum ⇒ từ chối ghi + cờ fraud
Cần làm rõ với khách hàng Thuật toán checksum cụ thể, độ dài, nơi lưu SecretSalt, quy trình xoay salt (rotation) — xem Q-16. Ước lượng số lượng khách để chọn độ dài sequence phù hợp — Q-17.

4.3 Vòng đời định danh — 2 giai đoạn

1
Giai đoạn tiếp nhận: lead vào từ bất kỳ kênh nào → Dataverse cấp LeadID tạm. Hồ sơ ở trạng thái Lead.
2
Giai đoạn kích hoạt: lead đủ điều kiện (Qualified) → sinh CusID chính thức có checksum → đồng bộ CusID xuống các hệ vệ tinh.
Điểm chưa tường minh trong đặc tả gốc "Đủ điều kiện (qualified)" là gì — có thanh toán lần đầu? Sale xác nhận nhu cầu? Điền đủ phone + email? Tiêu chí này quyết định thời điểm sinh CusID và cần khách hàng chốt — Q-18. Quan hệ giữa LeadID và CusID (LeadID có bị hủy hay lưu vết?) — Q-19.

4.4 Vòng đời trạng thái hồ sơ

LeadLeadID tạm Qualifiedsinh CusID + checksum Customercó giao dịch đạt tiêu chí (Q-18) phát sinh Order

Cần bổ sung: đặc tả gốc chỉ có 3 trạng thái Lead / Qualified / Customer. Đề xuất khách hàng cân nhắc thêm Inactive/Churned (ngưng tương tác) và Merged (hồ sơ bị gộp) để báo cáo chính xác — Q-20.

5.Luồng dữ liệu chi tiết

Mỗi luồng được mô tả theo mẫu: trigger → payload → xử lý → lưu trữ → hiển thị → xử lý lỗi. Payload dưới đây là kỳ vọng từ đặc tả gốc, cần xác minh với từng nhà cung cấp (mục 14).

5.1 Luồng L1 — Lead intake (Web form / Facebook / Zalo / TikTok / Walk-in)

1
Trigger: khách điền form web, để lại lead trên social, hoặc Sale nhập walk-in trên dotB. Không kênh nào nối thẳng vào dotB — tất cả qua Power Automate.
2
Payload tối thiểu: full_name, phone, email, source_channel, campaign/ref (nếu có), nhu cầu quan tâm. Danh sách trường chuẩn từng kênh cần chốt — Q-21.
3
Xác thực: website gọi HTTP trigger của Power Automate kèm secret key trong payload; secret sai → dừng flow (chặn request lạ). Với WordPress, gửi server-side (Contact Form 7 hook / PHP), tránh dán webhook lộ ra client.
4
Xử lý: Power Automate chuẩn hóa phone (090 123 4567 / +84901234567 → 0901234567) và email → gọi resolveIdentity (mục 7). Khớp → cập nhật hồ sơ hiện có (last_lead_source, course_interest, utm…), không tạo trùng; không khớp → tạo Lead mới (LeadID tạm), sinh sẵn phone_masked/email_masked.
5
Lưu trữ: bảng Lead/Customer trong Dataverse, kèm source, utm_source, utm_campaign, course_interest, page_url, created_time để báo cáo chuyển đổi theo kênh/chiến dịch.
6
Hiển thị: POST hồ sơ masked sang API dotB (dotB có sẵn API tạo lead, xác thực OAuth — mục 14.0 câu 36/42); lưu dotb_lead_id dotB trả về vào Dataverse để các lần cập nhật sau update theo ID này (dotB chưa có API update theo CusID — câu 37). Gán Sale phụ trách theo quy tắc phân bổ — chưa có trong đặc tả, cần chốt — Q-22.
7
Lỗi: thiếu cả phone lẫn email → không thể định danh: từ chối hay lưu "lead khuyết danh"? — Q-23. POST sang dotB lỗi → retry + hàng chờ đồng bộ lại (mục 11).

Chi tiết kỹ thuật từng bước (JSON mẫu, cấu hình trigger, code WordPress CF7/Elementor, checklist test end-to-end): xem tài liệu riêng "Hướng dẫn triển khai Website Form → Power Automate → Dataverse → dotB" (07/07/2026).

5.2 Luồng L2 — Đơn hàng Haravan → total_spend & tier

1
Trigger: Haravan bắn webhook order.created / order.paid về Power Automate.
2
Payload kỳ vọng: haravan_customer{phone, email}, line_items[], total, order_id. Xác minh Haravan có trả đủ phone+email — Q-04.
3
Xử lý: resolveIdentity(phone → email) tìm CusID. Khớp → ghi bảng Order (FK = CusID, source = Haravan). Không khớp → tạo Customer mới hoặc đưa vào review queue (điều kiện chọn nhánh nào cần chốt — Q-24).
4
Tính toán tại Dataverse (rollup): total_spend = Σ Order.amount WHERE CusID = X (gồm cả khóa học lẫn Haravan) → tier tra theo bậc: <5tr = Đồng · 5–20tr = Bạc · 20–50tr = Vàng · >50tr = Kim cương (ngưỡng cần khách xác nhận là chốt hay tạm — Q-25).
5
Hiển thị: Power Automate đẩy {total_spend, tier} sang hồ sơ dotB. Sale mở khách → "Tổng chi tiêu: 32.000.000đ · Hạng: VÀNG".
6
Đối soát: job đêm so tổng doanh thu Haravan vs tổng Order trong Dataverse, phòng webhook rớt (chi tiết mục 11).
Điểm chưa tường minh (a) Đơn hủy / hoàn tiền (order.cancelled/refund) có trừ total_spend không? Webhook nào? — Q-26. (b) Đơn khóa học (Course) ghi vào Order từ nguồn nào — dotB, thu ngân, hay hệ thống khác? Đặc tả gốc chỉ ghi source (Haravan/Course) mà chưa nêu luồng nhập đơn Course — Q-27. Gợi ý mới (14.0 câu 35): dotB có thể bắn sự kiện "Chốt đơn" qua webhook customize — đây là ứng viên tự nhiên cho nguồn đơn Course, cần dotB estimate. (c) Hạng có bị tụt khi hoàn tiền / có hiệu lực theo năm không? — Q-28.

5.3 Luồng L3 — Cuộc gọi VoIP24H → Call_Log → timeline dotB

1
Trigger: mỗi cuộc gọi kết thúc, VoIP24H bắn webhook call.ended.
2
Payload kỳ vọng: lead_ref, sale_id, call_started_at, duration_sec, voip_result, direction (in/out). Cần xác minh thêm who_hung_upQ-06.
3
Xử lý: resolveIdentity → gắn CusID → ghi Call_Log (immutable append — không sửa/xóa).
4
Hiển thị: đẩy sang dotB dạng activity/timeline: tổng số cuộc (COUNT WHERE CusID=X) + danh sách thời điểm, thời lượng, kết quả. Ví dụ: "Tổng 5 cuộc · Gần nhất 02/07 14:30 (95s, Connected) · 01/07 09:15 (8s, NoAnswer)…".
5
Bảo mật: dotB chỉ hiển thị metadata; file ghi âm KHÔNG lưu trên dotB — lưu tại Dataverse/kho riêng, truy cập theo quyền (nơi lưu, thời hạn lưu ghi âm cần chốt — Q-07).
6
Dùng chung: cùng nguồn Call_Log phục vụ SLA engine chấm điểm Sale — một nguồn, hai mục đích, không nhập liệu hai lần.
Điểm chưa tường minh Cuộc gọi đến từ số chưa có hồ sơ (khách lạ gọi vào) → tạo Lead mới tự động hay chỉ log chờ? — Q-29.

5.4 Luồng L4 — Kết quả thi App Exam → Exam_Result → dotB

1
Trigger: học viên hoàn thành bài thi cuối khóa → App Exam bắn webhook exam.completed.
2
Payload kỳ vọng: student_ref, course_code, score, result (Pass/Fail), exam_date, attempt_no.
3
Xử lý: resolveIdentity → gắn CusID → ghi Exam_Result (append). Khuyến nghị mạnh: khi ghi danh khóa học, đẩy CusID xuống App Exam để khớp 1-1 chính xác, tránh lệch do sai phone — xác minh App Exam nhận được CusID không — Q-08.
4
Hiển thị trên dotB: exam_status mới nhất (Pass / Fail / Chưa thi) + điểm + ngày thi + lần thi. Ví dụ: "Khóa PC-CB-01: ĐẬU (điểm 82, 28/06, lần 1)".
5
Giá trị nghiệp vụ: (a) chăm sóc học viên rớt — mời thi lại/học lại; (b) upsell khóa nâng cao cho học viên đậu.

5.5 Luồng L5 — Đồng bộ hiển thị Dataverse → dotB (masked)

Đây là luồng "ra" duy nhất, gom mọi kết quả từ L1–L4:

  • Nội dung đẩy: hồ sơ khách (tên, phone masked 09xx***567, email masked a***@gmail.com), total_spend, tier, tóm tắt lịch sử gọi, exam_status, lịch sử học legacy (kèm nhãn "dữ liệu cũ, chưa kiểm chứng").
  • Cơ chế: Power Automate ghi vào trường tùy chỉnh + activity timeline của dotB qua API.
  • Tính chất: các trường chỉ số là chỉ đọc với Sale; masking là bất biến, không có màn hình nào "mở khóa".
Rủi ro lớn nhất của thiết kế (khách hàng tự nhận định) Nếu dotB không cho đẩy trường tùy chỉnh / activity timeline từ ngoài vào, các yêu cầu hiển thị (chi tiêu, hạng, lịch sử gọi, trạng thái thi) không thể hiện trên dotB. Phương án dự phòng: iframe hoặc deep-link sang Dataverse portal. Cần hỏi dotB sớm nhấtQ-01, R-01.

5.6 Luồng L6 — Onboarding dữ liệu cũ (Legacy, một lần trước go-live)

1
Nguồn: sổ sách / file 3 năm gần nhất (danh sách học viên, khóa đã học, chi tiêu ước tính).
2
Đích: bảng Legacy_Records trong Dataverse — nhập trước go-live, dù chưa merge, chưa kiểm chứng.
3
Sử dụng: khi khách cũ quay lại (use case UC-5, mục 8.5), Sale tra Legacy_Records theo tên + SĐT + khoảng thời gian.
Điều kiện tiên quyết Nếu dữ liệu cũ còn trên sổ giấy khi go-live, Sale không tra cứu được → toàn bộ kịch bản khách cũ sụp đổ. Đây là hạng mục GĐ 0 của lộ trình (mục 13). Khối lượng, chất lượng, định dạng dữ liệu cũ cần khảo sát ngay — Q-30, R-02. Spec nhập liệu chi tiết = tài liệu riêng "Số hóa dữ liệu cũ".

6.Mô hình dữ liệu — Schema Dataverse

6.1 Customer (bảng master — một dòng / một người)

CộtKiểuRàng buộcGhi chú
CusIDtextPK, bất biếnĐịnh dạng CUST-<seq>-<checksum>
phonetextuniqueBusiness key 1 — số đầy đủ, CHỈ lưu tại Dataverse
phone_normalizedtextindexĐã chuẩn hóa (bỏ +84/khoảng trắng, 10 số) — dùng khớp trùng
phone_maskedtext (computed)Dạng 09xx***567 — bản duy nhất được đẩy sang dotB
emailtextindexBusiness key 2 — email đầy đủ, CHỈ lưu tại Dataverse
email_maskedtext (computed)Dạng a***@gmail.com — bản đẩy sang dotB
full_nametext
dotb_lead_idtextindexID lead do dotB trả về khi tạo (mục 14.0 câu 41) — bắt buộc lưu vì dotB chưa có API cập nhật theo CusID (câu 37); mọi lần update dotB dùng ID này
source / utm_source / utm_campaigntextKênh + tracking quảng cáo của lead đầu tiên (phục vụ báo cáo chuyển đổi theo kênh)
course_interesttextKhóa học khách quan tâm (từ form)
statuschoiceLead / Qualified / Customer (đề xuất mở rộng — Q-20)
total_spendcurrency (computed)rollup= Σ Order.amount — chi tiêu có bằng chứng, quyết định hạng
legacy_spendcurrencyChi tiêu cũ, đánh dấu unverified — tách riêng, KHÔNG vào hạng
lifetime_spendcurrency (computed)= total_spend + legacy_spend — chỉ tham khảo/tri ân
tierchoice (computed)Theo total_spend (KHÔNG gồm legacy): Đồng/Bạc/Vàng/Kim cương
created_on / modified_ondatetimeaudit

6.2 Order (từ Haravan + Course — append)

CộtKiểuGhi chú
order_idtext (PK)ID từ hệ nguồn
CusIDFK → Customer
sourcechoiceHaravan / Course
product_nametext
amountcurrencyĐầu vào rollup total_spend
order_datedatetime
haravan_customer_reftextTham chiếu ngược về Haravan (đối soát)

Đề xuất bổ sung cột: order_status (paid/cancelled/refunded) và paid_amount để xử lý hủy/hoàn (Q-26); line_items chi tiết nếu cần báo cáo theo sản phẩm.

6.3 Call_Log (từ VoIP24H — immutable append)

call_id (PK) · CusID (FK) · sale_id · call_started_at · duration_sec · voip_result · direction (in/out) — đề xuất thêm recording_ref (con trỏ tới file ghi âm trong kho riêng) và who_hung_up nếu VoIP24H hỗ trợ.

6.4 Exam_Result (từ App Exam — append)

exam_id (PK) · CusID (FK) · course_code · exam_date · score · result (Pass/Fail) · attempt_no

6.5 Course_History (ghi danh + legacy)

Đặc tả gốc nhắc đến ở kịch bản khách cũ: CusID (FK) · course_code · năm học (ước lượng) · source (LEGACY_MIGRATION / hệ thống) · confidence (verified / unverified_legacy). Cần chuẩn hóa đầy đủ khi thiết kế chi tiết — hiện đặc tả gốc chưa định nghĩa bảng ghi danh khóa học cho luồng mới (Q-27).

6.6 Legacy_Records (số hóa một lần)

Dữ liệu 3 năm cũ, tra cứu theo tên + SĐT + khoảng thời gian. Cấu trúc chi tiết thuộc spec riêng "Số hóa dữ liệu cũ" — tối thiểu: legacy_id · full_name · phone · course · year · spend_amount · evidence (có/không hóa đơn) · digitized_by · digitized_at.

6.7 Merge_Audit (immutable)

CộtGhi chú
merge_idPK
surviving_CusID / merged_CusIDHồ sơ giữ lại / hồ sơ bị gộp
matched_byphone / email / manual
old_phone / corrected_phoneChỉ lưu 4 số cuối — audit không phơi PII
operator_id / merged_atAi thao tác, khi nào

6.8 Quan hệ tổng thể

Customer CusID (PK) · phone · email Order1 khách — n đơn Call_Logimmutable Exam_Resultappend Course_Historygồm legacy Merge_Auditimmutable, 4 số cuối Legacy_Recordstra cứu thủ công liên kết thủ công khi xác nhận
Nguyên tắc lưu trữ Call_Log, Exam_Result, Merge_Audit là append-only (không sửa/xóa). Chính sách lưu trữ dài hạn (retention) cho từng bảng và cho file ghi âm chưa được khách nêu — Q-31.

7.Khớp trùng & hợp nhất hồ sơ (Identity Resolution)

Chạy tại Dataverse mỗi khi có bản ghi mới từ bất kỳ nguồn nào. Thứ tự ưu tiên 4 bước:

function resolveIdentity(new_record):
    # B1 — khớp phone chuẩn hóa (bỏ +84, khoảng trắng, về 10 số)
    match = Customer where normalized(phone) == normalized(new.phone)
    if match: return match.CusID

    # B2 — phone không khớp → thử email (lowercase)
    match = Customer where lower(email) == lower(new.email)
    if match: return match.CusID          # nghi phone sai → cờ PHONE_MISMATCH_REVIEW

    # B3 — khớp mờ: tên + một phần phone/email → hàng chờ Sale xác nhận
    candidates = fuzzyMatch(name, partial_phone, email)
    if candidates: return REVIEW_QUEUE(candidates)

    # B4 — không khớp → khách mới, cấp CusID mới
    return createNewCustomer(new_record)

7.1 Quy tắc cần làm rõ thêm với khách hàng

#Điểm mởĐề xuất của BA
1Ngưỡng "khớp mờ" ở B3 (giống tên bao nhiêu %, trùng mấy số cuối phone?)Trùng ≥ 4 số cuối phone + tên giống ≥ 80% (chuẩn hóa dấu) → vào review queueQ-32
2SLA xử lý hàng chờ review — ai xử lý, trong bao lâu, quá hạn thì sao?Sale được gán xử lý trong 24h; quá hạn escalate QLQ-33
3Khi merge 2 hồ sơ: hồ sơ nào "sống"? Dữ liệu con (Order/Call/Exam) trỏ lại thế nào?Hồ sơ tạo trước (CusID nhỏ hơn) sống; mọi FK của hồ sơ bị gộp được cập nhật về surviving_CusID; ghi Merge_AuditQ-34
4Một khách cố tình dùng 2 SĐT khác nhau (2 hồ sơ hợp lệ) — có cho phép tồn tại song song?Cho phép; chỉ merge khi có bằng chứng (OTP / khách xác nhận)Q-35

8.Kịch bản nghiệp vụ (Use case) — 5 câu hỏi kiểm tra của khách hàng

Khách hàng đưa 5 "câu hỏi kiểm tra" làm tiêu chí nghiệm thu. Mỗi kịch bản dưới đây gồm: tình huống → xử lý → tiêu chí chấp nhận (Acceptance Criteria).

8.1 UC-1 — Web lead + Walk-in, khách đọc SAI số điện thoại

Tình huống: khách để lead trên web (phone 0901234567). Đến trường, Sale nhập lại nhưng khách đọc nhầm 0901234568. Sale "nghi trùng" nhưng phone không khớp.

Ràng buộc cứng Masking không được gỡ để xử lý tình huống này. Tỷ lệ sai SĐT chỉ vài %; bỏ masking toàn bộ lead để sửa nhóm nhỏ = đổi rủi ro rò rỉ thường trực lấy một vấn đề hiếm — sai về kiến trúc. Sale sửa số mà không nhìn thấy số đầy đủ.

Ba cơ chế "sửa không cần thấy" (ưu tiên từ tốt nhất)

  1. Khách tự xác thực (tốt nhất): gửi OTP/Zalo tới số khách vừa đọc → khách nhập OTP → hệ thống tự xác nhận và merge. Sale không chạm số nào.
  2. Xác nhận bằng 4 số cuối: cảnh báo chỉ hiện "số hệ thống …567 · số vừa nhập …568 — xác nhận số nào đúng?". Đủ phân biệt, không đủ để chép mang đi.
  3. Ghi đè mù (blind overwrite): màn hình luôn hiện 09xx***567; Sale gõ số MỚI vào ô cập nhật, không cần thấy số cũ; backend chuẩn hóa, đối chiếu.

Luồng xử lý

1
Walk-in: Sale nhập số khách đọc (vào ô nhập, không thấy số cũ).
2
Backend: B1 khớp phone → KHÔNG (…568 ≠ …567); B2 khớp email → KHỚP (cùng an@gmail.com) → trả CusID cũ + cờ PHONE_MISMATCH_REVIEW.
3
dotB cảnh báo CHỈ 4 số cuối: "Đã có hồ sơ khớp email. Số hệ thống …567 · số vừa nhập …568. Xác nhận số nào đúng?"
4
Xác nhận: (a) tốt nhất — OTP tới số mới, khách nhập, tự merge; (b) thay thế — Sale hỏi "số anh kết thúc 567 hay 568?" rồi chọn.
5
Backend cập nhật phone. Phone không phải PK → sửa không phá liên kết; CusID giữ nguyên → mọi Order/Call/Exam vẫn trỏ đúng.
6
Ghi Merge_Audit: chỉ 4 số cuối cũ→mới + operator + thời điểm.
Tiêu chí chấp nhận UC-1
  • AC1: Không màn hình nào trong toàn bộ luồng hiển thị quá 4 số cuối của phone cho Sale.
  • AC2: Sau cập nhật, CusID không đổi; đếm Order/Call/Exam của khách trước và sau bằng nhau.
  • AC3: Merge_Audit có bản ghi tương ứng, tra được ai sửa, khi nào, 4 số cuối cũ→mới.
  • AC4: Sửa phone hàng loạt (bulk) bị chặn, cần QL duyệt.

8.2 UC-2 — Tổng chi tiêu & thứ hạng (gồm Haravan)

Yêu cầu: màn hình dotB hiển thị tổng chi tiêu (khóa học + Haravan) và thứ hạng. Luồng chi tiết tại mục 5.2.

Tiêu chí chấp nhận UC-2
  • AC1: Đơn Haravan order.paid xuất hiện trong total_spend trên dotB trong ≤ X phút (ngưỡng X cần chốt — Q-36).
  • AC2: tier đúng theo bậc: <5tr Đồng · 5–20tr Bạc · 20–50tr Vàng · >50tr Kim cương.
  • AC3: Phép tính thực hiện tại Dataverse; xóa/tạm ngưng dotB không ảnh hưởng số liệu.
  • AC4: Job đối soát đêm phát hiện được đơn thiếu (giả lập webhook rớt) và bù lại.

8.3 UC-3 — Lịch sử cuộc gọi

Yêu cầu: dotB hiển thị đã gọi bao nhiêu cuộc, thời điểm nào. Luồng chi tiết tại mục 5.3.

Tiêu chí chấp nhận UC-3
  • AC1: Cuộc gọi kết thúc → xuất hiện trên timeline dotB (thời điểm, thời lượng, kết quả) trong ≤ X phút.
  • AC2: Call_Log không sửa/xóa được từ bất kỳ UI nào (immutable).
  • AC3: dotB không lưu, không phát file ghi âm; ghi âm chỉ truy cập được theo quyền tại kho riêng.
  • AC4: Cùng bản ghi Call_Log được SLA engine đọc — không nhập liệu 2 lần.

8.4 UC-4 — Tình trạng học viên (đậu/rớt từ App Exam)

Yêu cầu: dotB hiển thị tình trạng thi Pass / Fail / Chưa thi + điểm, ngày, lần thi. Luồng chi tiết tại mục 5.4.

Tiêu chí chấp nhận UC-4
  • AC1: Thi xong → trạng thái hiện trên dotB trong ≤ X phút, đúng khóa (course_code), đúng lần thi (attempt_no).
  • AC2: Học viên thi nhiều lần → hiển thị kết quả mới nhất, lịch sử các lần vẫn tra được.
  • AC3: Nếu ghi danh có đẩy CusID xuống App Exam → khớp 1-1, không qua resolveIdentity.

8.5 UC-5 — Học viên cũ (3 năm trước, thời chưa có hệ thống) quay lại đăng ký

Cốt lõi: tách "lịch sử học" khỏi "tích lũy chi tiêu" — lịch sử học nạp ngay, chi tiêu cũ nạp theo chính sách.

Kịch bản 6 bước

1
Nhận diện khách cũ: nếu data cũ đã nạp Dataverse → resolveIdentity khớp → CusID có sẵn. Nếu chưa nạp → không khớp → bắt buộc bước con người xác nhận "khách có lịch sử cũ không" trước khi chốt là khách mới.
2
Sale tra cứu: hỏi "anh/chị từng học ở đây chưa?" → tra Legacy_Records theo tên + SĐT + khoảng thời gian. (Điều kiện: dữ liệu cũ đã được số hóa — mục 5.6.)
3
Tạo CusID mới + cờ LEGACY_PENDING: giao dịch hôm nay là thật, có bằng chứng → cấp CusID chính thức; cờ đưa hồ sơ vào hàng chờ nhập lịch sử.
4
Nạp lịch sử học (làm ngay): ghi Course_History nguồn LEGACY_MIGRATION, năm ước lượng, confidence = unverified_legacy. dotB hiện: "Lịch sử (trước hệ thống): Pha chế cơ bản ~2022 [dữ liệu cũ, chưa kiểm chứng]".
5
Nạp chi tiêu cũ theo chính sách, KHÔNG gộp thẳng: total_spend = chi tiêu có bằng chứng (ra hạng) · legacy_spend = chi tiêu cũ unverified (tách riêng) · lifetime_spend = tổng hai phần (chỉ tham khảo/tri ân).
6
Ghi audit: Merge_Audit lưu nguồn data, ai nhập, mức tin cậy. Nếu sau này tìm thấy CusID cũ đã migrate trùng → merge, ghi log.

Chính sách chi tiêu cũ — cần khách hàng QUYẾT ĐỊNH (Q-09)

Phương ánCách làmƯu / nhược
A. Chỉ tri ânKhông tính vào hạng; hiển thị "khách thân thiết từ 2022"; hạng tính từ chi tiêu mớiAn toàn số liệu, dễ vận hành / khách VIP cũ có thể phật ý
B. Tính nếu có bằng chứngCộng vào hạng nếu có hóa đơn/biên lai/bản ghi tin cậy; không thì như ACông bằng hơn / tốn công thẩm định, cần quy trình duyệt bằng chứng
Tiêu chí chấp nhận UC-5
  • AC1: Khách cũ có trong Legacy_Records → Sale tra được trong ≤ 1 phút tại quầy.
  • AC2: Lịch sử học legacy hiển thị trên dotB kèm nhãn "chưa kiểm chứng", tách bạch với dữ liệu hệ thống.
  • AC3: tier KHÔNG thay đổi bởi legacy_spend (trừ khi khách chọn phương án B và có bằng chứng được duyệt).
  • AC4: Toàn bộ thao tác nạp legacy có vết audit (nguồn, người nhập, mức tin cậy).

9.Bảo mật, masking & phân quyền

Nguyên tắc "SỬA KHÔNG CẦN THẤY" — ràng buộc cứng khi nghiệm thu dotB Masking là bất biến, không ngoại lệ. Mọi thao tác trên PII (sửa, xác nhận, merge) phải chạy được trên dữ liệu ĐÃ CHE. Nếu bất kỳ quy trình nào đòi Sale nhìn thấy số đầy đủ thì quy trình đó sai và phải thiết kế lại — không phải masking sai. Số đầy đủ chỉ tồn tại ở 2 nơi: Dataverse (backend) và điện thoại của chính khách.
Nguyên tắcThực thi
Dataverse là SoR duy nhấtMọi hệ vệ tinh đọc/ghi qua Power Automate, không giữ bản gốc PII
Masking bất biếndotB LUÔN hiện 09xx***567, a***@gmail.com. Không tồn tại "trường hợp cần sửa nên mở khóa"
Sửa không cần thấyGhi đè mù / xác nhận 4 số cuối / khách tự xác thực OTP — Sale không bao giờ đọc số đầy đủ
Checksum chống tạo lậuRecord từ hệ vệ tinh sai checksum → từ chối ghi + cờ fraud
Connector đứng tên khách hàngHaravan/VoIP/Exam nối vào Power Automate của khách hàng — dotB không làm trung gian sở hữu
Audit bất biếnMerge_Audit (chỉ 4 số cuối), Call_Log, Exam_Result: append-only, không sửa/xóa
Exit strategyThay bất kỳ hệ vệ tinh = ngắt 1 nhánh Power Automate; dữ liệu ở Dataverse nguyên vẹn
Phân quyền SaleChỉ thấy hồ sơ được gán, đã masked; total_spend / tier / exam = chỉ đọc
Chống lạm dụng sửa phoneMọi cập nhật phone log vào Merge_Audit; chỉ Sale có quyền; sửa hàng loạt cần QL duyệt (chống gom/đổi số bất thường)

9.1 Điểm bảo mật cần bổ sung ngoài đặc tả gốc

  • Bảo mật webhook: xác thực chữ ký/secret của webhook Haravan, VoIP24H, App Exam (HMAC, IP allowlist) — chưa được đặc tả — Q-37.
  • Ai được xem PII đầy đủ ở backend: danh sách vai trò admin Dataverse + cơ chế log truy cập — Q-13.
  • Tuân thủ pháp lý: Nghị định 13/2023/NĐ-CP về bảo vệ dữ liệu cá nhân — cần sự đồng ý của khách khi thu thập, quyền xóa dữ liệu; quy trình "khách yêu cầu xóa" chưa có — Q-38.
  • OTP/Zalo: chọn nhà cung cấp OTP, chi phí/tin, phương án khi khách không dùng Zalo — Q-39.

10.Báo cáo & đo lường (Power BI — read-only trên Dataverse)

Mọi báo cáo lấy từ một nguồn Dataverse duy nhất → số liệu nhất quán giữa mọi báo cáo.

#Chỉ sốNguồn bảngCông thức / định nghĩa cần chốtĐối tượng xem
1Tỷ lệ chuyển đổi lead → customerCustomer (status, source_channel)Mốc tính theo tháng lead vào hay tháng chuyển đổi? — Q-40BGĐ, QL Sale
2Tổng chi tiêu theo hạng kháchCustomer (tier, total_spend)Đã rõ (không gồm legacy)BGĐ
3Doanh thu Course vs HaravanOrder (source)Theo order_date hay paid_date? — Q-41BGĐ, Kế toán
4Tỷ lệ đậu/rớt theo khóaExam_ResultTính theo lần thi đầu hay lần cuối? — Q-42Đào tạo
5Connected rate cuộc gọiCall_Log (voip_result)Định nghĩa "connected" (duration ≥ ? giây) — Q-43QL Sale
6Tỷ lệ merge do sai phoneMerge_Audit (matched_by)Đo chất lượng data đầu vào theo kênhQL Sale, IT
7SLA phản hồi leadCall_Log + SLA engineTừ engine đã xây — chỉ đọc chung nguồnQL Sale

Cần chốt thêm: tần suất refresh Power BI, ai được cấp license xem (Q-14); dữ liệu trên Power BI có cần masked như dotB không (đề xuất: có, trừ nhóm được duyệt) — Q-44.

11.Vận hành: đồng bộ, đối soát & xử lý lỗi

11.1 Chế độ đồng bộ

  • Near-real-time: mọi luồng webhook (L1–L5) chạy tức thời qua Power Automate.
  • Đối soát đêm (nightly reconciliation): job so tổng Haravan vs tổng Order Dataverse phòng webhook rớt. Đề xuất mở rộng đối soát cho VoIP (đếm cuộc) và App Exam (đếm bài thi) — Q-45.

11.2 Ma trận xử lý lỗi (đề xuất — đặc tả gốc chưa có, cần khách xác nhận)

Tình huống lỗiPhát hiệnXử lý đề xuất
Webhook rớt / không đếnJob đối soát đêm lệch sốKéo lại theo API (backfill) theo khoảng ngày lệch; báo cáo chênh lệch cho IT
Webhook đến trùng (duplicate)Trùng order_id / call_id / exam_idIdempotent — khóa theo ID nguồn, ghi đè an toàn / bỏ qua
Payload thiếu phone lẫn emailValidate tại Power AutomateĐưa vào hàng chờ lỗi (dead-letter), thông báo IT; không tạo hồ sơ khuyết danh (Q-23)
Sai checksum CusID từ vệ tinhValidate checksumTừ chối ghi + cờ fraud + cảnh báo admin
Power Automate flow lỗi/quá tảiGiám sát run historyRetry tự động theo chính sách; cảnh báo qua email/Teams khi lỗi liên tiếp — Q-46
dotB API không nhận được pushResponse lỗi từ dotBRetry có backoff; hàng chờ đồng bộ lại; dashboard trạng thái đồng bộ

12.Yêu cầu phi chức năng (NFR) — đề xuất để khách chốt

Lưu ý Đặc tả gốc chưa nêu NFR nào. Bảng dưới là đề xuất khởi điểm của BA để khách hàng xác nhận hoặc điều chỉnh — Q-36, Q-47.
NhómYêu cầu đề xuất
Độ trễ đồng bộWebhook → hiển thị trên dotB ≤ 5 phút (P95); đối soát đêm hoàn tất trước 6h sáng
Thông lượngƯớc tính: ? lead/ngày, ? đơn/ngày, ? cuộc gọi/ngày (cần số liệu từ khách — Q-17)
Sẵn sàngNghiệp vụ tại quầy không được chặn khi 1 hệ vệ tinh chết; Dataverse theo SLA Microsoft
Sao lưu / khôi phụcBackup Dataverse theo chuẩn Power Platform; RPO/RTO cần chốt
Lưu trữ (retention)Call_Log/Exam_Result/Merge_Audit: giữ vĩnh viễn (append-only); ghi âm: ? tháng (Q-31)
Ngôn ngữ / múi giờTiếng Việt; Asia/Ho_Chi_Minh; chuẩn hóa datetime khi nhận webhook (UTC → local)
Chi phí licenseDataverse capacity, Power Automate premium connector, Power BI Pro — cần dự toán (Q-15)

13.Lộ trình triển khai & khối lượng ước tính & chi phí

Hạng mụcPhụ thuộc / đáp ứngGhi chú BA
0Số hóa data cũ vào Legacy_Records (onboarding một lần)Trước go-liveĐiều kiện tiên quyết của UC-5; cần spec riêng + đội nhập liệu (R-02)
1Dataverse schema + Identity Model + CusID/checksumNền — làm trước hếtChốt Q-16…Q-20 trước khi build
2Power Automate: Web/Social → Dataverse → dotB (masked)Đáp ứng mục 2, 4Chốt Q-01/Q-02/Q-03 với dotB trước (chặn rủi ro R-01)
3resolveIdentity + Merge_AuditĐáp ứng UC-1, UC-5Kèm màn hình review queue + cơ chế OTP
4Haravan webhook → Order → total_spend/tier → dotBĐáp ứng UC-2Kèm job đối soát đêm
5VoIP webhook → Call_Log → dotB timelineĐáp ứng UC-3Kèm liên kết SLA engine
6App Exam webhook → Exam_Result → dotBĐáp ứng UC-4Ưu tiên đẩy CusID lúc ghi danh
7Power BI + hoàn thiện đối soátĐáp ứng mục 10Chốt định nghĩa chỉ số Q-40…Q-44 trước khi dựng dashboard

13.1 Ước tính khối lượng công việc (man-day)

Tính chất ước tính Đây là ước tính sơ bộ (ROM — Rough Order of Magnitude), sai số ±30–40%, lập khi chưa có câu trả lời của các nhà cung cấp (Q-01…Q-08). Riêng câu trả lời của dotB (Q-01) có thể làm khối lượng GĐ 2–6 thay đổi đáng kể: nếu dotB không có API nhận trường tùy chỉnh, phải xây phương án iframe/portal thay thế (+15–25 MD). Sau buổi làm việc chốt mục 14, ước tính sẽ được cập nhật thành báo giá chính thức.
Hạng mụcMD (dev)Cơ sở ước tính
1Dataverse schema + Identity Model + CusID/checksum + phân quyền77 bảng + rollup total_spend/tier, plugin sinh checksum, security roles
2Lead intake (PA-01, PA-02) + push masked sang dotB14Web form 3 · connector FB/Zalo/TikTok 6 · tích hợp API dotB 5 (phụ thuộc Q-01)
3resolveIdentity + Merge_Audit + review queue + OTP/ZNS (PA-03, PA-09)16Logic khớp 4 bước 5 · merge+audit 4 · màn hình review queue 4 · tích hợp OTP/ZNS 3
4Haravan → Order → total_spend/tier + đối soát đơn (PA-04, PA-08)7Webhook + idempotent · rollup/tier · job đối soát + backfill
5VoIP24H → Call_Log → timeline dotB (PA-05)4Webhook · timeline dotB · liên kết SLA engine
6App Exam → Exam_Result → dotB + đẩy CusID lúc ghi danh (PA-06, PA-07)7Webhook 3 · hiển thị 2 · flow ghi danh 2
7Power BI (7 nhóm chỉ số) + hoàn thiện đối soát7Data model · 2–3 trang dashboard · phân quyền/refresh
Kiểm thử tích hợp end-to-end + UAT theo AC (UC-1…UC-5) + kiểm thử masking2Kiểm thử theo AC từng use case; kiểm thử "sửa không cần thấy" là điều kiện nghiệm thu
Tài liệu vận hành, đào tạo Sale/QL, hỗ trợ go-live2Đào tạo + hỗ trợ sau go-live (mức nhẹ)
Cộng phát triển≈ 66
BA / quản lý dự án / làm việc nhà cung cấp5Chốt Q-list, viết spec chi tiết, điều phối 4 vendor, họp khách hàng
TỔNG≈ 71 MDKhoảng tin cậy: 60 – 85 MD (chưa gồm GĐ 0)

GĐ 0 — số hóa dữ liệu cũ (tính riêng, không phải việc dev): chưa ước tính được vì phụ thuộc khối lượng bản ghi (Q-30). Công thức tham khảo: nhập tay từ sổ ≈ 1–2 phút/bản ghi → 5.000 bản ghi ≈ 10–20 ngày công nhập liệu (nhân với số bản ghi thực tế); cộng thêm 3–5 MD dev để dựng bảng Legacy_Records + form nhập + kiểm tra chất lượng.

13.2 Thời gian dự kiến (lịch)

Phương án độiCấu hìnhThời gian lịchGhi chú
Chuẩn (khuyến nghị)2 dev Power Platform + 1 BA/PM (kiêm test)~10–12 tuần (2,5–3 tháng)GĐ 4/5/6 chạy song song được sau khi GĐ 1–3 xong; GĐ 0 (nhập liệu) chạy song song bằng đội riêng
Tiết kiệm1 dev + 1 BA/PM bán thời gian~16–18 tuần (4–4,5 tháng)Rẻ hơn không đáng kể, rủi ro phụ thuộc 1 người
Rút gọn3 dev + 1 BA/PM + 1 tester~7–8 tuầnChỉ nhanh hơn nếu vendor trả lời Q-01…Q-08 sớm — vendor mới là nút thắt, không phải số dev

Đường găng (critical path): ① câu trả lời API của dotB (Q-01…Q-03) — nên gửi câu hỏi ngay tuần này, trước khi ký kế hoạch; ② GĐ 1 + GĐ 3 (nền định danh) chặn mọi giai đoạn sau; ③ số hóa dữ liệu cũ phải xong trước go-live để UC-5 chạy được.

Tóm tắt cho khách hàng Khối lượng ≈ 71 man-day (60–85) · thời gian ~2,5–3 tháng với đội 2 dev + 1 BA. Chưa gồm nhập liệu GĐ 0 (Q-30) và phần customize phía dotB (Q-49).

13.3 Chi phí ước tính

a) Chi phí xây dựng (one-time)

Đơn giá blended/MD71 MD (chuẩn)Khoảng 60 – 85 MD
1 – 1,5 triệu VND≈ 71 – 107 triệu VND≈ 60 – 128 triệu VND

Chưa gồm: (a) chi phí nhập liệu GĐ 0 (tính theo khối lượng Q-30); (b) chi phí customize phía dotB — dotB đã xác nhận (mục 14.0) các hạng mục field custom, activity timeline, webhook 4 sự kiện, API update theo CusID đều làm dạng customize và estimate man-day riêng sau khi thống nhất phạm vi (Q-49); (c) phí tin OTP/ZNS.

b) Chi phí license & vận hành (hàng tháng — theo giá niêm yết Microsoft, cần báo giá chính thức khi chốt)

KhoảnĐơn giá tham khảoSố lượng dự kiếnƯớc tháng
Power Automate Premium (tài khoản dịch vụ chạy flow)~15 USD/user/tháng1–2~0,4–0,8 triệu VND
Power Apps per-user (màn hình review queue cho QL/Sale — nếu không làm trong dotB)~20 USD/user/tháng0–5 (tùy Q-01)0 – 2,6 triệu VND
Power BI Pro (người xem báo cáo)~14 USD/user/tháng5–10~1,8–3,6 triệu VND
Dataverse dung lượng thêm (nếu vượt mức kèm license)~40 USD/GB/tháng0–2 GB0 – 2 triệu VND
OTP qua ZNS/SMS~300–800 VND/tintheo lượng walk-inkhông đáng kể
Tổng vận hành≈ 3 – 9 triệu VND/tháng

Chưa gồm phí thuê bao sẵn có của khách: dotB, Haravan, VoIP24H, App Exam. Bảo trì từ năm 2: thông lệ 15–20% chi phí xây dựng/năm (sửa lỗi, thay đổi nhỏ, theo dõi đồng bộ) ≈ 11 – 21 triệu VND/năm.

Tóm tắt cho khách hàng Khối lượng ≈ 71 man-day (60–85) · thời gian ~2,5–3 tháng với đội 2 dev + 1 BA · chi phí xây dựng ~71 – 107 triệu VND (đơn giá blended 1–1,5 triệu/MD) · vận hành ~3–9 triệu VND/tháng license. Chưa gồm chi phí customize phía dotB (Q-49) và nhập liệu GĐ 0 (Q-30).

14.Câu hỏi mở — cần khách hàng / nhà cung cấp trả lời CHỜ CHỐT

14.0 Kết quả xác minh dotB — cập nhật 07/07/2026 ĐÃ CÓ TRẢ LỜI

dotB đã trả lời checklist xác minh (bảng Q&A của nhà cung cấp, mục 35–42). Tóm tắt và hệ quả với thiết kế:

#Câu hỏiTrả lời của dotBHệ quả với thiết kế
35Cung cấp webhook cấu hình được?CUSTOMIZE Không mở cơ chế khách tự cấu hình webhook. Tích hợp đặc thù làm dạng customize, chi phí estimate theo man-day sau khi thống nhất luồng & phạm vi. Có thể bắn 4 sự kiện: Nhận lead, Mở chat, Chốt đơn, Cập nhật sản phẩm (payload: Lead ID, Sales ID, Timestamp)Sự kiện "Chốt đơn" là ứng viên trả lời Q-27 (nguồn đơn khóa học). Cần dotB estimate — Q-49
36API tạo lead từ bên ngoài?CÓ SẴNLuồng L1 (PA-01/02) khả thi ngay, không chờ customize
37API cập nhật lead theo CusID?CHƯA CÓ — sẽ xem xét dạng customizeDataverse phải lưu dotb_lead_id (dotB trả về khi tạo — câu 41) và update theo ID đó; mapping CusID ↔ dotb_lead_id giữ ở Dataverse
38Nhận field custom (total_spend, tier, exam_status)?CÓ — CUSTOMIZE cho phép mở rộng, chi phí theo phạm viUC-2/UC-4 hiển thị được trên dotB — có phí customize (Q-49)
39Hiển thị activity timeline từ ngoài đẩy vào?CUSTOMIZE Có sẵn Change Log; Lead Activity customize được; nhận activity từ ngoài cần đánh giá sau khi thống nhất luồngUC-3 (lịch sử gọi) khả thi nhưng phụ thuộc đánh giá + phí của dotB
40Bắt buộc phone/email đầy đủ hay chấp nhận masked?RỦI RO Bắt buộc có SĐT; email để trống được. Chưa xác nhận trường SĐT có chấp nhận giá trị masked 09xx***567 khôngĐụng ràng buộc cứng masking — phải làm rõ ngay (Q-48, R-08)
41Trả về ID lead sau khi tạo? — tự sinh lead IDLưu dotb_lead_id vào Dataverse ngay khi POST thành công (khắc phục câu 37)
42Cơ chế xác thực API?OAuthPower Automate gọi HTTP + OAuth; quản lý client credentials trong tenant khách hàng
Trạng thái Q-01…Q-03 sau vòng trả lời này
  • Q-01Trả lời một phần: field custom (câu 38) và activity (câu 39) đều làm ĐƯỢC nhưng qua customize có phí, chưa có estimate. Rủi ro R-01 hạ từ "không làm được" xuống "chi phí + tiến độ phía dotB chưa xác định".
  • Q-02Chưa trả lời: tắt "1-click integration" để ép mọi data qua Power Automate — cần hỏi tiếp.
  • Q-03Chưa trả lời đủ: câu 40 mới xác nhận SĐT bắt buộc; chưa xác nhận masking hiển thị, ô ghi đè mù, cảnh báo 4 số cuối → tách thành Q-48.

14.1 Nhóm A — Xác minh nhà cung cấp (chặn build, hỏi sớm nhất)

Hỏi aiCâu hỏiẢnh hưởng nếu trả lời "Không"
Q-01dotBCó API nhận & hiển thị trường tùy chỉnh (total_spend, tier, exam_status) và activity timeline (call log) do bên ngoài đẩy vào không?UC-2/3/4 không hiển thị được trên dotB → phải dùng iframe / deep-link sang Dataverse portal (R-01)
Q-02dotBCó tắt được "1-click integration" để ép mọi data đi qua Power Automate không?Vỡ nguyên tắc SoR — dữ liệu chạy thẳng vào dotB, mất chủ quyền dữ liệu
Q-03dotBHỗ trợ masking hiển thị (09xx***567) + ô "ghi đè mù" + cảnh báo 4 số cuối như mô tả UC-1 không? Có cam kết Sale không truy được số đầy đủ qua export/API?Vỡ ràng buộc cứng "sửa không cần thấy" — điều kiện nghiệm thu
Q-04HaravanWebhook order.created/paid có trả phone + email khách để khớp CusID không?Không khớp được đơn với hồ sơ → total_spend sai
Q-05HaravanCó nhận lưu CusID (metafield) trên hồ sơ khách Haravan để khớp 1-1 chiều ngược không?Chỉ khớp qua phone/email — chấp nhận được nhưng kém chính xác hơn
Q-06VoIP24HWebhook call.ended có đủ duration_sec, voip_result, direction, who_hung_up không?Thiếu dữ liệu cho timeline + SLA engine
Q-07VoIP24HFile ghi âm lấy qua API được không, lưu ở đâu, giữ bao lâu?Không chốt được kho ghi âm riêng + retention
Q-08App ExamNhận CusID lúc ghi danh để khớp 1-1 không? Có webhook exam.completed không?Phải khớp qua phone/email → rủi ro lệch định danh học viên
Q-48dotB(Mới — từ câu 40) Trường SĐT bắt buộc của dotB có chấp nhận giá trị masked 09xx***567 không? dotB có tính năng cần số thật (click-to-call, tìm kiếm theo số, gửi SMS) không? Nếu có, cơ chế nào để các tính năng đó chạy mà Sale vẫn không thấy số đầy đủ?Nếu dotB đòi số thật → vỡ ràng buộc cứng masking (R-08) — phải thiết kế lại (ví dụ: dotB gọi qua VoIP bằng tham chiếu CusID, không hiển thị số)
Q-49dotB(Mới — từ câu 35/37/38/39) Estimate man-day + báo giá + tiến độ cho các hạng mục customize: (a) field custom total_spend/tier/exam_status; (b) nhận activity timeline từ ngoài; (c) webhook 4 sự kiện (Nhận lead, Mở chat, Chốt đơn, Cập nhật sản phẩm); (d) API cập nhật lead theo CusIDChi phí này nằm NGOÀI ước tính mục 13.3 (là chi phí trả cho dotB); tiến độ customize của dotB có thể thành đường găng mới

14.2 Nhóm B — Quyết định kinh doanh (khách hàng chốt)

Câu hỏiĐề xuất của BA
Q-09Chính sách chi tiêu cũ: phương án A (chỉ tri ân) hay B (tính nếu có bằng chứng)? (mục 8.5)Bắt đầu bằng A, mở đường lên B khi có quy trình duyệt bằng chứng
Q-18Tiêu chí "qualified" để sinh CusID chính thức là gì?Có ít nhất 1 giao dịch thanh toán HOẶC Sale xác nhận nhu cầu + đủ phone/email
Q-22Quy tắc phân bổ lead cho Sale (round-robin? theo kênh? theo khu vực)?Round-robin trong nhóm trực, ưu tiên Sale từng chăm hồ sơ đó
Q-25Ngưỡng hạng (Đồng/Bạc/Vàng/Kim cương) là chốt hay tạm? Có review định kỳ?Chốt cho go-live; cấu hình được để đổi sau, kèm quy tắc chuyển hạng
Q-26Đơn hủy / hoàn tiền có trừ total_spend và tụt hạng không?Có trừ; hạng tính lại tự động theo rollup
Q-27Đơn khóa học (source=Course) nhập từ đâu — dotB, thu ngân, hay hệ khác? Luồng này chưa có trong đặc tả gốcCần vẽ luồng riêng L2b ngay khi khách xác nhận nguồn
Q-28Hạng có hiệu lực vĩnh viễn hay theo chu kỳ (ví dụ 12 tháng gần nhất)?Vĩnh viễn cho đơn giản giai đoạn 1
Q-09b / Q-35Khách dùng 2 SĐT → 2 hồ sơ song song có chấp nhận không?Chấp nhận, chỉ merge khi có bằng chứng (OTP)
Q-38Quy trình đáp ứng Nghị định 13 (đồng ý thu thập, quyền yêu cầu xóa dữ liệu)?Thêm checkbox consent ở form; quy trình xóa/ẩn danh hóa do admin thực hiện

14.3 Nhóm C — Chi tiết kỹ thuật / vận hành (chốt trong thiết kế chi tiết)

Câu hỏi
Q-12Phạm vi dữ liệu QL Sale được xem (toàn bộ đội? chi nhánh?)
Q-13Ai được xem PII đầy đủ ở backend Dataverse? Log truy cập thế nào?
Q-14Tần suất refresh Power BI; ai được cấp quyền xem?
Q-15Dự toán license: Dataverse capacity, Power Automate premium, Power BI Pro
Q-16Thuật toán checksum + nơi lưu SecretSalt + quy trình xoay salt
Q-17Ước lượng khối lượng: số khách hiện hữu, lead/ngày, đơn/ngày, cuộc gọi/ngày
Q-19Quan hệ LeadID ↔ CusID: LeadID có lưu vết sau khi kích hoạt không?
Q-20Bổ sung trạng thái Inactive/Churned, Merged vào vòng đời hồ sơ?
Q-21Danh sách trường chuẩn của lead theo từng kênh (web/FB/Zalo/TikTok)
Q-23Lead thiếu cả phone lẫn email: từ chối hay lưu chờ bổ sung?
Q-24Đơn Haravan không khớp hồ sơ: tự tạo Customer mới hay vào review queue? Tiêu chí chọn nhánh?
Q-29Cuộc gọi đến từ số lạ: tự tạo Lead hay chỉ log?
Q-30Khảo sát dữ liệu cũ: khối lượng bản ghi, định dạng (sổ/Excel), chất lượng, ai nhập, bao lâu xong?
Q-31Retention: ghi âm giữ bao lâu? Các bảng append-only giữ vĩnh viễn?
Q-32Ngưỡng fuzzy match ở bước B3 (tên %, số cuối phone)
Q-33SLA xử lý review queue (ai, bao lâu, escalation)
Q-34Quy tắc chọn hồ sơ "sống" khi merge + cập nhật FK dữ liệu con
Q-36Ngưỡng độ trễ đồng bộ chấp nhận được (đề xuất ≤ 5 phút P95)
Q-37Cơ chế xác thực webhook từng nhà cung cấp (HMAC/secret/IP allowlist)
Q-39Nhà cung cấp OTP/ZNS, chi phí, phương án khách không dùng Zalo
Q-40…Q-43Định nghĩa chính xác các chỉ số báo cáo (mục 10)
Q-44Power BI có cần masked PII như dotB không?
Q-45Mở rộng đối soát đêm cho VoIP + App Exam?
Q-46Kênh cảnh báo lỗi tích hợp (email/Teams/Zalo) + người trực
Q-47Xác nhận toàn bộ bảng NFR đề xuất (mục 12)

15.Giả định & Rủi ro

15.1 Giả định (Assumptions)

Giả địnhNếu sai thì…
A-01Khách hàng sở hữu tenant Microsoft (Dataverse + Power Automate) đứng tên mìnhVỡ nguyên tắc chủ quyền dữ liệu; phải mua/thiết lập trước GĐ 1
A-024 nhà cung cấp (dotB, Haravan, VoIP24H, App Exam) đều có webhook/API ở mức mô tả mục 14.1Luồng tương ứng phải chuyển sang polling định kỳ hoặc phương án thay thế
A-03Mỗi khách hàng có ít nhất một trong hai: phone hoặc emailCần chính sách lead khuyết danh (Q-23)
A-04Dữ liệu 3 năm cũ có thể số hóa xong trước go-liveUC-5 chỉ chạy một phần; cần kế hoạch số hóa dần sau go-live
A-05SLA engine hiện hữu có thể đọc Call_Log từ DataverseCần adapter riêng cho SLA engine

15.2 Rủi ro (Risks)

Rủi roMứcGiảm thiểu
R-01dotB hỗ trợ trường tùy chỉnh / timeline nhưng chỉ qua customize có phí (xác nhận 07/07/2026 — mục 14.0); estimate man-day, báo giá, tiến độ phía dotB chưa có → có thể đội chi phí hoặc thành đường găng mớiTRUNG BÌNH (hạ từ CAO)Yêu cầu dotB estimate sớm (Q-49); chốt phạm vi customize trước khi ký kế hoạch; giữ phương án dự phòng iframe / deep-link Dataverse portal nếu báo giá quá cao
R-08dotB bắt buộc trường SĐT (câu 40) — nếu không chấp nhận giá trị masked hoặc có tính năng cần số thật (click-to-call, tìm kiếm) → vỡ ràng buộc cứng "masking bất biến"CAOHỏi Q-48 ngay; phương án: ghi phone_masked vào trường SĐT nếu pass validation; tính năng gọi thực hiện qua VoIP bằng tham chiếu CusID không lộ số; nghiệm thu masking là điều kiện hợp đồng (R-03)
R-02Dữ liệu cũ không số hóa kịp trước go-live → kịch bản khách cũ (UC-5) sụpCAOKhởi động GĐ 0 ngay; khảo sát khối lượng (Q-30); ưu tiên số hóa nhóm khách có khả năng quay lại cao
R-03dotB không thực thi đúng masking (lộ số qua export/API/log)CAOĐưa "sửa không cần thấy" thành tiêu chí nghiệm thu cứng; kiểm thử thâm nhập màn hình + export trước go-live
R-04Webhook rớt âm thầm → thiếu đơn/cuộc gọi, total_spend saiTRUNG BÌNHJob đối soát đêm + backfill + cảnh báo chênh lệch
R-05Chất lượng phone/email đầu vào kém → nhiều bản ghi vào review queue, quá tải SaleTRUNG BÌNHChuẩn hóa + validate ngay tại form; đo "tỷ lệ merge do sai phone" (báo cáo #6) để cải thiện theo kênh
R-06Chi phí license Power Platform vượt dự kiến khi khối lượng tăngTRUNG BÌNHDự toán theo khối lượng (Q-15, Q-17) trước GĐ 1; theo dõi consumption hàng tháng
R-07Không tuân thủ Nghị định 13/2023 về dữ liệu cá nhânTRUNG BÌNHThêm consent tại điểm thu thập; quy trình xóa/ẩn danh; rà soát pháp lý (Q-38)

16.Thuật ngữ (Glossary)

Thuật ngữNghĩa trong tài liệu này
SoR — System of RecordKho dữ liệu gốc, nguồn sự thật duy nhất (= Dataverse)
Hệ vệ tinhdotB, Haravan, VoIP24H, App Exam — đọc/ghi qua Power Automate, không giữ bản gốc
PIIThông tin định danh cá nhân (SĐT, email, họ tên…)
MaskingChe một phần PII khi hiển thị: 09xx***567, a***@gmail.com
CusIDMã khách hàng duy nhất, bất biến, có checksum, do Dataverse cấp
resolveIdentityQuy trình khớp trùng 4 bước: phone → email → fuzzy → tạo mới
Review queueHàng chờ các ca nghi trùng cần con người xác nhận
RollupTrường tính tự động từ bảng con (total_spend = Σ Order.amount)
Append-only / ImmutableChỉ thêm bản ghi mới, không sửa/xóa bản ghi cũ
WebhookHệ nguồn tự động gọi sang khi có sự kiện (đơn mới, gọi xong, thi xong)
Đối soát (reconciliation)Job định kỳ so số liệu hai hệ để phát hiện thiếu/lệch
LegacyDữ liệu thời kỳ trước khi có hệ thống (≈ 3 năm), độ tin cậy "unverified"
OTP / ZNSMã xác thực một lần gửi qua SMS/Zalo — khách tự xác nhận số điện thoại
Tier (hạng)Đồng <5tr · Bạc 5–20tr · Vàng 20–50tr · Kim cương >50tr (theo total_spend)

Tài liệu do đội kỹ thuật soạn dựa trên "Đặc tả tích hợp v1.0" của khách hàng. Các mục đánh dấu Q-xx / A-xx / R-xx là điểm cần thống nhất trong buổi làm việc kế tiếp; sau khi chốt sẽ nâng phiên bản 1.0.