System requirements


Functional:


  • Number of spots in the parking lot
  • Location of garage, garage id
  • Size of vehicle (small, large)



Non-Functional:

  • I initially thought SQL however if we scale this application to millions of users especially based on geolocation, we quickly begin to run into the problem of scaling data. In this case we use a NoSQL db like mongodb because it allows a flexible schema (JSON format) and has a scalable architecture since it supports sharding which partitions data across different servers. It also has built in geospatial indexing to making queries more efficient based on location




Capacity estimation

Millions of daily active users due to the app being made to scale worldwide.





API design


isLotFull(lotId) -> get request to check if the selected lot is full


getAvailableSpots(lotId) -> get request will search a parking lot by its levels to display exactly which spots in the garage are available


reserveSpot(lotId,timeStart,timeEnd,userId,vehicleId)


timeTillKicked(userid,lotid,timeStart) -> This will refund a user if they have booked a spot but do not show up on time



Database design



User {

userId: int,

name: string,

vehicles: Vehicle[],

email: string,

phone: string,

}


VehicleType {

large:'large',

small:'small'

}


Vehicle {

vehicleId: int,

model: string,

make: string,

licensePlate: string,

type: VehicleType

}


Spot {

spotId:int,

parkingLevelId: int,

isAvailable: bool,

timeStart: datetime,

timeEnd: datetime,

databaseLockTimeStart datetime

}


ParkingLevel {

levelId: int,

parkingLotId: int,

spotStatus: Spot[]

}


ParkingLot {

lotId: int,

city: string,

longitude: float,

latitude: float,

totalSpots:int,

levels: Level[]

}


Reservation {

reservationId:int

currentUser: User

timeStart: datetime

timeEnd: datetime

spotTaken: Spot

}


Payment {

paymentId: int,

user: User

vehicle: Vehicle,

creditCard: string

}





High-level design

You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...


User will visit the app and be routed to the appropriate version of the app based on geolocation. They will input their garage Id and then the server will check if the garage has any spots. If it does, they will then be shown the first available spot there is, at this point a database lock will be placed on this specific spotId preventing someone else from trying to access it and a timer would begin. If the user takes too long the app will display a message saying they took too long and redirect them to the home screen. If the user decides to take the spot then a payment service such as Stripe will handle their payment. Then the database will be updated with the updated spot information. A timer will be activated from the moment the user's timeStart value and if they do not visit their spot within lets say 15 minutes, then they will be refunded a portion of their allotted time and the spot will open up again.






Request flows

  1. user creates a request to the api and the server's load balancer will route this request to the appropriate database shard based on geolocation.
  2. This request will be handled by the server taking into account parking lot capacity, user vehicle and other information input by the user and cache this information
  3. If the user purchases a spot, this payment will be handled by a payment service such as stripe and give the user a choice of few different spots in the parking garage based on success of the payment
  4. The server will utilize optimistic concurrency control to prevent data from being stale
  5. The information will then be written to the database





Detailed component design

Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...






Trade offs/Tech choices

Trade off availability for consistency and partition tolerance because we want something that is highly consistent so nobody views stale data for the available spots and partition tolerance so we can




Failure scenarios/bottlenecks

  • celebrity problem where one geolocation may experience lots of traffic especially if there is an event like a concert with thousands of people visiting a few garages
  • Since we traded off availability, the design won't be prioritized to be highly available





Future improvements

What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?