System requirements


Functional:

  1. Users should be able to reserve a parking spot in advance.
  2. User pay for parking spot : daily or monthly
  3. User take a vehical out of spot of anytime
  4. System checking user infomation : user name , time parking spot out or in
  5. Vehicle Type Accommodation:
    • Clearly specify the need to reserve spots based on vehicle size (compact, standard, large).
  6. Security Features:
  • Include functionalities for displaying or reporting any unauthorized vehicles parked.
  • Check for wrong user card


Non-Functional:

  1. Scalability: We are designing this for an company which manage building for other company hired. Assume : 1 building have 1000 parking slot
  2. Availability: System should always run for weekly working
  3. Consistency:
    • Emphasize the importance of data consistency, especially during updates or reservation changes, to prevent booking errors.
  4. Performance:
    • Implement measures to keep the system responsive even under heavy load, ensuring that user actions are processed within acceptable time frames.
  5. User Experience:
    • Focus on intuitive design for easy navigation and interaction, minimizing user effort in all system interactions.




Capacity estimation

I assume:

  • The company has 5 buildings
  • 1 buildings has 1 parking lot contain 1000 slot
  • 80% of users use it for short term parking, 8 hours
  • For each parking lot, there are depend on number of employee working on that building. So we could take 80% capacity of 1000 slot that is 800


Estimation:

  • 800 *5 building = 4000 reservation requests per day.
  • We have two request in or out so will be 8000 reservation requests per day.
  • Each reservation would mainly consists of:
    • User ID (20 bytes)
    • User's company name (5 byte)
    • Car type (1 byte)
    • Car ID (1 byte)
    • Payment info: total of month (1 byte)
    • Reservation start time (8 byte)
    • Reservation end time (8 byte)
    • Roughly totaling 50 bytes.
    • Other metadata: User company name,
  • Each day, we would add 500KB of data.
  • In 1 year, it would add up to 182MB, we extend 20% more so it will be 212MB.
  • In 5 years, It become 1GB





API design


User Management :

  • GET api/user/{userId}
  • POST api/user(userId, userCompany, CarType, carId)
  • PUT api/user(userId, userCompany, CarType, carId)

Reservations Management

  • POST api/reservation (userId, start_time, spot_id)
  • PUT api/reservation (userId, end_time)

Payment:

  • GET api/payment (userId)
  • POST api/confirmPayment




Database design


Database Choice: The user solution suggests using relational databases without additional context. Since this is a parking reservation system with a requirement for strong consistency (to prevent double booking) and considering the estimated data size, choosing an RDBMS is appropriate.


User Table:

  • user_Id (primary key)
  • user_name (string)
  • company_id (foreign key)


Company table:

  • company_id (primary_key)
  • name (string)


Vehicle table

  • vehicle_id (primary key)
  • name (string)
  • type (string)
  • register_id (string)


Reservation table:

  • reservation_id (primary key)
  • user_id (foreign key)
  • spot_id (foreign key)
  • time_start (date_time)
  • time_end (date_time)
  • status (string)

Spot table:

  • spot_id (primary key)
  • building_name (string)
  • floor (string)


Payment table:

  • payment_id (primary key)
  • user_id (foreign key)
  • daily_pay (number)
  • total_in_month ( number)
  • payment_status (string)





High-level design


flowchart TD

CL[Client] --> |HTTP Request| GW[API Gateway]

GW --> |Filter Requests| RL[Rate Limiter]

RL --> |Distribute Load| LB[Load Balancer]

LB --> |Handle Reservations| RES[Reservation Server]

RES --> |Query Cache| CC[Cache]

RES --> |SQL Queries| DB[Database]

RES --> |Send Messages| MQ[Message Queue]

MQ --> |Process Payments| PAY[Payment System]

RES --> |Send Notifications| NS[Notification System]

NS --> |Real-Time Alerts| CL

LB --> |User Data Handling| UX[User Server]

UX --> |SQL Queries| DB[Database]




Request flows

sequenceDiagram

  participant User

  participant Load Balancer

  participant APIGateway

  participant ReservationService

  participant PaymentService

  participant UserService

  participant Cache

  participant Database


  User->>Load Balancer: Request Reservation In POST/api/reservation()

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  APIGateway->>ReservationService: Make reservation

  ReservationService->>Cache: Insert new reservation

  ReservationService-->>APIGateway: Return Message success

  APIGateway-->>Load Balancer: Return Message success

  Load Balancer-->>User: Return Message success

  PaymentService->>Cache: Create Payment

  Cache->>Database: write-behind caching


  User->>Load Balancer: Request Reservation Out PUT/api/reservation()

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  ReservationService->>Database: Update reservation

  Database-->>ReservationService: Return Message success

  ReservationService->>PaymentService: Update Payment Daily

  PaymentService-->>ReservationService: Update Payment Daily Success

  ReservationService-->>APIGateway: Reservation Status

  APIGateway-->>User: Reservation Status


  User->>Load Balancer: Get User info get api/user/{user_id}

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  UserService->>Database: GET User Info

  Database-->>UserService: Return Message success

  UserService-->>APIGateway: Return Message success

  APIGateway-->>User: User Info


  User->>Load Balancer: Request User POST api/user()

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  UserService->>Database: Create User Info

  Database-->>UserService: Return Message success

  UserService-->>APIGateway: Return Message success

  APIGateway-->>User: User Status


  User->>Load Balance: Request Payment GET api/payment()

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  PaymentService->>Database: Get User payment

  Database-->>PaymentService: Return total number

  PaymentService-->>APIGateway: Return total number

  APIGateway-->>User: Return total number


  User->>Load Balancer: Payment confirm POST api/confirmPayment()

  Load Balancer->>APIGateway: Forward request

  APIGateway->>Cache: Check Authorization

  PaymentService->>Database: Get User payment

  Database-->>PaymentService: Update staus payment

  PaymentService-->>APIGateway: Return Message success

  APIGateway-->>User: Return Message success













Detailed component design

Database:

  • Stores all critical data such as user profiles, reservation details, transaction logs, and payment information. Ensures data persistence and consistency. Strong consistency we choose SQL: PostgreSQL
  • Scalability:
    • Vertical scaling:  By number of employee will grow we need more storage
    • Horizontal scaling: Db sharding by spot_id will improve read performance
  • Replicas: consider use coppy of main db if main db failing

API Gateway:

  • Security: handles user authentication and authorization
  • Rate Limiting: Implements rate limiting to prevent misuse and ensure fair use of service.
  • Request Routing: Distributes incoming requests to the appropriate backend services (e.g., Reservation Service, User Service).
  • Audit and Logging: Maintains logs for monitoring and auditing purposes to track and diagnose issues efficiently.

Load Balancer:

  • Health Monitoring: Continuously checks the health of service instances and reroutes traffic to healthy instances, avoiding downtimes.
  • Load Distribution: Uses algorithms such as round-robin or least connections to efficiently distribute traffic.

Cache:

  • Improves performance by storing frequently accessed data, such as available parking spots
  • Write Behind / Write Back: Write sequence data to cache and then import to db. Improve write performance
  • Read Through: Client read cache when make reservation out or user info. If miss cache read db





Trade offs/Tech choices

Database: we choose SQL

  • Pros: Strong consistecy, support complex join bettwen tables
  • Cons: Hard to scaling without more comlexities

Cache:

  • In-memory(Redis): Highly performant for storing frequently accessed data, reducing database load.
  • Cons: Can lose data if server down

API Gateway:

  • Complexity: when adding more routing logic
  • Debugging Difficulty: authorize fail,



Failure scenarios/bottlenecks

Failure Scenarios:

  1. Database Failure:
    • Scenario: The database becomes unavailable due to a hardware failure, network issue, or incorrect configuration.
    • Mitigation: Utilize database replicas and failover mechanisms. Implement regular backups and use a distributed transactional database system to ensure high availability.


2. Cache Invalidation/Failure:

    • Scenario: The cache returns stale data due to invalidation failures, leading to inconsistent views of available parking spots.
    • Mitigation: Implement cache expiration and invalidation strategies. Use a write-through or write-behind cache for critical data, ensuring the cache and database remain synchronized.


Bottlenecks:

  1. Database Write Bottlenecks:
    • Cause: High volume of simultaneous writes to the database, especially during peak reservation times.
    • Resolution: Optimize database write operations and consider sharding or partitioning data to spread the load.




Future improvements

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