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:
- Low latency on check-in and check-out
- Secure payment system
API Design
The api should contain ways to lock a spot while the client is paying, reserve a spot after payment confirmation from the payment system, get all available parking spots, get the confirmation qr code of the reserved spot along with details of its location (floor, number, etc).
POST /auth/:phonenumber - establish a session, authenticate using sms, session token to be saved on device
POST /lock/ body: {spot: string, start: string, end: string} - user is looking at this spot with intentions to reserve, lock it so other users cant reserve it until the timer runs out.
POST /reserve/ body: {spot: string, start: string, end: string} - reservation route, should use a third party verification token, and make sure spot isn't locked by anyone else
GET /spots/ - get all spots, mark reserved spots
GET /reservations/ - get a list of the reservations for the user, using jwt for security, to be displayed as a QR code when checking in and out to verify
High-Level Design
The system will be composed of the following services:
- payment service, perferably a proven third party
- reservation service, handles locking and reserving spots on certain times.
- authentication service, handles the phone number login/ sms verification
- Storage layer, containing a database for reservations, redis for locking and quick checkin.
- Client, for reserving spots and displaying reservations
- checkin service, performs verification of checkin and out. Performs penalties on overstaying vehicles, or on vehicles that use an unreserved spot, using jobs that run in periodic intervals and data from cameras on site. Also contain jobs that maintain the redis checkin cache.
- Use rate limiter and nginx to manage replicas for horizontal scaling, that will be dynamically scaled based on usage.
The user will enter the client page, through it he will see a diagram of the parking lot with all spots, with the reserved ones for the selected time marked red, locked ones grey, and available ones are green. When a user clicks a spot, it will be locked by the reservation service, and when he finalizes the purchase (using the payment service) it will be added to the Database through the reservation service.
When the user comes to the parking lot itself when the reservation arrives, he will display a QR that is displayed in the client, that validates against the checkin service. That same QR will be used to checkout. If a user is late on checkout, he will be asked to pay a fine, or some other penalty decided by the product team, for the doors to open. The same is true if the cameras show the user's car in a spot other then the reserved one. Room for imporvement includes a support button that notifies the admin of a wrongly taken spot, but that is not in the specifications.
Edge cases include dual attempt to reserve the same spot. In that case, the first one that managed to secure the redis lock will succeed, while the second one will receive an error that the spot has been locked.
Another edge case is payement success but reservation error. In that case, the payment should be stored in the Database as unused, and the reservation service retries as long as an unused payment exists. A 3 times limit on retries will stop a corrupted attempt from unlimited retries, and should alert the admin/maintainers. The user gets a confirmation sms when the reservation is successful, and if unsuccessful a failure sms with a link to support should be sent.
Detailed Component Design
# Reservation Service
Should implement the logic partaining to the reservations themselves. Performs locks on spots using redis to check quickly if a reservation is valid or not. Should have an ability to spawn jobs to release the locks from redis.
Each reservation is saved with a unique payment token, to verify each payment instance is only valid for one reservation.
# Checkin Service
Implements logic partaining to checking in and out, as well as real time penalties. When getting an entry request, verify the displayed QR against the cache, and if not found then against the Database. Has a job running 5 minutes prior to each timeslot to preload relevant reservations to the cache, and a job at the end of each timeslot to verify all reservations that should end have cleared their spot.
# Client
Use a lightweight frontend development framework such as React or Vue. Will contain pages for reserving spots at specific times, showing which spots are reserved, showing the time left for the reservation lock, and displaying QR's for upcoming reservations.