System requirements


Functional:

User should be able to find a open parking lot

User should be able to pay when they leave the parking lot



Non-Functional:

Availability over consistency when user try to find a parking lot

Consistency over availability when user make payment

System should identify the entering time and the leaving time for each car

The scalability should be not a big problem in this case, since the size of the parking lot is very limited

Parking record should be deleted after 30 days


Capacity estimation

Usually, there should able around 1 car per minute to enter or exit the parking lot. That's around 2000 RPC per day on average. For the spike time, we could have around 10000 RPC per day

We need to store the ticket_id, entering_time in the database, and we also need a database for all parking lot with information such as, lot_id, location, level. Since it's really related to the size of the parking lot. The entire database should not be too large.



API design

There should be three APIs in this case:


GetFreeLot()

This API should be able to get all free lots on the current level or location and inform the clients:

GetFreeLot(locations_id/level_id) -> the number of car


UpdateFreeLot()

This API should be able to update the database once a free parking lot is newly taken by a client:

UpdateFreeLot(location_id/level_id)


PaymentService()

This API should be able to take in the ticket information and calculate the payment for the client and then connect with billing platform such as Stripe to process the payment

PaymentService() -> ticketid, entering time

PaymentService(ticked_id) -> redirection to billing service



Database design

We can have a NoSQL key-value pair database in this case.

The first database should store the client information:

  • Ticket_id
  • entering_time

The second database should store the parking lot availability information

  • parking_id
  • location
  • level
  • availabiilty (occupied or not)




High-level design

Since we do not have too much queries in this case, we do not need a load balance.

The client should send GetFreeLot() and PaymentService() when they enter the park lot, both GetFreeLot() should pull up information in the parking lot database and PaymentService() should enter ticketid and entering to the ticket database.

Once client has parked their car or exit the current parking lot, client should send UpdateFreeLot() to the databse

Once the client is exiting the parking lot, it should send PaymentService with their ticket_id and the server should lookup in the database and check for the id and calculate the parking and redirect to the billing platform


Request flows

Since we do not have too much queries in this case, we do not need a load balance.

The client should send GetFreeLot() and PaymentService() when they enter the park lot, both GetFreeLot() should pull up information in the parking lot database and PaymentService() should enter ticketid and entering to the ticket database.

Once client has parked their car or exit the current parking lot, client should send UpdateFreeLot() to the databse

Once the client is exiting the parking lot, it should send PaymentService with their ticket_id and the server should lookup in the database and check for the id and calculate the parking and redirect to the billing platform




Detailed component design

PaymentService() should user base62 to randomly generate a ticket_id and make sure the ticket_id is not already in the database. It there is a collision in the database, PaymentService should randomly generate again until there is no collision. In our case, due to the limits of size of a parking lot, the chance get a collision is rare.


PaymentService(ticket_id) should search for a match in the Ticket databse. It there is not hit, it should redirect to a billing platform such as Stripe with max rate. Otherwise, it should pull up the entering time and calculate the payment with the current time and redirect the current rate with the billing platform


UpdateFreeLot(location_id/level_id) should prefer availability with short latency such as 10 ms. The consistency is not important in this case, since client can bear with incurate information.


GetFreeLot() should prefer availability and the latency should be less then 10ms




Trade offs/Tech choices

There are two ways to create the ticket id

  1. Randomly generate
  2. Hash

Pro of hash:

we do not need to randomly generate the number

Con of hash

The collision chance will increase

Pro of randomly generate

The collision chance will decrease

Con of randomly generate

It require computational power with high cost




Failure scenarios/bottlenecks

Client could lose their ticket or their ticket_id is not available in the system

  • Max parking fee should be applied


Database lost

  • we can add replica from time to time to ensure that ticket database is always online


Future improvements

Parking lot owner should be able to adjust the payment rate

Client should have a route to their closet parking lot

Use AI to scan the parking plate instead of giving them paper ticket