# StockLevel

## Description

StockLevel tracks the current quantity of a specific item at a specific storage location and stock type. It is the current-balance cache derived from InventoryLedger rows. Each row represents one balance slice such as `AVAILABLE` stock at a warehouse, `BLOCKED` stock in quarantine, or `IN_TRANSIT` stock held at a transit location.

StockLevel does not store reservation quantities. Reservations are demand commitments against available stock and are managed separately from physical stock types. Available-to-promise logic reads `StockLevel(stockType=AVAILABLE)` and subtracts reservation demand outside this table.

Site-level future inbound supply planning is handled by InventorySupplyPlan rather than StockLevel availability. StockLevel only represents current stock that already exists in a physical or logical location.

Stock level records persist even when all quantities reach zero — they are never deleted.

## Domain Model Definitions

### Model type

Standard

### Command Definitions

- Stock levels are updated internally by the following operations:
  - [postGoodsReceipt](../command/PostGoodsReceipt.md) - Increases the `AVAILABLE` type at the receiving location
  - [postGoodsIssue](../command/PostGoodsIssue.md) - Decreases the `AVAILABLE` type when issuing stock
  - [confirmStockAdjustment](../command/ConfirmStockAdjustment.md) - Adjusts the relevant type depending on the adjustment type
  - transfer shipment commands - Move quantity from source `AVAILABLE` to transit `IN_TRANSIT`
  - transfer receipt commands - Move quantity from transit `IN_TRANSIT` to destination `AVAILABLE`

### Query Definitions

- [getStockLevel](../query/GetStockLevel.md) - Retrieve the stock level for a specific item at a specific location
- [listStockLevels](../query/ListStockLevels.md) - List stock levels with optional filters
- [getSiteStockSummary](../query/GetSiteStockSummary.md) - Retrieve aggregated stock summary for a site

### Models

- StockLevel

### Invariants

- Unique per `(itemId, storageLocationId, stockType)`
- `stockType` must be one of `AVAILABLE`, `BLOCKED`, or `IN_TRANSIT`
- `AVAILABLE` is physically or logically present stock that can be promised after subtracting reservations
- `BLOCKED` is physically present but unavailable stock, such as quarantine or quality hold
- `IN_TRANSIT` is stock currently moving between locations and not available for sale or issue
- `quantity` cannot be negative
- Quantities are stored in the item's base unit of measure
- Records persist with zero quantities and are not deleted
- Concurrent movements must produce correct final quantities

### Relationships

- **References Item**: Each stock level references an Item from the item-management module
- **References StorageLocation**: Each stock level belongs to a specific storage location
