Requirements
Functional Requirements:
- Allow reservation of a parking spot.
- Process payment for the reservation.
- Enable parking of a car in the reserved spot.
- Support early departure before reservation time expires.
- Gate check-in/out.
- Handle no show.
Non-Functional Requirements:
- Reliability
- High Availability
- Secure
- Strong Consistency
API Design
RESERVE PLACE
POST /reserve
{
"car_plate": "str",
"lot_id": "str",
"check_in_time": "timestamp",
"check_out_time": "timestamp"
}
RESPONSE
{
"reserve_id": "str",
"price": "str"
}
CheckIn
REQUEST
POST /lot/check-in
{
"car_plate": "str
}
RESPONSE
SUCCESS
or
NO ACTUAL RESERVATION FOR THIS VEHICLE FOUND
CheckOut
POST /lot/check-out
{
"cat_plate": "str
}
RESPONSE
SUCCESS
or
THERE IS A PARKING DEBT FOR A VEHICLE
List of parking lots
GET /parking
{
lot_ids: ["str", "str", ...]
}
GET /parking?free=ture&size=medium
{
lot_ids: ["str", "str", ...]
}
GET /parking/{id}
{
lot_id: "str"
}
POST /parking/debt
{
"car_plate": int
}
POST /parking/pay
REQUEST
{
"car_data": "str"
"car_plate": "str"
}
High-Level Design
- There should be 3 types of business entities: parking lots, reservations and actions.
- Data should be consistent, everything can be stored in simple RDBMS.
- User visits FrontEnd, FrontEnd asks car size and car plate, after user typed it in, FrontEnd makes request for available parking lot of requested size. User click on lot which is good for him, that sends reservation request to BackEnd. After that user have link to payment processing. If payment is processed everything is ok. Camera makes a photo of every plate and autmatically tries check-in/check-out request
- LoadBalancer is used in case of traffic burst
- Ingress limits amount of RPS for IP, so users won't overload system by f5 on available place.
Detailed Component Design
- RDBMS structure:
- Parking lot has: ID, Size (Small, Medium, Big), Price
- Reservation has: ID, car_plate, TSTZRANGE, payed, create_time, expired
- Action has datetime, action [check_in, check_out]
- When user create reservation it considers as non free for 15 minutes. 15 minutes after create_time it becomes free if not payed. Free/Non Free logic is Bussiness logic, not something that is saved in db but determined on request
- GiST extension of postgres will provide strong consistency, so reservations won't overlap
- check-in works only if there is payed reservation found in correct timescope for the car_plate
- Parking debt exist in case if there is created parking which is not payed or in case checkout hasn't happened and there is 5 minute after checkout time
- If parking debt > 0 checkout won't happen
- If someone created reservation it is not considered "Free", so it cannot be reserved. The one who first reserved it got it. After reservation made websocket sends to Client information that place is not available anymore.
- Every minutes cron job check whether there are new places available, if yes then websocket sends message to Client about new lot
- If payment is successfull then reservation payment is set to true, otherwise set to false, BackEnd send Client message so client should retry payment.
- All Payment are delegated to PaymentProcessor. PaymentProcessor just validates data a send it to some credit card payment processor (Bank or Merchant)
- System won't allow to make overlapping interval.