Skip to content

Sale Service

@nx/sale sở hữu vòng đời cart-and-order: một SaleOrder đảm nhận cả hai vai trò (DRAFT cart + đơn hàng đã commit). Nó nhận webhook MQ-Pay cho sự kiện thanh toán, điều phối luồng kitchen ticket, quản lý allocation và reservation cho dining, đồng thời phát Kafka topic + WebSocket event tới inventory, finance và các UI hạ nguồn.

1. Tham chiếu nhanh

Thuộc tínhGiá trị
Package@nx/sale
CodeSVC-00030-SALE
LoạiMicroservice
RuntimeBun
Base ClassVerifierApplication
Vị trípackages/sale
Base Path/v1/api/sale
Dev Port31030
Container Port3000 (external 31030)
Snowflake ID3
DB Schemasale (đa bảng — xem Domain Model)
Binding Namespace@nx/sale

2. Mục đích & Phạm vi

Bao gồmLoại trừ
Một entity SaleOrder cho cart + order (DRAFT → … → COMPLETED / CANCELLED)Mutation tồn kho (ủy quyền cho @nx/inventory)
Item modes: PRODUCT (auto-merge) và CUSTOM (luôn tạo dòng mới)Tích hợp nhà cung cấp thanh toán (ủy quyền cho @nx/mq-pay)
Định giá checkout qua HTTP call tới @nx/pricingEngine tính thuế
Xử lý webhook thanh toán (MQ-Pay HTTP webhook)In hóa đơn (mối quan tâm frontend)
Tách bill: SaleCheck (nhóm thanh toán độc lập)Engine loyalty rewards
Gộp / tách order (có thể đảo ngược)Menu hướng khách hàng
Vòng đời kitchen ticket (FOH/BOH) — void, rush, ready, servedDữ liệu recipe / BOM (thuộc @nx/inventory)
Sử dụng allocation (DINE_IN tables, zones, units)
Reservation (đặt trước rồi đến)
Quản lý ca / phiên POS
Cộng điểm khách hàng (loyalty) khi thanh toán thành công
Báo cáo bán hàng (tổng hợp ngày, theo product/category, purchase summary)
Sự kiện WebSocket realtime (multi-room fanout)

3. Tech Stack

External:

LibraryMục đích
@venizia/ignisIoC container, DI, BaseService, BaseController, ControllerFactory
@venizia/ignis-helpersLogger, KafkaProducerHelper, Redis helper
@platformatic/kafkaKafka client (sale chỉ dùng producer với mặc định của helper — không cấu hình idempotent/lz4 tường minh)
honoHTTP server (qua IGNIS)
@hono/zod-openapiSinh OpenAPI từ Zod schema
@scalar/hono-api-referenceOpenAPI explorer tại /doc
drizzle-ormTruy cập DB qua PostgresCoreDataSource
pgPostgreSQL driver
lodashTiện ích

Internal:

PackageMục đích
@nx/coreSchema, repository (re-export), VerifierApplication, KafkaTopics, SaleOrderStatuses, SaleOrderItemModes, SaleConstraints
@nx/pricingChỉ HTTP — PricingNetworkService gọi pricing service để lấy giá động lúc checkout

4. Cấu trúc Dự án

packages/sale/
├── src/
│   ├── application.ts                # VerifierApplication subclass
│   ├── index.ts                      # bootstrapApplication()
│   ├── migrate.ts                    # bootstrapMigration()
│   ├── common/
│   │   ├── constants.ts              # SaleConstraints, ApplicationRoles
│   │   ├── keys.ts                   # BindingKeys
│   │   ├── rest-paths.ts             # 13 RestPaths
│   │   ├── webhook-types.ts          # PaymentWebhookEventTypes + zod schemas
│   │   ├── websocket.ts              # 7 WebSocket topics + room helpers
│   │   ├── sale-check.constants.ts   # check splitting helpers
│   │   ├── shift.types.ts            # shift session types
│   │   └── response.helper.ts        # response shaping
│   ├── components/
│   │   ├── kafka/                    # ApplicationKafkaComponent (chỉ producer)
│   │   └── websocket/                # ApplicationWebSocketComponent
│   ├── controllers/                  # 13 thư mục controller → 16 lớp controller được đăng ký
│   ├── datasources/                  # PostgresCoreDataSource
│   ├── migrations/processes/         # 2 migration (permissions, pos-session-report)
│   ├── models/                       # zod request/response schemas
│   ├── repositories/                 # re-exports từ @nx/core
│   └── services/                     # 20 services
├── package.json
└── tsconfig.json

5. Kiến trúc

Chi tiết: xem Architecture.

6. Tổng quan miền

ERD đầy đủ + bảng theo entity: xem Domain Model.

7. Tóm tắt Bề mặt

REST controllers — tham chiếu đầy đủ render trực tiếp từ /v1/api/sale/doc/openapi.json (live spec — Scalar viewer tại /doc, gateway portal):

ControllerBase pathGhi chú
SaleOrderController/sale-orders+ lifecycle (draft, items, checkout, revert, cancel, merge, split)
SaleOrderItemController/sale-order-itemsCRUD + override để validate quantity
SaleCheckController/sale-checks+ split, split-equal, merge, rollback
SaleOrderCheckController/sale-orders/:id/checksnested dưới order
KitchenStationController/kitchen-stationsCRUD
KitchenTicketController/kitchen-ticketsCRUD
KitchenTicketSaleOrderController/sale-orders/:id/kitchen-tickets/...sendToKitchen
KitchenTicketActionController/kitchen-tickets/:id/...void / rush / mark-ready / mark-served
KitchenTicketItemActionController/kitchen-ticket-items/:id/...start-cooking / mark-ready / mark-served / void
AllocationUsageController/allocation-usagesCRUD + batch complete/cancel
ReservationController/reservations+ create with allocation
ShiftController/pos/sessions+ open / close
CustomerController/customersCRUD
PointTransactionController/point-transactionsCRUD (đa số là đọc)
SalesReportController/reports/salesTổng hợp ngày, theo product, theo category, purchase-summary
PaymentWebhookController/webhooks/paymentTiếp nhận sự kiện MQ-Pay (no auth)

Async surface — tham chiếu đầy đủ tại API Events:

HướngChannelSố lượng
InboundHTTP webhook1 endpoint × 6 loại sự kiện
OutboundKafka2 (PAYMENT_SUCCESS, KITCHEN_TICKET_ITEM_STATUS_CHANGED)
OutboundWebSocket7 topic × nhiều room helpers (merchant/order/check/kitchen/allocation/reservation)

8. Components

ComponentFileMục đích
ApplicationKafkaComponentsrc/components/kafka/component.tsIdempotent producer; phát PAYMENT_SUCCESS + KITCHEN_TICKET_ITEM_STATUS_CHANGED (không có consumer)
ApplicationWebSocketComponentsrc/components/websocket/component.tsWebSocket emitter qua signal service; room fanout
Redis cache (tùy chọn)bind tại BindingKeys.APPLICATION_REDIS_CACHECache permission cho authorization

9. Services

ServiceFileMô tả ngắn
SaleOrderServicesale.service.tsCRUD đơn DRAFT, add/clear item, cancel, archive
SaleOrderItemServicesale-order-item.service.tsCập nhật item theo lô với row-level lock + recalc summary
CheckoutServicecheckout.service.tsDRAFT → PROCESSING; pricing v1+v2; revert
SaleCheckServicesale-check.service.tsTách bill: split, split-equal, merge, rollback
OrderMergeServiceorder-merge.service.tsGộp nhiều draft order; có thể đảo ngược
OrderSplitServiceorder-split.service.tsTách một order thành nhiều; phân phối lại item + allocation + pricing
KitchenTicketServicekitchen-ticket.service.tsSend-to-kitchen, void, rush, mark ready/served
KitchenTicketItemServicekitchen-ticket-item.service.tsChuyển trạng thái theo dòng + emit Kafka
AllocationUsageServiceallocation-usage.service.tsDINE_IN/TAKEAWAY/DELIVERY; reserved → completed/cancelled
ReservationServicereservation.service.tsLuồng booking với reserve allocation
ShiftServiceshift.service.tsPOS session: getCurrent, list, open, close, validate
CustomerServicecustomer.service.tsCRUD khách hàng
CustomerPointServicecustomer-point.service.tsCộng điểm loyalty khi thanh toán thành công (idempotent)
PaymentWebhookServicepayment-webhook.service.tsDispatcher sự kiện webhook (route tới handler SaleOrder vs SaleCheck)
SaleOrderPaymentWebhookServicesale-order-payment-webhook.service.tsXử lý sự kiện attempt + transaction cho SaleOrder; emit Kafka
SaleCheckPaymentWebhookServicesale-check-payment-webhook.service.tsCùng luồng cho SaleCheck
PricingNetworkServicepricing-network.service.tsHTTP client gọi @nx/pricing cho calculate() + calculateV2()
AllocationSnapshotServiceallocation-snapshot.service.tsSnapshot trạng thái allocation unit/zone trên sự kiện order để audit
ProductVariantSnapshotServiceproduct-variant-snapshot.service.tsSnapshot metadata product variant lúc add order-item
SalesReportServicesales-report.service.tsTruy vấn tổng hợp daily / product / category / purchase

10. Repositories

RepositoryNguồnGhi chú
SaleOrderRepository@nx/core+ updateSummaryFromItems, getDailySummary, getProductSales, getCategorySales
SaleOrderItemRepository@nx/core+ updateAll, deleteAll
SaleCheckRepository@nx/core+ recalculateTotals
SaleCheckItemRepository@nx/core+ createAll
KitchenTicketRepository@nx/core+ findByIdempotencyKey, getNextSequence, evaluateTicketAutoProgression
KitchenTicketItemRepository@nx/core+ createAll
KitchenStationRepository@nx/core
AllocationUsageRepository@nx/core+ existsBySaleOrderId
AllocationUnitRepository / AllocationZoneRepository@nx/core
ReservationRepository@nx/core
PosSessionRepository@nx/core+ findOpenByDeviceId
PosSessionReportRepository@nx/core
PointTransactionRepository@nx/core+ existsBySaleOrderId
CustomerRepository@nx/core
SaleChannelRepository@nx/core
ProductVariantRepository, ProductIdentifierRepository, ProductInfoRepository@nx/coreĐọc liên package
ConfigurationRepository@nx/coreĐọc cấu hình thanh toán đã mã hóa
FinanceTransactionRepository, FinanceWalletRepository@nx/coreĐọc liên package cho metadata finance lúc checkout
PurchaseOrderRepository@nx/coreĐọc liên package cho báo cáo bán hàng
MetaLinkRepository, SettingRepository, DeviceRepository@nx/coreLiên package

11. Điểm vào

FileMục đích
src/index.tsService entry → bootstrapApplication()
src/migrate.tsMigration entry → bootstrapMigration()
src/application.tsApplication extends VerifierApplication

12. Cấu hình

Env vars + dữ liệu seed: xem Configuration.

13. Vận hành

Triển khai + observability + bảo mật + runbook: xem Operations.

14. Trang liên quan

Concepts — vì sao/cách thức:

Reference — tra cứu:

Features — đào sâu:

Decisions:

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