Bỏ qua

User Story 02: Chức năng Cung cấp Thông tin Khuyến mãi

Mã tài liệu: US-02 Phiên bản: 1.0
Epic: Trải nghiệm Người dùng tại Booth Người tạo: Stephen
Ngày hiệu lực: 13/09/2025 Người phê duyệt: Stephen

1. User Story

Với vai trò là một người mua sắm, Tôi muốn hỏi về các chương trình khuyến mãi đang diễn ra tại địa điểm này, Để tôi không bỏ lỡ các ưu đãi và có thể đưa ra quyết định mua sắm tốt hơn.

2. Mô tả (Description)

Sau tính năng "Chỉ đường", đây là user story quan trọng thứ hai, trực tiếp biến AI Booth từ một công cụ cung cấp thông tin thành một công cụ hỗ trợ bán hàng và marketing. Tính năng này mang lại giá trị thương mại rõ ràng cho các Tenant, khuyến khích họ cập nhật nội dung thường xuyên và là một minh chứng cho ROI (Lợi tức Đầu tư) của sản phẩm.

3. Tiêu chí Chấp nhận (Acceptance Criteria - AC)

  • AC1: Khi người dùng hỏi một câu chung về khuyến mãi (ví dụ: "Có giảm giá gì không?"), hệ thống phải trả lời bằng giọng nói và hiển thị danh sách các chương trình khuyến mãi nổi bật đang diễn ra.
  • AC2: Khi người dùng hỏi về khuyến mãi của một cửa hàng cụ thể (ví dụ: "Adidas có khuyến mãi gì không?"), hệ thống phải trả về thông tin khuyến mãi của riêng cửa hàng đó (nếu có).
  • AC3: Mỗi thông tin khuyến mãi được hiển thị phải bao gồm các chi tiết cơ bản: Tên chương trình, cửa hàng áp dụng, mô tả ngắn và thời hạn hiệu lực.
  • AC4: Giao diện hiển thị phải trực quan, có thể dưới dạng các "thẻ" (cards), mỗi thẻ đi kèm hình ảnh bắt mắt (nếu được cung cấp).
  • AC5: Nếu không có chương trình khuyến mãi nào, hoặc cửa hàng được hỏi không có khuyến mãi, AI phải phản hồi một cách lịch sự, ví dụ: "Hiện tại tôi chưa có thông tin khuyến mãi nào. Bạn có thể quay lại sau nhé."
  • AC6 (Quy tắc Toàn cục): Nếu không có bất kỳ tương tác nào trong vòng 15 giây, hệ thống phải tự động quay trở về màn hình chờ mặc định.

4. Luồng Tương tác (Interaction Flow - "Happy Path")

  1. Bắt đầu: Người dùng tiếp cận Booth và được Avatar chào hỏi.
  2. Ra lệnh: Người dùng hỏi: "Ở đây có chương trình ưu đãi nào hấp dẫn không?". Giao diện chuyển sang trạng thái "Đang lắng nghe".
  3. Xử lý: Hệ thống ghi nhận, xử lý và gửi yêu cầu lên backend. Giao diện hiển thị trạng thái "Đang suy nghĩ".
  4. Phản hồi: Hệ thống trả về kết quả.
    • Giọng nói: "Dạ, hiện đang có một số ưu đãi đặc biệt ạ. Nổi bật có chương trình 'Mua 2 tặng 1' tại cửa hàng ABC..."
    • Hình ảnh: Màn hình hiển thị một danh sách các thẻ khuyến mãi. Mỗi thẻ có hình ảnh, tiêu đề và mô tả ngắn.
  5. Tương tác: Người dùng có thể cuộn (scroll) để xem hết danh sách và chạm vào một thẻ cụ thể để xem chi tiết (chi tiết sẽ là một user story khác).
  6. Kết thúc: Người dùng rời đi. Sau 15 giây, màn hình tự động quay về trạng thái chờ.

5. Thiết kế & Giao diện Người dùng (UX/UI Design)

  • Toàn bộ thiết kế phải tuân thủ nghiêm ngặt "Tiêu chuẩn Thiết kế UX/UI cho EZD AI Booth v1.0".
  • Link tới Figma: [Link đến file Figma chứa thiết kế chi tiết cho luồng này]
  • Các trạng thái màn hình chính cần thiết kế:
    • Result State (Promotion View): Trạng thái hiển thị danh sách các thẻ khuyến mãi. Cần thiết kế chi tiết cho component "Promotion Card".

6. Phân tích Kỹ thuật & Hợp đồng API (Technical & API Contract)

  • Các thành phần liên quan:
    • Frontend: Tương tự US-01, nhưng UI Application cần có component mới để render danh sách khuyến mãi.
    • Backend: Tương tự US-01, nhưng InteractionProcessingService sẽ có thêm logic để truy vấn dữ liệu khuyến mãi từ CMS (Content Management System) do Tenant quản lý.
  • Hợp đồng API (API Contract):
    • Endpoint: POST /v1/ezd/interactions/query (Dùng chung endpoint, backend sẽ dựa vào NLP để phân loại intent).
    • Request Body (Booth gửi lên):
      {
        "booth_id": "string",
        "session_id": "string",
        "input_text": "string" 
      }
      
    • Success Response (Backend trả về - 200 OK):
      {
        "speech_text": "string",
        "display_type": "promotion_list",
        "promotion_data": [
          {
            "promotion_id": "string",
            "title": "string",
            "store_name": "string",
            "end_date": "YYYY-MM-DD",
            "image_url": "string",
            "short_description": "string"
          }
        ]
      }
      
    • Error Responses (Backend trả về):
      • 404 Not Found: {"error_code": "PROMOTION_NOT_FOUND", "speech_text": "..."} (Áp dụng khi không tìm thấy bất kỳ khuyến mãi nào).

7. Các Yếu tố Phụ thuộc (Dependencies)

  • Hệ thống Quản lý Nội dung (CMS): Đây là yếu tố phụ thuộc quan trọng nhất. Phải có một giao diện trên Tenant Dashboard cho phép Tenant có thể tự nhập liệu, quản lý và cập nhật thông tin khuyến mãi (tên, mô tả, ngày bắt đầu/kết thúc, hình ảnh...).
  • Dữ liệu: Tenant phải cung cấp một bộ dữ liệu khuyến mãi ban đầu để đội ngũ có thể tiến hành kiểm thử.

8. Thước đo Thành công (Success Metrics)

  • Tỷ lệ Hoàn thành Tác vụ: > 90% các câu hỏi về khuyến mãi được trả lời thành công (hiển thị danh sách hoặc thông báo không có).
  • Tỷ lệ Tương tác (Engagement Rate): % người dùng có thực hiện hành động cuộn hoặc chạm vào các thẻ khuyến mãi sau khi chúng được hiển thị.
  • Tần suất Cập nhật của Tenant: Theo dõi số lần các Tenant đăng nhập và cập nhật thông tin khuyến mãi qua CMS mỗi tháng.

Chắc chắn rồi. Dựa trên tài liệu us-02.md, chúng ta sẽ xây dựng một sơ đồ luồng nghiệp vụ (business flow) để trực quan hóa hành trình của người dùng khi họ hỏi về thông tin khuyến mãi.

Sơ đồ này sẽ thể hiện rõ các bước xử lý, các điểm quyết định và các kết quả có thể xảy ra, giúp cả team hiểu rõ về mặt nghiệp vụ của tính năng này.

9. Business Flow

flowchart TD
    %% --- Định nghĩa Style cho các khối để dễ đọc hơn ---
    classDef startEnd fill:#2DA44E,stroke:#fff,color:#fff,font-weight:bold,shape:stadium
    classDef process fill:#161B22,stroke:#0A74DA,color:#F0F6FC
    classDef decision fill:#D18A06,stroke:#fff,color:#0D1117,shape:diamond
    classDef userIo fill:#0A74DA,stroke:#fff,color:#fff,shape:parallelogram

    %% --- Bắt đầu Luồng ---
    Start([Bắt đầu: Người dùng<br>tiếp cận Booth]):::startEnd
    Start --> UserAsks["Người dùng hỏi về khuyến mãi<br>(chung hoặc cho cửa hàng cụ thể)"]:::userIo

    %% --- Xử lý Yêu cầu ---
    UserAsks --> SystemProcesses["<b>Hệ thống xử lý:</b><br>1. Speech-to-Text<br>2. NLP (Phân tích intent 'find_promotion')<br>3. Truy vấn CMS/CSDL về khuyến mãi"]:::process
    SystemProcesses --> FoundDecision{Tìm thấy chương trình<br>khuyến mãi phù hợp?}:::decision

    %% --- Nhánh Thành công (Happy Path) ---
    FoundDecision -- "Có" --> PrepareResponse["<b>Hệ thống chuẩn bị phản hồi:</b><br>- Tạo câu trả lời giọng nói<br>- Lấy dữ liệu các thẻ khuyến mãi<br>(hình ảnh, text, ngày hết hạn...)"]:::process
    PrepareResponse --> DisplaySuccess["<b>Hiển thị Kết quả:</b><br>- Avatar nói về các ưu đãi<br>- Hiển thị danh sách các thẻ<br>khuyến mãi trực quan"]:::userIo

    %% --- Nhánh Thất bại (Error Path) ---
    FoundDecision -- "Không" --> DisplayError["<b>Phản hồi Lịch sự:</b><br>'Xin lỗi, hiện tại tôi chưa có<br>thông tin khuyến mãi nào...'"]:::userIo

    %% --- Vòng lặp Tương tác & Kết thúc ---
    DisplaySuccess --> InteractionLoop{Chờ tương tác tiếp theo...}:::decision
    DisplayError --> InteractionLoop

    InteractionLoop -- "Người dùng hỏi tiếp" --> UserAsks
    InteractionLoop -- "Timeout sau 15 giây" --> ResetState["Reset Booth<br>về màn hình chờ mặc định"]:::process
    ResetState --> End([Kết thúc Phiên]):::startEnd

Diễn giải Sơ đồ:

  1. Bắt đầu: Luồng được khởi tạo khi người dùng hỏi một câu liên quan đến khuyến mãi.
  2. Hệ thống xử lý: Backend thực hiện các bước cần thiết, đặc biệt là truy vấn vào hệ thống quản lý nội dung (CMS) để tìm kiếm các chương trình khuyến mãi hợp lệ.
  3. Điểm Quyết định: Hệ thống kiểm tra xem có tìm thấy bất kỳ chương trình khuyến mãi nào khớp với yêu cầu của người dùng hay không.
  4. Nhánh Thành công (Happy Path): Nếu "Có", hệ thống sẽ chuẩn bị một phản hồi đa phương tiện, bao gồm cả giọng nói và một danh sách các thẻ khuyến mãi trực quan trên màn hình, đúng như mô tả trong AC1, AC2, AC3, AC4.
  5. Nhánh Thất bại: Nếu "Không", hệ thống sẽ đi theo luồng xử lý lỗi, thông báo cho người dùng một cách lịch sự rằng không có thông tin, đúng như AC5.
  6. Vòng lặp & Kết thúc: Tương tự như luồng trước, sau khi phản hồi, hệ thống sẽ chờ đợi hành động tiếp theo từ người dùng. Nếu người dùng hỏi tiếp, luồng sẽ quay lại. Nếu không, bộ đếm thời gian 15 giây sẽ kích hoạt và reset booth về trạng thái ban đầu.

Ghi chú của Kiến trúc sư (Architect's Note): Sự thành công của user story này phụ thuộc rất nhiều vào CMS phía backend. Giao diện cho Tenant nhập liệu phải cực kỳ đơn giản và trực quan. Về phía API, display_type là chìa khóa để frontend biết cần phải render giao diện bản đồ (từ US-01) hay giao diện danh sách khuyến mãi. Điều này một lần nữa khẳng định tầm quan trọng của việc tuân thủ "Hợp đồng API".