StockLock is an enterprise-grade inventory reservation system built to solve one of the most common and complex problems in e-commerce: The Checkout Race Condition.
When selling highly limited, high-value items (like Super Cars), multiple users attempting to buy the last available unit at the exact same millisecond can result in overselling and database corruption. StockLock solves this by implementing a distributed double-lock strategy, guaranteeing that one physical unit maps exclusively to one buyer.
- Framework: Next.js 16 (App Router) with Turbopack
- Language: TypeScript
- Database: PostgreSQL (Hosted on Supabase)
- ORM: Prisma
- Caching & Locking: Upstash Redis (Serverless Redis)
- Styling: Tailwind CSS v4 + Shadcn UI
- Real-Time Sync: Server-Sent Events (SSE) via Native Node.js
EventEmitter
This project was built to demonstrate advanced backend concurrency management and system design:
To prevent race conditions when two users click "Reserve" at the exact same time:
- Layer 1: Redis Distributed Lock (
SET NX EX) Before hitting the database, the API attempts to acquire an exclusive lock on the specificproductIdandwarehouseIdcombination in Redis. If acquired, the request proceeds. If not, it means another thread is actively reserving that item, and a429 Too Many Requestsis returned. - Layer 2: Postgres Transactions & Row-Level Locking
Inside the database, operations are wrapped in a strict
$transaction. The system dynamically checks if(total_stock - reserved_stock) >= requested_quantitybefore applying the atomic update.
Network drops happen. If a user clicks "Checkout" and their internet reconnects and fires the request a second time, they shouldn't be charged twice or reserve two cars.
- Every reservation request generates a unique
Idempotency-Key(UUID) from the frontend. - The backend stores this key alongside the successful response. If a duplicate request arrives with the same key within 24 hours, the backend bypasses processing and simply replays the exact same HTTP response.
Instead of relying on heavy client-side polling (setInterval), this app utilizes a custom Server-Sent Events streaming endpoint (/api/stock/stream).
- When a reservation is successfully created, confirmed, or released, a global Node.js
EventEmitterfires. - The SSE endpoint instantly catches this event and pushes the updated live stock counts directly to every connected browser. This creates an incredibly dynamic "live auction" feel with zero manual reloading required.
Luxury cars are prime targets for scalper bots. To prevent a bot from spamming the reservation endpoint and maliciously locking up all the stock:
- An Upstash Redis Sliding Window Rate Limiter protects the core API.
- It enforces a strict limit: A maximum of
3reservation attempts per IP address every10 seconds. Excess requests are blocked in single-digit milliseconds to protect the Postgres database from DDoS.
A globally accessible context (CurrencyProvider) allowing the frontend to dynamically switch between USD, INR, EUR, and GBP. It applies accurate formatting algorithms based on the user's locale (e.g., standard Western commas vs. the Indian Numbering System).
The relational data model revolves around the concept of holding temporary reservations without permanently destroying stock until payment is confirmed.
Product: Details about the item (e.g., Porsche 911 GT3).Warehouse: Physical locations storing the items.Stock: The junction table tracking the exact amount of aProductin a specificWarehouse. It holdstotal(physical boxes) andreserved(items currently sitting in someone's 10-minute checkout window).Reservation: Tracks the status of the hold (PENDING,CONFIRMED,RELEASED) and its strict expiry timestamp.
-
Clone the repository and install dependencies:
npm install
-
Create a
.envfile in the root directory and add your credentials:# Supabase Postgres DATABASE_URL="postgresql://[USER]:[PASS]@[HOST]:6543/postgres?pgbouncer=true" DIRECT_URL="postgresql://[USER]:[PASS]@[HOST]:5432/postgres" # Upstash Redis UPSTASH_REDIS_REST_URL="https://[YOUR-UPSTASH-URL].upstash.io" UPSTASH_REDIS_REST_TOKEN="[YOUR-UPSTASH-TOKEN]" RESERVATION_EXPIRY_MINUTES=10 NEXT_PUBLIC_APP_URL="http://localhost:3000"
-
Push the database schema:
npx prisma generate npx prisma db push
-
Seed the database with the Super Cars:
npm run prisma:seed # (or: npx prisma db seed) -
Run the development server:
npm run dev
Open http://localhost:3000 to view the application!
Built for the Allo Health Engineering Challenge.