ADR-0004. AllocationUsage(usageType, usageId) đa hình dùng chung cho SaleOrder + Reservation
| Trường | Giá trị |
|---|---|
| Trạng thái | Accepted |
| Ngày | 2026-03-12 |
| Người quyết định | Phat Nguyen |
| Thay thế cho | - |
Bối cảnh
- Một bàn ăn (AllocationUnit) có thể bị chiếm bởi một SaleOrder đang hoạt động (khách đang ăn) hoặc một Reservation (đặt chỗ cho tương lai).
- Cả hai đều cần: đơn vị chiếm, khung thời gian, trạng thái (ACTIVE/SUCCESS/CANCELLED/EXPIRED), người phụ trách.
- Hai bảng song song (
SaleOrderAllocation+ReservationAllocation) làm trùng lặp mô hình và phá vỡ các truy vấn dùng chung như "lúc 7 giờ tối còn bàn nào trống".
Quyết định
Một bảng AllocationUsage duy nhất với cặp cột đa hình (usageType, usageId) được sinh qua generatePrincipalColumnDefs({ discriminator: 'usage' }):
usageType ∈ {SALE_ORDER, RESERVATION}usageIdtham chiếu tới id của parent- Cùng vòng đời, cùng phòng WebSocket, cùng chuỗi huỷ dây chuyền
Khi một Reservation chuyển sang CHECKED_IN, sale tạo một SaleOrder và usageType của AllocationUsage được cập nhật thành SALE_ORDER còn usageId trỏ tới id của đơn mới (vẫn là cùng một dòng usage tiếp tục).
Hệ quả
| Ưu | Nhược |
|---|---|
| Một mô hình chiếm chỗ duy nhất | Không có DB FK tới parent (do đa hình) |
| Truy vấn "lúc 7 giờ tối còn trống" chỉ quét một bảng | Tầng service phải kiểm tra usageId có tồn tại |
| Chuỗi huỷ dây chuyền đồng nhất | Phải ép kiểu/phân biệt loại trong code service |
Phát tán WebSocket qua getAllocationUsageRooms chạy được cho cả hai | An toàn kiểu dựa vào TS, không phải DB |
Các phương án đã cân nhắc
| Phương án | Ưu | Nhược | Lý do từ chối |
|---|---|---|---|
| Bảng riêng cho mỗi loại usage | DB FK chặt chẽ | Trùng lặp schema + truy vấn + phòng WS | Nhọc công bảo trì |
AllocationUsage với cả saleOrderId + reservationId (nullable, loại trừ nhau) | Một bảng, vẫn giữ được FK | Ràng buộc loại trừ phức tạp; truy vấn luôn phải lọc theo loại | Phương án nửa vời |
Tham chiếu
core/src/models/schemas/allocation/allocation-usage/schema.tssale/src/services/allocation-usage.service.tssale/src/services/reservation.service.ts(tạo Reservation + AllocationUsage trong cùng một TX)