Skip to content

[Phase 1] Inventory Reservation & Hold System #64

@syed-reza98

Description

@syed-reza98

Priority: P0 (Critical)

Phase: 1 - E-Commerce Core
Epic Link: Product / Checkout (#15, #19, Order Processing placeholder #24)
Estimate: 3 days
Type: Story

Context

Implement short-lived inventory reservations to prevent overselling between cart and final payment, enabling accurate stock display and reducing race conditions under concurrent demand.

Scope

  • InventoryReservation model (productId / variantId, quantity, storeId, cart/session reference, expiresAt)
  • API: POST /api/inventory/reserve (batch reservation with validation)
  • API: POST /api/inventory/release (manual release)
  • Automatic expiration job (sweeper) every minute
  • Integration with Order creation to convert reservation → decrement

Acceptance Criteria

  • Reservation creation fails if insufficient available stock (currentStock - activeReservations >= requested)
  • Expired reservations released (stock availability recalculated) within < 60s of expiry
  • Order creation consumes reservations atomically (transaction) & prevents double decrement
  • Reservation TTL configurable (default 15 minutes)
  • Ability to extend reservation once (e.g. payment delay)
  • Audit log entry: action: inventory_reservation_created / released / consumed
  • Low stock alert logic excludes reserved quantity for proactive alert accuracy

Data Model (Draft)

model InventoryReservation {
  id          String   @id @default(cuid())
  storeId     String
  productId   String
  variantId   String?
  quantity    Int
  status      ReservationStatus @default(ACTIVE)
  cartId      String? // if cart session
  orderId     String? // set when consumed
  expiresAt   DateTime
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  @@index([storeId, productId])
  @@index([expiresAt])
}

enum ReservationStatus {
  ACTIVE
  CONSUMED
  EXPIRED
  RELEASED
}

Dependencies

Metrics

  • Overselling incidents reduced to 0/month
  • Reservation latency < 150ms p95
  • Expiration sweep accuracy > 99%

Testing Checklist

  • Concurrent reservations for same product (race-free)
  • Expiration release job frees stock
  • Conversion on order creation removes reservation & decrements stock once
  • Extension updates expiresAt

Risk

High integrity risk if absent (score: 16). Supports scaling & channel sync.

References

  • docs/GITHUB_ISSUES_COMPARISON_ANALYSIS.md
  • Industry pattern: cart hold / soft allocation

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions