Consistenty the system must be consistency and must not fail when a payment is done
Reliability the system must be reliable
Mid Availability If the system stops for some time, will be acceptable
The system handle 150 veicles in total in a given time. That mean that is the worst case scenario not the average;
Total of 90 writes per hour, that is very easy to handle;
Data Capacity
90 writes per hour = 2k writes per day
Lets assume to storage all the data(paymentinfo, metda) it will cost 5Kb
Total in a day = 10Mb
Total in a year = 3.65GB
Total in 5 years = 20GB
Obs: If we need to scale the Application it self we could multiply this values for N, where N is the number of parking slot business we want to handle.
For example if we want to handle in our infra 1000 parking slots we will be talking about 2Milions writes per day instead
The api should accomodate request for all the basic funcionalities and need to be authorized by and API key, because the toten or the other system in the place will be the agent of most of the funcionalities
POST /park
Description: Creates a new park session passing the licen and type
Body {
type: 'car' |'moto'
license: string @unique
},
Response {
type: 'car' |'moto'
license: string @unique
status: 'unparked'
}
PUT /park/:slot/:license
Description: Update the vehicle
Response {
ok: true,
parkTime: date
}
PUT /unpark/:slot/:license
Description: Update the vehicle
Response {
ok
unparkTime: date
}
GET /slots
Description: Return all the slots; Can be filtered by occupied of free
Params {
free: bool,
occupied: bool
}
Response {
slots: [{
id: string,
vehicles: string | null
status: string
....
}]
}
POST /park/:licensed
...
For this type of model it will be better to use a SQL database
We have relations for Cars, slots, also for payment information and the strutuct it self; It can accommodate reports data also for knowing the income; the most used slots and the performance of the parking slot ; but we will focus only in the main design
// slot
{
id: number
sector: string
sizeType: 'cars' | 'moto'
accessibility: 'elder' | 'wheelchair' | 'none'
}
// car
{
id: number
license: string
createdAt: date
}
//park-session
{
slotId: id
carId: id
enterTime: id
parkTime: Date
leaveTime: Date
paymentId: id
}
// payment
{
id: ''
hoursBilled: number
value: number
paymentMethod: enum
paymentProvider: enum
receipt: string //receipt URL
...
}
The system should start with the client making the request to the server. I will added a load balancer only if we are going to consider applying this for multiple parking slots. Eather case, we need a secure auth layer in the server layer;
The client will talk with the server. The server need to talk to the database and also with a payment service that in this case will be thirdpartie payment. We also push back communication like webooks for updating the systems implace.
We may provide some dashboard and our own system to view all the information about the parking slot. That can be an static site hosted in a object storage that communicate directly via server with another auth.
The flow would start by creating a new session and if it does not exists registering the vehicle; For the client(system will make an authorized request); Passing the vehicle information. The server will validate the information; Checking for out of patterns, duplications; For example if the car already exists we just register then enter time; Then save the info into the database and notify with the push notification service.
Next the user may park and another trigger for the server will appear; This type the section of the cark will be updated with the parking time; When leaving the user will pay and will register in his session the payment; After leaves another call is made to finish the session and register the leave time
With a load balancer attached and server bein a container we can scale with a kubernate or other seveless provider;
Database can be replicated by provider as this is a multi-tenet approach;
We can use third parties push notification service like firebase;
Dasboard can be a static website hosted in a S3 bucket
Payment Service must handle multiple types of payments for redundancy; Like stripe and others
The server can track the status by the enterTime(without parkTime it means that he still looking for a spot) or parkTime only(meaning that he still parked and did not leaved);
Authlayer can be a tool like coginito from was for easy implementation
The choice of archecture is simpler to adapt to the use case; I can't pay a tool in a huge infrastructure because of the cost and return of the operation
The choice of using an auth layer as coginito is to easy handle this part of the project and give more attention to the product it self;
Load balancer will secure scaling;
As we calculate; Don't see a problem in the database to handle multiple request;
Choice of thirdparte push notification service and payment service with redutant is to avoid cost o implementing own services and manting what third parties services can handle better;
As the system will not scale globality this will be enough
RDS for the database; backup enabled;
The system mail fail for lack of connection in multiple providers; The client may went of and be unable to call our system; We can do anything about that, but we can rety webookcalls for example to keep the clients system update;
We need redundancy in the providers, where they may fail; PaymentService, Push notifications; All of that need to have at leas 3 different providers implemented;
Backup is crucial; We need consistency in the data, so constant backup is a must; So we are using rds for provision backup; also is important to maintain regular backup, with an external job that can send the that to other cloud providers to keep the recovery;
We have edge cases like what we do with cars the stay more than 48 hours;
We have problems that can happen in payments, may and additional support and rout for state that the session was payde by money and other improvements