Skip to content

Type Deep Dive — Approval and Adjustment Flows

1. Import / Export

1.1 Cùng engine, khác vocabulary

Import và export FE thực chất dùng chung:

  • inventory_document
  • export_request.graphql
  • action changeInventoryDocumentStatus

Import list chỉ là export list được filter bằng type_id = import.

Điều này giải thích vì sao:

  • semantics FE dễ bị lệch,
  • code import đang reuse hook/query của export,
  • naming route/moduleId hiện không luôn phản ánh engine thật.

1.2 Fast path import Excel

InventoryImport.tsx đi đường ngắn:

  1. upload/parse Excel
  2. insert inventory_document
  3. gọi ngay changeInventoryDocumentStatus(... inventory_released)

Nó khác hẳn flow import form thường và vì vậy là một boundary test riêng.

2. Check request

Check request dùng inventory_request.

Ở detail page, FE rebuild capture trước khi đổi status balanced.

Khi backend nhận status balanced:

  • thiếu hàng -> sinh import document released
  • thừa hàng -> sinh export document released

Nghĩa là:

  • adjustment movement của check không phải user tự nhập từng phiếu,
  • mà là side effect tự sinh từ event.

3. Transfer request

Transfer request cũng dùng inventory_request, nhưng complete không phải điểm cuối.

Flow thật:

  1. FE tạo/duyệt transfer request
  2. backend tạo order_transfer
  3. export inventory_document được release
  4. order chuyển delivering
  5. import inventory_document ở kho nhận được auto-sinh
  6. khi import release xong mới order_transfer_completed

Vì vậy test transfer phải ít nhất đi qua:

  • request,
  • order transfer,
  • export document,
  • import document.

4. Transfer goods / shipping

TransferGoods là boundary riêng:

  • có draft,
  • có diff tab,
  • có thể fan-out nhiều note theo receive_warehouse_id,
  • có runtime filter status khá phức tạp.

Điều này cho thấy UI “chuyển hàng” không chỉ là wrapper cho transfer request, mà là một workflow riêng gắn với shipping_note.

5. Internal order

InternalOrders hiện là host chung cho:

  • material order
  • transfer order

Nó không còn là inventory request list thuần. Runtime logic chủ yếu đi theo:

  • order_kind
  • order_service_status

Kết luận:

  • nội bộ kho không nên mô tả chỉ bằng inventory request,
  • phải nhìn cả order layer.

6. Rủi ro / Findings kỹ thuật

IDMứcFinding
AF-F01P1transfer_goods đang drift moduleId giữa root route và create/detail/submenu.
AF-F02P1ROUTE_INVENTORY_IMPORT gắn nhầm moduleId = export_request_sheet.
AF-F03P1Menu import/export cho BranchPOS nhưng route guard lại không khớp hoàn toàn với submenu visibility.
AF-F04P1InventoryImport.tsx có bug validation “Chưa chọn kho!” nhưng lại check danh sách inventory thay vì warehouseId.
AF-F05P1TransferRequestDetail đang hard-code branch-type taxonomy ở FE để gate status, không có permission source thống nhất.
AF-F06P2TransferGoods list có runtime visibility rule phức tạp hơn hẳn route guard, dễ gây mismatch giữa menu và dữ liệu nhìn thấy.