Screenshots


The problem
If two people book the last copy of a lens for overlapping dates at the same moment, a simple "check, then insert" lets both bookings through. One of them shows up to an empty shelf.
What I built
- Per-unit inventory, so the shop tracks each physical camera instead of a stock count
- Booking inside one database transaction that locks the candidate units before assigning one
- Stripe deposits held as authorizations, with webhooks as the single source of truth for payment
- Unpaid bookings that expire after 30 minutes, so nobody can hold gear forever
- Zod schemas shared between the React client and the Express API
- An admin console with an occupancy grid and calendar
- 67 automated tests with Vitest
The hardest part
Two bookings, one lens
Checking availability and then inserting a booking leaves a gap where a second request can slip in. I run the whole booking in one transaction and lock the candidate units first, so a second request waits until the first one finishes and then sees the unit is taken.
-- inside the booking transaction (simplified)
SELECT id FROM "Unit"
WHERE "productId" = $1
FOR UPDATE; -- a second booking waits here