Skip to content

PRD: POS & order bếp

ModuleĐơn hàng (CORE-07)PRD IDPRD-KIT-001
StatusShippedOwnerOrders squad
Date2026-03-23Versionv1.0
Packages@nx/sale · @nx/core · apps/sale-rendererURDKIT · STA · POS

TL;DR

Cho phép một quán F&B phục vụ đầy đủ đẩy các món trong đơn xuống bếp dưới dạng phiếu và theo dõi quá trình nấu theo thời gian thực, không ai phải tải lại màn hình. Phiếu được định tuyến tới các trạm chế biến có tên, đi qua các trạng thái nấu theo từng món tự động đẩy trạng thái của phiếu, và dùng void-and-resend để một món đã gửi không bao giờ bị sửa tại chỗ. Kết quả: khu bếp có một hàng đợi công việc trực tiếp, chính xác, còn khu phục vụ thấy trạng thái ngay khi bếp thao tác.

1. Context & Problem

Module Đơn hàng đã bao phủ vòng đời giỏ-tới-checkout-tới-thanh-toán, nhưng một quán F&B phục vụ đầy đủ cần nửa còn lại ở khu bếp: các món trong đơn phải xuống tới bếp, đi qua quá trình nấu, và cập nhật màn hình chế biến mà không ai phải tải lại màn hình. Hiện tại chưa có bất kỳ thực thể nào phía bếp - các món chỉ tồn tại trên sale order, nên bếp không có hàng đợi công việc, không có trạng thái nấu theo từng món, và không có cách đẩy trạng thái ngược lại khu phục vụ. Với các nhà hàng và quán cà phê HKD/SME mà KICKO nhắm tới, khoảng trống này chặn mô hình phục vụ F&B phổ biến nhất (báo bếp, nấu, phục vụ), khiến POS không dùng được ngoài quầy tính tiền nhanh.

Increment này xây dựng quản lý order bếp (KDS) trên nền vòng đời sale order hiện có: phiếu được gửi từ một sale order xuống bếp, các trạm có tên để định tuyến, trạng thái nấu theo từng món, và lan truyền trạng thái trực tiếp qua WebSocket.

2. Goals & Non-Goals

Goals

  • Gửi các món trong đơn xuống bếp dưới dạng phiếu có các dòng món, với một lần gửi idempotent để một lần báo bếp lặp lại không bao giờ tạo ra phiếu thứ hai (KIT).
  • Một vòng đời phiếu đầy đủ (PENDING → PROCESSING → READY → COMPLETED / VOIDED) và một vòng đời nấu theo từng món (PENDING → COOKING → READY → SERVED / VOIDED).
  • Tự động đẩy trạng thái - trạng thái phiếu tiến tự động theo trạng thái các món của nó.
  • Cơ chế void-and-resend - một món đã gửi sẽ bị void và gửi lại, không bao giờ sửa tại chỗ.
  • Các trạm bếp có tên theo từng merchant với định tuyến theo danh mục sản phẩm và cấu hình máy in cho từng trạm (STA).
  • Cập nhật thời gian thực tới màn hình bếp và dashboard khi phiếu được tạo / cập nhật / hoàn thành.
  • Đánh dấu một món đã phục vụ kích hoạt việc trừ kho phía sau.

Non-Goals

  • Một ứng dụng màn hình bếp riêng biệt - increment này chỉ giao phần backend cùng bề mặt apps/sale-renderer (Dự kiến).
  • Luồng hoàn / trả hàng và phần nội tại trừ kho - thuộc về Kho hàng.
  • Quản lý sơ đồ bàn / chỗ ngồi (Dự kiến).
  • Phiên ca POS (POS) - liệt kê để đầy đủ phạm vi; schema/service phiên không nằm trong increment này.

3. Success Metrics

MetricMục tiêu / tín hiệu
Độ tươi thời gian thựcMàn hình bếp phản ánh thay đổi trạng thái mà không cần tải lại thủ công; fan-out qua WebSocket mỗi lần tạo / cập nhật / hoàn thành
Tính toàn vẹn khi gửiKhông có phiếu trùng cho một lần báo bếp lặp lại (gửi idempotent giữ vững khi retry)
Độ chính xác tự đẩy trạng tháiTrạng thái phiếu luôn khớp với tổng hợp trạng thái các món của nó
Độ phủ định tuyếnCác món rơi đúng trạm được map theo danh mục sản phẩm
Đúng đắn khi phục vụĐánh dấu một món đã phục vụ kích hoạt trừ kho đúng một lần một cách đáng tin

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
Thu ngânBáo bếp các món trong đơn và thấy khi nào món sẵn sàng phục vụ
Nhân viên bếpLàm việc trên hàng đợi phiếu trực tiếp, đẩy món cooking → ready → served, void món lỗi
Quản lý / ChủCấu hình các trạm, định tuyến theo danh mục, và máy in từng trạm

Core scenarios: thu ngân báo bếp các món → một phiếu hiện trên màn hình của trạm được định tuyến → nhân viên bếp đẩy món cooking → ready → served, phiếu tự đẩy trạng thái, và khu phục vụ thấy trạng thái trực tiếp; một món lỗi bị void và gửi lại thay vì sửa.

5. User Stories

  • Là một thu ngân, tôi muốn gửi các món trong đơn xuống bếp bằng một thao tác, để khu bếp nhận phiếu công việc ngay lập tức.
  • Là một thu ngân, tôi muốn một lần báo bếp lặp lại là idempotent, để một lần chạm đúp không bao giờ tạo phiếu trùng.
  • nhân viên bếp, tôi muốn mỗi món mang trạng thái nấu riêng, để tôi theo dõi một phiếu nhiều món một cách chính xác.
  • nhân viên bếp, tôi muốn phiếu tự đẩy trạng thái theo các món của nó, để tôi không phải duy trì trạng thái phiếu riêng bằng tay.
  • nhân viên bếp, tôi muốn void và gửi lại một món đã gửi, để các chỉnh sửa không bao giờ ngầm thay đổi một phiếu đang chạy.
  • Là một quản lý, tôi muốn định tuyến các danh mục sản phẩm tới các trạm có tên với cấu hình máy in riêng, để mỗi trạm chỉ thấy và in công việc của nó.
  • Là một thu ngân, tôi muốn trạng thái bếp cập nhật màn hình theo thời gian thực, để khu phục vụ biết khi nào phục vụ mà không phải hỏi.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Gửi các món trong đơn xuống bếp - tạo một phiếu với các dòng mónURD-KIT-001
FR-2Gửi idempotent - một lần gửi trùng tạo ra cùng một phiếuURD-KIT-002
FR-3Vòng đời phiếu PENDING → PROCESSING → READY → COMPLETED / VOIDEDURD-KIT-003
FR-4Vòng đời nấu theo từng món PENDING → COOKING → READY → SERVED / VOIDEDURD-KIT-004
FR-5Trạng thái phiếu tự đẩy theo trạng thái các món của nóURD-KIT-005
FR-6Các thay đổi dùng void-and-resend - món đã gửi không bị sửa tại chỗURD-KIT-006
FR-7Cờ rush và số thứ tự theo từng đơn để sắp xếp phiếuURD-KIT-007
FR-8Cập nhật thời gian thực tới màn hình bếp và dashboardURD-KIT-008
FR-9Đánh dấu một món đã phục vụ kích hoạt trừ khoURD-KIT-009
FR-10Tạo các trạm có tên theo từng merchant (i18n)URD-STA-001
FR-11Định tuyến các danh mục sản phẩm tới các trạmURD-STA-002
FR-12Cấu hình máy in cho từng trạm với tự động inURD-STA-003

Toàn bộ nội dung yêu cầu và tiêu chí nghiệm thu nằm trong Orders URD. PRD này tham chiếu chứ không lặp lại chúng.

7. Non-Functional Requirements

AreaYêu cầu
Thời gian thựcTạo / cập nhật / hoàn thành phiếu fan-out qua WebSocket; apps/sale-renderer subscribe để nhận trạng thái trực tiếp
IdempotencyViệc gửi được keyed để các retry gộp về một phiếu duy nhất; không trùng công việc bếp
Tenancy & authzMọi thao tác scope theo từng merchant (x-merchant-id); kiểm soát bởi permission sale/bếp
Tính toàn vẹn dữ liệuTrạng thái phiếu luôn là tổng hợp xác định từ trạng thái các món; chỉnh sửa là void-and-resend, không bao giờ sửa tại chỗ
Tính nhất quánViệc gửi và các chuyển trạng thái là transactional; lỗi một phần không để lại phiếu mồ côi
i18nTên trạm và các trạng thái hiển thị cho người dùng là song ngữ ({ en, vi })

8. UX & Flows

Bề mặt chính: các view phiếu bếp nằm trong apps/sale-renderer, subscribe vào luồng WebSocket để nhận trạng thái phiếu/món trực tiếp; cấu hình trạm và định tuyến được quản lý theo từng merchant.

9. Data & Domain

EntityVai trò
KitchenTicketPhiếu được gửi xuống bếp - trạng thái, cờ rush, số thứ tự theo từng đơn, gán trạm
KitchenTicketItemMột dòng phiếu - tham chiếu order item, mang trạng thái nấu riêng
KitchenStationMột khu chế biến có tên (i18n) với định tuyến theo danh mục và cấu hình máy in

Chỉ mang tính khái niệm - schema và bất biến đầy đủ ở sale domain model.

10. Dependencies & Assumptions

Phụ thuộc vào

  • Sale Order (URD-ORD) - phiếu được báo bếp từ các order item.
  • Danh mục sản phẩm (Sản phẩm) - định tuyến trạm map danh mục tới trạm.
  • Kho hàng (Kho hàng) - một món đã phục vụ kích hoạt trừ kho.
  • Vận chuyển thời gian thực (@nx/sale WebSocket) - để fan-out trạng thái trực tiếp.

Giả định

  • Merchant chạy luồng F&B phục vụ đầy đủ (báo bếp), không chỉ quầy tính tiền.
  • Các trạm và định tuyến theo danh mục được cấu hình trước khi báo bếp các món.
  • Các client (ví dụ apps/sale-renderer) giữ một subscription WebSocket đang hoạt động để nhận cập nhật trực tiếp.

11. Risks & Open Questions

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Báo bếp trùng tạo ra hai phiếuViệc gửi là idempotent qua key; các retry gộp về một phiếu
Trạng thái phiếu lệch khỏi trạng thái các mónTrạng thái là tổng hợp tự động xác định, không duy trì bằng tay
Sửa một món đã gửi tại chỗBị cấm theo thiết kế - void-and-resend là con đường chỉnh sửa duy nhất
Bỏ lỡ một cập nhật WebSocket khiến màn hình cũMàn hình subscribe vào tạo / cập nhật / hoàn thành; kết nối lại sẽ đồng bộ lại
Chưa có ứng dụng KDS riêngBackend + bề mặt apps/sale-renderer giao ngay; ứng dụng KDS độc lập là Dự kiến

12. Release Plan & Launch Criteria

AspectKế hoạch
PhaseP2 - xem danh mục feature Đơn hàng (KIT, STA Built)
RolloutTất cả merchant; không feature flag
MigrationCác migration sale-schema cho các entity bếp mới; không backfill dữ liệu
Launch criteriaBáo bếp → phiếu → định tuyến trạm → nấu → phục vụ đã kiểm chứng đầu-cuối; gửi idempotent giữ vững; tự đẩy trạng thái khớp trạng thái các món; cập nhật trực tiếp tới được apps/sale-renderer
MonitoringSố lượng phiếu theo từng merchant, tỉ lệ lỗi / trùng khi gửi, sức khỏe phân phối WebSocket, tính nhất quán giữa phục vụ và trừ kho

13. FAQ

Một món bếp đã gửi có sửa được không? Không - các món đã gửi không bao giờ bị sửa tại chỗ. Dùng void-and-resend: void món đó và gửi một món mới.

Điều gì xảy ra nếu một lần báo bếp được gửi hai lần? Không có gì bị trùng - việc gửi là idempotent theo key, nên một lần báo bếp lặp lại quy về cùng một phiếu.

Trạng thái phiếu thay đổi như thế nào? Nó tự đẩy theo trạng thái các món của nó; không có trạng thái phiếu riêng duy trì bằng tay.

Phiếu hiện ở đâu? Trên màn hình của trạm được định tuyến trong apps/sale-renderer, cập nhật trực tiếp qua WebSocket - không cần tải lại. Một ứng dụng KDS riêng là Dự kiến.

Phục vụ một món có làm dịch chuyển kho không? Có - đánh dấu một món đã phục vụ kích hoạt trừ kho phía sau (thuộc về Kho hàng).

Đây có phải tính năng phiên ca POS không? Không - phiên POS (URD-POS) thuộc cùng dòng feature nhưng là một increment riêng; PRD này bao phủ phiếu bếp và các trạm.

References

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