Skip to content

PRD: Phiếu kho

ModuleKho (CORE-06)PRD IDPRD-TKT-001
StatusIn-progressOwnerInventory squad
Date2026-05-26Versionv0.1
Packages@nx/core · @nx/inventoryURDTKT

TL;DR

Cung cấp cho merchant một document duy nhất - Phiếu kho (Inventory Ticket) - để ghi nhận, điều phối, và thực thi mọi thao tác kho: chuyển giữa các địa điểm, điều chỉnh tồn, kiểm kê, trả hàng, và hủy bỏ. Mỗi phiếu mang line item và đi qua một vòng đời phê duyệt chung, nên một biến động đã lên kế hoạch chỉ được áp vào tồn sau khi được duyệt, với biến động cuối cùng truy vết đầy đủ về đúng phiếu đã cho phép nó.

1. Bối cảnh & Vấn đề

Các thao tác kho - chuyển tồn giữa các địa điểm, điều chỉnh số lượng, kiểm kê, trả hàng về vendor hoặc từ customer, hủy bỏ tồn hư hỏng - đều cần một document ghi nhận ý định, đi qua phê duyệt, và chỉ chạm vào tồn ở bước cuối cùng. Kho đã có địa điểm, mục, tồn, và audit trail bất biến, nhưng chưa có document thao tác gắn một biến động đã lên kế hoạch với các dòng tracking cuối cùng của nó.

Khi không có document như vậy, mọi thay đổi tồn ngoài mua hàng đều ad-hoc: không có trạng thái có kiểm soát giữa "dự định" và "đã áp", không có cổng phê duyệt, và không có một bản ghi duy nhất để chủ chỉ vào và nói "đây là lý do tồn biến động". Aggregate Phiếu kho chính là document đó. Nó được mô hình hóa để bao trùm toàn bộ không gian thao tác ngay từ đầu - nhiều loại phiếu, một vòng đời chung, reference partner/origin đa hình, và một self-link trả hàng/backorder - nên các milestone sau bổ sung hành vi thực thi mà không cần migration schema thêm.

2. Mục tiêu & Ngoài phạm vi

Mục tiêu

  • Một InventoryTicket header duy nhất bao trùm mọi loại thao tác tồn: Transfer, Adjustment, Cycle Count, Return to Vendor, Return from Customer, Scrap/Disposal, cộng thêm Purchase Request, Stock In, và Internal Use.
  • Một vòng đời chung DRAFT → SUBMITTED → APPROVED → IN_PROGRESS → COMPLETED / CANCELLED, thể hiện bằng hằng số có kiểu với các guard chuyển trạng thái (canSubmit / canApprove / canStart / canComplete / canCancel).
  • Line item (InventoryTicketItem) mang số lượng kế hoạch so với thực tế, lưu cùng header với CRUD scoped theo merchant và soft-delete.
  • Một schema dành sẵn các cột cấu trúc cho phần thực thi về sau (partner ref đa hình, origin ref đa hình, self-link trả hàng/backorder, link PO đã sinh, lùi ngày hiệu lực, mã lý do) nên không cần migration sau này để bổ sung hành vi.

Ngoài phạm vi

  • Thực thi vòng đời tác động tồn - hoàn tất một phiếu để tạo dòng InventoryTracking và cập nhật tồn (URD-TKT-004) được hoãn sang một milestone sau; service CRUD chưa hiện thực các chuyển trạng thái.
  • Route ghi aggregate đa dòng (header + item trong một lần gọi) - hoãn cùng với vòng đời.
  • Tách thực thi một phần cho backorder - cột self-link đã dành sẵn, chưa có hành vi trong increment này.
  • Đặt giữ theo báo giá / hạn mức và bắt buộc chặn tồn âm tại POS - ngoài phạm vi module theo URD.

3. Success Metrics

MetricMục tiêu / tín hiệu
Độ bao phủ thao tácMột ticket header mô hình hóa 100% các loại thao tác tồn đã lên kế hoạch - không cần document riêng cho từng loại
Độ bền schemaPhần thực thi về sau đáp ứng với zero migration schema bổ sung (cột dành sẵn từ đầu)
Cô lập tenancyMọi phiếu và dòng đều scoped theo merchant; đọc xuyên merchant trả về rỗng
Tính đúng vòng đờiMọi thay đổi trạng thái đi qua một guard chuyển trạng thái; không chuyển trạng thái bất hợp lệ nào được lưu

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
Nhân viên khoSoạn một phiếu cho thao tác kho, gắn các dòng của nó, và điều phối đi phê duyệt
Chủ / Quản lýRà soát và duyệt phiếu trước khi chúng ảnh hưởng tồn; hủy phiếu sai
Hệ thống (milestone sau)Áp một phiếu đã duyệt vào tồn và ghi audit trail khi hoàn tất

Kịch bản chính: tạo một phiếu với loại thao tác cho trước → thêm line item (số lượng kế hoạch) → submit → approve → start → complete (thực thi tồn hoãn sang milestone sau) - hoặc hủy từ bất kỳ trạng thái chưa-kết-thúc nào.

5. User Stories

  • nhân viên kho, tôi muốn tạo một phiếu với loại thao tác cụ thể (chuyển, điều chỉnh, kiểm kê, trả hàng, hủy bỏ), để một biến động kho đã lên kế hoạch có một nơi duy nhất.
  • nhân viên kho, tôi muốn gắn line item với số lượng kế hoạch, để phiếu nêu chính xác cái gì nên biến động.
  • nhân viên kho, tôi muốn submit một phiếu đi phê duyệt, để tồn không bị chạm tới cho đến khi ai đó ký duyệt.
  • chủ, tôi muốn duyệt hoặc hủy một phiếu qua các chuyển trạng thái có guard, để chỉ các bước vòng đời hợp lệ được cho phép.
  • chủ, tôi muốn mọi phiếu và dòng của nó được cô lập theo merchant của tôi, để merchant khác không bao giờ thấy hoặc thay đổi chúng.
  • nền tảng, tôi muốn schema đã sẵn mang các cột partner, origin, return-link, PO-đã-sinh và mã lý do, để hành vi thực thi về sau không cần migration.

6. Functional Requirements

#Yêu cầuURD ref
FR-1InventoryTicket header mô hình hóa toàn bộ không gian thao tác - 9 loại (PURCHASE_REQUEST, STOCK_IN, TRANSFER, INTERNAL_USE, ADJUSTMENT, CYCLE_COUNT, RETURN_TO_VENDOR, RETURN_FROM_CUSTOMER, SCRAP_DISPOSAL), một superset của 6 loại URD liệt kêURD-TKT-001
FR-2Vòng đời chung DRAFT → SUBMITTED → APPROVED → IN_PROGRESS → COMPLETED / CANCELLED, dưới dạng status có kiểu với ACTIVE_SET/TERMINAL_SET và các guard canSubmit/canApprove/canStart/canComplete/canCancelURD-TKT-002
FR-3Line item (InventoryTicketItem) mang số lượng kế hoạch so với thực tế, lưu cùng headerURD-TKT-003
FR-4Hoàn tất một phiếu tạo các entry tracking và cập nhật tồnURD-TKT-004
FR-5Line item dành sẵn cột lot/serial ở lớp schemaURD-TKT-005
FR-6Ghi đè địa điểm theo từng mục - header mang nguồn/đích, các dòng tách theo từng binURD-TKT-006
FR-7Header dành sẵn một partner reference đa hình (Vendor / Customer) và một origin reference đa hình cho liên kết về sauURD-TKT-001
FR-8Header dành sẵn một self-link trả hàng/backorder, một link PO đã sinh, một mã lý do, và một ngày hiệu lực để lùi ngàyURD-TKT-006
FR-9Header và dòng scoped theo merchant với soft-delete; CRUD tôn trọng cô lập merchantURD-TKT-002

Toàn văn yêu cầu và tiêu chí chấp nhận nằm trong URD Kho. PRD này tham chiếu chúng thay vì lặp lại. FR-4 (hoàn tất tác động tồn) và route ghi aggregate đa dòng được lên lịch cho một milestone sau - xem §2 Ngoài phạm vi và §12.

7. Non-Functional Requirements

Khía cạnhYêu cầu
Toàn vẹn dữ liệuKhi phần thực thi tồn đáp ứng, thay đổi tồn và entry tracking của nó được ghi cùng nhau - không có thay đổi tồn nào mà thiếu một entry audit bất biến tương ứng
Tenancy & authzMọi thao tác scoped theo merchant (x-merchant-id); kiểm soát bởi permission của inventory
An toàn vòng đờiChuyển trạng thái chỉ qua các guard predicate; trạng thái kết thúc (COMPLETED / CANCELLED) là bất biến
Độ bền schemaCột cấu trúc dành sẵn từ đầu nên phần thực thi về sau không cần migration
Soft-deleteHeader và dòng dùng soft-delete; bản ghi đã soft-delete bị loại khỏi listing tiêu chuẩn
Độ chính xácSố học số lượng kế hoạch/thực tế dùng độ chính xác thập phân (float(value, 4))
i18nNhãn loại/trạng thái/partner hiển thị cho người dùng là song ngữ ({ en, vi })

8. UX & Flows

Màn hình chính (trong apps/client): danh sách phiếu, tạo/sửa phiếu theo loại thao tác, trình soạn line item, và control trạng thái vòng đời. Controller và route definition của phiếu nằm trong @nx/inventory (controllers/inventory-ticket{,-item}).

9. Data & Domain

Thực thểVai trò
InventoryTicketDocument thao tác - identifier ITI_…, loại, trạng thái, địa điểm nguồn/đích, partner đa hình, origin đa hình, self-link trả hàng/backorder, link PO đã sinh, mã lý do, ngày hiệu lực, timestamp vòng đời, scope merchant
InventoryTicketItemMột dòng phiếu - reference tới mục với số lượng kế hoạch so với thực tế; dành sẵn cột lot/serial và cột địa điểm theo từng bin
InventoryTicketTypes9 loại thao tác, nhóm Procurement / Routine / Returns / End-of-life; PURCHASE_REQUEST chỉ là workflow (không tác động tồn, sinh ra một PO)
InventoryTicketStatusesStatus vòng đời có kiểu + ACTIVE_SET/TERMINAL_SET/isTerminal và các guard chuyển trạng thái
InventoryTicketPartnerTypesVendor / Customer với nhãn i18n cho việc phân biệt partner

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

10. Phụ thuộc & Giả định

Phụ thuộc vào

  • Địa điểm kho (URD-LOC) - phiếu tham chiếu một địa điểm nguồn/đích.
  • Mức tồn & audit biến động (URD-STK · URD-TRK) - bước hoàn tất hoãn lại về sau sẽ đọc tồn và ghi các dòng tracking.
  • Vendor / Customer (URD-VEN) - partner reference đa hình trỏ tới một vendor hoặc customer.
  • Đơn mua hàng (URD-PO) - một phiếu PURCHASE_REQUEST sinh ra một PO qua link PO-đã-sinh được dành sẵn.

Giả định

  • Merchant có ít nhất một địa điểm kho cho các reference nguồn/đích.
  • Phần hoàn tất tác động tồn đáp ứng ở một milestone sau trước khi tính năng dùng được đầu-cuối.

11. Rủi ro & Câu hỏi mở

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Thực thi vòng đời chưa được hiện thực - service mới là CRUD thuầnTheo dõi như một Ngoài phạm vi của increment này; các handler chuyển trạng thái và route aggregate lên lịch cho một milestone sau
Bề rộng schema (9 loại, ref đa hình) khi chưa có hành vi có thể lệch với nhu cầu thựcCột dành sẵn có chủ ý để tránh migration; hành vi được kiểm chứng khi phần thực thi đáp ứng
Ngữ nghĩa tách thực thi một phần cho backorder chưa định nghĩaCột self-link đã dành sẵn; hành vi tách là một câu hỏi thiết kế mở cho milestone thực thi
Hoàn tác một phiếu đã hoàn tất so với tracking đã ghiMở: định nghĩa đường hoàn tác/bù trừ khi hoàn tất đã ghi tồn

12. Kế hoạch Phát hành & Tiêu chí Ra mắt

Khía cạnhKế hoạch
PhaseP2 (thao tác đa địa điểm) - xem danh mục tính năng URD
RolloutMọi merchant; không feature flag
MigrationThực thể mới (InventoryTicket, InventoryTicketItem) được thêm với bộ cột đầy đủ; không dự kiến migration sau cho phần thực thi
Tiêu chí ra mắtIncrement này: schema header + dòng và CRUD scoped theo merchant đã kiểm chứng. Hoàn chỉnh tính năng (milestone sau): các chuyển trạng thái submit→approve→start→complete được thực thi và một phiếu COMPLETED ghi tracking + cập nhật tồn
Giám sátLượng phiếu theo từng merchant theo loại, số lần guard chuyển trạng thái từ chối, và (sau khi có thực thi) kiểm tra nhất quán tồn-so-với-tracking

13. FAQ

Hoàn tất một phiếu có làm biến động tồn ngay hôm nay không? Chưa - increment này ship schema header/dòng và CRUD scoped theo merchant. Phần hoàn tất tác động tồn (URD-TKT-004) được lên lịch cho một milestone sau.

Vì sao có 9 loại phiếu khi URD liệt kê 6? Schema mô hình hóa toàn bộ không gian thao tác ngay từ đầu (thêm Purchase Request, Stock In, và Internal Use) nên các milestone sau bổ sung thực thi mà không cần migration schema.

PURCHASE_REQUEST dùng để làm gì? Đó là một loại chỉ-workflow - nó không tác động tồn trực tiếp mà thay vào đó sinh ra một đơn mua hàng qua link PO-đã-sinh được dành sẵn.

Một merchant có thể thấy phiếu của merchant khác không? Không - mọi phiếu và dòng đều scoped theo merchant (x-merchant-id) với soft-delete; đọc xuyên merchant trả về rỗng.

Giao hàng một phần/trả hàng được xử lý thế nào? Header mang một cột self-link trả hàng/backorder, dành sẵn từ bây giờ; hành vi tách thực thi một phần được định nghĩa khi phần thực thi vòng đời đáp ứng.

References

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