Skip to content

Pushti2005/Task-Management

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ Todo Task Management API

A production-ready RESTful API for managing tasks, built with Node.js, Express.js, and MongoDB following the MVC architecture pattern.


πŸ“Œ Project Overview

This project is a complete backend solution for a To-Do / Task Management application. It provides a clean REST API with full CRUD operations, input validation, centralised error handling, optional filtering, and a unit test suite β€” built to production-grade standards.


✨ Features

  • βœ… Create, Read, Update, Delete tasks
  • βœ… Mark tasks as completed (with double-completion guard)
  • βœ… Filter tasks by completed status or category
  • βœ… Sort tasks by createdAt or dueDate
  • βœ… Input validation with meaningful error messages
  • βœ… Centralised error handling middleware
  • βœ… Optional dueDate and category fields
  • βœ… MVC architecture with clean separation of concerns
  • βœ… Async/await throughout β€” no callback hell
  • βœ… Jest + Supertest unit & integration tests

πŸ›  Tech Stack

Layer Technology
Runtime Node.js
Framework Express.js v4
Database MongoDB (Mongoose)
Environment dotenv
Testing Jest + Supertest
Dev Server Nodemon

πŸ“ Folder Structure

todo-api/
β”œβ”€β”€ config/
β”‚   └── db.js                 # MongoDB connection logic
β”œβ”€β”€ controllers/
β”‚   └── taskController.js     # Business logic for each route
β”œβ”€β”€ middleware/
β”‚   └── errorMiddleware.js    # 404 handler + global error handler
β”œβ”€β”€ models/
β”‚   └── taskModel.js          # Mongoose schema & model
β”œβ”€β”€ routes/
β”‚   └── taskRoutes.js         # Express Router β€” maps URLs to controllers
β”œβ”€β”€ tests/
β”‚   └── task.test.js          # Jest + Supertest test suite
β”œβ”€β”€ utils/
β”‚   └── asyncHandler.js       # HOF to wrap async controllers
β”œβ”€β”€ .env                      # Environment variables (git-ignored)
β”œβ”€β”€ .env.example              # Template for environment variables
β”œβ”€β”€ .gitignore
β”œβ”€β”€ package.json
└── server.js                 # App entry point

βš™οΈ Setup Instructions

Prerequisites

1. Clone the Repository

git clone https://github.com/your-username/todo-api.git
cd todo-api

2. Install Dependencies

npm install

3. Configure Environment Variables

cp .env.example .env

Open .env and fill in your values:

PORT=5000
MONGO_URI=mongodb://localhost:27017/todo_db
NODE_ENV=development

4. Start the Development Server

npm run dev

The server will start at: http://localhost:5000

5. Start in Production

npm start

πŸ”‘ Environment Variables

Variable Description Default
PORT Port the server listens on 5000
MONGO_URI Full MongoDB connection string mongodb://localhost:27017/todo_db
NODE_ENV Environment: development/production development

πŸ”Œ API Endpoints

Base URL: http://localhost:5000/api

Method Endpoint Description
POST /tasks Create a new task
GET /tasks Get all tasks (supports filters)
GET /tasks/:id Get a single task by ID
PUT /tasks/:id Update a task
DELETE /tasks/:id Delete a task

Query Parameters (GET /api/tasks)

Param Type Description Example
completed Boolean Filter by completion status ?completed=true
category String Filter by category ?category=work
sort String Sort by field (prefix - for descending) ?sort=-createdAt

πŸ“¬ Sample Requests & Responses

βž• Create a Task

Request

POST /api/tasks
Content-Type: application/json

{
  "title": "Complete internship assignment",
  "description": "Build a Node.js REST API with MVC architecture",
  "dueDate": "2025-07-01",
  "category": "work"
}

Response 201 Created

{
  "success": true,
  "data": {
    "_id": "6651abc123def456789gh012",
    "title": "Complete internship assignment",
    "description": "Build a Node.js REST API with MVC architecture",
    "completed": false,
    "dueDate": "2025-07-01T00:00:00.000Z",
    "category": "work",
    "createdAt": "2025-06-01T10:00:00.000Z",
    "updatedAt": "2025-06-01T10:00:00.000Z"
  }
}

πŸ“‹ Get All Tasks

Request

GET /api/tasks

Response 200 OK

{
  "success": true,
  "count": 2,
  "data": [
    {
      "_id": "6651abc123def456789gh012",
      "title": "Complete internship assignment",
      "completed": false,
      "category": "work",
      "createdAt": "2025-06-01T10:00:00.000Z"
    },
    {
      "_id": "6651abc123def456789gh013",
      "title": "Buy groceries",
      "completed": true,
      "category": "personal",
      "createdAt": "2025-05-31T08:30:00.000Z"
    }
  ]
}

πŸ” Get Tasks with Filters

GET /api/tasks?completed=false&category=work&sort=-createdAt

✏️ Update a Task

Request

PUT /api/tasks/6651abc123def456789gh012
Content-Type: application/json

{
  "completed": true
}

Response 200 OK

{
  "success": true,
  "data": {
    "_id": "6651abc123def456789gh012",
    "title": "Complete internship assignment",
    "completed": true,
    "updatedAt": "2025-06-02T14:30:00.000Z"
  }
}

❌ Already Completed Error (Business Rule)

Request

PUT /api/tasks/6651abc123def456789gh012
Content-Type: application/json

{
  "completed": true
}

Response 400 Bad Request

{
  "success": false,
  "message": "Task is already marked as completed"
}

πŸ—‘οΈ Delete a Task

Request

DELETE /api/tasks/6651abc123def456789gh012

Response 200 OK

{
  "success": true,
  "message": "Task \"Complete internship assignment\" deleted successfully",
  "data": {
    "id": "6651abc123def456789gh012"
  }
}

⚠️ Validation Error (Missing Title)

{
  "success": false,
  "message": "Task title is required and cannot be empty"
}

⚠️ Not Found Error

{
  "success": false,
  "message": "Task not found with ID: 6651abc123def456789gh012"
}

πŸ§ͺ Running Tests

npm test

This runs the full Jest + Supertest test suite with coverage reporting.

For a test-specific MongoDB database, add to .env:

MONGO_URI_TEST=mongodb://localhost:27017/todo_test_db

πŸ— Code Architecture & Key Decisions

MVC Pattern

Layer File Responsibility
Model models/taskModel.js Schema definition, DB interaction
View JSON responses (API) Structured JSON output
Controller controllers/taskController.js Business logic, input validation
Router routes/taskRoutes.js Maps HTTP verbs to controller methods

Why asyncHandler?

Without it, an unhandled async error hangs the request indefinitely. This utility wraps every controller so any rejected Promise is automatically forwarded to Express's error pipeline β€” eliminating repetitive try/catch blocks.

Why centralised error middleware?

All error formatting lives in one place. Controllers simply throw or set res.status() and throw. This ensures 100% consistent error response shapes across the entire API.

Why runValidators: true on update?

By default, Mongoose skips schema validators on findByIdAndUpdate. Enabling this ensures constraints like maxlength and enum are enforced on edits, not just on creation.


πŸš€ Future Improvements

  • JWT authentication & user accounts
  • Pagination for large task lists (?page=1&limit=10)
  • Task priority levels (low / medium / high)
  • Search tasks by keyword in title/description
  • Rate limiting (express-rate-limit)
  • Swagger/OpenAPI documentation
  • Docker containerisation
  • CI/CD pipeline with GitHub Actions
  • In-memory MongoDB (mongodb-memory-server) for isolated testing

πŸ“„ License

MIT Β© 2025

About

Node.js REST API for task management built with Express and MongoDB

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors