Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
The
The system should allow for all employees and managers to read from the system at the same time. This roughly represents the start of a working week or when shifts are published. E.g. 100 employees and 10 managers means 110 concurrent requests to read data should not overwhelm the system.
Assume most users will be primarily reading data from the system. Assume at most 1 shift per employee per day. It will be hard for an employee to request shift swaps concurrently. Assume all employees can request swaps at the same time. So 100 employees means 100 concurrent swap requests could come in at once.
Endpoints:
Employee endpoints:
Manager endpoints:
All employees and managers must be registered in an Identity and Access Management system. The API will also be registered in the IAM as a resource the users can access. They must have either the "employee" or "manager" role assigned to them. Employees and managers will authenticate against the IAM and their roles will come through as claims and the API will come through as a scope in the issued JSON Web Token. Azure Active Directory or Amazon Cognito are examples of cloud provided IAMs we could use.
The user interface will be a simple static web site. Users will authenticate against an IAM and with the resulting token they will be able to make requests against the API. A front-end library such as React would be suitable and a meta-framework such as NextJS could help speed up development by reducing boilerplate and initial setup time.
The API will authenticate users by checking the signature against the known IAM key, the issuer (the expected IAM tenant), and that it is scoped to the API. The API will define the endpoints listed above. A library like Express or NestJS could help scaffold the API. The API and the database will work together to ensure only one employee is assigned to a shift at any one time.
The database will store all employee shifts and swap requests. It will need to support transactions and row level locking to ensure data consistency.
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
There are 3 operations that are critical when it comes to data consistency:
The database can be used to enforce consistency.
For creating a swap request, a transaction will be started, then a read for any open request between two shifts with an exclusive lock on those rows will be executed. The lock will hold until the end of the transaction. If a record is found then it immediately returns an error. If not then creation can occur.
The same strategy can be used for accepting and approving. First read the desired rows inside a transaction with an exclusive row lock. Then determine if processing can proceed and, if so, modify the target rows. For example, when approving a swap. First ready the request and the two shifts involved. This will prevent any other process from modifying the request status or swapping the shift employees.
If performance becomes a concern a shared in-memory cache such as Redis can be introduced to shield the database from excessive locking of rows.