Inventory Module Feature List
Inventory feature surfaces, stock lifecycle behavior, and production-readiness checklist.
Inventory Module - Feature List
1. Feature Overview
Inventory uses a mixed execution model:
- synchronous admin APIs for read + manual operations
- asynchronous stock lifecycle processing for order-driven reserve/finalize/release
The module currently targets physical product inventory safety and admin operational visibility.
2. Surface Ownership Matrix
| Surface | Route/Queue | Owner |
|---|---|---|
| Admin API | /api/admin/inventory | InventoryAdminController |
| Reserve worker | orders_reservations | InventoryReserveProcessor |
| Finalize worker | orders_stock_finalize | InventoryFinalizeProcessor |
| Release worker | orders_stock_release | InventoryReleaseProcessor |
| Admin async jobs | inventory | InventoryAdjustProcessor |
3. Admin Feature Matrix
| Capability | Endpoint | Permission |
|---|---|---|
| Paginated inventory list | GET /api/admin/inventory | Inventory_READ |
| Low-stock view | GET /api/admin/inventory/low-stock | Inventory_READ |
| Product inventory detail | GET /api/admin/inventory/:productId | Inventory_READ |
| Manual stock adjust | POST /api/admin/inventory/:productId/adjust | Inventory_UPDATE |
| Bulk sync/reconciliation | POST /api/admin/inventory/bulk-sync | Inventory_UPDATE |
4. Stock Lifecycle Feature Matrix
| Lifecycle step | Trigger owner | Queue/job | Mutation |
|---|---|---|---|
| Reserve | order create | orders_reservations + stock.reserve | available -, reserved + |
| Finalize | payment success | orders_stock_finalize + stock.finalize | reserved -, total - |
| Release | cancel/failure/expire | orders_stock_release + stock.release | reserved -, available + |
| Adjust | admin action | inventory + stock.adjust | total ±, available ± |
| Sync | admin/system reconcile | inventory + stock.sync | available = total - reserved |
5. Runtime Rules
5.1 Reserve
- uses row lock + transaction
- rejects insufficient stock when oversell disabled
- auto-creates zeroed row if missing (current behavior)
5.2 Finalize
- uses row lock + transaction
- requires existing row
- validates reserved/total sufficiency before deduction
5.3 Release
- uses row lock + transaction
- missing row is safe no-op
- no-reserved state is safe no-op
5.4 Adjust
- supports positive/negative adjustment
- prevents negative resulting quantities
- creates inventory row when missing
5.5 Sync
- reconciles one product or all products
- updates only inconsistent rows
6. Data Model Feature Coverage
Implemented in product_inventory:
- one-row-per-product
- total/reserved/available quantities
- low-stock threshold
- track-inventory switch
- allow-oversell switch
- non-negative DB check constraints
7. Error Feature Coverage
| Scenario | Error code |
|---|---|
| insufficient available stock | INVENTORY_INSUFFICIENT_STOCK |
| invalid mutation math | INVENTORY_INVALID_OPERATION |
| negative result on adjust | INVENTORY_INVALID_ADJUSTMENT |
| missing row on finalize | INVENTORY_NOT_FOUND |
Defined but currently not emitted:
INVENTORY_ALREADY_FINALIZEDINVENTORY_ALREADY_RELEASED
8. Queue and Worker Feature Coverage
Implemented consumers:
orders_reservationsorders_stock_finalizeorders_stock_releaseinventory
Current queue mismatch:
orders_stockis registered and owned by dispatcher, but has no processor consumer.
9. Integration Feature Coverage with Order
Implemented outbox emission points:
- order create emits
stock.reserve - payment success emits
stock.finalize - cancel/payment_failed/expired emits
stock.release
Quantity source:
- order integration uses
order_items.quantity
10. Test Coverage Snapshot
Implemented inventory tests include:
- unit tests for
InventoryService - unit tests for reserve/release processors
- integration test for reserve flow
Observed status:
- targeted inventory test suite passes in current workspace run
11. Missing/Partial Features (Production Gaps)
11.1 Audit logging
- Mongo
AuditLogwrites for inventory mutations are expected by plan but not implemented in service logic.
11.2 Cache integration
- inventory cache env keys exist but service does not use cache yet.
11.3 Queue contract hygiene
orders_stockqueue has no active consumer.
11.4 Admin DTO semantics
bulk-syncrequest currently requirestriggerbut runtime does not use it.
12. Release Checklist
- Admin APIs enforce permissions and return consistent
ResponseDtoenvelopes. - Reserve/finalize/release lifecycle is fully wired through outbox -> dispatcher -> queue -> processor -> service.
- Stock adjustments cannot push totals below zero.
- Low-stock view reflects threshold correctly.
- Queue registration and processor coverage are aligned (remove or implement
orders_stock). - Inventory mutation audit trail requirement is satisfied (Mongo audit logging).
- Inventory env contract includes only keys actually used in runtime.
13. Before-Payment Readiness Gate (Inventory Perspective)
Must be true before Stripe/payment rollout:
- finalize/release inventory transitions are stable across payment success/failure retries
- refund and return strategy is defined for stock compensation (if required)
- stale legacy queue/job/config entries are cleaned or explicitly retained
- inventory docs and order docs agree on stock lifecycle ownership
14. Integration Flows
14.1 Reserve flow (checkout/buy-now)
- order path writes outbox
stock.reserve - dispatcher enqueues
orders_reservations - reserve processor calls
InventoryService.reserveStock - service mutates
availableandreserved
14.2 Finalize flow (payment success)
- payment-success path writes outbox
stock.finalize - dispatcher enqueues
orders_stock_finalize - finalize processor calls
InventoryService.finalizeStock - service mutates
reservedandtotal
14.3 Release flow (cancel/failure/expire)
- order path writes outbox
stock.release - dispatcher enqueues
orders_stock_release - release processor calls
InventoryService.releaseStock - service returns reserved quantities to available safely
15. File Ownership Map
apps/api/src/modules/inventory/admin/*- admin API surfaceapps/api/src/modules/inventory/shared/*- stock domain logicapps/api/src/modules/inventory/processors/*- queue workersapps/api/src/modules/order/*- lifecycle event emitters and dispatcher ownershippackages/db/src/schema/inventory/*- schema contractspackages/jobs/src/index.ts- queue and job contracts
See Also
16. Operational Acceptance Scenarios
16.1 Stock reservation safety
- creating two overlapping orders for same SKU does not oversell when
allowOversell=false - second reservation path returns
INVENTORY_INSUFFICIENT_STOCKwith no negative values persisted - row-level locking ensures only one reservation mutation wins per transaction boundary
16.2 Payment reconciliation behavior
- duplicate payment success callbacks do not double-deduct
totalQuantity - payment failure after prior success does not produce invalid inventory transitions
- expired-payment release only restores quantities that are still reserved
16.3 Manual adjustment operations
- positive adjustment increases
totalQuantityandavailableQuantityequally - negative adjustment respects non-negative invariants
- adjustment API remains role-gated by
Inventory_UPDATE
16.4 Bulk sync reconciliation
- sync updates only drifted rows (
available != total - reserved) - already-correct rows are returned unchanged
- reconciliation is safe to rerun repeatedly
17. Monitoring and Runbook Signals
Track these signals before declaring inventory complete for production:
- queue depth and failure counts for
orders_reservations,orders_stock_finalize,orders_stock_release, andinventory - rate of
INVENTORY_INSUFFICIENT_STOCKerrors by product and hour - count of rows where
available != total - reservedafter scheduled sync - ratio of reserve events to finalize/release events (stuck reservations detector)
Runbook checks:
- if reserve jobs spike in failures, inspect low-stock products and
allowOversellstate first - if finalize jobs stall, inspect payment callback health and outbox dispatch lag
- if release jobs lag, verify cancel/payment-failure handlers are still emitting outbox events
- if drift count grows, run admin bulk-sync and inspect mutation sources
18. Deferred Work (Explicitly Out of Current Scope)
- dedicated inventory history API powered by Mongo
AuditLog - realtime customer stock push events
- return/refund stock compensation policy automation beyond existing order refund status flow
- inventory cache read-through integration for admin list/detail paths
Inventory Module Backend Documentation
Inventory runtime architecture, stock mutation rules, queue processing behavior, and operational constraints.
Starter Nest Backend Guidelines
This document explains how the `apps/api` service is structured, how to extend it safely, and how to write and test new backend code with NestJS. It is intentionally beginner-friendly—treat it as the playbook for everyday backend work in this repo.