System requirements


Functional:

User to be able to reserve parking spot, extend time, cancel reservation

Parking spots will have rate depending on size (small, medium, large)

User can view available spots

In this case, user will need to input payment method every time (no automatic payment)



Non-Functional:

Available -> Users could be parking at any time

Consistent -> Cannot have any double bookings



Capacity estimation

1,500,000 per day -> 20 transactions per second


User Table:

10,000,000 users -> 400 000 000bytes -> 400 000 KB -> 400MB


Reservation Table:

20,000,000 parking spots -> 100,000,000bytes -> 100,000 KB -> 100MB


Spot to License Plate:

20,000,000 parking spots -> 220,000,000bytes ->220,000KB -> 220MB


Looking at estimations, scaling for writes and scaling to increase transactions per second wont be necessary




API design

Public Endpoints:

/GET/Price:SpotID

  • return price -> rate * hours


/POST/Reservation

Body contains spotID,licensePlate

  • Pay and reserve spot
  • Extend spot if spot is taken and request body has same license plate


/POST/Cancel

Body contains spotID

  • Cancel Reservation


/GET/Parking/SpotID

  • See when parking spot expires


/GET/Lot:LotID

  • Get available/unavailable parking spots in lot







Database design

Use SQL, MySQL

User Table:

First Name VARCHAR (20)

Last Name VARCHAR (20)


Reservation Table:

Parking SpotID INT (4)

LotID INT(4)

Size CHAR(1)


Reference Table for Size to Pay rate:

Size CHAR(1)

Pay Rate Float(4)


Reference Table for Spot to License Plate:

Parking SpotID INT (4)

License Plate VARCHAR(7)



High-level design

User can reserve spot, cancel reservation or extend


Extending reservation will use same endpoint as paying, if license plate matches the car that is currently parked, extend time


User can cancel reservation 24 hours in advance







Request flows

Client loads page: get spots for lot from /GET/Lot:LotID

Client gets rate for specific spot from /GET/Price:SpotID

Client reserves a spot with /POST/Reservation

Client can cancel reservation 24hours in advance with /POST/Cancel

Client can extend spot with /GET/Parking/SpotID


Request -> Gateway -> Loadbalancer -> Server -> DB -> Server -> Client





Detailed component design

Extending reservation will use same endpoint as paying, if license plate matches the car that is currently parked, extend time


Client loads page: get spots for lot from /GET/Lot:LotID

Client gets rate for specific spot from /GET/Price:SpotID

Client reserves a spot with /POST/Reservation

Client can cancel reservation 24hours in advance with /POST/Cancel

Client can extend spot with /GET/Parking/SpotID


Request -> Gateway -> Loadbalancer -> Server -> DB -> Server -> Clien

Implement Stripe/Visa for payment, note that retries should be handled on their side


If transaction fails, send response back to user

  • Check if failure is on us, if it is retry 2 more times, if failure is from payment, send failure response right away

Note that failed payment will create failure response



Trade offs/Tech choices

Use SQL (MySQL), strong relationships between rows and use of ACID property to avoid race conditions



Failure scenarios/bottlenecks

Spike in requests during peak hours, for example people need to park and pay in the morning to get to work

  • Can shard database by region/province
  • Load balancer will direct request to correct DB
    • Have Active/Passive load balancer to avoid single point of failure
  • Can have a replication of each DB to avoid having single point of failure in DB (Master/Slave and elect slave as master if master is down)





Future improvements

Create new features depending on what customers want