# TANRAIL ONE — Phase 3.2 Inventory Workflows

## 1. The Immutability Principle
Stock movements in TANRAIL ONE are strictly **immutable**. 
- Once a `StockMovement` is recorded (e.g., 50 units received), it cannot be updated or deleted.
- **Mistake Handling:** If a user accidentally receives 50 instead of 5, they cannot edit the historic movement. They must execute a corrective `ADJUST` movement of -45 (with a mandatory reason referencing the original mistake). This preserves the absolute chronological truth of the ledger.

## 2. Transaction Integrity & Source of Truth
**CRITICAL DECISION:** The `StockMovement` ledger is the absolute, authoritative Source of Truth for all inventory. 
- The `StockBalance` table acts strictly as a **materialized projection (cache)** of the ledger.
- **Why?** Calculating SUM(quantity) across millions of ledger rows for every dashboard load is unscalable. 
- **Integrity Rule:** If the `StockBalance` table is ever corrupted or suspected of drifting, it can be mathematically destroyed and rebuilt from scratch by aggregating the `StockMovement` ledger.

## 3. Concurrency Strategy
Because two users might attempt to issue the last remaining 10 units simultaneously, Inventory requires a strict locking mechanism.
- **Strategy:** Pessimistic Database Locking.
- When an `ISSUE` or `TRANSFER` is initiated, the Core Inventory Service will execute `DB::transaction()` and apply a `lockForUpdate()` exclusively on the specific `StockBalance` row.
- If User B attempts to issue while User A's transaction is processing, User B's transaction will block at the database level, read the newly updated balance after User A finishes, and subsequently fail the negative stock check (if enabled).

## 4. Negative Stock Policy
**HUMAN DECISION REQUIRED**
- **Scenario:** The system says we have 0 Rice. The chef physically holds a bag of Rice (perhaps it was purchased offline and not yet entered). The chef needs to issue it to cook an order. 
- **Option A (Strict):** The system rejects the issue. The manager is forced to officially `RECEIVE` the Rice before the chef can `ISSUE` it. (High integrity, slow operations).
- **Option B (Permissive):** The system allows the balance to drop to -1. When the manager later enters the receipt of +10, the balance resolves to 9. (High operational speed, weak integrity).
- **Recommendation:** TANRAIL ONE should configure this via a Business Unit level setting (`allow_negative_stock` boolean), defaulting to `false`. This pushes the decision to the specific business operator rather than hardcoding a global restriction.

## 5. Audit Trail
Because `StockMovement` is immutable and captures the `user_id`, `type`, `quantity`, `reference_type`, and `reference_id`, it inherently satisfies the Audit Trail requirement. No secondary audit table is required for stock quantity changes. 

## 6. Reporting Requirements
The Core supports the following conceptual operational reports (Dashboards are not implemented in Phase 3.2):
- **Current Stock:** Querying `StockBalance`.
- **Stock Movement Ledger:** Filtering `StockMovement` by Item, Location, or Date.
- **Low Stock Alerts:** Querying `StockBalance` where `quantity <= minimum_threshold` (future field).
- **Stock Valuation:** (Future integration combining `StockBalance.quantity` * `Item.base_price`).
