Requirements


Functional Requirements:

End-to-End Reserve Journey: 1. Uあser searches → 2. System holds a spot (Status: PENDING) → 3. User pays → 4. Payment Gateway sends callback → 5. System confirms reservation (Status: CONFIRMED).

Payment Handoff & Callback: The system hands off to a 3rd-party (e.g., Stripe) with a unique SessionID. Once paid, Stripe hits our Webhook endpoint. This ensures we don't rely on the client-side redirect for critical state changes.



Non-Functional Requirements:


Define the system constraints to ensure stability and performance.

  • High Availability: The system must be operational 24/7 (99.99% uptime). A downtime means cars cannot enter/exit, leading to physical congestion.
  • Scalability: Must support thousands of parking lots and millions of daily transactions.
  • Consistency: Strong consistency is required for payments and spot allocation to prevent double-booking.
  • Low Latency: Gate entry/exit validation and spot availability checks must happen in real-time (<200ms).


API Design

MethodEndpointHeadersDescription
POST/v1/reservationsIdempotency-KeyReserves a spot. Required key to prevent duplicate bookings on retries.
GET/v1/reservations/{id}-Poll for reservation status.
POST/v1/payments/webhookX-Signature

Secure callback from payment provider to finalize reservation.


High-Level Design

  • API Gateway: Handles Rate Limiting per LotID to mitigate Hot-lot surge.
  • Message Queue (Kafka): Used to decouple the Payment Webhook from the Reservation Service. This handles high bursts of payment confirmations.
  • Consistency: Use a Relational DB with REPEATABLE READ isolation to handle overlapping intervals correctly during the "Check Availability" phase.





Detailed Component Design

Handling Hot-lot Surge & Concurrency

To handle high traffic for a specific popular lot ("Hot-lot"), we implement Distributed Rate Limiting at the Gateway level and use Redis distributed locks with a short TTL for the specific LotID_TimeWindow key during the booking process.

Reservation Hold & Expiration (The "Hold" Problem)

When a user starts a booking, we create a temporary hold for 10 minutes.

  • Potential Issue: Hold expires before payment finalize.
  • Solution: The Payment Webhook check if the hold is still valid. If expired, it triggers an automatic refund process via the Payment Service.

Idempotency & Retries

To ensure a retry of a POST /reservations call doesn't create two bookings:

  • The client sends a UUID as an Idempotency-Key.
  • The server stores this key in Redis for 24 hours. If a duplicate key arrives, the server returns the previous successful response without re-processing.

Stale Cache & Overlapping Intervals

  • Stale Cache: We use a Write-through Cache for spot availability. Any DB update invalidates the Redis entry to ensure users don't see "Available" for a spot that was just booked.
  • Intervals: We use SQL queries with NOT EXSITS and interval overlap logic:
  • (StartA<EndB) AND (EndA>StartB)
  • This ensures no two reservations for the same spot overlap in time.

5. Non-Functional Requirements (NFR Strategy)

  • High Availability: Multi-Region active-passive setup with failover via Route 53.
  • Scalability: Horizontal Pod Autoscaling (HPA) for microservices based on CPU/Request count.
  • Low Latency: Read-replicas for lot metadata and Redis for real-time inventory checks.
  • Consistency: Transactional Outbox Pattern to ensure the DB update and Message Queue emission happen atomically.