Welcome to the TaskFlow API documentation. This guide is designed to help you integrate the TaskFlow backend into your frontend application. Whether you are using fetch, axios, or any other library, this guide will provide you with the exact steps and code snippets you need.
- Base URL
- Response Format
- Authentication Flow
- Docker Setup
- API Endpoints
- Real-time Notifications
- Frontend Integration Examples
All API requests should be made to:
http://localhost:3000 (or your production URL)
The API uses a standard response wrapper for all successful requests. This makes it easy for you to handle data consistently.
Success Response Structure:
{
"data": { ... }, // The actual data you requested
"statusCode": 200 // The HTTP status code
}Error Response Structure:
{
"statusCode": 400,
"message": "Error message here",
"error": "Bad Request"
}TaskFlow uses JWT (JSON Web Tokens) for authentication.
- Register/Login: When you register or log in, the API returns an
accessTokenand arefreshToken. - Access Token: This token is short-lived. You must include it in the
Authorizationheader for all protected routes.- Header format:
Authorization: Bearer <your_access_token>
- Header format:
- Refresh Token: This token is long-lived. Use it to get a new
accessTokenwhen the old one expires.
You can run the entire TaskFlow API and MongoDB using Docker. This is the easiest way to get started.
- Docker installed on your machine.
- Docker Compose installed.
- Clone the repository.
- Create a
.envfile in the root directory and add your environment variables (see.env.example). - Run Docker Compose:
docker compose up --build
- Access the API: The API will be available at
http://localhost:3000.
- api: The NestJS application.
- mongodb: The MongoDB database.
- URL:
/auth/register - Method:
POST - Body:
{ "name": "John Doe", "email": "john@example.com", "password": "password123" } - Response: Returns
accessTokenandrefreshToken.
- URL:
/auth/login - Method:
POST - Body:
{ "email": "john@example.com", "password": "password123" } - Response: Returns
accessTokenandrefreshToken.
- URL:
/auth/refresh - Method:
POST - Headers:
Authorization: Bearer <your_refresh_token> - Response: Returns a new
accessToken.
- URL:
/auth/logout - Method:
POST - Headers:
Authorization: Bearer <your_access_token> - Body:
{ "refreshToken": "<your_refresh_token>" }
- URL:
/users/me - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
- URL:
/users - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
- URL:
/tasks - Method:
POST - Headers:
Authorization: Bearer <your_access_token> - Body:
{ "title": "Task Title", "description": "Optional description", "status": "Todo", // Optional: Todo, InProgress, Done "priority": "Medium", // Optional: Low, Medium, High "dueDate": "2023-12-31T23:59:59Z", // Optional "teamId": "team_mongo_id", "assigneeId": "user_mongo_id" // Optional }
- URL:
/tasks - Method:
GET - Headers:
Authorization: Bearer <your_access_token> - Query Params:
status,priority,teamId,assigneeId(all optional)- Example:
/tasks?status=Todo&priority=High
- Example:
- URL:
/tasks/:id - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
- URL:
/tasks/:id - Method:
PATCH - Headers:
Authorization: Bearer <your_access_token> - Body: Any field from the Create Task body.
- URL:
/tasks/:id - Method:
DELETE - Headers:
Authorization: Bearer <your_access_token>
- URL:
/tasks/:id/attachments - Method:
POST - Headers:
Authorization: Bearer <your_access_token> - Body:
FormDatawith a field namedfile.
- URL:
/teams - Method:
POST - Headers:
Authorization: Bearer <your_access_token> - Body:
{ "name": "Team Name", "description": "Optional description" }
- URL:
/teams - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
- URL:
/teams/:id - Method:
PATCH - Headers:
Authorization: Bearer <your_access_token>
- URL:
/tasks/:taskId/comments - Method:
POST - Headers:
Authorization: Bearer <your_access_token> - Body:
{ "content": "Your comment here" }
- URL:
/tasks/:taskId/comments - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
- URL:
/analytics/teams/:teamId/tasks - Method:
GET - Headers:
Authorization: Bearer <your_access_token>
TaskFlow uses Socket.io for real-time updates.
- Connect: Connect to the base URL.
- Listen for Events:
task-<taskId>-new-comment: Triggered when someone adds a comment to a task you are watching.
async function login(email, password) {
const response = await fetch('http://localhost:3000/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
const result = await response.json();
if (response.ok) {
// Save tokens to localStorage
localStorage.setItem('accessToken', result.data.accessToken);
localStorage.setItem('refreshToken', result.data.refreshToken);
console.log('Login successful!');
} else {
console.error('Login failed:', result.message);
}
}async function getMyProfile() {
const token = localStorage.getItem('accessToken');
const response = await fetch('http://localhost:3000/users/me', {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
},
});
const result = await response.json();
return result.data; // This is your user object
}If a request fails with a 401 (Unauthorized) error, your accessToken might have expired. Use the refreshToken to get a new one:
async function refreshAccessToken() {
const refreshToken = localStorage.getItem('refreshToken');
const response = await fetch('http://localhost:3000/auth/refresh', {
method: 'POST',
headers: {
Authorization: `Bearer ${refreshToken}`,
},
});
const result = await response.json();
if (response.ok) {
localStorage.setItem('accessToken', result.data.accessToken);
return result.data.accessToken;
} else {
// Refresh token also expired, redirect to login
window.location.href = '/login';
}
}import { io } from 'socket.io-client';
const socket = io('http://localhost:3000');
// Listen for new comments on a specific task
const taskId = '12345';
socket.on(`task-${taskId}-new-comment`, (comment) => {
console.log('New comment received:', comment);
// Update your UI here
});