System requirements
Functional:
- User Registration and Authentication:
- Users should be able to create an account and log in securely.
- Parking Spot Reservation:
- Users should be able to reserve a parking spot in advance, specifying the start and end time.
- Parking Spot Availability Check:
- Users should be able to check the availability of parking spots for their desired time frame before making a reservation.
- Payment Processing:
- Users should be able to make payments for their reservations via multiple payment methods (credit card, PayPal, etc.).
- Check In and Check Out:
- The system should allow users to check in when they arrive and check out when they leave.
- Cancellation or Modification of Reservations:
- Users should have the option to cancel or modify their reservations before the start time.
- Notifications and Alerts:
- The system should send notifications regarding reservation confirmations, reminders, and cancellations.
- Multi-Vehicle Support:
- The system should support various types of vehicles (cars, trucks, motorcycles) and possibly accommodate special requirements (e.g., electric vehicle charging spots).
- Admin Management Portal:
- An interface for administrators to manage parking lot operations, view reservations, and handle user inquiries.
- Usage Reports:
- Generating reports for management to analyze usage patterns and optimize operations.
Non-Functional:
- Scalability:
- The system should be able to handle growing numbers of users and increased reservation requests, especially during peak hours or occasions (e.g., events or holidays).
- Availability:
- The system should ensure high availability, ideally 99.9% uptime. Users should be able to access the system at any time without significant downtime.
- Performance:
- The system should have quick response times for user actions, such as checking availability (within milliseconds), making reservations, and processing payments.
- Security:
- The system should implement strong security measures, including user authentication, secure payment processing (PCI compliance), and protection against data breaches.
- Usability:
- The user interface should be intuitive and user-friendly, allowing customers to navigate through the functionalities easily and complete their tasks with minimal steps.
- Maintainability:
- The system should be designed in a way that allows for easy updates, bug fixes, and feature enhancements without major downtime or disruption.
- Data Consistency:
- The system must ensure that all data is consistent, particularly for reservations. There should be no double reservations or data integrity issues.
- Fault Tolerance:
- The system should have a plan for handling failures gracefully, ensuring that users can still access necessary functionalities even in the event of a component failure.
- Audit and Monitoring:
- There should be logging and monitoring tools to track system performance, user activities, and any errors that occur, allowing administrators to respond to issues proactively.
- Compliance:
- The system should comply with relevant regulations and standards (e.g., GDPR for data protection, local laws regarding parking services).
Capacity estimation
- Number of Parking Lots:
- The company manages 100 parking lots on average in each country.
- Average Capacity per Parking Lot:
- Each parking lot has a capacity of approximately 200 cars.
Based on these assumptions, here’s the breakdown:
- Total Number of Parking Lots: 100 parking lots per country
- If we consider operations in 10 countries, the total number of parking lots would be:
- 1000 parking lots
- Total Parking Spots Across All Lots:
- 200,000 parking spots
API design
Define what APIs are expected from the system...
API Endpoint: /accounts
Method: POST
Body:
{
"email": ...
"password: ...
}
Response:
Appropriate Status Code
Body:
{
"userId": ...
}
API Endpoint: /parkingspots
Method: GET
Example Request showing filter parameters:
GET /parkingspots?parking-lot-id=123&start-at=2025-01-16T13:00:00&end-at=2025-01-16T15:00:00&vehicle-type=car
Response:
Appropriate Status Code
Body:
{
"availableSpots: [
{
"spotId": "A1",
"lotId": "123",
"vehicleType": "car",
"reserved": false
},
{
"spotId": "A2",
"lotId": "123",
"vehicleType": "car",
"reserved": false
},
]
}
API Endpoint: /reservations
Method: POST
Authorization Header: JWT
Body:
{
"lotId": 123,
"spotId": "A1",
"startAt": timestamp,
"endAt": timestamp,
"vehicleType": "car"
}
Response
Appropriate Status Code
Body
{
"reservationID": 56464
}
API Endpoint: /reservations
Method: POST
Authorization Header: JWT
Body:
{
"reservationId": 56464,
"paymentMethod": "creditCard",
"paymentToken": token
}
Response:
Appropriate Status Code
{
"transactionId": 123,
"status": "paid"
}
checkIn()
Input: reservation_id, authentication
Output: parking_session_id
checkOut()
Input: parking_session_id, authentication
Output: parking_session_id
cancelReservation()
Input: reservation_id, authentication
Output: cancellation_id
updateReservation()
Input: reservation_id, new_start_at, new_end_at, new_vehicle_type, new_parking_spot_id
Output: reservation_id
Database design
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
table: users
columns:
- id primary_key
- email string
- encrypted_password string
table: parking_lots
columns:
- id primary_key
- location string
table parking_spots
columns:
- id primary_key
- parking_lot_id foreign_key
- vehicle_type string
table reservations
columns:
- id primary_key
- parking_spot_id foreign_key
- vehicle_type string
- start_at timestamp
- end_at timestamp
- user_id foreign_key
table cancllations
columns:
- id primary_key
- reservation_id foreign_key
- cancelled_at timestamp
table: parking_sessions
columns:
- id primary_key
- reservation_id foreign_key
- started_at timestamp
- ended_at timestamp
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...
Request flows
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
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
Explain any trade offs you have made and why you made certain tech choices...
Given the capacity estimates above, we should be able to concurrently handle reservations in a single reservation database. If the company were to significantly scale up to the point where a single reservation database was no longer sufficient, there would be a few options. The most straightforward would likely be to shard data into multiple reservation databases based on geographic region. Assuming the geographic regions are reasonably large, most users will likely not be booking parking reservations across multiple regions. However for use cases where we did want to present the user a history of all their reservations, and the user had parked in parking lots stored in separate databases, the reservation service would need to be prepared at the application layer to join together the appropriate data.
We could also scale the reservation database horizontally, and in that case we would need to select select appropriate coordination mechanisms among the instances of the reservation database, and choose between consistency or availability. If it is most important that a user never reserve a parking spot that is already booked by someone else, we should favor consistency over availability. If it is most important that a user never attempt to submit a reservation and receive an error message that the reservation could not be completed, we should favor availability.
Given the significant negative user experience of booking a spot that is already reserved, I would recommend favoring consistency. To ensure consistency across multiple instances of the reservation database, any writes creating new reservations need to be written to a sufficient number of databases in the cluster before the write is considered a success and the response is returned by the reservation service to the user. This consistency will come at the cost of increased latency.
The diagram shows separate databases for the authentication service and the payment/reservations services. This separation of the databases will allow each to be scaled independently, and to be optimized for different read/write patterns. The user database can also follow more strict security policies. However, this separation comes with added complexity that may not be warranted at the estimated capacity. By separating this data, the application layer will have additional work to do to ensure appropriate user ids are passed through to the payment/reservation services after user authentication occurs, and the application layer may need to handle joining together data across the separate databases.
Failure scenarios/bottlenecks
Try to discuss as many failure scenarios/bottlenecks as possible.
Any of the items shown in the diagram from the API Gateway down could be a point of failure. To ensure appropriate uptime, we would need to select an appropriate strategy where either a backup API Gateway can be promoted and traffic routed to the promoted API Gateway or where there are multiple active API Gateways at a time and traffic is routed between them.
For each of the services, multiple instances can run at a time so that no one service is a single point of failure. A solution such as Kubernetes can manage ensuring an appropriate number of instances of each service are running at any given time, or the API Gateway would need to be able to discover the instances of each service and be able to direct traffic among the instances appropriately.
For each of the databases, we should have replica databases ready to be promoted if the active database goes down, and appropriate backups kept so that data is not lost on failure of a database instance.
Future improvements
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?