Our system will have the following endpoints:
We will use an event driven architecture for this application. This allows us to easily accommodate things like bookings, check-in/outs, no shows and update the state of our application quickly.
We will also need a database with tables for users, parking spots, bookings and checkin-checkout. We can us a relational database like Postgres to store our data. We will perform joins to get the time slots where a parking lot is booked and update checkin-checkout tables when users come in and go.
We will use Stripe to process payments for parking space. We will use Kafka to handle our events and create producers like the reserveSpot, checkIn endpoints and consumers like sending confirmation email and update database services.
Application components:
Request flow:
On average we can assume that we will get 100 requests/minute for viewing available spots, 10 requests/minute for booking and less check-in/out. To improve performance of viewAvailableParkingSpots, we will cache booking data. We can also use read replicas of the database to improve performance.
All of our endpoints are stateless so we can containerize each service and use container orchestration to scale up and down depending on traffic.
viewAvailableParkingSpot -
Assuming 100 requests per minute, we use the cached bookings data to show the available parking spots to users. When a user clicks on a parking spot we start a 5 minute timer and mark this spot as unavailable. After time expires we unblock the spot if user did not complete payment. This let's us avoid double booking cases.
reserveSpot -
Before sending user to payment provider, we first check that the selected spot is available and not already booked. Otherwise we stop the process and ask the user to look for another spot. We collect details like email, start and end times for the booking etc and then send the user to Stripe to complete payment. Once we receive payment confirmation event from Stripe, we send the confirmation email to the user.
This approach prevents double booking and ensures that one parking spot is booked by just one user. We also put the parking spot in temporarily unavailable state while the payment is processing so other users can not see this parking spot as available. Depending on the booking completion we update the parking spot's status to free or unavailable in the database.
checkIn -
At the gate, take booking confirmation number, validate it and allow entry up to 5 minutes before
and 10 minutes after the booking time. Update database and mark the user as present.
checkout -
Similarly at the gate take booking confirmation number and update database.
lateCheckout -
Take the confirmation number, calculate fine and accept point of sale transaction. If user is unable to pay add balance to their account.