New Assignment Backend
New Assignment Backend
md 2024-12-16
Key Points:
One Organization, One Admin: Each organization has a single Admin with full control over the
system.
Role-Based Access Control: Users have distinct roles (Admin, Editor, Viewer), with permissions
tailored to their responsibilities.
Entity Relationships: Albums belong to Artists, and Tracks are associated with Albums and
Artists.
Favorites: Users can personalize their experience by marking items as favorites for easy retrieval.
Your Task
Your task is to develop a RESTful API that allows users to manage their music library. The API should support
the features listed below. Ensure you follow best practices for API development, including proper status
codes, error handling, and response payloads.
Evaluation Criteria
API correctness: Ensure all 25(0 to 24) endpoints function as expected with proper request and
response handling.
Code structure and cleanliness.
Error handling and status code implementation.
Adherence to best practices in RESTful API design.
Use Node.js for the backend and any database of your choice.
Submission
Create a new repository on GitHub and push your code to it.
Deploy your API to a hosting service (e.g. Render Heroku, Vercel, AWS, etc.)
Render is a free hosting service which you can use to deploy your API https://render.com/docs/free
Submit the repository link and the hosted API URL/Hosted URL(baseUrl).
Make sure you proved your hosted URL(baseUrl) in the submission based on that we will check the
endpoints; example: base-url:https://your-hosted-url/ or base-url:https://your-hosted-
url/api/v1
Based on the base-url we will check the endpoints, Base-url/logout, Base-url/signup, base-url/users, etc.
API responses must be in JSON format.
For GET requests, ensure the response structure matches the examples provided.
use same endpoint as below
1 / 34
readme.md 2024-12-16
Features
Authentication and Authorization
Implement authentication and role-based access control using a method of your choice.
Roles:
Admin: Full CRUD operations on all entities, including user management.
Editor: Can edit and delete Artists, Albums, Tracks, and their own details (e.g., updating their
password).
Viewer: Read-only access to all entities.
The first user registered in the system automatically becomes an Admin.
Entity Management
1. Users:
Admins can manage users by adding, deleting, and updating their roles (except for other Admins).
2. Artists, Albums, Tracks:
Full CRUD operations based on role permissions.
3. Favorites:
Users can add or remove their favorite Artists, Albums, and Tracks.
Database Schema
You are encouraged to design the tables based on the requirements provided. Below are hints for the schema
structure.
1. User Table
2. Artist Table
3. Album Table
2 / 34
readme.md 2024-12-16
4. Track Table
5. Favorites Table
Status Codes
Below is a brief summary of all the endpoints and their key response codes: these status codes will be checked
for each endpoint,a nd all get requests should return the same response format as below
3 / 34
readme.md 2024-12-16
Endpoints
Base URL: your-hosted-url/api/v1
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/logout
Responses:
4 / 34
readme.md 2024-12-16
{
"status": 200,
"data": null,
"message": "User logged out successfully.",
"error": null
}
{
"status": 400,
"data": null,
"message": "Bad Request",
"error": null
}
Request Endpoint:
POST BASE-URL/signup
Request Body:
{
"email": "[email protected]",
"password": "password"
}
Responses:
5 / 34
readme.md 2024-12-16
{
"status": 201,
"data": null,
"message": "User created successfully.",
"error": null
}
{
"status": 400,
"data": null,
"message": "Bad Request, Reason:${Missing Field}",
"error": null
}
{
"status": 409,
"data": null,
"message": "Email already exists.",
"error": null
}
Request Endpoint:
POST BASE-URL/login
Request Body:
{
"email": "[email protected]",
"password": "securePassword123"
}
6 / 34
readme.md 2024-12-16
Responses:
{
"status": 200,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"message": "Login successful.",
"error": null
}
{
"status": 400,
"data": null,
"message": "Bad Request, Reason:${Missing Field}",
"error": null
}
{
"status": 404,
"data": null,
"message": "User not found.",
"error": null
}
Description: Retrieve a list of all users under the same Admin. This endpoint can only be accessed by
the Admin user. Pagination is supported using limit and offset.
Query Parameters:
7 / 34
readme.md 2024-12-16
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/users?limit=5&offset=0&role=Editor
or
GET BASE-URL/users
Responses:
{
"status": 200,
"data": [
{
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"email": "[email protected]",
"role": "editor",
"created_at": "2024-12-03T10:00:00Z"
},
...4 more
],
"message": "Users retrieved successfully.",
"error": null
}
8 / 34
readme.md 2024-12-16
{
"status": 400,
"data": null,
"message": "Bad Request",
"error": null
}
{
"status": 401,
"data": null,
"message": "Unauthorized Access",
"error": null
}
Description: Only the Admin can create new users by providing their email, password, and role. The
role cannot be "admin" when creating a new user, and users can only create other users with the
"editor" or "viewer" roles.
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
POST BASE-URL/users/add-user
Request Body:
{
"status": 409,
"data": null,
"message": null,
"error": "Email already exists."
}
9 / 34
readme.md 2024-12-16
Responses:
{
"status": 201,
"data": null,
"message": "User created successfully.",
"error": null
}
{
"status": 400,
"data": null,
"message": "Bad Request",
"error": null
}
{
"status": 401,
"data": null,
"message": "Unauthorized Access",
"error": null
}
{
"status": 403,
"data": null,
"message": "Forbidden Access/Operation not allowed.",
"error": null
}
10 / 34
readme.md 2024-12-16
{
"status": 409,
"data": null,
"message": "Email already exists.",
"error": null
}
Description: Only the Admin can delete a user by providing their user ID.
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
DELETE BASE-URL/users/:user_id
or
DELETE BASE-URL/users/123e4567-e89b-12d3-a456-426614174000
Responses:
11 / 34
readme.md 2024-12-16
{
"status": 200,
"data": null,
"message": "User deleted successfully.",
"error": null
}
{
"status": 404,
"data": null,
"message": "User not found.",
"error": null
}
Description: The user of any role can update their password by providing the old password and a new
password.
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
PUT BASE-URL/users/update-password
Request Body:
{
"old_password": "oldPassword",
"new_password": "newPassword"
}
12 / 34
readme.md 2024-12-16
Responses:
// No response body
or
<empty response>
You can filter artists by Grammy status, visibility, and control the number of records returned using limit and
offset.
Query Parameters:
Request Headers:
{
"Authorization": "Bearer <token>"
13 / 34
readme.md 2024-12-16
Request Endpoint:
GET BASE-URL/artists?limit=5&offset=0&grammy=10&hidden=false
or
GET BASE-URL/artists
Responses:
{
"status": 200,
"data": [
{
"artist_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Adele",
"grammy": 5,
"hidden": false,
},
...4 more
],
"message": "Artists retrieved successfully.",
"error": null
}
Request Headers:
14 / 34
readme.md 2024-12-16
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/artists/:artist_id
or
GET BASE-URL/artists/123e4567-e89b-12d3-a456-426614174000
Responses:
{
"status": 200,
"data": {
"artist_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Adele",
"grammy": 5,
"hidden": false
},
"message": "Artist retrieved successfully.",
"error": null
}
15 / 34
readme.md 2024-12-16
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
POST BASE-URL/artists/add-artist
Request Body:
{
"name": "Eminem",
"grammy": 15,
"hidden": false
}
Responses:
{
"status": 201,
"data": null,
"message": "Artist created successfully.",
"error": null
}
16 / 34
readme.md 2024-12-16
Description: Update an artist by providing their artist ID, details such as name, Grammy status, and
visibility(hidden).
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
PUT BASE-URL/artists/:artist_id
or
PUT BASE-URL/artists/123e4567-e89b-12d3-a456-426614174000
Request Body:
{
"name": "Eminem",
"grammy": 18,
"hidden": false
}
{
"name": "Eminem (Slim Shady)"
}
Responses:
17 / 34
readme.md 2024-12-16
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
DELETE BASE-URL/artists/:artist_id
Responses:
{
"status": 200,
"data": {
"artist_id": "123e4567-e89b-12d3-a456-426614174000"
},
"message": "Artist:${artist_name} deleted successfully.",
"error": null
}
18 / 34
readme.md 2024-12-16
Description: Retrieve a list of all albums, can filter the albums by artist and visibility(hidden), and
control the number of records returned using limit and offset.
Query Parameters:
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/albums?limit=5&offset=0&artist_id=123e4567-e89b-12d3-a456-
426614174000&hidden=false
or
GET BASE-URL/albums
Responses:
19 / 34
readme.md 2024-12-16
{
"status": 200,
"data": [
{
"album_id": "123e4567-e89b-12d3-a456-426614174000",
"artist_name": "Eminem",
"name": "Recovery",
"year": 2010,
"hidden": false,
},
...4 more
],
"message": "Albums retrieved successfully.",
"error": null
}
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/albums/:album_id
or
GET BASE-URL/albums/123e4567-e89b-12d3-a456-426614174000
20 / 34
readme.md 2024-12-16
Responses:
{
"status": 200,
"data": {
"album_id": "123e4567-e89b-12d3-a456-426614174000",
"artist_name": "Eminem",
"name": "Recovery",
"year": 2010,
"hidden": false
},
"message": "Album retrieved successfully.",
"error": null
}
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
POST BASE-URL/albums/add-album
Request Body:
21 / 34
readme.md 2024-12-16
{
"artist_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Marshall Mathers LP",
"year": 2000,
"hidden": false
}
Responses:
{
"status": 201,
"data": null,
"message": "Album created successfully.",
"error": null
}
Description: Update an album by providing its album ID, details such as name, year, and
visibility(hidden).
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
22 / 34
readme.md 2024-12-16
PUT BASE-URL/albums/:album_id
or
PUT BASE-URL/albums/123e4567-e89b-12d3-a456-426614174000
Request Body:
{
"name": "Marshall Mathers LP 2",
"year": 2013,
"hidden": false
}
{
"name": "Marshall Mathers LP 2"
}
Responses:
23 / 34
readme.md 2024-12-16
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
DELETE BASE-URL/albums/:album_id
or
DELETE BASE-URL/albums/123e4567-e89b-12d3-a456-426614174000
Responses:
{
"status": 200,
"data": null,
"message": "Album:${album_name} deleted successfully.",
"error": null
}
24 / 34
readme.md 2024-12-16
Description: Retrieve a list of all tracks, can filter the tracks by artist, album, and visibility(hidden), and
control the number of records returned using limit and offset.
Query Parameters:
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/tracks?limit=5&offset=0&artist_id=123e4567-e89b-12d3-a456-
426614174000&album_id=123e4567-e89b-12d3-a456-426614174000&hidden=false
or
GET BASE-URL/tracks
Responses:
{
"status": 200,
"data": [
25 / 34
readme.md 2024-12-16
{
"track_id": "123e4567-e89b-12d3-a456-426614174000",
"artist_name": "Eminem",
"album_name": "Recovery",
"name": "Not Afraid",
"duration": 263,
"hidden": false,
},
...4 more
],
"message": "Tracks retrieved successfully.",
"error": null
}
Request Headers:
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/tracks/:track_id
or
GET BASE-URL/tracks/123e4567-e89b-12d3-a456-426614174000
26 / 34
readme.md 2024-12-16
Responses:
{
"status": 200,
"data": {
"track_id": "123e4567-e89b-12d3-a456-426614174000",
"artist_name": "Eminem",
"album_name": "Recovery",
"name": "Not Afraid",
"duration": 263,
"hidden": false
},
"message": "Track retrieved successfully.",
"error": null
}
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
POST BASE-URL/tracks/add-track
27 / 34
readme.md 2024-12-16
Request Body:
{
"artist_id": "123e4567-e89b-12d3-a456-426614174000",
"album_id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Not Afraid",
"duration": 263,
"hidden": false
}
Responses:
{
"status": 201,
"data": null,
"message": "Track created successfully.",
"error": null
}
Description: Update a track by providing its track ID, details such as name, duration, and
visibility(hidden).
{
"Authorization": "Bearer <token>"
}
28 / 34
readme.md 2024-12-16
Request Endpoint:
PUT BASE-URL/tracks/:track_id
or
PUT BASE-URL/tracks/123e4567-e89b-12d3-a456-426614174000
Request Body:
{
"name": "Not Afraid (Explicit)",
"duration": 263,
"hidden": false
}
{
"name": "Not Afraid (Explicit)"
}
Responses:
29 / 34
readme.md 2024-12-16
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
DELETE BASE-URL/tracks/:track_id
or
DELETE BASE-URL/tracks/123e4567-e89b-12d3-a456-426614174000
Responses:
{
"status": 200,
"data": null,
"message": "Track:${track_name} deleted successfully.",
"error": null
}
30 / 34
readme.md 2024-12-16
Description: Retrieve the user's favorite items based on the category(artist, album, or track) provided.
Query Parameters:
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
GET BASE-URL/favorites/:category?limit=5&offset=0
or
GET BASE-URL/favorites/artist
Responses:
31 / 34
readme.md 2024-12-16
{
"status": 200,
"data": [
{
"favorite_id": "123e4567-e89b-12d3-a456-426614174000",
"category": "artist",
"item_id": "123e4567-e89b-12d3-a456-426614174000", // item_id based on
category type (artist_id, album_id, track_id)
"name": "Eminem",
"created_at": "2024-12-03T10:00:00Z"
},
...4 more
],
"message": "Favorites retrieved successfully.",
"error": null
}
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
POST BASE-URL/favorites/add-favorite
Request Body:
{
"category": "artist", // artist, album, track
"item_id": "123e4567-e89b-12d3-a456-426614174000" // item_id based on category
type (artist_id, album_id, track_id)
}
32 / 34
readme.md 2024-12-16
Responses:
{
"status": 201,
"data": null,
"message": "Favorite added successfully.",
"error": null
}
Description: Remove a favorite item from the user's list by providing its favorite ID.
Request Headers:
{
"Authorization": "Bearer <token>"
}
Request Endpoint:
DELETE BASE-URL/favorites/remove-favorite/:favorite_id
or
DELETE BASE-URL/favorites/remove-favorite/123e4567-e89b-12d3-a456-426614174000
33 / 34
readme.md 2024-12-16
Responses:
{
"status": 200,
"data": null,
"message": "Favorite removed successfully.",
"error": null
}
34 / 34