Backend Development
Scenario
You are a junior backend developer at “Productivity Inc.,” a startup building a new suite of productivity tools. Your first major assignment is to build the entire backend for their flagship product, TaskMaster. This API will be the engine that powers the entire application, handling user accounts, project management, and individual tasks.
This is a capstone project designed to synthesize the skills you have learned across multiple modules. You will plan and execute the development of a real-world, secure, and functional RESTful API from the ground up. Success will require careful planning, clean code, and a solid understanding of authentication and authorization principles.
This project emphasizes the DRY (Don’t Repeat Yourself) principle. You are strongly encouraged to reference, reuse, and adapt the code and patterns you have developed in the labs and lessons from previous modules.
Core Concepts Assessed
- Node.js & Express: Server setup, modular routing, middleware implementation, and RESTful API design.
- MongoDB & Mongoose: Complex schema design with relationships (
ref
), data validation, and advanced Mongoose queries for CRUD operations. - Authentication & Authorization: JWT-based user authentication (registration and login), password hashing with
bcrypt
, and multi-layered, ownership-based authorization rules.
Instructions
Phase 1: Planning and Setup (Foundation)
- Plan Your API: Before writing any code, plan your data models and API endpoints. Think about the relationships between users, projects, and tasks. What information does each model need? What routes will you need to perform all the required actions? Creating a simple
README.md
to outline your API (e.g.,POST /api/users/login
,GET /api/projects
, etc.) is highly recommended. - Project Initialization:
- Create a new project directory and initialize it with
npm
. - Install all necessary dependencies:
express
,mongoose
,bcrypt
,jsonwebtoken
,dotenv
. - Create a
.gitignore
file to excludenode_modules
and.env
.
- Create a new project directory and initialize it with
- Environment Configuration: Create a
.env
file to store yourMONGO_URI
,PORT
, and a secureJWT_SECRET
. - Modular Structure: Design a clean, modular folder structure. All logic should be separated by concern. A suggested structure:
config/
(for database connection)models/
(for Mongoose schemas)routes/api/
(for different route files likeuserRoutes.js
,projectRoutes.js
, etc.)utils/
(for authentication helpers)server.js
(main entry point)
Phase 2: Data Modeling (The Blueprint)
User
Model: Define auserSchema
that includes fields forusername
,email
(must be unique), andpassword
. It must include apre-save
hook to hash the password usingbcrypt
, as demonstrated in Module 418.Project
Model: Define aprojectSchema
. A project should have aname
, adescription
, and, most importantly, a reference to the user who owns it. This is a critical field for authorization.// Example field in projectSchema user: { type: Schema.Types.ObjectId, ref: 'User', required: true }
Task
Model: Define ataskSchema
. A task should havetitle
,description
, astatus
(e.g., ‘To Do’, ‘In Progress’, ‘Done’), and a reference to the project it belongs to.
Phase 3: Authentication API (The Gatekeeper)
- User Routes: Create
userRoutes.js
. - Registration (
POST /api/users/register
): This endpoint should create a new user, ensuring the password gets hashed by the model’spre-save
hook. - Login (
POST /api/users/login
): This endpoint should find a user by their email, compare the provided password with the stored hash, and, if successful, generate and return a signed JSON Web Token (JWT).
Phase 4: Projects API (Managing the Big Picture)
- Project Routes: Create
projectRoutes.js
. - Security First: All routes in this file must be protected by your authentication middleware. Only a logged-in user can perform any action on projects.
- Full CRUD:
POST /api/projects
: Create a new project. The owner’s ID must be taken from thereq.user
object (provided by the auth middleware) and saved with the new project.GET /api/projects
: Get all projects owned by the currently logged-in user.GET /api/projects/:id
: Get a single project by its ID. This must be protected by an ownership check—a user can only get a project they own.PUT /api/projects/:id
: Update a project. Also protected by an ownership check.DELETE /api/projects/:id
: Delete a project. Also protected by an ownership check.
Phase 5: Tasks API (The Nitty-Gritty)
- Task Routes: Create
taskRoutes.js
. - Nested & Secure: The key here is that tasks are children of projects. This relationship must be reflected in your routes and your security model.
- Full CRUD for Tasks:
POST /api/projects/:projectId/tasks
: Create a new task for a specific project. Before creating the task, you must verify that the logged-in user owns the project specified by:projectId
.GET /api/projects/:projectId/tasks
: Get all tasks for a specific project. This also requires an ownership check on the parent project.PUT /api/tasks/:taskId
: Update a single task. This is the most complex authorization check. You must:- Find the task by
:taskId
. - From the task, find its parent project.
- Verify that the logged-in user owns that parent project.
- Find the task by
DELETE /api/tasks/:taskId
: Delete a single task. This requires the same complex authorization check as the update route.
Submission Instructions
- Ensure your application runs without errors.
- Test every endpoint thoroughly using an API client like Insomnia or Postman. Pay special attention to the security rules:
- Try to access protected routes without a token.
- Log in as User A and attempt to access data owned by User B. All such attempts should be rejected with a
403 Forbidden
or similar status.
- Submit a link to your completed GitHub repository. Ensure your
.env
file is included in.gitignore
and not pushed to the repository.
Grading Rubric
Criteria | Excellent | Satisfactory | Needs Improvement | Points |
---|---|---|---|---|
Project Planning & Documentation | (9-10 pts) A thoughtful README.md is present, outlining the API endpoints and project purpose. | (7-8 pts) A README.md exists but is basic, missing key details about the API structure. | (0-6 pts) No README.md or planning document is present. | 10 |
Project Structure & Modularity | (14-15 pts) Project has a clean, modular structure ( config , models , routes , utils ) with a clear separation of concerns. | (11-13 pts) Project has a structure, but some logic is misplaced (e.g., database connection in server.js ). | (0-10 pts) Project lacks a logical structure; most or all code is in a single file. | 15 |
Configuration & Env. Security | (14-15 pts).env is used for all secrets and config. .gitignore correctly excludes node_modules and .env . | (11-13 pts).env is used, but one secret might be missing. .gitignore might be incomplete. | (0-10 pts) Secrets are hardcoded in the application files. .gitignore is missing or incorrect. | 15 |
Mongoose Schema Definition | (27-30 pts) All schemas ( User , Project , Task ) are defined with all required fields, correct data types, and appropriate validation. | (21-26 pts) Schemas are mostly correct but may be missing a field, have an incorrect data type, or lack validation. | (0-20 pts) Schemas are incomplete, have multiple errors, or are missing entirely. | 30 |
Data Model Relationships (ref ) | (27-30 pts) The ref property is used perfectly to establish the User -> Project and Project -> Task relationships. | (21-26 pts) Relationships are established, but there may be a minor error in the ref configuration on one model. | (0-20 pts) The relationships between models are not implemented correctly, are non-functional, or are missing. | 30 |
Password Security (bcrypt ) | (18-20 pts) A pre-save hook on the User model flawlessly and securely hashes passwords before saving. | (14-17 pts) Password hashing is implemented, but not as a pre-save hook (e.g., it’s done in the route handler). | (0-13 pts) Password hashing is not implemented, or it is non-functional/insecure. | 20 |
User Registration Endpoint | (18-20 pts) The POST /register endpoint works robustly, creating new users and correctly handling errors for duplicate emails. | (14-17 pts) The registration endpoint works but lacks proper error handling for duplicate users or edge cases. | (0-13 pts) The registration endpoint is non-functional or has major security flaws. | 20 |
User Login & JWT Implementation | (18-20 pts) The POST /login endpoint securely validates credentials against the hashed password and issues a correctly signed JWT. | (14-17 pts) The login endpoint works, but may have inconsistent error messages or minor issues with JWT signing. | (0-13 pts) The login endpoint is non-functional, does not compare passwords correctly, or fails to issue a JWT. | 20 |
Projects API: CRUD Functionality | (27-30 pts) All five Project CRUD endpoints ( POST , GET all, GET one, PUT , DELETE ) are implemented correctly and function as expected. | (21-26 pts) Most Project CRUD endpoints work, but one or two may have bugs or are incomplete. | (0-20 pts) Multiple Project CRUD endpoints are non-functional or missing. | 30 |
Projects API: Authorization | (36-40 pts) Ownership-based authorization is flawlessly implemented for all relevant project routes, returning filtered lists and blocking access to other users’ data with a 403 status. | (28-35 pts) Authorization logic is flawed; it is missing from one route or doesn’t correctly block access in all cases. | (0-27 pts) Authorization is missing entirely, allowing any logged-in user to manage any project. | 40 |
Tasks API: CRUD Functionality | (27-30 pts) All four Task CRUD endpoints are implemented correctly using the specified nested routes (e.g., POST /api/projects/:projectId/tasks ). | (21-26 pts) Most Task CRUD endpoints work, but the routing structure may not correctly reflect the nested relationship. | (0-20 pts) Multiple Task CRUD endpoints are non-functional, or the routing is completely incorrect. | 30 |
Tasks API: Authorization | (36-40 pts) The complex authorization logic (checking ownership of the PARENT project) is implemented perfectly for ALL task operations. | (28-35 pts) Authorization is present but flawed; e.g., it is not implemented on all routes or doesn’t check the parent project. | (0-27 pts) No authorization logic is present, allowing users to manipulate tasks in projects that are not their own. | 40 |
Total | 300 |