The task here is to finish the provided 'barebone' backend by implementing all endpoints and required functionality, and setting up the database following these requirements. The goal of this 'project' is to end up with a working REST API with CRUD endpoints for a simple user management, paired with authorization and authentication methods.
For the backend we are using two modern frameworks, NestJS and Prisma running on Node 14. To make the database setup as simple as possible, we will use a SQlite DB. One part of this task will thus be, to familiarize yourself with the technology stack.
The repository as provided throws NotImplementedException() for the missing functions, as well as misses the data structures and database.
Data is being transferred between functions using Data Transfer Objects. This need to be implemented in accordance with the data model. Optionally, data validation should be implemented as well to assure that valid data is being sent into the application.
The database should follow this schema:
Command lines:
npx prisma migrate dev
for migrationnpx prisma db seed
for seeding
- GET /user should query for users with these optional filtering parameters:
limit
Limit the number of results returnedoffset
Skip the first n resultsupdatedSince
Return only items which were updated since Date.id
An Array of id(s) to limit the query toname
a LIKE search for namescredentials
include the related credentials in resultemail
search for matching email
- GET /user/:id should return one specific user with that id
- (public) POST /user should create a new user with credentials
- PATCH /user should update a user if it exists and should update credentials if they exist IF the user has not been deleted previously
- DELETE /user marks the user as deleted and also removes related credentials rows, but does NOT remove the user row itself
- (public) POST /user/authenticate authenticates the user with an email/password combination and returns a boolean
- (public) POST /user/token authenticates the user with an email/password combination and returns a JWT token
- (public) POST /user/validate validates a Bearer token sent via authorization header and returns a boolean
- Endpoints marked (public) should allow access without authorization
- Endpoints not marked (public) should check JWT tokens and map to users
- Health Check endpoints should be public and no JWT should be required
- Non-public endpoints called by Admin users should allow requests to modify all users, while regular users should locked into their own user - they are only allowed to work on their own user id
- Passwords need to be hashed and salted
- If possible, unit tests should check the functionality of the various endpoints and services
- Alternatively, discuss why certain tests were not implemented, necessary or useful, or suggest a test environment
- Discuss improvements to the data models or endpoints
- Feel free to suggest other solutions to implement similar projects (but for this skill check, do use the given tech stack as provided here)
- Fork this repository
- Make modifications as you see fit
- Add all your notes into this readme
- Send us the link to your fork
- Tell us how long it took you to get the repository to the state you sent us - remember: it's ok to take time if it's done properly.
- Import Hiring Backend Test.postman_collection.json into the latest Postman client and run the collection tests. Depending on how you seed your database, some tests may need to be adjusted for ids. Please take a screenshot of the results like this one:
- Send us this screenshot as well as the export of your postman tests.
- the following should run without errors:
yarn
npx migrate reset
yarn test
- the
Get specific user
endpoint was in the admin folder therefore it hadadminToken
. but its test expected to receive a 401 error on accessing userid:2. IDK if it was a misplace or mistake in the test. to fix this issue I moved it to theAs User
folder. - the
Create new user
endpoint can pass the test only the first time, the next time it will raise an exception, in my design email is a unique field.
- the fact that the password is saved in another table then the user has the following benefits, I didn't change that design though.
- (security wise): in the future, this system can be upgraded in a way to forbid user use an old password when a user forgets their password.
- also we can have information about the DateTime of the last password, in case of a data leak, we can inform users to change passwords, and based on that field we can detect which users still using a leaked password and force them to change.
- I also add a field for email_confirmation to understand if the user activate the validate the email entered or not.
- User with email_confirmation: false consider disable users.
- when we delete a user, it is going to be soft delete, and we still keep the information in the user table, this forces us to not use the unique key on the email field.
- but the system must prevent users to create a new account with an already existing email(not deleted).
- to accomplish this, when someone requests to create a user, we have to check this email is not exist(not delete) and then create the user.
- I use raw SQL among with
transaction
in this function to have a single SQL command tocheck email existence
andcreate
the user if it does not already exist. to use transactions in the way that I used, I had to upgrade Prisma to4.8.0
. - this function can handle concurrency under high load and won't let two requests at the same time create two users with the same email, one will fail.