Functional Features:
- User can reserve a parking spot.
- User pays for the reservation.
- User can park a car on the parking spot.
- User can leave before the reservation time expires.
- One common error case to handle is when a user makes a reservation, but fails to show up. In this case, we would charge for the first 24 hours.
Non-Functional Features:
- Scalability - our system should able to handle 1000 request over the world.
- Availability - system should has up time 99%.
- Consistency - should not be double booking of the same park spot.
Capacity estimation
Number of parking lots = 1000
Parking lot capacity = 200
Reservation requests per/day = 200 * 1000 = 200 000
Each reservation will add 128 byte in DB * 128 = 25.6MB of data per day.
API design
API used by user:
check_capacity(lot_ID, vehicle_type, start_date_time, end_date_time) - checks the number of spare spots in the given parking lot and returns the price.
reserveSpot(user_id, lot_id, vechile_type, start_time, end_time) - returns reservation_id and price. Also forwarded on 3d party payment system.
completeReservation(reservation_id, payment_token) - verifies the payment token with the 3rd party payment mechanism, and finalizes the reservation.
API used by parking lot:
vechile_arrived(reservation_id, time)
vechile_left(reservation_id, time)
Reservation table:
- reservation_ID (primary key)
- lot_ID (foreign key)
- user_ID (foreign key)
- start_time
- end_time
- vehicle_type (foreign key)
- payment_status (paid, unpaid, canceled)
- completion_status (to be completed, fulfilled, canceled)
Vehicle_Type table:
- vehicle_type_ID
Lot table:
- lot_ID (primary key)
- contact_info_ID (foreign key)
- Lot_Space ID (foreign key to Lot_Space table)
- capacities (foreign key to Lot_Capacity table)
Lot_Capacity table:
- lot_space ID (primary key)
- vehicle_type (foreign key to Vehicle_Type)
- number of space
Contact_Info table:
- contact_info_ID (primary key)
- contact_type
- contact_value
User table:
- user_ID (primary key)
- contact_info_ID (foreign key)
- vehicles (foreign key to Vehicle table)
Vehicle table:
- vehicle_ID (primary key)
- vehicle_type (foreign key to Vehicle_Type table)
Transaction table:
- transaction_ID (primary key)
- user_ID (foreign key)
- vehicle_ID (foreign key)
- check_in_date_time
- check_out_date_time
There can be enhancements, e.g., reviews for the parking lot, and reviews for the users. But for now, I will focus on the tables above.
High-level design
Parking lot - notifies when car arrive or left
Client - user , that wants to get parking spot
Api gateway - mediator fro http requests
Reservation service - checks for empty place and update reservation in database
Payment service - 3d party for payments
healthcheck monitor - checks if all components of our system are available
cache - caching most use data to reduce latency reading from database
Request flows
checkCapacity request handles by reservation service. It checks if we have an empty spot.
reserveSpot request - handles by reservation service. Adds. a new reservation in the system and redirect user for payment service.
completeReservation - after payment, user confirms that spot was paid by token.
vechile_arrived - notifies, when car arrived on parking lot.
vechile_left- notifies, when car left from parking lot.
Detailed component design
For reservation we can use first fit slot allocation or time-slot reservation with time intervals or bitmap approach to achieve time complexity O(1)
Trade offs/Tech choices
Nosql db provides good horizontal scaling, but for us most important to have consistency, I mean we should prevent double booking of the same spot. SQL BD it is good choise , for instance PostgresSql
Failure scenarios/bottlenecks
Backend service are stateless. DB will be a bottleneck , it will difficult to scale. We can partitioned DB by parking id. Also we should use some heathcheck system.
In case of db crashes , would be better to use master-slave db approach with replication of db instances.
Future improvements
I believe that we use need to use CDN