Skip to content

PRD: Kênh bán

ModuleCommerce (CORE-03)PRD IDPRD-SC-001
StatusShippedOwnerCommerce squad
Date2026-06-01Versionv1.0
Packages@nx/commerce · apps/bo · apps/clientURDSC

TL;DR

Cho phép một merchant bán qua một hoặc nhiều kênh bán (dine-in, takeout, delivery), được tạo tự động khi onboarding và sau đó quản lý qua aggregate của merchant hoặc thêm hàng loạt vào một merchant có sẵn. Mỗi kênh mang các liên kết inventory-location và cấu hình terminal/print riêng, một slug duy nhất theo từng merchant, và một định danh hệ thống - và không thể vô hiệu hóa khi vẫn còn các đơn hàng đang hoạt động phụ thuộc vào nó. Kết quả: kiểm soát ở cấp kênh việc lấy stock từ đâu và hóa đơn in như thế nào, không còn các lượt tra cứu rộng theo toàn merchant tùy tiện.

1. Context & Problem

Một merchant bán qua nhiều kênh - dine-in, takeout, delivery - và mỗi kênh hành xử khác nhau: nó có thể lấy stock từ một location khác, in tới một terminal khác, hoặc dùng một mẫu hóa đơn khác. Commerce vốn đã tạo (các) kênh mặc định một thao tác duy nhất khi onboarding và quản lý chúng bên trong aggregate của merchant, nhưng kênh chỉ là một bản ghi mỏng: inventory location và cấu hình terminal/print nằm ở scope merchant, nên hai kênh dưới cùng một merchant không thể khác nhau, và các lượt tra cứu cấu hình được khóa theo merchant thay vì theo kênh. Cũng không có bộ chặn nào ngăn việc vô hiệu hóa một kênh trong khi nó vẫn còn các đơn hàng đang hoạt động phụ thuộc, dẫn tới nguy cơ bỏ rơi các giao dịch đang dang dở.

Increment này nâng kênh bán thành một đơn vị cấu hình hạng nhất: các liên kết location và cấu hình terminal/print chuyển lên kênh, các lượt tra cứu cấu hình được scope theo sale-channel-id, và một bộ chặn vô hiệu hóa bảo vệ các đơn hàng đang dang dở - cùng với các màn hình back-office được làm lại để người dùng quản lý tất cả qua một giao diện nhất quán.

2. Goals & Non-Goals

Goals

  • (Các) kênh mặc định được tạo khi onboarding và quản lý như một phần của các thao tác aggregate của merchant.
  • Tạo hàng loạt kênh cho một merchant có sẵn, với slug duy nhất theo từng merchant và một định danh hệ thống được sinh ra khi tạo.
  • Gắn các inventory location vào một kênh (tùy chọn khi tạo) để một kênh lấy stock từ (các) location riêng của nó.
  • Mang cấu hình terminal và print-template trên kênh, với các lượt tra cứu cấu hình được scope theo sale-channel-id.
  • Chặn việc vô hiệu hóa một kênh vẫn còn các đơn hàng đang hoạt động phụ thuộc.
  • Các màn hình tạo/sửa back-office nhất quán cho việc quản lý kênh.

Non-Goals

  • CRUD kênh bán độc lập bên ngoài aggregate của merchant - Dự kiến (xem Commerce URD Non-Goals).
  • Phân cấp kênh (cha-con) - URD-SC-006 là ưu tiên Could và nằm ngoài increment này.

3. Success Metrics

MetricTarget / signal
Cấu hình theo kênh100% lượt tra cứu terminal/print/cấu hình được khóa theo sale-channel-id (không có fallback rộng theo merchant)
Độ phủ onboardingMọi merchant đã onboarding đều có ít nhất một kênh mặc định kèm định danh hệ thống
Tính toàn vẹn slugKhông có slug kênh trùng trong cùng một merchant
An toàn đơn hàngKhông có lượt vô hiệu hóa kênh đang còn đơn hàng hoạt động phụ thuộc

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
OwnerThiết lập các kênh bán khi onboarding; kiểm soát mỗi kênh lấy stock từ đâu và in như thế nào
ManagerThêm/sửa kênh cho một merchant có sẵn, liên kết inventory location, quản lý cấu hình terminal/print
Thu ngân (client)Bán đúng kênh để stock được lấy từ đúng location và hóa đơn in đúng

Core scenarios: onboarding tạo kênh mặc định → owner thêm hàng loạt hoặc quản lý qua aggregate thêm kênh → liên kết inventory location và cấu hình terminal/print theo từng kênh → vô hiệu hóa một kênh không dùng (bị chặn nếu còn đơn hàng hoạt động phụ thuộc).

5. User Stories

  • Là một owner, tôi muốn (các) kênh mặc định được tạo khi onboarding, để tôi có thể bán ngay lập tức.
  • Là một manager, tôi muốn tạo hàng loạt kênh cho một merchant có sẵn, để mở rộng kênh bán mà không cần chạy lại onboarding.
  • Là một manager, tôi muốn mỗi kênh liên kết (các) inventory location riêng, để một kênh lấy stock từ đúng nơi.
  • Là một manager, tôi muốn cấu hình terminal và print-template trên kênh, để hóa đơn in tới đúng thiết bị với đúng mẫu.
  • Là một manager, tôi muốn một slug duy nhất cho mỗi kênh trong merchant, để các định danh kênh không xung đột.
  • Là một owner, tôi muốn một kênh đang còn đơn hàng hoạt động phụ thuộc được bảo vệ khỏi việc vô hiệu hóa, để không bỏ rơi các giao dịch đang dang dở.

6. Functional Requirements

#RequirementURD ref
FR-1(Các) kênh mặc định được tạo khi onboardingURD-SC-001
FR-2Kênh được quản lý như một phần của các thao tác aggregate của merchantURD-SC-002
FR-3Kênh có thể được tạo hàng loạt cho một merchant có sẵnURD-SC-003
FR-4Slug kênh là duy nhất trong cùng một merchantURD-SC-004
FR-5Một định danh hệ thống duy nhất được sinh ra khi tạo và không thể sửaURD-SC-005
FR-6Kênh có thể được vô hiệu hóa hoặc lưu trữ; việc vô hiệu hóa bị chặn khi kênh còn đơn hàng hoạt động phụ thuộcURD-SC-007
FR-7Inventory location có thể gắn vào một kênh (tùy chọn khi tạo); một kênh lấy stock từ (các) location đã liên kếtURD-SC-002
FR-8Cấu hình terminal và print-template được mang trên kênh; các lượt tra cứu cấu hình được scope theo sale-channel-idURD-SC-002

Toàn văn yêu cầu và tiêu chí nghiệm thu nằm trong Commerce URD. PRD này tham chiếu chúng thay vì lặp lại.

7. Non-Functional Requirements

AreaRequirement
Toàn vẹn dữ liệuKênh + các liên kết inventory-location được ghi một thao tác duy nhất bên trong aggregate; một partial-unique index đảm bảo một liên kết duy nhất cho mỗi (saleChannelId, inventoryLocationId)
Tenancy & authzMọi thao tác được scope theo từng merchant (x-merchant-id); kiểm soát bởi các permission kênh bán của commerce
Nhất quánAggregate create/update áp dụng quy tắc smart-update của merchant (chỉ ID = xóa, ID+data = cập nhật, không ID = tạo) một thao tác duy nhất
An toàn đơn hàngMột kênh còn đơn hàng hoạt động phụ thuộc không thể bị vô hiệu hóa (được kiểm tra trước khi đổi status)
i18nNhãn kênh hiển thị cho người dùng là song ngữ ({ en, vi })

8. UX & Flows

Các màn hình chính (trong apps/bo): màn hình danh sách, tạo và sửa kênh bán với một SaleChannelForm / form thông tin chung dùng chung; bộ chọn kênh cùng ràng buộc inventory-location/terminal xuất hiện trong apps/client tại điểm bán.

9. Data & Domain

EntityVai trò
SaleChannelBản ghi kênh bán - tên, slug duy nhất theo merchant, định danh hệ thống, status, cấu hình terminal/print
SaleChannelInventoryLocationDòng liên kết nối một kênh với một hoặc nhiều inventory location (sắp theo priority)
Cấu hình kênhCấu hình được mã hóa/khóa, tra cứu theo sale-channel-id

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

10. Dependencies & Assumptions

Phụ thuộc vào

  • Merchant aggregate (URD-MER) - kênh được tạo và quản lý bên trong aggregate của merchant.
  • Onboarding (URD-ORG) - (các) kênh mặc định được tạo một thao tác duy nhất khi onboarding.
  • Inventory location (Inventory) - một kênh liên kết tới các inventory location có sẵn.

Giả định

  • Một merchant tồn tại (hoặc đang được tạo trong cùng aggregate) trước khi quản lý kênh.
  • Các inventory location tồn tại trước khi có thể liên kết vào một kênh.

11. Risks & Open Questions

Risk / câu hỏiMitigation / trạng thái
Cấu hình kênh trôi dạt sau khi chuyển tra cứu khỏi merchant-idLượt tra cứu được khóa nhất quán theo sale-channel-id; fallback rộng theo merchant đã bị gỡ
Trùng liên kết inventory-location trên một kênhPartial-unique index trên (saleChannelId, inventoryLocationId)
Vô hiệu hóa một kênh giữa lúc đang bánBộ chặn ngăn vô hiệu hóa khi còn đơn hàng hoạt động tham chiếu kênh
CRUD kênh độc lập bên ngoài aggregateNgoài phạm vi; Dự kiến theo URD Non-Goals
Phân cấp kênh (cha-con)Ưu tiên Could (URD-SC-006); hoãn lại

12. Release Plan & Launch Criteria

AspectPlan
PhaseP1 (nền tảng) - xem URD feature catalog
RolloutMọi merchant; không feature flag
MigrationBackfill onboarding đảm bảo các merchant có sẵn có một kênh mặc định; cấu hình terminal/print chuyển lên kênh
Launch criteriaOnboarding tạo một kênh mặc định; batch/aggregate create đã kiểm chứng; slug duy nhất theo merchant được thực thi; tra cứu cấu hình theo kênh đã kiểm chứng; bộ chặn vô hiệu hóa chặn các kênh còn đơn hàng hoạt động phụ thuộc
MonitoringSố kênh trên mỗi merchant, tỷ lệ chặn vô hiệu hóa, lỗi tra cứu cấu hình theo sale-channel-id

13. FAQ

Tôi có thể quản lý một kênh bên ngoài aggregate của merchant không? Không trong increment này - kênh được quản lý qua aggregate của merchant hoặc thêm hàng loạt vào một merchant có sẵn. CRUD kênh độc lập là Dự kiến.

Mỗi kênh có location stock riêng không? Một kênh có thể liên kết một hoặc nhiều inventory location (tùy chọn khi tạo), nên nó lấy stock từ (các) location riêng thay vì một location duy nhất rộng theo merchant.

Tại sao tôi không thể vô hiệu hóa một kênh? Vì nó vẫn còn đơn hàng hoạt động phụ thuộc. Bộ chặn vô hiệu hóa bảo vệ các giao dịch đang dang dở; hãy đóng hoặc chuyển các đơn hàng đó trước.

Cấu hình terminal/print giờ nằm ở đâu? Trên kênh. Các lượt tra cứu cấu hình được scope theo sale-channel-id, nên hai kênh dưới cùng một merchant có thể in khác nhau.

Phân cấp kênh có được hỗ trợ không? Không - phân cấp kênh cha-con (URD-SC-006) là ưu tiên Could và không thuộc increment này.

References

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