Skip to content

PRD: Yêu cầu kinh doanh

ModuleKhách hàng (CORE-09)PRD IDPRD-INQ-001
StatusShippedOwnerCustomer squad
Date2026-04-06Versionv1.0
Packages@nx/outreach · @nx/coreURDINQ

TL;DR

Cho phép một khách tiềm năng gửi yêu cầu kinh doanh từ trang marketing công khai - thông tin liên hệ, thông tin doanh nghiệp, và một lời nhắn - và cung cấp cho đội sales back-office một tín hiệu theo thời gian thực ngay khi một lead xuất hiện. Mỗi inquiry được theo dõi qua vòng đời rõ ràng NEW → assigned → replied → converted/lost, nên không lead nào đến mà không được nhìn thấy và mỗi lần theo dõi đều có audit trail.

1. Context & Problem

Trang marketing Overture công khai là nơi khách tiềm năng liên hệ, nhưng một lead chỉ có giá trị nếu đội sales nhìn thấy và xử lý nó. Nếu không có đường đi thu thập-và-thông-báo có cấu trúc, các inquiry hoặc nằm im trong hộp thư hoặc buộc đội phải poll một danh sách - lead trở nên cũ, quyền sở hữu không rõ ràng, và không có ghi nhận ai đã trả lời hay inquiry được giải quyết ra sao. Khi KICKO nhắm tới các doanh nghiệp HKD/SME qua đăng ký tự phục vụ, phễu lead đầu vào phải đáng tin cậy và có trách nhiệm rõ ràng.

Feature này thu thập inquiry như một record hạng nhất trong @nx/outreach, đẩy một tín hiệu WebSocket theo thời gian thực tới admin khi gửi, và theo dõi mỗi lead qua một vòng đời được kiểm soát để sales có thể assign, trả lời, và giải quyết nó.

2. Goals & Non-Goals

Goals

  • Thu thập một inquiry từ trang công khai với thông tin liên hệ, thông tin doanh nghiệp, và một lời nhắn trong một lần gửi.
  • Thông báo cho admin theo thời gian thực qua WebSocket ngay khi một inquiry mới được gửi - không cần polling.
  • Theo dõi việc assign, trả lời, chuyển đổi, và lý do thất bại của mỗi inquiry qua một vòng đời (NEW → assigned → replied → converted/lost).

Non-Goals

  • Engine chiến dịch Email / SMS (Dự kiến - xem URD §7).
  • Phân khúc và nhắm mục tiêu khách hàng.
  • Phân tích giá trị trọn đời của inquiry / lead.

3. Success Metrics

MetricTarget / signal
Độ trễ thông báoInquiry mới hiện ra cho admin theo thời gian thực (đẩy WebSocket dưới một giây), không phải bằng polling
Độ đầy đủ khi thu thập100% lần gửi công khai được lưu với thông tin liên hệ + thông tin doanh nghiệp + lời nhắn
Trách nhiệm với leadMỗi inquiry hiển thị người được assign, tác giả/thời điểm trả lời, và một kết quả cuối
Thời gian phản hồi đầu tiênThời gian trung vị NEW → replied theo mỗi merchant có xu hướng giảm

4. Personas & Use Cases

PersonaMục tiêu trong feature này
Site Visitor (Lead)Gửi một inquiry từ trang công khai mà không cần tài khoản
SalesThấy lead mới ngay lập tức, nhận chúng, trả lời, và giải quyết là converted hoặc lost
Owner / AdminTheo dõi lượng lead đầu vào và đảm bảo không inquiry nào bị bỏ sót

Core scenarios: một visitor gửi một inquiry → nó được lưu là NEW và admin được thông báo theo thời gian thực → một sales rep assign nó cho chính mình → trả lời (ghi nhận tác giả + thời điểm) → đánh dấu converted hoặc lost kèm lý do.

5. User Stories

  • Là một site visitor, tôi muốn gửi một inquiry với thông tin liên hệ và thông tin doanh nghiệp của mình kèm một lời nhắn, để doanh nghiệp có thể theo dõi với tôi.
  • Là một sales rep, tôi muốn được thông báo theo thời gian thực khi một inquiry mới đến, để tôi có thể phản hồi nhanh mà không cần poll một danh sách.
  • Là một sales rep, tôi muốn assign một inquiry cho chính mình, để quyền sở hữu rõ ràng.
  • Là một sales rep, tôi muốn trả lời một inquiry và có lần trả lời cùng thời điểm của tôi được ghi nhận, để việc theo dõi có thể kiểm tra được.
  • Là một sales rep, tôi muốn đánh dấu một inquiry là converted hoặc lost (kèm lý do), để kết quả của lead được ghi lại.

6. Functional Requirements

#RequirementURD ref
FR-1Thu thập một inquiry từ endpoint gửi công khai với thông tin liên hệ, thông tin doanh nghiệp, và lời nhắn; inquiry mới bắt đầu ở status NEWURD-INQ-001
FR-2Khi gửi, phát ra một thông báo WebSocket theo thời gian thực tới admin mang theo id của inquiry, type, tên, email, tên doanh nghiệp, subject, và thời điểm tạoURD-INQ-002
FR-3Thông báo được publish lên topic INQUIRY_SUBMITTED, fan-out tới một room cấp-toàn-bộ và một room theo từng inquiryId để có thể nhắm tới một inquiry cụ thểURD-INQ-002
FR-4Theo dõi việc assign, trả lời (tác giả + thời điểm), chuyển đổi, và lý do thất bại của một inquiryURD-INQ-003
FR-5Đưa một inquiry qua vòng đời NEW → assigned → replied → converted/lostURD-INQ-004
FR-6Quản lý inquiry qua CRUD (find / find-by-id / count / create / update / delete), mỗi cái được gate bởi một resource InquiryPermissions.*URD-INQ-003..004

Toàn bộ nội dung requirement và tiêu chí chấp nhận nằm trong Customer URD. PRD này tham chiếu tới chúng thay vì lặp lại.

7. Non-Functional Requirements

AreaRequirement
Phân phối thời gian thựcWebSocket emitter được Redis hậu thuẫn và chạy ở chế độ single hoặc cluster từ env; thông báo fan-out qua các instance
Suy giảm nhẹ nhàngNếu socket service chưa sẵn sàng, lần gửi vẫn lưu inquiry và thông báo no-op kèm một cảnh báo - việc thu thập không bao giờ thất bại do đường đi thông báo
Tenancy & authzCác endpoint quản lý inquiry được scope theo merchant (x-merchant-id) và gate bởi InquiryPermissions; lần gửi công khai không cần xác thực
Data integrityMọi record inquiry dùng soft-delete, giữ lại lịch sử lead
i18nNhãn/status hướng tới người dùng là song ngữ ({ en, vi })

8. UX & Flows

Các màn hình chính: form inquiry công khai nằm trên trang marketing Overture; danh sách inquiry back-office, chi tiết, và các điều khiển vòng đời (kèm badge/toast báo có lead mới theo thời gian thực) nằm trong apps/client.

9. Data & Domain

EntityVai trò
InquiryRecord lead - thông tin liên hệ, thông tin doanh nghiệp, lời nhắn, type, status, người được assign, lần trả lời, và kết quả (lý do converted/lost)
WebSocket topic / roomTopic INQUIRY_SUBMITTED (observation/outreach/inquiry/submitted); một room collection cộng với một room theo từng inquiryId để phân phối có nhắm mục tiêu

Chỉ ở mức khái niệm - schema đầy đủ và các bất biến nằm trong Outreach domain model.

10. Dependencies & Assumptions

Phụ thuộc vào

  • @nx/outreach - sở hữu record inquiry, vòng đời CRUD, và WebSocket component.
  • @nx/core - schema.ts / model.ts inquiry dùng chung và các primitive base WebSocket emitter / socket-event.
  • Redis - hậu thuẫn WebSocket emitter cho việc fan-out xuyên instance.

Giả định

  • Trang Overture công khai render form inquiry và post tới endpoint gửi.
  • Một subscriber phía client (badge sidebar / toast thời gian thực) trong apps/client tiêu thụ thông báo.
  • Việc gửi email (SMTP) nằm ngoài phạm vi module này; việc theo dõi diễn ra qua vòng đời, không qua feature này.

11. Risks & Open Questions

Risk / câu hỏiGiảm thiểu / trạng thái
Socket service ngừng → admin bỏ lỡ thông báoLần gửi vẫn lưu; thông báo no-op kèm cảnh báo, nên inquiry không bao giờ bị mất - admin vẫn thấy nó trong danh sách
Fan-out thông báo qua các instanceEmitter Redis-hậu-thuẫn ở chế độ cluster xử lý phân phối đa-instance
Spam / lạm dụng lead trên một endpoint công khaiMở: cân nhắc rate-limiting / captcha trên lần gửi công khai
Không có kênh theo dõi emailNgoài phạm vi; engine chiến dịch là Dự kiến trong URD

12. Release Plan & Launch Criteria

AspectPlan
PhaseP2 - xem URD feature catalog (INQ)
RolloutTất cả merchant; không feature flag
MigrationKhông (các trường schema/model inquiry được thêm trong @nx/core)
Launch criteriaLần gửi công khai lưu một inquiry NEW; admin nhận thông báo thời gian thực đầu-cuối; vòng đời assign → reply → converted/lost được kiểm chứng
MonitoringLượng inquiry theo merchant, tỷ lệ gửi thông báo thành công/thất bại, thời gian NEW → replied

13. FAQ

Admin có phải refresh để thấy inquiry mới không? Không - một thông báo WebSocket được đẩy khi gửi, nên một lead mới hiện ra theo thời gian thực.

Điều gì xảy ra nếu WebSocket service ngừng khi một inquiry được gửi? Inquiry vẫn được lưu; thông báo bị bỏ qua kèm một cảnh báo. Admin vẫn thấy nó trong danh sách inquiry - việc thu thập không bao giờ phụ thuộc vào đường đi thông báo.

Một visitor có thể gửi inquiry mà không có tài khoản không? Có - endpoint gửi công khai không cần xác thực. Việc quản lý inquiry (find/assign/reply/resolve) cần xác thực và được gate bởi permission.

Gửi một inquiry có gửi email cho lead không? Không - không có kênh email/SMS trong module này. Việc theo dõi được ghi nhận qua vòng đời inquiry.

Các status của inquiry là gì? NEW → assigned → replied → converted/lost, kèm một lý do lost được ghi nhận khi áp dụng.

References

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.