docs: resolve Assignment open questions, unblock Lane C
Stakeholder decided: createAssignment() blocks if AssetItem.status isn't in_stock, and update routes use PATCH /api/<entity>/[id] (applies to both Assignment and PurchaseOrder). Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e3a3780253
commit
f325abf22c
@@ -107,11 +107,13 @@ Entity mới, độc lập với `AssetModel`.
|
||||
- Assign 1 `License` phải **tăng** `License.seatsUsed`, và phải **bị từ chối** nếu `seatsUsed >= seatsTotal` (không overbook). Trả lại (set `returnedAt`) **giảm** `seatsUsed`. Toàn bộ phải chạy trong 1 transaction — đây chính là rủi ro seat-count race condition mà `code-reviewer` đã note trước đó cho `License` (xem "Trạng thái hiện tại" ở `../CLAUDE.md`, mục `License`) — `Assignment` là chỗ thực sự implement/exercise seat counting lần đầu tiên.
|
||||
- Chuyển tài sản giữa nhân viên (case đặc biệt đã note ở trên: "Tài sản luân chuyển giữa phòng ban / chi nhánh") = đóng `Assignment` cũ (`returnedAt = now`) + tạo `Assignment` mới, cả hai trong 1 transaction. Không cần entity "Transfer" riêng.
|
||||
- `AssetItem.status` phải đồng bộ theo trạng thái `Assignment`: tạo `Assignment` → status `assigned`; trả lại → status `in_stock`, trừ nhánh RMA/sửa chữa đã note ở "Case đặc biệt cần xử lý" (đó là case riêng, không đi qua path trả-lại-thông-thường này).
|
||||
- **Chốt 2026-08-02 (trả lời 2 câu hỏi mở của `pm`):** (a) `createAssignment()` phải **chặn** nếu `AssetItem.status` hiện tại khác `in_stock` (vd không cho assign 1 item đang `repair`/`retired`) — trả lỗi 400, không chỉ dựa vào điều kiện "chưa có Assignment active nào". (b) Route "update" (trả lại/chuyển giao `Assignment`, nhận hàng `PurchaseOrder`) dùng `PATCH /api/<entity>/[id]` — tiền lệ REST-shape đầu tiên cho update trong codebase, áp dụng thống nhất cho cả `Assignment` và `PurchaseOrder`, không dùng action-based sub-route.
|
||||
|
||||
**Ràng buộc dữ liệu:**
|
||||
- `Assignment.employeeId` bắt buộc, trỏ tới 1 `Employee` có thật.
|
||||
- Đúng 1 trong `assetItemId`/`licenseId` được set (XOR) — validate Zod `.refine()`.
|
||||
- Không được có > 1 `Assignment` active cho cùng 1 `AssetItem` tại 1 thời điểm (enforce ở tầng application, không phải DB constraint).
|
||||
- Tạo `Assignment` bị chặn nếu `AssetItem.status` khác `in_stock` (400).
|
||||
- `License.seatsUsed` tăng/giảm đồng bộ trong 1 transaction khi assign/return; assign bị chặn nếu `seatsUsed >= seatsTotal`.
|
||||
|
||||
## Module tương lai: Rack/Slot management + IoT (chưa build, chỉ note kiến trúc)
|
||||
|
||||
Reference in New Issue
Block a user