💫 Welcome! 🎉
This backend exercise involves building a Node.js/Express.js app that will serve a REST API. We imagine you should spend around 3 hours at implement this feature.
All models are defined in src/model.js
A profile can be either a client
or a contractor
.
clients create contracts with contractors. contractor does jobs for clients and get paid.
Each profile has a balance property.
A contract between and client and a contractor.
Contracts have 3 statuses, new
, in_progress
, terminated
. contracts are considered active only when in status in_progress
Contracts group jobs within them.
contractor get paid for jobs by clients under a certain contract.
The exercise requires Node.js to be installed. We recommend using the LTS version.
-
Start by creating a local repository for this folder.
-
In the repo root directory, run
npm install
to gather all dependencies. -
Next,
npm run seed
will seed the local SQLite database. Warning: This will drop the database if it exists. The database lives in a local filedatabase.sqlite3
. -
Then run
npm start
which should start both the server and the React client.
❗️ Make sure you commit all changes to the master branch!
-
The server is running with nodemon which will automatically restart for you when you modify and save a file.
-
The database provider is SQLite, which will store data in a file local to your repository called
database.sqlite3
. The ORM Sequelize is on top of it. You should only have to interact with Sequelize - please spend some time reading sequelize documentation before starting the exercise. -
To authenticate users use the
getProfile
middleware that is located under src/middleware/getProfile.js. users are authenticated by passingprofile_id
in the request header. after a user is authenticated his profile will be available underreq.profile
. make sure only users that are on the contract can access their contracts. -
The server is running on port 3001.
Below is a list of the required API's for the application.
-
GET
/contracts/:id
- It should return the contract only if it belongs to the profile calling. - Fixed - Can make it better to include client and contractor details. -
GET
/contracts
- Returns a list of contracts belonging to a user (client or contractor), the list should only contain non terminated contracts. - Done -
GET
/jobs/unpaid
- Get all unpaid jobs for a user (either a client or contractor), for active contracts only. - Done -
POST
/jobs/:job_id/pay
- Pay for a job, a client can only pay if his balance >= the amount to pay. The amount should be moved from the client's balance to the contractor balance. - Done -
POST
/balances/deposit/:userId
- Deposits money into the the the balance of a client, a client can't deposit more than 25% his total of jobs to pay. (at the deposit moment) - Done -
GET
/admin/best-profession?start=<date>&end=<date>
- Returns the profession that earned the most money (sum of jobs paid) for any contactor that worked in the query time range. -
GET
/admin/best-clients?start=<date>&end=<date>&limit=<integer>
- returns the clients the paid the most for jobs in the query time period. limit query parameter should be applied, default limit is 2.
[
{
"id": 1,
"fullName": "Reece Moyer",
"paid" : 100.3
},
{
"id": 200,
"fullName": "Debora Martin",
"paid" : 99
},
{
"id": 22,
"fullName": "Debora Martin",
"paid" : 21
}
]
When you have finished the assignment, zip your repo (make sure to include .git folder) and send us the zip.
Thank you and good luck! 🙏