Appearance
Tóm tắt quyết định (Decision Brief) — Tích hợp Pancake CRM (Pancake CRM Integration)
Phiên bản: 1.0 Ngày: 15/05/2026 Độ phức tạp: L (Lớn) Module: webhook, crm-api, notification-v2-api, FE crm + settingsTrạng thái package: Bản nháp — sẵn sàng review
Mục đích: Cửa vào full package — PO/Sếp/Tech Lead/Delivery đọc 5 phút nắm phạm vi, quyết định lớn, ảnh hưởng, rủi ro. Canonical: nếu brief xung đột với
SOURCE_OF_TRUTH.md, ưu tiênSOURCE_OF_TRUTH.md.
Đầu vào chuẩn (Canonical Inputs)
| File | Vai trò |
|---|---|
SOURCE_OF_TRUTH.md | Nguồn sự thật chuẩn + Solution Lock (25 DEC) |
EVIDENCE_PACK.md | Bằng chứng từ Phase 3 (4 Explore subagents) |
prd.md / ui-spec.md / dev-spec.md / qa-test-plan.md / handoff.md / go-live-checklist.md | File owner |
1) Tóm tắt 5 phút
- Vấn đề: Manager đang copy-paste thủ công 50-200 lead/ngày từ Pancake CRM (40+ kênh) sang Diva CRM. Telesale mất window vàng 30 phút, KPI conversion không đo realtime, ~2h/ngày manager loss.
- Giải pháp MVP-1 (inbound 1 chiều): Pancake gửi webhook
record→ Diva auto match phone E.164 → tạo/cập nhật khách → tạo ticket → auto-assign telesale theo round-robin chi nhánh REUSEticket_distributecó sẵn → notify realtime. - Production-ready: 4-layer outage recovery (webhook + adaptive polling + daily reconciliation + DLQ replay) để đảm bảo zero-miss SLO = 0 events/ngày. Pancake suspension prevention bằng fail-open 200 mọi case + idempotency 3-tuple.
- Effort & timeline: ~37 dev-days, calendar 5.5-6 tuần (2 BE + 1 FE + 1 QA). Pilot 4 tuần (W1 = 1 source → W4 = 40+ all).
- Rủi ro lớn nhất: Pancake auto-suspend webhook nếu 80% error / 30 phút → mất lead toàn bộ. Đã mitigate bằng DEC-003 fail-open + DEC-015 4-layer recovery.
2) Bản đồ package
| File | Đọc khi cần | Phụ trách |
|---|---|---|
SOURCE_OF_TRUTH.md | Đối chiếu canonical truth / conflict | PO/BA + TL |
EVIDENCE_PACK.md | Xem bằng chứng code/screen/db Phase 3 | PO/BA + TL |
prd.md | Duyệt nghiệp vụ, DEC, FR/AC (10 FR), công thức | PO/BA |
ui-spec.md | Thiết kế 4 tabs Pancake Settings + delta dropdown source | UI/UX + FE |
dev-spec.md | Schema 4 bảng mới + ALTER 2 bảng + 7 cron + flow 15 step | TL + BE/FE |
qa-test-plan.md | Test plan, oracle, chaos test outage + duplicate | QA |
handoff.md | RACI, timeline 6 tuần, blocker, thứ tự việc | Delivery + TL |
go-live-checklist.md | Pilot W1-W4 gates, rollback, monitoring | Ops + TL |
3) Khóa phạm vi
Trong phạm vi (MVP-1)
| # | Nội dung | Ref |
|---|---|---|
| 1 | Inbound webhook POST /api/pancake/record/{token} — fail-open 200, idempotency 3-tuple | prd.md FR-001/FR-002/FR-003 |
| 2 | Phone E.164 normalize (libphonenumber reuse) + advisory lock per phone chống race | FR-005/FR-006 |
| 3 | Match account, smart update Q2.b (chỉ tạo ticket khi phone/source/VIP-tag đổi) | FR-005/FR-009 |
| 4 | Auto-assign REUSE ticket_distribute round-robin 1-tier per branch | FR-008 |
| 5 | Ticket source mới ticket_source_pancake (slot 9) + FE delta 3 file | FR-010/FR-018 |
| 6 | Settings UI 4 tabs (kết nối + map source→branch + audit/DLQ + health) | FR-012 |
| 7 | 4-layer outage recovery + DLQ replay UI | FR-014/P1.2 |
| 8 | Compliance opt-out qua customer_consent.consent_data.marketing | FR-017 |
| 9 | Pilot 4 tuần với 3 mức feature flag (kill switch + connection status + per-source toggle) | FR-015 |
| 10 | Notify telesale realtime + admin alert Loose mode (branch=NULL) | FR-011/FR-024 |
Ngoài phạm vi
| # | Mục | Lý do | Ref |
|---|---|---|---|
| 1 | Outbound Diva → Pancake (POST records/tickets) | Defer MVP-2 — ROI chưa đủ | prd.md A2 |
| 2 | Pancake POS, Pancake Botcake, Pancake ticket event | Sản phẩm khác / chưa publish | A2 |
| 3 | Multi-workspace, multi-tenant | Diva chỉ có 1 workspace Pancake | A2 |
| 4 | Tag mapping table riêng | DEC-008 dùng tag NAME input tay | A2 |
| 5 | Shopee/TikTok/Lazada tích hợp | Pattern code extendable, scope MVP-2+ | A2 |
| 6 | Geo address normalize | Chỉ lưu raw text trong pancake_metadata | A2 |
| 7 | Real-time analytics dashboard | M2/M3 — query trực tiếp ticket+event đủ | A2 |
4) Quyết định đã khóa (top 10 trong tổng 25 DEC)
| Quyết định | Ý nghĩa | Ref |
|---|---|---|
| DEC-001: Inbound 1 chiều MVP-1, outbound defer MVP-2 | Chốt scope rõ ràng, tránh creep | prd.md Z |
| DEC-002: Split webhook + crm-api qua Hasura event trigger | Tránh Pancake suspension (return 200 < 1s); reuse pattern Stringee | Z |
| DEC-003: Fail-open trả 200 mọi case | Tránh ramp-up error rate → 80%/30 phút suspend | Z |
DEC-006: ALTER contact_book ADD primary_phone + FK + UNIQUE | Fix design doc claim sai (column chưa exist) | Z + SOURCE_OF_TRUTH |
DEC-007: 4 bảng Pancake mới dùng disabled BOOLEAN (Diva pattern), KHÔNG deleted_at | Đồng nhất với toàn bộ Diva DB | Z |
| DEC-008: VIP tag matching theo NAME (text) case-insensitive, admin input tay | Đơn giản hơn fetch tag list từ Pancake API | Z |
DEC-011: Smart update Q2.b — chỉ tạo ticket khi phone/source/VIP-tag đổi | Tránh spam ticket trùng cho khách Pancake update liên tục | Z |
DEC-012: REUSE ticket_distribute.GetTicketUpdates round-robin | Tiết kiệm -1.5d, đồng nhất logic phân công | Z |
DEC-014: Opt-out qua customer_consent.consent_data->'marketing', KHÔNG thêm column do_not_contact | Reuse table có sẵn | Z |
| DEC-015: 4-layer outage recovery (webhook + adaptive polling + reconciliation + DLQ) | Đảm bảo zero-miss SLO | Z |
15 DEC còn lại (technical details, infrastructure choices, UI specifics) — xem
prd.mdZ hoặcSOURCE_OF_TRUTH.md§1.
5) Bản đồ ảnh hưởng
| Khu vực | Reuse/Extend/Build mới | Điều cần chú ý | Ref |
|---|---|---|---|
| UI dropdown ticket source | ✅ Reuse (auto-render từ array) | 3 file delta: types.ts + i18n/vi.ts + sourceDescriptions (Tickets.tsx) | ui-spec.md B0 |
| UI Settings Pancake | 🆕 Build mới 4 tabs + 1 container page | Pattern XDetailLayout reuse từ AppSettingsSmsTemplate.tsx | ui-spec.md SCR-01..05 |
| Backend webhook receiver | 🔧 Extend services/webhook | Add pancake.go handler, HMAC + IP middleware mới | dev-spec.md C5 |
| Backend event handler | 🆕 Build mới event_pancake_process_record.go 15-step | Reuse Hasura event trigger pattern + GetTicketUpdates helper | dev-spec.md C5 |
| Backend cron | 🔧 Extend (pattern reuse) | 7 cron mới pancake_* | dev-spec.md C6 |
| Backend REST client | 🆕 Build mới pkg/pancake/client.go + circuit breaker sony/gobreaker | Chỉ GET /sources MVP-1 | dev-spec.md C5 |
| Database | 🔧 Extend account, contact_book + 🆕 4 bảng pancake_* + INSERT 1 master data | Latest migration ts 1777870069927 → mới 1777870069928+ | dev-spec.md C4/C7 |
| Permission | 🔧 Extend module_permission_action + 🆕 module pancake_crm_integration 6 actions | Default seed Admin; Dynamic Permission override sau | dev-spec.md C8 |
| Notification | 🆕 Build 3 template mới (noti_ticket_assigned_pancake, noti_pancake_unmapped_branch, noti_pancake_outage) | ✅ Reuse notification-v2-api dispatch | dev-spec.md C5 STEP 13 |
| QA / Regression | Full FR coverage + chaos test outage + duplicate stress | Pilot 4 tuần chia regression theo wave | qa-test-plan.md D1 |
6) Rủi ro và blocker
| Mức | Rủi ro / blocker | Phụ trách | Cách xử lý | Ref |
|---|---|---|---|---|
| Cao | Pancake auto-suspend webhook (80% error / 30 phút) | BE + Ops | DEC-003 fail-open 200 + DEC-015 4-layer recovery + monitoring alert 1 phút | prd.md A7 RSK-001 |
| Cao | HMAC signature/IP whitelist chưa verify với Pancake support | Ops | PD-001/002 — out-of-band gọi 0972273341 trước W4 launch | handoff.md blocker |
| Cao | Race condition tạo account trùng khi 2 webhook đồng thời cùng phone | BE | DEC-020 pg_advisory_xact_lock per phone | A7 RSK-002 |
| Trung bình | Pancake outage = mất lead | BE + Ops | Cron 6 adaptive polling fallback + Cron 7 daily reconciliation | A7 RSK-003 |
| Trung bình | Branch=NULL ticket bị bỏ quên | PO + Manager | DEC-010 push admin in-app + Tab 3 audit log filter | A7 RSK-004 |
| Trung bình | FE delta hardcode source slot ngoài TicketSources (report module) | FE | F18 estimate +0.5d sau grep audit | A7 RSK-005 |
| Trung bình | customer_consent.consent_data.marketing key chưa confirm | PO + BE | PD-003 confirm trước Phase 4 SPECIFY | A7 RSK-006 |
| Trung bình | DLQ + Replay UI scope mới (3d) — chưa có pattern | BE + FE | Build mới theo design doc P1.2 spec | A7 RSK-007 |
| Thấp | KPI baseline manual workflow chưa đo | PO + Manager | PD-011 — 1 tuần đo trước W1 | A7 RSK-008 |
| Thấp | Pancake retry policy/rate limit chưa biết | QA | PD-005/006 — test W1 với webhook.site | Non-block |
7) Tóm tắt bàn giao
| Nhóm | Việc chính | File cần đọc |
|---|---|---|
| PO/BA | Confirm 12 PD (đặc biệt PD-001/002/003), chốt VIP tag list, đo KPI baseline | decision-brief.md, prd.md Z + A5 + A10 |
| Tech Lead | Review schema 4 bảng + migration order + permission model | decision-brief.md, prd.md Z, dev-spec.md C1-C5 |
| BE Dev | Webhook handler + event processor 15-step + 7 cron + REST client + advisory lock | dev-spec.md C1-C12 |
| FE Dev | 4 tab Settings UI + dropdown delta + permission menu hide | ui-spec.md SCR-01..05, dev-spec.md C2 |
| QA | E2E test pilot 4 wave + chaos test outage + duplicate stress + load 100k/tháng | qa-test-plan.md D1-D5 |
| Ops | PD-001/002 với Pancake support, setup monitoring + Grafana board | go-live-checklist.md E1-E2, handoff.md out-of-band §14 |
| DevOps | Deploy webhook public endpoint + scale crm-api horizontally + alertmanager rules | dev-spec.md C10, go-live-checklist.md E2 |
8) Điểm còn mở (12 PD)
Block phân theo mức: Launch-blocker = phải resolve trước W4 production. Phase-blocker = block phase tiếp theo. Non-block = parallel ok.
| ID | Câu hỏi | Phụ trách | Hạn | Block | Mặc định tạm |
|---|---|---|---|---|---|
| PD-001 | Pancake webhook HMAC signature header tên gì | Ops | Trước 25/06/2026 (W4) | Launch | Trust IP+URL token W1-W3 |
| PD-002 | Pancake IP whitelist range | Ops + Dev | Trước 25/06/2026 | Launch | Capture từ logs W1 |
| PD-003 | customer_consent.consent_data key opt-out (marketing?) | BE + PO | Trước Phase 4 SPECIFY (~22/05/2026) | Phase-FR-017 | Default marketing |
| PD-004 | VIP tag IDs initial seed | PO | Trước 04/06/2026 (W2) | Non-block | VIP, Hot Lead, Khách lớn, Khách quay lại |
| PD-005 | Pancake retry policy chi tiết | QA | W1 test (28/05-04/06) | Non-block | Assume exponential 5 retries |
| PD-006 | Pancake REST /sources rate limit | QA | W1 test | Non-block | Cache 1h, throttle 429 |
| PD-008 | Pilot 4 tuần exact source list | PO + Marketing | Trước 28/05/2026 (W1) | Non-block | PO chọn theo volume |
| PD-009 | Hasura concurrency: 1 cron supported? | TL | Phase 4 SPECIFY | Non-block | Fallback advisory lock |
| PD-011 | KPI baseline manual workflow (response time hiện tại) | PO + Manager | Trước W1 | KPI-measurement | Đo 1 tuần |
| PD-012 | Notification noti_pancake_outage kênh nào | PO | Trước W1 | Non-block | DEC-010 default push admin |
2 PD không block: PD-007 (Pancake
ticketevent publish?) + PD-010 (Pancake public API roadmap) — monitor quarterly.
Sẵn sàng review v1.0 — Phase 5.2 Multi-Perspective Review đã hoàn thành. Xem v1.1 Pass 1 Resolutions bên dưới.
9) Pass 1 Resolutions v1.1 (Phase 5.2 outcome)
Date: 15/05/2026 | Reviewers: PO/BA + Tech Lead + QA/DevOps + FE/UX
9.1) Verdict tổng hợp
| Reviewer | Verdict | P0 |
|---|---|---|
| PO/BA | Approve-with-conditions | 4 |
| Tech Lead | BLOCK | 5 (architecture mismatch) |
| QA + DevOps | Approve-with-conditions | 9 |
| FE + UI/UX | Approve-with-conditions | 4 |
Tổng: 22 P0 critical issues consolidated → Pass 1 fixes applied.
9.2) New decisions chốt (DEC-026..028)
| DEC | Quyết định | Lý do |
|---|---|---|
| DEC-026 | Slot 9 "Pancake CRM" hiển thị trong filter Customer-Service report + Telesales report (auto-render) | KPI revenue/conversion per source PHẢI include ticket Pancake |
| DEC-027 | Permission replay_dlq REUSE update action (không add new action) | Tránh đụng 5 chỗ shared infra. M2 add granular nếu cần |
| DEC-028 | Pancake handler dùng direct pgxpool.Pool (bypass Hasura cho 15-step flow) | Hasura GraphQL không support BeginTx + pg_advisory_xact_lock + FOR UPDATE. Option A đơn giản nhất |
9.3) DEC-006 revised v1.1
contact_book.primary_phone ĐÃ TỒN TẠI (migration 1693889973118). Migration #3 chỉ ADD UNIQUE (account_id), KHÔNG ADD COLUMN, KHÔNG ADD FK.
9.4) New PDs
| PD | Block | Owner | Hạn |
|---|---|---|---|
PD-013 ticket.first_response_at exist? | Block-KPI-measure (FORMULA-002) | BE+PO | 22/05/2026 |
PD-014 Pancake /records?modified_since endpoint verify | Block-Cron-7 | Ops+QA | W1 |
9.5) Severity sync 3 file
| PD | decision-brief cũ | handoff cũ | Mới (consistent 3 file) |
|---|---|---|---|
| PD-003 | Phase-block | Phase 4 SPECIFY | Phase-block + audit data coverage |
| PD-008 | Non-block | W1 setup | Block-W1-start |
| PD-011 | Non-block | Block-pilot-start | Block-pilot-start |
9.6) Effort impact
| Item | Δ |
|---|---|
| DEC-028 pgxpool foundation | +2d BE |
| Component build (XJsonViewer + XMetricCard) | +2d FE |
| QA P0 conditions | +2d QA |
| DevOps explicit allocation | +3d (chưa có trong v1.0) |
| Various P1 | +0.25d |
| Total | +9.25d → ~46d (vs 37d cũ) |
| Calendar | 6 tuần (tight) — vẫn fit |
9.7) Document hierarchy mới
decision-brief.md (cửa vào — file này)
├── REVIEW_REPORT.md (Pass 1 outcome tổng hợp 4 reviewer)
├── SOURCE_OF_TRUTH.md §10 (canonical truth — DEC-006 revised + DEC-026..028)
├── EVIDENCE_PACK.md §11 (Pass 1 corrections: contact_book truth + architecture verified)
├── prd.md Z' v1.1 (Decision Log canonical)
├── dev-spec.md C13 (architecture Option A pgxpool)
├── ui-spec.md (pending B-Resolutions)
├── qa-test-plan.md D7 (11 new TC + DS-002 v2)
├── handoff.md §9 (RACI + +9.25d effort)
└── go-live-checklist.md E7 (3 alert rules + HMAC spec + step split)9.8) Phase 6 + Phase 7 next steps
- ✅ Phase 5.2 Multi-Perspective Review done
- ✅ Phase 5.3 Pass 1 fixes applied (9/9 file updates)
- ⏳ Phase 5.3 lint re-run (verify 0 ERROR maintained)
- ⏳ Phase 6 finalize sign-off
- ⏳ Phase 7
/publish-doc pancake-crm-integration+ git push dva-doc GitHub