# Transfer execution (synchronous)

## Preconditions

- Transfer status **`approved`**.
- Source warehouse **≠** destination warehouse.
- Quantity **positive**.
- **`InventoryStockMovementApplyCore`** validates catalog (active warehouse/item) identical to stock in/out norms.

## Locking

1. Lock the **`inventory_stock_transfers`** row `FOR UPDATE` (exclusive decision point).
2. Lock **projection** rows `(tenant, warehouse, item)` in **ascending `warehouse_id` order** to reduce cross-transfer deadlock hazard (always lock the numerically smaller warehouse projection first regardless of transit direction).

## Steps (single transaction)

1. **`transfer_out`** on source warehouse with **locked source projection**.
2. **`transfer_in`** on destination warehouse with **locked destination projection**.
3. Persist transfer header **`completed`**, **`correlation_id`**, **`transfer_out_movement_id`**, **`transfer_in_movement_id`**, **`completed_at`**.

## Consistency invariant

Outgoing absolute quantity consumed from source FIFO ledger slice equals inbound absolute quantity added at destination — same human-entered **`quantity`** drives both postings.
