Overview
The Inventory service manages seat reservations with time-limited holds (15-minute TTL). It uses Redis for distributed locking to prevent race conditions and ensures seat availability is managed consistently across the platform. Port: 50002 (external), 5002 (internal)Database Schema:
bc_inventoryDependencies: PostgreSQL, Redis, Kafka
Responsibilities
- Create temporary seat reservations (15-minute TTL)
- Implement distributed locking via Redis to prevent double-booking
- Track reservation status (active, expired, confirmed)
- Publish
reservation-createdevents to Kafka - Handle optimistic concurrency control with row versioning
- Expire reservations automatically via background workers
API Endpoints
Endpoints are defined using minimal API style inReservationEndpoints.
Create Reservation
Creates a new seat reservation with a 15-minute TTL. Returns 409 if the seat is already reserved.
The ID of the seat to reserve
The ID of the customer making the reservation
~/workspace/source/services/inventory/src/Inventory.Api/Endpoints/ReservationEndpoints.cs
The ID of the newly created reservation
The ID of the reserved seat
The customer who made the reservation
When the reservation will expire (typically 15 minutes from creation)
- 404 Not Found: Seat not found
- 409 Conflict: Seat is already reserved
- 500 Internal Server Error: Other failures
Domain Models
Reservation
Represents a temporary seat reservation with TTL.Unique reservation identifier
Reference to the reserved seat
Customer/user who made the reservation
When the reservation was created
When the reservation expires (typically CreatedAt + 15 minutes)
Reservation status:
active, expired, or confirmed~/workspace/source/services/inventory/src/Inventory.Domain/Entities/Reservation.cs
Seat
Inventory’s internal view of seat availability.Unique seat identifier
Venue section
Row identifier
Seat number
Whether the seat is currently reserved
Row version for optimistic concurrency control
~/workspace/source/services/inventory/src/Inventory.Domain/Entities/Seat.cs
Configuration
Database Connections
appsettings.json
JWT Authentication
Infrastructure Ports
The Inventory service defines several infrastructure ports for external dependencies:IRedisLock
Provides distributed locking via Redis to prevent concurrent reservation attempts on the same seat.IKafkaProducer
Publishes events to Kafka topics.reservation-created: When a new reservation is successfully createdreservation-expired: When a reservation TTL expires (via background worker)
IDbInitializer
Handles database initialization and migrations on service startup.Reservation Flow
- Request received: Client sends
POST /reservationswithSeatIdandCustomerId - Acquire lock: Service attempts to acquire a Redis lock on the seat
- Check availability: Verify seat is not already reserved (using row version)
- Create reservation: Insert reservation record with 15-minute TTL
- Update seat: Mark seat as reserved with optimistic concurrency check
- Publish event: Send
reservation-createdevent to Kafka - Release lock: Release the Redis lock
- Return response: Return reservation details with
201 Created
Concurrency Control
- Redis Locks: Distributed locks prevent simultaneous reservation attempts
- Row Versioning: Optimistic concurrency using
Versionbyte array onSeatentity - Conflict Handling: Returns
409 Conflictif seat is already reserved
Background Workers
A background worker periodically checks for expired reservations and:- Updates reservation status to
expired - Releases the seat (marks as available)
- Publishes
reservation-expiredevent to Kafka
Architecture Notes
- Uses MediatR for CQRS-style command/query handling
- Uses Minimal APIs for endpoint registration
- Implements Ports and Adapters pattern for infrastructure concerns
- Database initialization runs on service startup via
IDbInitializer
