Requirements


Functional Requirements:

  • Allow users to reserve a parking spot based on vehicle type (compact, large, EV, handicapped).
  • Process payments securely for the reservation, supporting dynamic, time-based pricing.
  • Enable parking of a car in the specific reserved spot.
  • Support early departure before the reservation time expires, triggering partial refunds or charge adjustments.
  • Facilitate automated gate check-in/out via License Plate Recognition (LPR) or QR codes.
  • Automatically handle "no-shows" by freeing up unutilized spots after a grace period.

Non-Functional Requirements:

  • High Availability & Reliability: The system must not trap users inside or cause traffic pile-ups outside if a single component fails. Gate functionality needs a fallback offline mode.
  • Low Latency: Gate check-in/out validation must occur in under 500ms.
  • Consistency: Strict prevention of double-booking the same spot at the same time.
  • Scalability: Capable of expanding to multiple parking lot locations globally with varying capacities.


API Design

We will use RESTful principles for client-facing operations.

  • POST /v1/reservations
    • Payload: user_id, lot_id, vehicle_type, start_time, end_time
    • Response: reservation_id, spot_id, status
  • PUT /v1/reservations/{reservation_id}/cancel
    • Response: status, refund_amount
  • POST /v1/gates/check-in
    • Payload: lot_id, gate_id, identifier (license plate string or QR token)
    • Response: action (open_barrier, deny), spot_id
  • POST /v1/gates/check-out
    • Payload: lot_id, gate_id, identifier
    • Response: action (open_barrier), pending_charges
  • POST /v1/payments
    • Payload: reservation_id, amount, payment_method_id
    • Response: transaction_id, status




High-Level Design

The architecture is broken down into modular, independent services to isolate failures and scale components independently.

  • Client Interfaces: Mobile Apps (for users) and IoT Gate Terminals (cameras/scanners).
  • API Gateway: Routes incoming traffic, handles rate-limiting, SSL termination, and user authentication.
  • Core Services:
    • Reservation Service: Handles the lifecycle of a booking.
    • Spot Management Service: Tracks real-time availability and physical location of spots.
    • Gate Service: Interfaces with physical hardware. Designed for extreme low latency.
    • Payment Service: Integrates with external payment processors (e.g., Stripe).
  • Message Broker (Kafka/RabbitMQ): Facilitates asynchronous communication between services (e.g., Gate Service notifying Spot Service of an entry).
  • Data Layer:
    • Relational DB (PostgreSQL): Stores users, reservations, parking lot configurations, and payment ledgers.
    • Cache (Redis): Stores active sessions, fast-lookup reservation tables for the gates, and real-time available spot counters.






Detailed Component Design

1. Spot Allocation & Concurrency Control

  • Problem: Two users try to book the last available compact spot at the exact same millisecond.
  • Solution: We use a relational database with strict ACID properties.
  • Mechanism: * When a reservation request comes in, the system starts a database transaction.
    • We use a SELECT ... FOR UPDATE query to lock the specific row of an available parking spot.
    • If successful, the spot's status is updated to RESERVED for the specified time block, and the transaction commits. If the row was already locked by another thread, the system catches the failure and retries fetching a different available spot.
    • To prevent database overload during high traffic, we maintain an atomic counter in Redis for available_spots_by_type. If the Redis counter is zero, we reject the request immediately without hitting the database.

2. Low-Latency Gate Check-In/Out

  • Problem: Querying a massive database to verify a license plate at the gate can take too long, causing physical traffic jams.
  • Solution: Read-optimized caching and asynchronous state updates.
  • Mechanism:
    • When a reservation is created, an event is sent to Redis, caching a key-value pair: Plate_XYZ: {reservation_id, spot_id, valid_time}.
    • When a car pulls up to the gate, the Gate Service queries Redis. This takes less than 5ms.
    • If valid, the Gate Service immediately sends the "open barrier" command to the hardware.
    • After the gate opens, the Gate Service fires an asynchronous event to the Message Broker: VehicleEnteredEvent.
    • The Spot Management Service consumes this event at its own pace and updates the primary PostgreSQL database to mark the spot as OCCUPIED.

3. Handling No-Shows and Early Departures

  • Problem: Unused spots cost money. We need a way to reliably free up inventory if someone leaves early or doesn't show up.
  • Solution: Time-To-Live (TTL) events and state-machine transitions.
  • Mechanism:
    • No-Shows: When a reservation starts, a message is placed into a delayed queue (or a Redis Key-Space Notification) with a TTL of the grace period (e.g., 30 minutes). If the VehicleEnteredEvent is not received before the TTL expires, a worker function executes, changes the reservation status to NO_SHOW, applies the penalty fee via the Payment Service, and releases the spot back into the available pool.
    • Early Departure: When a VehicleExitedEvent is received before the end_time, the system immediately recalculates the cost, triggers a refund via the Payment Service if applicable, and unlocks the spot for new reservations instantly.