Project: FlowState (Enterprise Kanban) Version: 1.0
All successful API responses will follow this format:
{
"success": true,
"data": { ... },
"message": "Optional success message"
}All error responses will follow this format:
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "The requested board does not exist."
}
}Endpoints marked with [Auth] require JWT in Authorization header: Authorization: Bearer <token>. Token stored in frontend memory (not localStorage for XSS protection).
POST api/auth/register
-
Description: Creates a new user account.
-
Body:
{
"email": "user@example.com",
"password": "securePassword123",
"name": "John Doe"
}Note: Passwords are automatically trimmed of leading/trailing whitespace, but internal spaces are preserved.
- Response (201 Created):
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUz...",
"user": {
"id": "123",
"name": "John Doe",
"email": "user@example.com",
"role": "user",
"created_at": "2025-01-20T10:00:00Z"
}
}
}- Error (409 Conflict - User Already Exists):
{
"success": false,
"error": {
"code": "USER_002",
"message": "User with this email already exists"
}
}- Error (400 Bad Request - Missing Required Fields):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Missing required fields"
}
}- Error (400 Bad Request - Invalid Input):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Invalid email format"
}
}- Error (400 Bad Request - Length Limits):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Email must not exceed <MAX_EMAIL_LENGTH> characters"
}
}- Error (500 Internal Server Error - bcrypt failiure):
{
"success": false,
"error": {
"code": "SERVER_001",
"message": "Internal Server Error"
}
}POST api/auth/login
- Body:
{ "email": "user@example.com", "password": "securePassword123" }- Response (200 OK):
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUz...",
"user": {
"id": "123",
"name": "username",
"email": "user@example.com",
"role": "user",
"created_at": "2025-01-20T10:00:00Z",
"updated_at": "2025-01-27T10:00:00Z"
}
}
}- Error (401 Unauthorized - Invalid email or password):
{
"success": false,
"error": {
"code": "AUTH_001",
"message": "invalid email or password"
}
}- Error (401 Unauthorized - Invalid email or password length):
{
"success": false,
"error": {
"code": "AUTH_001",
"message": "invalid email or password"
}
}- Error (400 Bad Request - Missing Fields)
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Missing required fields"
}
}- Error (400 Bad Request - Invalid Input)
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Invalid email format"
}
}GET api/auth/me [Auth]
-
Description: Validates token and returns current user data.
-
Response (200 OK):
{
"success": true,
"data": {
"id": "123",
"name": "John Doe",
"email": "user@example.com",
"role": "user"
}
}- Error (401 Unauthorized - Token Expired):
{
"success": false,
"error": {
"code": "AUTH_002",
"message": "Token has expired, please login again"
}
}- Error (401 Unauthorized - Invalid Token):
{
"success": false,
"error": {
"code": "AUTH_003",
"message": "Invalid token"
}
}- Error (401 Unauthorized - User not found):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}GET api/boards [Auth]
-
Description: Returns boards where the user is an owner or member.
-
Response (200 OK):
{
"success": true,
"data": [
{"id": "b1",
"title": "Project Alpha",
"owner_id": "u1",
"members": [],
"created_at": "2025-01-15T10:30:00.000Z"},
{"id": "b2",
"title": "Marketing",
"owner_id": "u2",
"members": ["u3", "u4"],
"created_at": "2025-01-14T08:20:00.000Z"}
]
},
- Error (401 Unauthorized):
{
"success": false,
"error": {
"code": "AUTH_004",
"message": "User not authenticated"
}
}POST api/boards [Auth]
-
Body:
{ "title": "New Board" } -
Response (201 Created):
{
"success": true,
"data": {
"id": "b1",
"title": "New Board",
"owner_id": "u1",
"members": [],
"created_at": "2025-01-15T10:30:00.000Z"
}
}- Error (400 Bad Request - Missing Title):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Title is required to create a board"
}
}- Error (400 Bad Request - Title Too Long):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Board title must be less than <MAX_BOARD_TITLE_LENGTH> characters"
}
}- Error (404 Not found):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (400 Bad Request - CastError)
{
"success": false,
"error": {
"code": "VAL_001",
"message": "invalid OID foramt"
}
}- Error (400 Bad Request - Limit Exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Can't create new board. Maximum limit(<MAX_BOARDS_PER_USER>) exceeded"
}
}GET api/boards/:id [Auth]
-
Description: Fetches the board, including all its columns and tasks (populated via virtual relationships).
-
Note: This endpoint performs a lightweight permission check before aggregating data. Invalid requests are rejected before heavy database operations occur.
-
Permissions: Admin, Board Owner, or Board Member.
-
Response (200 OK):
```json
{
"success": true,
"data": {
"id": "b1",
"title": "Project Alpha",
"owner_id": "u1",
"members": ["u2", "u3"],
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T11:00:00.000Z",
"columns": [
{
"id": "c1",
"board_id": "b1",
"title": "To Do",
"order": 0,
"created_at": "2025-01-15T10:35:00.000Z",
"updated_at": "2025-01-15T10:35:00.000Z",
"tasks": [
{
"id": "t1",
"title": "Fix Bug",
"description": "Fix login error on safari",
"priority": "high",
"assignee_id": "u2",
"column_id": "c1",
"board_id": "b1",
"order": 0,
"created_at": "2025-01-16T09:00:00.000Z",
"updated_at": "2025-01-16T09:00:00.000Z"
}
]
}
]
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (403 Forbidden - Board access denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Board access denied"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Missing Fields):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Missing required fields"
}
}DELETE api/boards/:id [Auth]
-
Description: Deletes a board.
-
Permission: Only Board Owner or Admin.
-
Constraint: Board must be empty (no columns).
-
Response (200 OK):
{
"success": true,
"message": "Board deleted successfully"
}- Error (400 Bad Request - Not Empty):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Cannot delete board with existing columns"
}
}- Error (403 Forbidden):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Not Authorized"
}
} - Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}PATCH api/boards/:id [Auth]
- Permission: Only Board Owner or Admin
- Body:
{ "title": "Updated Title" } - Response (200 OK):
{
"success": true,
"data": {
"id": "b1",
"title": "Updated Title",
"owner_id": "u1",
"members": ["u2"],
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-27T10:00:00.000Z"
}
}- Error (403 Forbidden):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only board owner or admin can update this board"
}
}- Error (400 Bad Request - Missing Title):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Title is required to update board"
}
}- Error (400 Bad Request - Title Too Long):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Board title must be less than <MAX_BOARD_TITLE_LENGTH> characters"
}
}- Error (404 Not Found) - board not found or deleted before update:
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (404 Not Found) - user not found:
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}POST api/boards/:id/members [Auth]
- Permission: Only Board Owner or Admin
- Body:
{ "members": ["u3", "u4"] } - Response (200 OK):
{
"success": true,
"data": {
"id": "b1",
"title": "Project Alpha",
"owner_id": "u1",
"members": ["u2", "u3", "u4"],
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
}
}- Error (400 Bad Request - Missing/Invalid Inputs):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Members list must be an array with at least one user ID."
}
}- Error (400 Bad Request - Empty/ white space only input):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Members list must contain at least one valid user ID"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only admin or board owner can add members"
}
}- Error (404 Not Found - User/Board Doesn't Exist):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}or
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (400 Bad Request - Board Limit Exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Can only add maximum of <MAX_MEMBERS_PER_BOARD> members at a time"
}
}- Error (400 Bad Request - Member array size exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Can only add maximum of <MAX_MEMBERS_PER_BATCH> members at a time"
}
}- Error (400 Bad Request - Already Member):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "User id <userId> is already a member of this board"
}
}- Error (400 Bad Request - Board Owner cannot be added):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Board owner is a member by default"
}
}DELETE api/boards/:id/members/:userId [Auth]
- Description: Removes a user from the board's member list.
- Side Effect: The removed user is automatically unassigned from all tasks on this board.
- Permission: Only Board Owner or Admin
- Response (200 OK):
{
"success": true,
"data": {
"id": "b1",
"title": "Project Alpha",
"owner_id": "u1",
"members": ["u2"],
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-01-27T10:00:00.000Z"
}
}- Error (400 Bad Request - Not a Member):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "User is not a member of this board"
}
}- Error (400 Bad Request - Cannot Remove Owner):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Cannot remove board owner from members"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only admin or owner can remove members"
}
}- Error (404 Not Found - User/Board):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}POST api/columns [Auth]
- Permission: Only Board Owner or Admin.
- Body:
{ "board_id": "b1", "title": "In Progress" }- Response (201 Created):
{
"success": true,
"data": {
"id": "c1",
"board_id": "b1",
"title": "In Progress",
"order": 3,
"tasks": [],
"created_at": "2025-01-18T10:00:00.000Z"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only admin or board owner can create column"
}
}- Error (400 Bad Request - Limit Exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Can't create new column. Maximum limit <MAX_COLUMNS_PER_BOARD> exceeded"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Requested board doesn't exist"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "Requested user doesn't exist"
}
}- Error (400 Bad Request - Missing Fields):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Required fields are not provided"
}
}- Error (400 Bad Request - Title Too Long)
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Column title must not exceed <MAX_COLUMN_TITLE_LENGTH> characters"
}
}- Error (400 Bad Request - CastError)
{
"success": false,
"error": {
"code": "VAL_001",
"message": "invalid OID foramt"
}
}PATCH api/columns/:id/order [Auth]
- Description: Handles moving a column to a new position.
- Permission: Only Board Owner or Admin.
- Behavior:
- Reordering: Moves column to the new index.
- Shifting:
- Moving Down: Columns between the old and new position shift UP (-1) to fill the gap.
- Moving Up: Columns between the new and old position shift DOWN (+1) to make room.
- Body:
{ "new_order_index": 2 }- Response (200 OK):
{
"success": true,
"message": "Column moved successfully"
}- Error (400 Bad Request - Invalid Input):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "New order must be a non-negative integer"
}
}- Error (400 Bad Request - Out of Bounds):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "New order <NEW_ORDER> exceeds last column index <MAX_ALLOWED_ORDER>"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only admin or board owner can move column"
}
}- Error (404 Not Found - Column/User/Board):
{
"success": false,
"error": {
"code": "COLUMN_001",
"message": "Column not found"
}
}or
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}or
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}PATCH api/columns/:id [Auth]
-
Permission: Only Board Owner or Admin.
-
Body:
{ "title": "New Title" } -
Response (200 Updated):
{
"success": true,
"data": {
"id": "69667b960aea16b2e8ba9b61",
"board_id": "69667b5e0aea16b2e8ba9b5c",
"title": "new title",
"order": 0,
"created_at": "2026-01-13T17:06:30.751Z",
"updated_at": "2026-02-08T07:52:41.086Z"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Only admin or board owner can update column"
}
}- Error (400 Bad Request - Title Too Long)
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Column title must not exceed <MAX_COLUMN_TITLE_LENGTH> characters"
}
}- Error (404 Not Found -User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (404 Not Found - column not exists or deleted):
{
"success": false,
"error": {
"code": "COLUMN_001",
"message": "Column not found"
}
}- Error (400 Bad Request - Missing Fields):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Title is required to update column"
}
}DELETE api/columns/:id [Auth]
-
Description: Deletes a column.
-
Permission: RESTRICTED. Only Board Owner or Admin can delete columns.
-
Constraint: Column must be empty (no tasks).
-
Response (200 OK):
{
"success": true,
"message": "Column deleted successfully"
}- Error (400 Bad Request - Not Empty):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Cannot delete column with existing tasks"
}
}- Error (403 Forbidden):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Not Authorized"
}
} - Error (404 Not Found - Column):
{
"success": false,
"error": {
"code": "COLUMN_001",
"message": "Column not found"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}POST api/tasks [Auth]
-
Permission: User must be Board Owner OR Member.
-
Body:
{
"board_id": "b1",
"column_id": "c1",
"title": "Implement Login",
"priority": "high"
}- Response (201 Created):
{
"success": true,
"data": {
"id": "t1",
"title": "Implement Login",
"description": "",
"priority": "high",
"assignee_id": null,
"column_id": "c1",
"board_id": "b1",
"order": 1,
"created_at": "2025-01-20T10:00:00Z",
"updated_at": "2025-01-20T10:00:00Z"
}
}- Error (403 Forbidden):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "You must be a member of this board to create tasks."
}
}- Error (400 Bad Request - Limit Exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Cannot create more than <MAX_TASKS_PER_COLUMN> tasks per column"
}
}- Error (400 Bad Request - Assignee Violation):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Assignee must be a member or the owner of the board"
}
}- Error (404 Not Found - Column not found):
{
"success": false,
"error": {
"code": "COLUMN_001",
"message": "Column not exists or not in the specified board"
}
}- Error (404 Not Found - User/Assignee not found):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board not found):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (400 Bad Request - Missing Fields):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "Required fields are not provided"
}
}- Error (400 Bad Request - title too long):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Task title must not exceed <MAX_TASK_TITLE_LENGTH> characters"
}
}- Error (400 Bad Request - Invalid priority):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Invalid priority type"
}
}- Error (400 Bad Request - CastError)
{
"success": false,
"error": {
"code": "VAL_001",
"message": "invalid OID foramt"
}
}PATCH api/tasks/:id/move [Auth]
-
Description: Critical endpoint. Handles moving a task within the same column OR to a different column.
-
Authorization:
- Admin: Can move any task.
- Board Owner: Can move any task on their board.
- Board Member: Can move any task on the board they are a member of.
-
Behavior:
- Same Column Move: Reorders tasks within the column. Other tasks shift to accommodate the new position.
- Cross Column Move: Moves task to the new column at the specified index. Tasks in the source column shift up to close the gap. Tasks in the target column shift down to make room.
- Constraint: Cannot move a task to a column on a different board (
VALIDATION_ERROR).
-
Body:
{
"target_column_id": "c2",
"new_order_index": 0
}- Response (200 OK):
{
"success": true,
"message": "Task moved successfully"
}- Error (400 Bad Request - Invalid Target):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Cannot move task to a column on a different board"
}
}- Error (400 Bad Request - Missing Fields):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Target column and non-negative order are required"
}
}- Error (403 Forbidden - Access Denied):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Not Authorized"
}
}- Error (404 Not Found - Task):
{
"success": false,
"error": {
"code": "TASK_001",
"message": "Task not found"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (404 Not Found - Column):
{
"success": false,
"error": {
"code": "COLUMN_001",
"message": "Target column does not exist"
}
}- Error (400 Bad Request - Limit Exceeded):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Maximum tasks per column <MAX_TASKS_PER_COLUMN> reached"
}
}PATCH api/tasks/:id [Auth]
-
Permission: Board Owner, Admin, or Member.
-
Description: Updates any subset of task fields. Used for renaming, changing description, re-prioritizing, or assigning users.
-
Validation: -
prioritymust be one of['low', 'medium', 'high'].assignee_idmust be a valid user who is a Member of the board (or the Owner).
-
Unassigning Users: To unassign a task, set
assignee_idtonull. For convenience (e.g., handling form inputs), the API also accepts empty strings""or whitespace-only strings" ", which are automatically converted tonull. -
Body: (Any subset of fields)
{
"title": "New Title",
"description": "Updated description",
"priority": "high",
"assignee_id": "u5"
}- Body (Example - Unassign):
{
"assignee_id": ""
}
// OR
{
"assignee_id": null
}- Error (404 Not Found - Assignee User Not Found):
{
"success": false,
"error": {
"code": "USER_001",
"message": "Assignee doesn't exist"
}
}- Error (404 Not Found - TASK_NOT_FOUND):
{
"success": false,
"error": {
"code": "TASK_001",
"message": "Task not found"
}
}- Error (404 Not Found - BOARD_NOT_FOUND):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}- Error (404 Not Found - USER_NOT_FOUND):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (403 Forbidden - BOARD_ACCESS_DENIED):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Not Authorized"
}
}- Error (400 Bad Request - Empty/only white space task title):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Task title cannot be empty or only white spaces"
}
}- Error (400 Bad Request - invalid priority type):
{
"success": false,
"error": {
"code": "VAL_001",
"message": "Invalid priority value"
}
}- Error (400 Bad Request - Max task title length exceed):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Task title must not exceed <MAX_TASK_TITLE_LENGTH> characters"
}
}- Error (400 Bad Request - Max task description length exceed):
{
"success": false,
"error": {
"code": "VAL_003",
"message": "Task description must not exceed <MAX_TASK_DESCRIPTION_LENGTH> characters"
}
}- Error (400 Bad Request - MISSING_REQUIRED_FIELDS):
{
"success": false,
"error": {
"code": "VAL_002",
"message": "At least one field is required to update"
}
}DELETE api/tasks/:id [Auth]
- Permission: RESTRICTED. Only Board Owner or Admin can delete tasks.
- Behavior: Deletes the task and reorders remaining tasks in the column to close the gap (shifts subsequent tasks result in
order - 1). - Response (200 OK):
{
"success": true,
"message": "Task deleted successfully"
}- Error (403 Forbidden):
{
"success": false,
"error": {
"code": "BOARD_002",
"message": "Not Authorized"
}
} - Error (404 Not Found - Task):
{
"success": false,
"error": {
"code": "TASK_001",
"message": "Task not found"
}
}- Error (404 Not Found - User):
{
"success": false,
"error": {
"code": "USER_001",
"message": "User not found"
}
}- Error (404 Not Found - Board):
{
"success": false,
"error": {
"code": "BOARD_001",
"message": "Board not found"
}
}| Code | Meaning | Context |
|---|---|---|
200 |
OK | Request succeeded |
201 |
Created | Resource created (Register, Create Task) |
400 |
Bad Request | Validation error (missing fields) |
401 |
Unauthorized | Missing or invalid Token |
403 |
Forbidden | Valid token, but not allowed (e.g., deleting someone else's board) |
404 |
Not Found | ID does not exist |
409 |
Conflict | Resource already exists (e.g., Duplicate Email) |
500 |
Server Error | Something went wrong on the backend |
- Global limit: 100 requests per 15 minutes per IP
- Applied to all
/api/*routes - Returns 429 status code when exceeded
- Auth limit: 5 requests per 15 minutes per IP
- Strictly Applied to:
POST /api/auth/registerandPOST /api/auth/login - Reason: Prevents brute-force attacks and spam account creation.
- Strictly Applied to:
- Allowed origins: * Development:
http://localhost:3000- Production: defined via
FRONTEND_URLenv variable
- Production: defined via
- Credentials: true
- Methods: GET, POST, PATCH, DELETE
| Code | Name | Description | Common Causes |
|---|---|---|---|
| AUTH_001 | Invalid Credentials | invalid email or password | Wrong password, unregistered email, or violation of field length limits during login |
| AUTH_002 | Token Expired | JWT has expired | Session timeout |
| AUTH_003 | Token Invalid | JWT signature invalid | Tampered token |
| AUTH_004 | User Not Authenticated | User identity not verified | Missing user in JWT payload |
| BOARD_001 | Board Not Found | Requested board doesn't exist | Invalid board ID |
| BOARD_002 | Access Denied | User not authorized | Non-member accessing board |
| TASK_001 | Task Not Found | Requested task doesn't exist | Invalid task ID |
| TASK_002 | Invalid Column | Target column doesn't exist | Moving task to deleted column |
| VAL_001 | Validation Error | Request body validation failed | Missing required fields |
| VAL_002 | MISSING_REQUIRED_FIELDS | Missing required fields | User hasn't provided required fields or contain only whitespace |
| VAL_003 | Business Rule Violation | Request technically valid but violates logic constraints | Exceeding 20 tasks/column, Title > 150 chars, Email > 255 chars, Password > 50 chars |
| RATE_001 | Rate Limit Exceeded | Too many requests | Hitting 100 req/15min limit |
| URL_001 | URL Not Found | URL Not Found | Undefined URL |
| SERVER_001 | INTERNAL ERROR | Internal Server doesn't work | server crashes |
| USER_001 | User Not Found | Requested user doesn't exist | Invalid user ID in JWT payload |
| USER_002 | User Already Exists | Email already registered | Duplicate registration attempt |
| COLUMN_001 | Column Not Found | Requested column doesn't exist | Invalid column ID |
Zustand store structure:
board: { id, title, owner_id, columns[] } | null
isLoading: boolean
error: string | nullOptimistic Update Flow
- User drags task
- UI updates immediately
- API call fires in background
- On success: do nothing
- On failure: revert UI + show toast