feat: add inventory transaction audit trail (Phase 2)

Adds complete audit trail for all stock movements:
- InventoryTransaction model with transaction types (reserve, fulfill,
  release, adjust, set, import, return)
- Alembic migration for inventory_transactions table
- Transaction logging in order_inventory_service for all order operations
- Captures quantity snapshots, order references, and timestamps

Each inventory operation now creates a transaction record for
accountability and debugging.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-01 18:12:09 +01:00
parent 871f52da80
commit 049e3319c3
5 changed files with 468 additions and 7 deletions

View File

@@ -188,9 +188,63 @@ INFO: Fulfilled 2 units of product 123 for order ORD-1-20260101-ABC123
WARNING: Order ORD-1-20260101-ABC123 inventory operation failed: No inventory found
```
## Audit Trail (Phase 2)
All inventory operations are logged to the `inventory_transactions` table.
### Transaction Types
| Type | Description |
|------|-------------|
| `reserve` | Stock reserved for order |
| `fulfill` | Reserved stock consumed (shipped) |
| `release` | Reserved stock released (cancelled) |
| `adjust` | Manual adjustment (+/-) |
| `set` | Set to exact quantity |
| `import` | Initial import/sync |
| `return` | Stock returned from customer |
### Transaction Record
```python
class InventoryTransaction:
id: int
vendor_id: int
product_id: int
inventory_id: int | None
transaction_type: TransactionType
quantity_change: int # Positive = add, negative = remove
quantity_after: int # Snapshot after transaction
reserved_after: int # Snapshot after transaction
location: str | None
warehouse: str | None
order_id: int | None # Link to order if applicable
order_number: str | None
reason: str | None # Human-readable reason
created_by: str | None # User/system identifier
created_at: datetime
```
### Example Transaction Query
```python
from models.database import InventoryTransaction, TransactionType
# Get all transactions for an order
transactions = db.query(InventoryTransaction).filter(
InventoryTransaction.order_id == order_id
).order_by(InventoryTransaction.created_at).all()
# Get recent stock changes for a product
recent = db.query(InventoryTransaction).filter(
InventoryTransaction.product_id == product_id,
InventoryTransaction.vendor_id == vendor_id,
).order_by(InventoryTransaction.created_at.desc()).limit(10).all()
```
## Future Enhancements
1. **Inventory Transaction Log** - Audit trail for all stock movements
2. **Multi-Location Selection** - Choose which location to draw from
3. **Backorder Support** - Handle orders when stock is insufficient
4. **Return Processing** - Increase stock when orders are returned
1. **Multi-Location Selection** - Choose which location to draw from
2. **Backorder Support** - Handle orders when stock is insufficient
3. **Return Processing** - Increase stock when orders are returned
4. **Transaction API** - Endpoint to view inventory history