Skip to content

MK Inventory Allocation Capability Rebuild Packet

  • Packet status: DETAILED SOURCE-RECONCILED REBUILD INPUT / POLICY, TARGET-ROLE AND RUNTIME REVIEW REQUIRED
  • Capability: inventory-lot allocation to an existing MK outbound shipment
  • Process owner: PROC-OMS-INVENTORY-TO-OUTBOUND-ALLOCATION-MK
  • Operating profile: mk-order
  • Current module: oms.allocation
  • Current primary records: T_INVENTORY_LOT, T_LOAD_ALLOCATION, T_LOAD, T_LOAD_ITEM
  • Related source records: T_TRANSLOAD, source inbound T_LOAD/T_LOAD_ITEM
  • Related target bridge: T_EQUIPMENT, T_EQUIPMENT_LOAD
  • Target stack: React + Next.js + framework-independent TypeScript application/domain/repository contracts + MySQL first
  • Worker requirement: none for the core local allocation transaction; use a worker only for separately approved asynchronous effects
  • Later database target: PostgreSQL after accepted React + Next.js + TypeScript + MySQL stabilization
  • Current Process contract: MK_SCHEDULE_ALLOCATION_WORKFLOW.md
  • Current source authority: MK_INVENTORY_ALLOCATION_SOURCE_AUTHORITY.md
  • Important boundary: this packet assembles current behavior, target contracts and migration requirements. It does not approve open allocation, reversal, UOM, quantity/weight or role policy.

1. Capability Outcome

1.1 Business problem

MK receiving creates inventory lots, while outbound Sales records requested shipment demand. Allocation must establish an explicit, tenant-scoped relation between eligible received inventory and an existing outbound shipment without making Inbound or Outbound CRUD itself the allocation authority.

The capability must preserve these distinctions:

Inbound receipt
!= Inventory Lot eligibility
!= Allocation commitment
!= Outbound demand completion
!= Scale / Packing / Delivery completion

1.2 Required user-visible result

An authorized inventory/allocation operator can:

  1. enter the Allocation Workbench through the assigned MK menu;
  2. search eligible source lots and understand the exact inbound source identity;
  3. add intended source lots to a basket;
  4. select one existing outbound shipment with an active container/equipment bridge;
  5. preview quantity, weight, UOM, rate and target identity before commit;
  6. apply the basket once;
  7. reread the exact created outbound item, allocation relation and source-lot balance;
  8. distinguish allocation completion from physical shipment completion;
  9. recover from stale balance, duplicate, timeout or unknown result without replaying the complete basket blindly;
  10. correct or reverse an allocation only through an explicitly approved owner command;
  11. retain stable Wiki topics when the current PHP page later moves to React + Next.js.

1.3 Explicit non-goals

This packet does not approve:

  • one universal MK order or inventory status;
  • allocation as a side effect of ordinary Inbound or Outbound Save;
  • hidden allocation inside Booking Save;
  • a generic table/column mutation API;
  • automatic conversion between arbitrary UOM values;
  • silent over-allocation or negative remaining balances;
  • blind replay after a missing response;
  • hard deletion as the target reversal model;
  • a universal unallocate path before downstream-lock policy is accepted;
  • a new asynchronous worker for the core local transaction;
  • route-by-route copying of current PHP into TypeScript;
  • PostgreSQL conversion in the first React/Next.js write wave.

2. Current Truth Table

Statement Current source-reconciled truth
Workbench selects an existing outbound shipment Yes
Workbench creates a new target shipment No
One basket row represents one source lot/source order item pair Yes
Current UI allocates the full displayed remaining lot Yes
Current UI supports partial-lot quantity/weight entry No
Current Apply creates a new outbound item for every basket source Yes
Current Apply creates one T_LOAD_ALLOCATION row per new outbound item Yes
The whole basket is one local DB transaction Yes
A later row failure rolls back earlier rows in the request Yes, under the current request transaction
Immediate lot update decrements REMAIN_NET_WEIGHT Yes
Immediate lot update decrements REMAIN_QUANTITY No
Current write validates LOT_STATUS='OPEN' again Not proven in the write helper
Current write validates the complete source item/transload eligibility again Not proven
Current write validates UOM compatibility or conversion No approved validation found
Current request has a durable idempotency token No
Current general unallocate/reversal command exists Not source-confirmed
Outbound item delete is blocked when an active allocation exists Yes
Outbound allocated-item update fully reconciles allocation and lot balance No
Booking compatibility can affect lot/allocation state Yes, separately documented
React + Next.js allocation implementation exists No

Every downstream document must classify statements as:

CURRENT SOURCE-RECONCILED
CURRENT RUNTIME-VERIFIED
USER-APPROVED FUTURE PLAN
TARGET MIGRATION DESIGN
OPEN POLICY / UNKNOWN

3. Capability Boundary

3.1 Allocation owns

  • selection of eligible source lot(s);
  • selection of one eligible existing outbound shipment;
  • accepted source-to-target allocation relation;
  • allocation quantity, weight, rate, UOM and remark snapshot;
  • target outbound item created for the allocation under current parity behavior;
  • conditional source balance consumption;
  • exact post-commit source/target/allocation readback;
  • duplicate, stale, unknown-result and reversal reconciliation;
  • allocation audit and correction reason in the target model.

3.2 Allocation does not own

  • receipt or lot materialization;
  • arbitrary lot quantity/weight correction;
  • general Outbound header/item CRUD;
  • Booking lifecycle;
  • Scale, Packing, Delivery or Cost completion;
  • Commercial fulfillment;
  • Yard/Warehouse physical movement;
  • cross-tenant or customer-specific policy;
  • hidden cleanup initiated from another module.

3.3 Cross-owner handoff

Inbound receipt owner
-> exact Inventory Lot
-> Allocation owner
-> exact T_LOAD_ALLOCATION + target Outbound Item
-> Outbound/Scale/Packing/Delivery owners

A child owner must reread its own authoritative data. No child may infer completion from a success toast or another child’s label.


4. Actors And Capabilities

4.1 Actors

Actor Normal responsibility Must not do
Inventory/Allocation operator review source lots, basket and target; apply; reread; escalate conflicts edit DB rows, assume an unallocate path, replay unknown requests
Receiving operator establish and correct received source evidence through Inbound/Inventory owner change allocation rows from Inbound editor
Shipping operator establish outbound shipment and review allocated demand allocate through ordinary Outbound Save
Manager/Administrator review conflict, correction or reversal; authorize bounded recovery use generic mutation as a universal recovery
Support/Migration operator inspect exact IDs, request identity, callers and parity invent business policy or modify Production without authorization

4.2 Target semantic capabilities

oms.allocation.view
oms.allocation.preview
oms.allocation.apply
oms.allocation.correct
oms.allocation.reverse
oms.allocation.reconcile
oms.allocation.support

Target authorization is evaluated from authenticated actor, tenant, profile, semantic capability, record scope and current state. Numeric role IDs and CLIENT_ID === 2 are compatibility inputs only.

4.3 Record-scope rules

  • source lot, source order/item/transload and target order/item must belong to the effective tenant;
  • target order must be an active MK Outbound Sales order;
  • source lot must be active and eligible under accepted lot policy;
  • actor must not infer access from a visible row alone;
  • direct IDs must be revalidated server-side;
  • correction/reversal requires stronger capability and downstream-state review than ordinary Apply.

5. Current Entry And Interaction Model

5.1 Current entry

Operations > Orders > Allocation Workbench
slug: mk-allocation-workbench
module: oms.allocation

5.2 Current page model

The page exposes:

  • source mode/filter/search;
  • eligible source-lot list;
  • client-side basket;
  • existing target-shipment selector;
  • selected target summary;
  • Apply to Existing Shipment action.

Client-side state and localStorage are convenience state only. They are not allocation authority or durable intent.

5.3 Current basket identity

INVENTORY_LOT_ID : SOURCE_ORDER_ITEM_ID

The UI copies the displayed full REMAIN_QUANTITY and REMAIN_NET_WEIGHT into the Apply payload. It does not present a partial-allocation input.

5.4 Current target behavior

The Workbench requires an existing target order with:

  • active Outbound Sales classification;
  • active equipment-load/equipment bridge;
  • nonempty container number;
  • nonempty size;
  • equipment-load status not RETURNED or BROKEN.

It does not create a new outbound shipment.


6. State Model

These are semantic state families. They are not automatic schema changes.

6.1 Inventory Lot eligibility projection

ELIGIBLE
PARTIALLY_AVAILABLE
EXHAUSTED
HELD
CLOSED
CONFLICT

Current source-list evidence commonly treats an active OPEN lot with positive REMAIN_NET_WEIGHT as eligible. The target policy must also define quantity, UOM, source status, hold/close and correction rules.

6.2 Outbound demand allocation projection

UNALLOCATED
PARTIALLY_ALLOCATED
ALLOCATED
OVERALLOCATED_CONFLICT
NOT_APPLICABLE

Current Workbench creates new target items per source lot rather than allocating against a preexisting demand line. The target must preserve this for parity initially or explicitly approve a different demand-line model.

6.3 Allocation relation state

ACTIVE
CORRECTED
REVERSED
CONFLICT

Current source primarily represents active versus soft-deleted allocation rows. The target should preserve immutable correction/reversal evidence rather than hard-delete financial/inventory history.

6.4 Basket state

DRAFT_CLIENT_ONLY
PREVIEWED
COMMITTED
CONFLICT
UNKNOWN

Current basket is client-only until Apply. A target preview/request identity may be durable or idempotently reconstructable; the exact persistence design remains a P5/P6/P12 decision.


7. Authoritative Data And Identity

7.1 Entity relationship

erDiagram
    T_LOAD ||--o{ T_LOAD_ITEM : contains
    T_INVENTORY_LOT ||--o{ T_LOAD_ALLOCATION : supplies
    T_LOAD_ITEM ||--o{ T_LOAD_ALLOCATION : receives
    T_LOAD ||--o{ T_LOAD_ALLOCATION : target_order
    T_LOAD_ITEM ||--o{ T_INVENTORY_LOT : source_item
    T_TRANSLOAD ||--o{ T_INVENTORY_LOT : source_receipt
    T_EQUIPMENT_LOAD }o--|| T_LOAD : bridges_target
    T_EQUIPMENT ||--o{ T_EQUIPMENT_LOAD : identifies_container

7.2 Stable current identities

Identity Purpose
T_INVENTORY_LOT.ID/UUID source inventory identity
SOURCE_ORDER_ID source Inbound Purchase header
SOURCE_ORDER_ITEM_ID exact source line
SOURCE_TRANSLOAD_ID exact receipt/execution bridge
target T_LOAD.ID/UUID existing Outbound Sales shipment
created target T_LOAD_ITEM.ID target line created by current Apply
T_LOAD_ALLOCATION.ID authoritative source-to-target relation
request token, target design duplicate/unknown-result reconciliation
correction/reversal identity, target design immutable adjustment chain

7.3 T_INVENTORY_LOT field dictionary

Field Meaning / rule
ID, UUID stable lot identity; never use list position
CLIENT_ID tenant scope
SOURCE_ORDER_ID originating Inbound order
SOURCE_ORDER_ITEM_ID originating line
SOURCE_TRANSLOAD_ID originating receipt/transload
LOT_STATUS current lot lifecycle label; accepted eligibility criteria remain policy-owned
INBOUND_QUANTITY source received quantity snapshot
INBOUND_NET_WEIGHT source received net-weight snapshot
REMAIN_QUANTITY remaining quantity projection/persisted value; current Apply does not immediately decrement it
REMAIN_NET_WEIGHT remaining net-weight value; current Apply conditionally decrements it
UOM lot UOM; target must validate compatibility/conversion explicitly
COMMODITY_ID/NAME lot commodity evidence
UNIT_RATE current source rate snapshot/proposal for target line
OWNER_COMPANY_ID inventory owner/counterparty context
WAREHOUSE_LOCATION physical-location projection; does not itself prove allocation eligibility
DELETED_AT soft-delete boundary

7.4 Target T_LOAD / T_LOAD_ITEM

Field group Meaning
target T_LOAD.ID/UUID existing Outbound Sales order
order direction/class must remain active Sales/Outbound
Booking/container/equipment references target operational bridge; separate owner
target T_LOAD_ITEM.ID current Apply-created line for one source lot
QUANTITY allocated/requested quantity snapshot; current helper inserts integer-normalized quantity
NET_WEIGHT or equivalent target allocated weight snapshot
UOM target line UOM
commodity/rate/remark source snapshot or operator-approved values

7.5 T_LOAD_ALLOCATION

Field Target semantic meaning
ID stable allocation relation identity
CLIENT_ID tenant scope
OUTBOUND_ORDER_ID target shipment
OUTBOUND_ORDER_ITEM_ID exact target line
INVENTORY_LOT_ID exact source lot
ALLOCATED_QUANTITY accepted allocated quantity
ALLOCATED_NET_WEIGHT accepted allocated net weight
ALLOCATED_RATE rate snapshot when applicable
REMARK bounded operator/business note, not hidden state
DELETED_AT current soft-delete compatibility; target reversal should retain reason/history

7.6 Target request identity

The target Apply command requires a stable request identity, for example:

allocationRequestToken
+ tenant
+ targetOrderId
+ normalized ordered source rows
+ preview/freshness fingerprint

The final storage location is not selected here. The identity must allow exact duplicate and timeout reconciliation without reapplying lot consumption.


8. Current Quantity, Weight And UOM Asymmetry

8.1 Current immediate write

For each basket row the current helper:

  1. creates a target Outbound item;
  2. creates a T_LOAD_ALLOCATION row with quantity and weight;
  3. conditionally decrements only T_INVENTORY_LOT.REMAIN_NET_WEIGHT;
  4. leaves REMAIN_QUANTITY unchanged in that immediate command.

8.2 Why this matters

The system can show:

allocated quantity recorded
+ allocated weight recorded
+ remaining weight reduced
+ remaining quantity unchanged until another reconciliation path

This is not automatically wrong if quantity is informational for certain UOMs, but no universal approved policy was found. A migration must not silently copy the asymmetry without documenting the rule.

8.3 Target decision required

For every supported UOM define:

  • authoritative consumption dimension: quantity, weight or both;
  • allowed precision and rounding;
  • conversion source and version;
  • zero handling;
  • lower-bound check;
  • remaining-value update;
  • conflict/reconciliation behavior.

No implicit conversion is allowed.


9. Semantic Query Contracts

9.1 GetEligibleInventoryLots

Input:

tenant context
source mode
optional inbound order
search text
page/limit

Returns:

  • lot and exact source identities;
  • commodity, UOM, inbound and remaining quantity/weight;
  • lot/source/receipt state;
  • warehouse/source-mode projection;
  • allocation summary;
  • eligibility result and blocking reasons;
  • freshness/version marker.

No mutation.

9.2 GetAllocationTargets

Returns existing eligible Outbound Sales shipments with:

  • order/Booking/reference;
  • container/equipment/size;
  • active bridge state;
  • current allocated quantity/weight summary;
  • target freshness marker;
  • blocking reason.

9.3 GetAllocationPreview

Input:

target order identity
ordered source lot rows
requested quantity/weight/UOM per source

Returns:

  • exact normalized rows;
  • source and target freshness;
  • projected target lines;
  • projected source balances;
  • UOM/precision warnings;
  • duplicate/conflict detection;
  • basket atomicity statement;
  • request fingerprint.

No mutation.

9.4 GetOutboundAllocationState

Returns target order, target items, active allocations, source lots and independently owned downstream blockers.

9.5 GetInventoryLotBalanceAndAllocationHistory

Returns source receipt, original values, active allocations, corrections/reversals, current remaining values and any conflict.

9.6 GetAllocationResultByRequestToken

Returns:

NOT_FOUND
COMMITTED
CONFLICT
UNKNOWN_NEEDS_RECONCILIATION

with exact target item/allocation IDs and source before/after values.


10. Semantic Command Contracts

10.1 AllocateInventoryBasket

Purpose: parity command for the current all-or-nothing basket.

Input:

{
  "requestToken": "uuid",
  "targetOrderId": 123,
  "targetVersion": "...",
  "rows": [
    {
      "inventoryLotId": 45,
      "sourceOrderId": 10,
      "sourceOrderItemId": 11,
      "sourceTransloadId": 12,
      "quantity": "10.000",
      "netWeight": "20000.000",
      "uom": "LB",
      "rate": "0.1200",
      "remark": ""
    }
  ]
}

Required server behavior:

  1. authenticate tenant/actor/capability;
  2. normalize and validate unique ordered rows;
  3. check request-token duplicate;
  4. reread target order/equipment bridge;
  5. reread every source lot and exact source relation;
  6. validate status, balance, commodity, UOM and freshness;
  7. begin one local transaction;
  8. conditionally consume accepted source balances;
  9. create target item and allocation relation per row under the accepted parity model;
  10. write audit/correction metadata;
  11. commit all rows or none;
  12. reread target items, allocations and source balances;
  13. return exact IDs and before/after values.

No provider call and no worker are required.

10.2 AllocateInventoryToOutbound

Single-row semantic variant. It may share the same application command internally but must preserve the same idempotency and readback contract.

10.3 CorrectAllocation

Allowed only after accepted policy defines:

  • editable fields;
  • source balance correction;
  • target item correction;
  • downstream locks;
  • reason/audit;
  • whether correction creates a new immutable adjustment relation.

10.4 ReverseAllocation

Target recommendation:

original allocation remains
+ reversal record/reason/actor/time
+ source balance restored conditionally
+ target item disposition explicit
+ downstream blockers reread

Do not hard-delete evidence as the primary target model.

10.5 ReconcileAllocationUnknownResult

Input: request token and strongest source/target identities.

Result:

FOUND_AND_READ_BACK
CONFIRMED_ABSENT_RETRY_ALLOWED
PARTIAL_OR_CONFLICT_MANUAL_REVIEW
UNKNOWN_MANUAL_REVIEW

10.6 No generic mutation command

The target must not expose:

POST table=T_LOAD_ALLOCATION
PATCH T_INVENTORY_LOT.REMAIN_NET_WEIGHT

as the business contract.


11. Stable Error Catalog

Code Meaning / operator action
ALLOCATION_UNAUTHENTICATED sign in through assigned account
ALLOCATION_FORBIDDEN actor lacks capability or record scope
ALLOCATION_PROFILE_NOT_APPLICABLE tenant/profile does not support this flow
ALLOCATION_SOURCE_NOT_FOUND reread source lot/filter
ALLOCATION_SOURCE_NOT_ELIGIBLE source state/hold/close blocks allocation
ALLOCATION_TARGET_NOT_FOUND target shipment absent/foreign/deleted
ALLOCATION_TARGET_NOT_READY target lacks accepted container/size/bridge state
ALLOCATION_UOM_MISMATCH stop; use approved conversion/correction policy
ALLOCATION_QUANTITY_INVALID quantity zero/negative/precision invalid
ALLOCATION_WEIGHT_INVALID weight zero/negative/precision invalid
ALLOCATION_INSUFFICIENT_QUANTITY requested quantity exceeds accepted balance
ALLOCATION_INSUFFICIENT_WEIGHT requested weight exceeds accepted balance
ALLOCATION_STALE_BALANCE source changed after preview; refresh
ALLOCATION_STALE_TARGET target changed after preview; refresh
ALLOCATION_DUPLICATE_REQUEST return prior committed result; do not reapply
ALLOCATION_DUPLICATE_RELATION equivalent active source-target allocation exists
ALLOCATION_BASKET_CONFLICT one or more rows fail; no commit under all-or-nothing policy
ALLOCATION_DOWNSTREAM_LOCKED Scale/Packing/Delivery/other accepted child blocks correction/reversal
ALLOCATION_REVERSE_CONFLICT reversal cannot restore safely
ALLOCATION_RESULT_UNKNOWN reread by request/source/target before retry
ALLOCATION_DATA_CONFLICT persisted rows/balances disagree; manual review
ALLOCATION_SCHEMA_NOT_READY required schema/index/precision unavailable
UNEXPECTED_ERROR safe generic message plus correlation ID

Internal SQL and raw data/provider details are logged safely and not exposed as validation text.


12. Transaction, Concurrency And Idempotency

12.1 Current transaction

Current Apply executes one request-level local DB transaction. A later basket-row error rolls back earlier row inserts and balance updates.

12.2 Required target serialization

The target must serialize competing consumption of the same source lot without relying on application memory.

Acceptable mechanisms may include:

  • conditional atomic balance update with affected-row verification;
  • repository-level optimistic version/fingerprint;
  • a bounded database lock strategy approved for the target DB/runtime.

The exact mechanism is selected by P5/P11/P12. The invariant is:

one accepted source balance
cannot be consumed twice

12.3 Idempotency

The same request token and normalized payload:

  • returns the original committed result;
  • does not create another target item;
  • does not insert another allocation;
  • does not decrement the lot again.

A reused token with a different payload returns a conflict.

12.4 Basket atomicity

Recommended initial migration parity:

all rows committed
or
no row committed

If Product later wants partial basket success, it requires an explicit policy, per-row request identity, UI and recovery redesign. It must not emerge accidentally from implementation.


13. Exception And Recovery Matrix

ID Detection Required reread Safe recovery Must not repeat blindly
ALLOC-EXC-010 source disappeared from list lot + source item/transload select another eligible source or escalate stale basket Apply
ALLOC-EXC-020 target no longer eligible target order/equipment bridge choose corrected target after owner review same Apply
ALLOC-EXC-030 stale/insufficient balance lot + active allocations refresh preview; submit adjusted request once old quantity/weight
ALLOC-EXC-040 two operators apply same lot request result + lot/allocation history accept winning commit; loser refreshes second full basket
ALLOC-EXC-050 Apply response missing request token, target items, allocation rows, lot balances use committed result or retry only when absence confirmed full Apply button
ALLOC-EXC-060 later basket row fails transaction/result + all source/target rows under current parity expect no rows; reconcile if evidence disagrees individual assumptions
ALLOC-EXC-070 quantity/weight remaining disagree lot original values + active allocations stop and reconcile through Allocation/Inventory owner manual field overwrite
ALLOC-EXC-080 outbound item edited after allocation item + allocation + lot use approved correction/reversal ordinary Outbound Save
ALLOC-EXC-090 inbound lot/source edited after allocation source item/transload/lot/allocation/ledger use approved Inventory/Allocation correction source-row overwrite
ALLOC-EXC-100 Booking compatibility changed/deleted allocation Booking, order/item, lot, allocation and logs stop dependent work; reconcile exact children another Booking Save
ALLOC-EXC-110 unallocate requested allocation + all downstream children follow approved reversal policy or escalate delete row/manual balance add
ALLOC-EXC-120 foreign/denied direct ID tenant/actor/record scope return through assigned menu/account alternate direct route

Universal rule:

Do not repeat Apply, source correction, target edit or Booking Save
until lot + target item + allocation + request identity are reread.

14. Current Caller And Consumer Map

Current writers

  • Allocation Workbench Apply route;
  • oms.allocation/post_handler.php;
  • mk_sales_order_post_handle(... APPLY_WORKBENCH ...);
  • mk_sales_order_insert_allocated_item();
  • current Booking compatibility behavior can separately update/delete allocation-related rows;
  • current Inbound lot reconciliation recalculates remaining balances from active allocations.

Current readers/consumers

  • Allocation Workbench source and target queries;
  • Outbound order detail/readiness;
  • Inbound/lot detail and inventory reports;
  • Scale, Packing, Export Brokerage and Trade/Cost projections where they consume target/source rows;
  • Wiki/operator procedures and support investigation.

Current compatibility risks

  • source query eligibility is stronger than parts of the write revalidation;
  • role/tenant context is legacy on current routes;
  • outbound item updates can diverge from allocation balances;
  • no general reversal owner is source-confirmed;
  • Booking compatibility can mutate the same records;
  • no durable request token prevents replay after response loss.

15. Target Component Map

flowchart TB
    React[React Allocation Workspace]
    Next[Next.js Server Components / Route Handlers]
    App[TypeScript Allocation Application]
    Policy[Allocation Policy / UOM / Eligibility]
    Repo[Allocation + Lot + Outbound Repository]
    DB[(MySQL)]
    Audit[Audit / Reconciliation Read Model]

    React --> Next
    Next --> App
    App --> Policy
    App --> Repo
    Repo --> DB
    App --> Audit

React owns

  • source/target search and selection;
  • basket/preview presentation;
  • loading, empty, denied, stale, conflict, unknown and success states;
  • exact result IDs and balance changes;
  • accessible/mobile interaction;
  • no-blind-retry guidance.

React does not own eligibility, balance arithmetic, transaction or reversal policy.

Next.js owns

  • session/tenant/actor adapter;
  • server read composition;
  • Route Handler transport;
  • runtime payload validation;
  • safe error mapping and correlation ID;
  • no business SQL or hidden allocation mutation.

TypeScript application/domain owns

  • source and target eligibility;
  • quantity/weight/UOM policy;
  • request idempotency;
  • basket atomicity;
  • transaction orchestration;
  • correction/reversal;
  • exact readback and reconciliation.

Repository owns

  • tenant-scoped reads;
  • conditional balance write;
  • target item/allocation persistence;
  • immutable correction/reversal evidence;
  • MySQL and later PostgreSQL implementation.

Worker

Not required for the core local allocation. Introduce a worker only for separately approved asynchronous child effects; it must not delay or own the local allocation commit.


16. UI State Contract

The target workspace must implement:

Loading sources
No eligible sources
Loading targets
No eligible targets
Denied
Validation error
Stale source
Stale target
UOM conflict
Basket preview
Submitting
Committed with exact rows
Unknown result — reread in progress
Data conflict — stop and escalate
Correction/reversal blocked

Success presentation includes:

  • target order identity;
  • created target item IDs;
  • allocation IDs;
  • each source lot before/after quantity and weight;
  • UOM/rate snapshot;
  • next owner/action;
  • statement that Scale/Packing/Delivery are not complete.

The UI must not clear the basket and show success unless authoritative readback is available. If the response is lost, it must switch to reconciliation rather than invite another Apply.


17. Policy Decision Summary

Open decisions are owned in MK_INVENTORY_ALLOCATION_POLICY_DECISION_MATRIX.md.

Critical decisions before write migration:

  1. full-lot-only versus partial allocation;
  2. quantity, weight or dual consumption authority by UOM;
  3. UOM conversion and rounding;
  4. target line per source lot versus allocation to an existing demand line;
  5. all-or-nothing basket versus explicit partial batch;
  6. request idempotency storage;
  7. source eligibility revalidation;
  8. duplicate relation uniqueness;
  9. correction/unallocate/reversal model;
  10. downstream locks;
  11. role/capability mapping;
  12. Booking compatibility retirement;
  13. optimistic concurrency/versioning;
  14. PostgreSQL precision, constraints and index design.

18. Migration Plan

ALLOC-W0 Characterization

  • exact branch/schema/index/precision;
  • active callers/readers;
  • target-role page/API/record matrix;
  • current basket transaction and failure behavior;
  • response-loss/duplicate behavior;
  • quantity/weight drift fixtures;
  • Booking compatibility impact;
  • current Wiki content.

ALLOC-W1 Typed read model

Build TypeScript repositories and queries against MySQL; compare source/target/balance results with current PHP.

ALLOC-W2 React + Next.js read-only workspace

Use current PHP as writer. Validate target-role source/target/preview presentation.

ALLOC-W3 Shadow preview and reconciliation

Compute target eligibility, normalization and projected balances without writing. Compare with current Apply inputs/results.

ALLOC-W4 One-writer parity Apply

Activate AllocateInventoryBasket for a bounded cohort. Preserve current full-lot, one-target, one-line-per-source and all-or-nothing behavior initially unless policies are changed explicitly.

ALLOC-W5 Idempotency and unknown-result recovery

Require request token, exact duplicate result and support reconciliation.

ALLOC-W6 Correction and reversal

Activate only after policy, downstream locks, audit and source-balance restoration are accepted.

ALLOC-W7 Target-role stabilization

Normal, denied, stale, concurrent, duplicate, unknown and recovery evidence plus field observation.

ALLOC-W8 PHP caller-zero

Prove old Apply and internal helper callers are zero before removal. Remove compatibility only after user acceptance.

ALLOC-W9 PostgreSQL later

Preserve decimal precision, conditional lower-bound constraints, relation identity, idempotency and reversal history after React + Next.js + MySQL stabilization.


19. Rollback

Rollback from the new writer means:

  1. stop routing new Apply commands to TypeScript;
  2. preserve every committed allocation, target item and lot balance;
  3. reconcile in-flight/unknown request tokens;
  4. restore PHP writer for new requests only;
  5. keep new read/audit evidence available;
  6. do not replay baskets;
  7. do not delete/recreate allocation history;
  8. verify source/target balance parity before resuming.

Rollback does not mean:

hard-delete target items
hard-delete allocation rows
manually add lot weight
run both writers
replay unknown requests

20. PostgreSQL Preservation

The later repository must preserve:

  • exact decimal precision for quantity, weight and rate;
  • explicit UOM values and conversion version when used;
  • conditional nonnegative balance enforcement;
  • tenant-scoped foreign keys/indexes;
  • stable allocation/request/reversal identity;
  • uniqueness/idempotency rules;
  • immutable audit/reversal chain;
  • current soft-delete semantics until an approved replacement exists;
  • transaction isolation/concurrency behavior proven by scenarios.

Do not rely on MySQL implicit casts, integer truncation or case-insensitive comparison without an explicit compatibility decision.


21. Stable Verification Scenarios

Current capability

ALLOC-SCN-010  Single eligible lot -> existing target
ALLOC-SCN-020  Multiple lots -> same target, all rows commit
ALLOC-SCN-030  Later basket row fails -> complete rollback
ALLOC-SCN-040  Same lot concurrently submitted by two operators
ALLOC-SCN-050  Apply response lost after commit
ALLOC-SCN-060  Same request token replay
ALLOC-SCN-070  Source lot closed/deleted/empty after preview
ALLOC-SCN-080  Target missing container/size or invalid bridge state
ALLOC-SCN-090  UOM mismatch or unsupported conversion
ALLOC-SCN-100  Quantity/weight remaining-value divergence
ALLOC-SCN-110  Outbound item edited after allocation
ALLOC-SCN-120  Inbound source/lot edited after allocation
ALLOC-SCN-130  Correction/unallocate/reversal allowed or blocked
ALLOC-SCN-140  Foreign tenant, denied role and direct-ID access
ALLOC-SCN-150  Booking compatibility modifies allocation/lot
ALLOC-SCN-160  Source list eligibility differs from write eligibility

Migration

ALLOC-MIG-SCN-010  PHP/TypeScript source-list parity
ALLOC-MIG-SCN-020  Target-list and preview parity
ALLOC-MIG-SCN-030  One-writer parity Apply
ALLOC-MIG-SCN-040  Request-token duplicate and timeout reconciliation
ALLOC-MIG-SCN-050  Concurrent lower-bound protection
ALLOC-MIG-SCN-060  Rollback to PHP without replay
ALLOC-MIG-SCN-070  PHP caller-zero
ALLOC-MIG-SCN-080  PostgreSQL balance/idempotency parity

Evidence records:

  • exact revision/environment/schema;
  • actor/tenant/profile;
  • before/after rows and IDs;
  • request token;
  • transaction/result;
  • cleanup or retained conflict fixture;
  • screenshots/API/DB evidence where authorized;
  • limitations and next owner.

22. Definition Of Ready For Implementation

  • [ ] Product accepts full/partial lot behavior.
  • [ ] Quantity/weight/UOM authority is accepted.
  • [ ] Basket atomicity is accepted.
  • [ ] Target-line model is accepted.
  • [ ] Request idempotency/version strategy is accepted.
  • [ ] Correction/reversal/downstream-lock policy is accepted or explicitly out of first wave.
  • [ ] Role/page/API/record matrix is available.
  • [ ] Current schema/index/caller inventory is pinned.
  • [ ] Booking compatibility interaction is characterized.
  • [ ] Runbook and current Wiki content are reviewed.
  • [ ] One-writer selector and rollback are approved.
  • [ ] Stable scenarios and fixtures are ready.

23. Definition Of Complete

A migration wave is complete only when:

  • intended role enters the normal React workspace;
  • source/target/preview parity is accepted;
  • exactly one writer owns Apply;
  • duplicate/timeout cannot consume twice;
  • quantity/weight/UOM and source balances remain correct;
  • correction/reversal behavior is explicit;
  • operator can recover without blind replay;
  • old PHP callers are zero before removal;
  • Wiki/current route/runbook are aligned;
  • rollback is rehearsed;
  • user accepts the visible result;
  • stabilization observation is complete.

Documentation alone does not establish completion.

---

Source: docs/reconstruction/MK_INVENTORY_ALLOCATION_CAPABILITY_REBUILD_PACKET.md — ctc repository · This page is an English translation of the source document. Identifiers, file paths and code symbols are unchanged.