Ca / POS Session
1. Tổng quan
| Thuộc tính | Giá trị |
|---|---|
| ID | FEAT-SALE-SHIFT |
| Trạng thái | Stable |
| Owner | sale-team |
| Phụ thuộc | Device, SaleChannel, SaleOrder (liên kết qua openedInSessionId/closedInSessionId) |
Một PosSession đại diện cho ca của một thu ngân trên một POS device cụ thể. Nó mở với một floating tiền mặt, gắn vào tất cả row SaleOrder được tạo trong ca, và đóng với bước đối chiếu (kỳ vọng vs thực tế tiền mặt). Khi shift management bật, SaleOrderService chặn tạo order nếu không có session mở cho device.
2. Mô hình thực thể
Chi tiết trường — xem Mô hình miền §3.7.
3. Vòng đời
| Từ | Sự kiện | Đến | Side effect |
|---|---|---|---|
OPEN | closeSession | CLOSED | tính cashDiscrepancy = actualCash − expectedCash; tạo snapshot PosSessionReport |
Bất biến: nhiều nhất một session OPEN per (merchantId, deviceId). Áp đặt bởi ShiftService.validateAndAttachSession và một partial unique index.
4. Vận hành
ShiftService (shift.service.ts — 943 dòng).
| Phương thức | Chữ ký | Mục đích |
|---|---|---|
getCurrentSession | { context, deviceId } | Lấy session OPEN cho một device, hoặc null |
listSessions | { context, where, page, ... } | Danh sách lọc (CRUD) |
openSession | { context, data: TOpenSessionRequest } | Validate không có session mở khác; tạo OPEN với openingFloat |
closeSession | { context, id, data: TCloseSessionRequest } | Tính discrepancy; tạo PosSessionReport; OPEN → CLOSED. Theo dõi closeRecountCount cho retry. |
isShiftManagementEnabled | { merchantId } | Feature flag per-merchant (đọc từ Configuration) |
validateAndAttachSession | { deviceId, merchantId } | Dùng bởi SaleOrderService.createDraftOrder — chặn nếu yêu cầu shift nhưng không có session mở |
5. REST Endpoints
| Verb | Path | Auth | Permission | Handler |
|---|---|---|---|---|
POST | /pos/sessions | JWT/BASIC | Shift.openSession | openSession |
POST | /pos/sessions/:id/close | JWT/BASIC | Shift.closeSession | closeSession |
GET | /pos/sessions | JWT/BASIC | Shift.list | CRUD |
GET | /pos/sessions/current?deviceId=... | JWT/BASIC | Shift.getCurrent | getCurrentSession |
| 6× CRUD | /pos/sessions | JWT/BASIC | Shift.<crud> | CRUD |
OpenAPI live:
/v1/api/sale/doc/openapi.json.
6. Sự kiện
Outbound: Sale hiện không phát sự kiện WebSocket hoặc Kafka riêng cho shift. Session được quan sát qua REST.
7. Flow đối chiếu
8. Trang liên quan
- Sale Order — order gắn vào session
- Mô hình miền