Functional:
API design
Here's a breakdown of the essential REST
API for our Employee Swap System.
User service:
PUT /auth/login - authenticate a user
PUT /auth/logout - log out user
POST /auth/register - register new user:
{ "name": "name1"
"email":....
"phone": ...
"employe_id":
"position":
"department":
"manager_id"
}
Employee shift matching service:
PUT /shift_matching/v1/swap/{employee_id}/{shift_id} - try to confirm the shift swap for the {shift_id} by an employee {empoloyee_id} Return:
{ "swap_id"....
"status": IN_PROGRESS,APPROVED_BY_MANAGER,APPROVED_BY_OTHER_EMPLOYEE,CANCELED
"createdAt": ....
}
GET /shift_matching/v1/swap/{employee_id}/status/{swap_id} - return the swap status:
{ "swap_id"....
"status": IN_PROGRESS,APPROVED_BY_MANAGER,APPROVED_BY_EMPLOYEE,CANCELED
"createdAt": ....
}
GET /shift_matching/v1/shift/{employee_id}
return the available shifts for an employee
{[.
'shift_id':
'employee_id':
'start_time':
'end_time':
'last_swap_date':
'status':
]}
PUT /shift_matching/swap/manager/{manager_id}/approve/{swap_id} - a manager approves the suggested shift if both employees agree.
Employee Shift service:
GET /employee_shift/v1/shift/{employee_id}/shifts?startDate=..&endDate=..&offset=..&pageSize=.. - get the list of the shifts belonging to the employee:
{ "employee_id":...
"shifts":[
{ "shift_id":....
"startFrom":
"endTo":
'status':
'last_swap_date'
},
....
]
POST /employee_shift/v1/shift/{employee_id}
Persist new shift for an employee.
body:
{ 'shift_id'
'employee_id'
'start_date':
'end_date':
'status':
'last_swap_date':
}
PUT /employee_shift/v1/shift/{employee_id}
Update the shift information for an employee.
See the diagram from the high-level architecture.
API Gateway provides DDoS protection and TLS termination, and routes the requests to the right service nodes.
The user service:
Employee shift matching service:
IN_PROGRESS,APPROVED_BY_MANAGER,APPROVED_BY_OTHER_EMPLOYEE,CANCELED
Employee shift service:
The client application:
Kafka:
Postgres:
Redis:
Employee shift matching service:
This is an essential service and it's used to match the given employee shift. The service prepared the possible shift swap using the Hungarian algorithms and returns the list of shifts to the user. This service returns the swap status update to the client application by using long-polling. It's overkill to use the WebSocket because the swap frequency is low. This service is stateless and if it's down, this service just reads the necessary information from the Employee Shift service and the client application and puts them into Redis. This service is orchestrated by Kubernetes, which cares about the service health and availability. We can use the Kubernetes autoscaling mechanism to regulate the resources to process the user requests efficiently. It cares if some shfit swap is hanging over 1 day, it would be evicted from Redis as outdated.
The Redis cluster is isolated from the Employee shift matching service. The Redis cluster is a highly available and fault-tolerant solution.
The client application is developed to have a comfortable and simple interface for employees. It shows the possible shifts, requests the swap status from the Employee shift matching service. Also, if the Employee shift service is down, it may resend the last information about the swap shift.
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...