PRD: Tổ chức thực đơn & hiển thị theo kênh
| Module | Sản phẩm (CORE-05) | PRD ID | PRD-SCH-001 |
| Trạng thái | Shipped | Chủ sở hữu | Product squad |
| Ngày | 2026-06-15 | Phiên bản | v1.0 |
| Packages | @nx/commerce · @nx/core · @nx/search | URD | SCH · PRD |
TL;DR
Cho phép merchant tổ chức những gì mình bán thành các kênh bán hàng - bề mặt thực đơn có tên, đa ngôn ngữ, phân cấp (tại quầy, mang đi, giao hàng, một ki-ốt) - và kiểm soát, theo từng kênh, sản phẩm nào hiển thị. Một sản phẩm được gán vào một hoặc nhiều kênh khi tạo; việc gán chính là công tắc hiển thị. Mỗi kênh mang một chuỗi vị trí kho theo thứ tự ưu tiên để nguồn kho đúng được tự chọn khi xuất hàng, có trạng thái vòng đời (kích hoạt / ngừng / lưu trữ), và không thể bị ngừng khi vẫn còn đơn đang hoạt động. Mọi danh sách kênh và sản phẩm đều được phục vụ đã lọc theo quyền của người gọi - một chủ chỉ thấy kênh của các merchant của mình, admin thấy tất cả - nên thực đơn một thiết bị nhận được luôn được giới hạn theo người đang hỏi.
1. Bối cảnh & Vấn đề
Danh mục (PRD-PRD-001) định nghĩa các sản phẩm một merchant bán, nhưng không định nghĩa ở đâu mỗi sản phẩm được chào bán. Một merchant hiếm khi bán cùng một danh sách ở mọi nơi: thực đơn tại chỗ khác với giao hàng, một ki-ốt chỉ hiển thị một tập con, một quầy thời vụ cần bề mặt riêng. Không có khái niệm kênh, mọi thiết bị sẽ thấy một danh mục phẳng và merchant không thể bật một sản phẩm cho giao hàng trong khi vẫn tắt nó tại quầy.
Hai khoảng trống nữa theo sau. Thứ nhất, một kênh phải biết kho lấy hàng từ đâu - vị trí kho nào xuất các đơn của nó - và cần một mặc định hợp lý khi có nhiều khả năng. Thứ hai, thực đơn một thiết bị nhận được phải được giới hạn theo người đang hỏi: một chủ của hai merchant phải thấy đúng kênh của hai merchant đó, một nhân viên chỉ merchant được phân công, admin thấy tất cả - mà không cần mỗi người gọi tự lọc bằng tay.
Đợt này lấp các khoảng trống đó. Nó giới thiệu kênh bán hàng như bề mặt thực đơn, việc gán sản phẩm vào kênh như kiểm soát hiển thị, một chuỗi vị trí kho theo thứ tự ưu tiên cho mỗi kênh, một trạng thái vòng đời với chốt chặn khi ngừng, và phục vụ đã lọc theo quyền cho mọi lượt đọc kênh và sản phẩm.
2. Mục tiêu & Không-mục-tiêu
Mục tiêu
- Cho phép chủ tạo kênh bán hàng trong một merchant - tên/mô tả đa ngôn ngữ, một định danh hệ thống, một slug duy nhất theo merchant.
- Biến việc gán sản phẩm vào kênh thành kiểm soát hiển thị: một sản phẩm chỉ hiển thị trong một kênh khi được gán vào đó.
- Gán sản phẩm vào kênh như một phần của bước tạo sản phẩm toàn vẹn, để một sản phẩm hiển thị ngay từ ngày đầu.
- Cho mỗi kênh một trạng thái vòng đời (kích hoạt / ngừng / lưu trữ) và từ chối ngừng khi còn đơn đang hoạt động.
- Mang một chuỗi vị trí kho theo thứ tự ưu tiên cho mỗi kênh; vị trí ưu tiên thấp nhất là mặc định tự chọn.
- Hỗ trợ phân cấp cha-con giữa các kênh để nhóm các bề mặt thực đơn.
- Phục vụ mọi danh sách kênh và sản phẩm đã lọc theo quyền của người gọi; admin bỏ qua bộ lọc.
Không-mục-tiêu
- Định nghĩa sản phẩm, biến thể, định danh - được nêu trong PRD-PRD-001.
- Bậc giá theo từng kênh - do fare theo ngữ cảnh kênh đảm nhận (FAR).
- Mức tồn kho và biến động - thuộc Kho; một kênh chỉ tham chiếu một vị trí, nó không giữ tồn kho.
- Đi qua chuỗi kho như một fallback nhiều bước khi xuất hàng - hôm nay chỉ vị trí mặc định (ưu tiên thấp nhất) được tiêu thụ; chuỗi theo thứ tự được ghi lại để dùng sau.
- Xử lý đơn hàng và thanh toán qua một kênh - thuộc Đơn hàng.
3. Chỉ số Thành công
| Chỉ số | Mục tiêu / tín hiệu |
|---|---|
| Kiểm soát hiển thị | Một sản phẩm chỉ hiển thị trong một kênh khi được gán vào đó; bỏ gán sẽ loại nó ra |
| Phục vụ đã giới hạn | Danh sách kênh/sản phẩm của một người gọi chỉ trả về các hàng của merchant của họ; admin thấy tất cả |
| An toàn khi ngừng | Không kênh nào còn đơn đang hoạt động có thể bị ngừng |
| Rõ nguồn kho | Mọi kênh giải quyết được đúng một vị trí kho mặc định không mơ hồ |
| Toàn vẹn slug | Không hai kênh đang hoạt động trong một merchant chia sẻ một slug |
4. Chân dung & Tình huống
| Chân dung | Mục tiêu trong tính năng |
|---|---|
| Chủ / Quản lý | Dựng thực đơn theo từng bề mặt, bật/tắt sản phẩm theo kênh, đặt nguồn kho của kênh |
| Thu ngân / Thiết bị | Nhận thực đơn đã giới hạn theo merchant và kênh hiện tại |
| Admin / Super Admin | Kiểm tra kênh trên mọi merchant mà không bị lọc theo vai trò |
Tình huống cốt lõi: một chủ với một quán cà phê tạo kênh Giao hàng và kênh Tại quầy. Sản phẩm mới chỉ gán cho Tại quầy; một tập con cũng được gán cho Giao hàng, nên ứng dụng tài xế hiển thị một thực đơn nhỏ hơn. Chuỗi kho của Giao hàng để vị trí kho hậu cần lên đầu, nên các đơn của nó tự lấy hàng từ đó. Khi chủ thử ngừng Tại quầy trong khi một bàn vẫn còn đơn mở, hệ thống từ chối cho đến khi đơn được đóng.
5. User Stories
- Là một chủ, tôi tạo một kênh bán hàng cho mỗi bề mặt bán, để mỗi thiết bị hiển thị đúng thực đơn.
- Là một chủ, tôi gán một sản phẩm vào những kênh nó nên xuất hiện, để hiển thị là một công tắc duy nhất.
- Là một chủ, tôi đặt chuỗi vị trí kho của một kênh, để các đơn của nó tự lấy hàng từ đúng nơi.
- Là một chủ, tôi không thể vô tình ngừng một kênh còn đơn đang chạy, để không bao giờ bỏ mắc một phiếu mở.
- Là một nhân viên, tôi chỉ thấy kênh và sản phẩm của các merchant được phân công, để thực đơn của tôi không bao giờ là của merchant khác.
- Là một admin, tôi đọc được kênh của mọi merchant không bị lọc theo vai trò, để hỗ trợ bất kỳ tenant nào.
6. Yêu cầu Chức năng
| # | Yêu cầu | URD ref |
|---|---|---|
| FR-1 | Chủ có thể tạo kênh bán hàng trong một merchant, mỗi kênh có tên/mô tả đa ngôn ngữ và một định danh hệ thống tự sinh | URD-SCH-001 |
| FR-2 | Slug kênh là duy nhất giữa các kênh đang hoạt động trong cùng một merchant | URD-SCH-002 |
| FR-3 | Một kênh có trạng thái vòng đời: kích hoạt, ngừng, lưu trữ | URD-SCH-003 |
| FR-4 | Chủ có thể cập nhật một kênh; một cập nhật rỗng (không có trường) bị từ chối | URD-SCH-004 |
| FR-5 | Việc ngừng một kênh bị từ chối khi nó còn đơn bán đang hoạt động | URD-SCH-005 |
| FR-6 | Kênh hỗ trợ phân cấp cha-con | URD-SCH-006 |
| FR-7 | Một sản phẩm được gán vào một hoặc nhiều kênh; việc gán quyết định nó có hiển thị trong kênh đó không | URD-SCH-007 · URD-PRD-014 |
| FR-8 | Các gán sản phẩm-vào-kênh được ghi như một phần của bước tạo sản phẩm toàn vẹn | URD-SCH-008 |
| FR-9 | Một kênh mang một chuỗi vị trí kho theo thứ tự ưu tiên; vị trí ưu tiên thấp nhất là mặc định tự chọn; chuỗi được diff-sync khi cập nhật | URD-SCH-009 |
| FR-10 | Xóa một kênh sẽ bỏ gán các sản phẩm của nó và soft-delete kênh | URD-SCH-010 |
| FR-11 | Danh sách/đếm kênh và sản phẩm được phục vụ đã lọc theo quyền của người gọi; admin bỏ qua bộ lọc | URD-SCH-011 · URD-ACC-001..004 |
| FR-12 | Kênh và sản phẩm có thể tìm kiếm, giới hạn theo các merchant của người gọi | URD-SCH-012 |
| FR-13 | Tạo kênh đầu tiên của một merchant hoàn tất bước onboarding kênh của merchant | URD-SCH-013 |
Nội dung yêu cầu đầy đủ và tiêu chí chấp nhận nằm trong URD Sản phẩm - SCH. PRD này tham chiếu chúng thay vì nhắc lại.
7. Yêu cầu Phi Chức năng
| Lĩnh vực | Yêu cầu |
|---|---|
| Toàn vẹn | Tạo kênh cùng chuỗi kho của nó là một giao dịch; tạo sản phẩm ghi các gán kênh trong cùng bước toàn vẹn - thất bại một phần roll back trọn vẹn |
| Tenancy & authz | Mọi thao tác giới hạn theo merchant (x-merchant-id) và được kiểm soát bởi quyền kênh bán hàng |
| Đọc đã giới hạn theo quyền | Danh sách, đếm, và tìm kiếm giải quyết các grant merchant của người gọi và lọc về chúng; người gọi isAlwaysAllowed bỏ qua |
| Duy nhất | Slug kênh duy nhất theo merchant giữa các hàng đang hoạt động; một vị trí kho xuất hiện tối đa một lần trong một kênh |
| Soft-delete | Kênh và các gán được soft-delete; không có gì bị xóa vật lý |
| i18n | Tên và mô tả kênh là song ngữ ({ en, vi }) |
8. UX & Luồng
Bề mặt kênh cho phép chủ đặt tên một kênh, đặt slug, sắp xếp chuỗi vị trí kho (trên cùng = nguồn mặc định), và đặt nó dưới một cha. Bề mặt sản phẩm cho phép chủ chọn các kênh một sản phẩm xuất hiện. Thiết bị yêu cầu thực đơn và nhận chỉ các kênh và sản phẩm mà quyền của họ cho phép.
9. Dữ liệu & Miền
| Thực thể | Vai trò |
|---|---|
SaleChannel | Một bề mặt thực đơn trong một merchant - tên, slug, trạng thái, cha tùy chọn |
SaleChannelProduct | Liên kết hiển thị - một sản phẩm chỉ hiển thị trong một kênh khi liên kết này còn sống |
SaleChannelInventoryLocation | Một vị trí trong chuỗi nguồn kho theo thứ tự ưu tiên của kênh (ưu tiên thấp nhất = mặc định) |
Chỉ ở mức khái niệm - lược đồ đầy đủ và bất biến nằm trong mô hình miền commerce. Quan hệ là tham chiếu mềm; toàn vẹn được thực thi trong service kênh và sản phẩm, không phải bởi khóa ngoại CSDL.
10. Phụ thuộc & Giả định
Phụ thuộc vào
- Danh mục sản phẩm (PRD-PRD-001, PRD) - sản phẩm là thứ một kênh làm hiển thị.
- Commerce / Merchant (Commerce) - kênh giới hạn theo một merchant; kênh đầu tiên hoàn tất một bước onboarding merchant.
- Kho (Kho) - chuỗi tham chiếu các vị trí kho; một vị trí phải tồn tại trước khi được thêm.
- Đơn hàng (Đơn hàng) - chốt chặn khi ngừng đọc các đơn đang hoạt động của một kênh.
@nx/search- kênh và sản phẩm được lập chỉ mục và phục vụ đã giới hạn theo các merchant của người gọi.
Giả định
- Một merchant tồn tại và các grant của người gọi giải quyết được những merchant họ được thấy.
- Các vị trí kho được chuỗi của một kênh tham chiếu thuộc cùng merchant.
11. Rủi ro & Câu hỏi Mở
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Một kênh bị bỏ không có nguồn kho | Vị trí ưu tiên thấp nhất của chuỗi luôn là mặc định; trùng lặp trong đầu vào gộp về lần xuất hiện đầu |
| Ngừng một kênh giữa ca | Bị từ chối khi còn đơn đang hoạt động; chủ phải đóng hoặc hủy chúng trước |
| Rò rỉ thực đơn liên-merchant | Mọi danh sách/đếm/tìm kiếm giải quyết các grant của người gọi và lọc về chúng; chỉ admin bỏ qua |
| Trùng slug trong một merchant | Bị từ chối trước khi lưu; slug duy nhất theo merchant giữa các kênh đang hoạt động |
| Chuỗi kho được đi qua như một fallback | Không phải hôm nay - chỉ vị trí mặc định được tiêu thụ; chuỗi theo thứ tự được ghi cho logic xuất hàng tương lai |
12. Kế hoạch Phát hành & Tiêu chí Ra mắt
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P2 - SCH trong danh mục tính năng URD |
| Triển khai | Mọi merchant; không feature flag |
| Migration | Không - kênh và các gán chạy trên lược đồ commerce hiện có |
| Tiêu chí ra mắt | Một sản phẩm chỉ hiển thị trong một kênh khi được gán; tạo kênh giải quyết được một vị trí kho mặc định; ngừng khi còn đơn đang hoạt động bị từ chối; mọi danh sách kênh/sản phẩm được lọc về các merchant của người gọi; admin bỏ qua |
| Giám sát | Tỉ lệ từ chối khi ngừng, kênh không có vị trí mặc định, kiểm tra phạm vi danh sách liên-merchant |
13. FAQ
Làm sao để ẩn một sản phẩm khỏi một kênh nhưng không khỏi kênh khác? Gán sản phẩm chỉ vào các kênh nó nên xuất hiện - việc gán là công tắc hiển thị. Bỏ gán sẽ loại nó khỏi kênh đó mà không động đến các kênh khác.
Vị trí kho "mặc định" của một kênh là gì? Vị trí đầu tiên trong chuỗi của kênh - giá trị ưu tiên thấp nhất. Các đơn trên kênh đó tự lấy hàng từ nó. Bạn có thể sắp xếp lại chuỗi khi cập nhật; phần còn lại được ghi cho fallback tương lai.
Tại sao tôi không thể ngừng một kênh? Vì nó vẫn còn đơn đang hoạt động. Đóng hoặc hủy chúng trước, rồi mới ngừng.
Một admin có thấy kênh của mọi merchant không? Có - người gọi admin và super-admin bỏ qua lọc theo vai trò; mọi người gọi khác chỉ thấy kênh của các merchant họ được grant.
Kênh có thể lồng nhau không? Có - một kênh có thể có một cha, nên các bề mặt thực đơn có thể được nhóm.
Tham chiếu
- URD: Sản phẩm - SCH · PRD · ACC
- PRD liên quan: Danh mục sản phẩm, biến thể & định danh · Hệ thống Fare & Định giá
- Module: Sản phẩm - tổng quan + năng lực
- Developer: @nx/commerce · @nx/core · @nx/search