{ "info": { "name": "ColaFlow Sprint 1 API", "description": "ColaFlow ProjectManagement API Collection for Frontend Integration\nGenerated: 2025-11-04\nBackend: http://localhost:5167", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "variable": [ { "key": "baseUrl", "value": "http://localhost:5167", "type": "string" }, { "key": "accessToken", "value": "", "type": "string" }, { "key": "refreshToken", "value": "", "type": "string" }, { "key": "tenantId", "value": "", "type": "string" }, { "key": "userId", "value": "", "type": "string" }, { "key": "projectId", "value": "", "type": "string" }, { "key": "epicId", "value": "", "type": "string" }, { "key": "storyId", "value": "", "type": "string" }, { "key": "taskId", "value": "", "type": "string" } ], "item": [ { "name": "1. Authentication", "item": [ { "name": "Register Tenant", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 200) {", " const response = pm.response.json();", " pm.collectionVariables.set('accessToken', response.accessToken);", " pm.collectionVariables.set('refreshToken', response.refreshToken);", " pm.collectionVariables.set('tenantId', response.tenantId);", " pm.collectionVariables.set('userId', response.userId);", " console.log('Tenant registered successfully!');", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"email\": \"admin@testcompany.com\",\n \"password\": \"Admin123!\",\n \"fullName\": \"Test Admin\",\n \"companyName\": \"Test Company\",\n \"slug\": \"testcompany\"\n}" }, "url": { "raw": "{{baseUrl}}/api/tenants/register", "host": ["{{baseUrl}}"], "path": ["api", "tenants", "register"] }, "description": "Register a new tenant (company signup). This creates a new tenant and the first user (TenantOwner)." }, "response": [] }, { "name": "Login", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 200) {", " const response = pm.response.json();", " pm.collectionVariables.set('accessToken', response.accessToken);", " pm.collectionVariables.set('refreshToken', response.refreshToken);", " pm.collectionVariables.set('tenantId', response.tenantId);", " pm.collectionVariables.set('userId', response.userId);", " console.log('Login successful!');", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"tenantSlug\": \"testcompany\",\n \"email\": \"admin@testcompany.com\",\n \"password\": \"Admin123!\"\n}" }, "url": { "raw": "{{baseUrl}}/api/auth/login", "host": ["{{baseUrl}}"], "path": ["api", "auth", "login"] }, "description": "Login with tenant slug, email, and password. Returns JWT access token and refresh token." }, "response": [] }, { "name": "Get Current User", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/auth/me", "host": ["{{baseUrl}}"], "path": ["api", "auth", "me"] }, "description": "Get current authenticated user information from JWT token." }, "response": [] }, { "name": "Refresh Token", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 200) {", " const response = pm.response.json();", " pm.collectionVariables.set('accessToken', response.accessToken);", " pm.collectionVariables.set('refreshToken', response.refreshToken);", " console.log('Token refreshed successfully!');", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"refreshToken\": \"{{refreshToken}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/auth/refresh", "host": ["{{baseUrl}}"], "path": ["api", "auth", "refresh"] }, "description": "Refresh access token using refresh token." }, "response": [] }, { "name": "Logout", "request": { "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"refreshToken\": \"{{refreshToken}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/auth/logout", "host": ["{{baseUrl}}"], "path": ["api", "auth", "logout"] }, "description": "Logout and revoke refresh token." }, "response": [] } ] }, { "name": "2. Projects", "item": [ { "name": "List Projects", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects"] }, "description": "Get all projects for the current tenant." }, "response": [] }, { "name": "Create Project", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('projectId', response.id);", " console.log('Project created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"name\": \"Sprint 1 Project\",\n \"description\": \"Test project for frontend integration\",\n \"key\": \"SPR1\",\n \"ownerId\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/projects", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects"] }, "description": "Create a new project." }, "response": [] }, { "name": "Get Project", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}"] }, "description": "Get project by ID." }, "response": [] }, { "name": "Update Project", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"name\": \"Updated Sprint 1 Project\",\n \"description\": \"Updated project description\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}"] }, "description": "Update project details." }, "response": [] }, { "name": "Delete Project", "request": { "method": "DELETE", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}"] }, "description": "Archive/delete a project." }, "response": [] } ] }, { "name": "3. Epics", "item": [ { "name": "List Project Epics", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}/epics", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}", "epics"] }, "description": "Get all epics for a project." }, "response": [] }, { "name": "Create Epic (Independent)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('epicId', response.id);", " console.log('Epic created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"projectId\": \"{{projectId}}\",\n \"name\": \"Sprint 1 Epic\",\n \"description\": \"Test epic for frontend integration\",\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/epics", "host": ["{{baseUrl}}"], "path": ["api", "v1", "epics"] }, "description": "Create epic using independent endpoint (POST /api/v1/epics)." }, "response": [] }, { "name": "Create Epic (Nested)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('epicId', response.id);", " console.log('Epic created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"name\": \"Sprint 1 Epic (Nested)\",\n \"description\": \"Test epic created via nested endpoint\",\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}/epics", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}", "epics"] }, "description": "Create epic using nested endpoint (POST /api/v1/projects/{projectId}/epics)." }, "response": [] }, { "name": "Get Epic", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/epics/{{epicId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "epics", "{{epicId}}"] }, "description": "Get epic by ID." }, "response": [] }, { "name": "Update Epic", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"name\": \"Updated Sprint 1 Epic\",\n \"description\": \"Updated epic description\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/epics/{{epicId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "epics", "{{epicId}}"] }, "description": "Update epic details." }, "response": [] } ] }, { "name": "4. Stories", "item": [ { "name": "List Epic Stories", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/epics/{{epicId}}/stories", "host": ["{{baseUrl}}"], "path": ["api", "v1", "epics", "{{epicId}}", "stories"] }, "description": "Get all stories for an epic." }, "response": [] }, { "name": "List Project Stories", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}/stories", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}", "stories"] }, "description": "Get all stories for a project." }, "response": [] }, { "name": "Create Story (Independent)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('storyId', response.id);", " console.log('Story created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"epicId\": \"{{epicId}}\",\n \"title\": \"Sprint 1 Story\",\n \"description\": \"Test story for frontend integration\",\n \"priority\": \"Medium\",\n \"estimatedHours\": 8,\n \"assigneeId\": null,\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/stories", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories"] }, "description": "Create story using independent endpoint (POST /api/v1/stories)." }, "response": [] }, { "name": "Create Story (Nested)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('storyId', response.id);", " console.log('Story created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"title\": \"Sprint 1 Story (Nested)\",\n \"description\": \"Test story created via nested endpoint\",\n \"priority\": \"High\",\n \"estimatedHours\": 12,\n \"assigneeId\": null,\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/epics/{{epicId}}/stories", "host": ["{{baseUrl}}"], "path": ["api", "v1", "epics", "{{epicId}}", "stories"] }, "description": "Create story using nested endpoint (POST /api/v1/epics/{epicId}/stories)." }, "response": [] }, { "name": "Get Story", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}"] }, "description": "Get story by ID." }, "response": [] }, { "name": "Update Story", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"title\": \"Updated Sprint 1 Story\",\n \"description\": \"Updated story description\",\n \"status\": \"InProgress\",\n \"priority\": \"High\",\n \"estimatedHours\": 16,\n \"assigneeId\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}"] }, "description": "Update story details." }, "response": [] }, { "name": "Delete Story", "request": { "method": "DELETE", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}"] }, "description": "Delete a story." }, "response": [] }, { "name": "Assign Story", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"assigneeId\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}/assign", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}", "assign"] }, "description": "Assign story to a user." }, "response": [] } ] }, { "name": "5. Tasks", "item": [ { "name": "List Story Tasks", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}/tasks", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}", "tasks"] }, "description": "Get all tasks for a story." }, "response": [] }, { "name": "List Project Tasks (Kanban)", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/projects/{{projectId}}/tasks?status=&assigneeId=", "host": ["{{baseUrl}}"], "path": ["api", "v1", "projects", "{{projectId}}", "tasks"], "query": [ { "key": "status", "value": "", "description": "Optional: Filter by status (Todo, InProgress, Done)" }, { "key": "assigneeId", "value": "", "description": "Optional: Filter by assignee" } ] }, "description": "Get all tasks for a project (used for Kanban board)." }, "response": [] }, { "name": "Create Task (Independent)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('taskId', response.id);", " console.log('Task created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"storyId\": \"{{storyId}}\",\n \"title\": \"Sprint 1 Task\",\n \"description\": \"Test task for frontend integration\",\n \"priority\": \"High\",\n \"estimatedHours\": 4,\n \"assigneeId\": null,\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/tasks", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks"] }, "description": "Create task using independent endpoint (POST /api/v1/tasks)." }, "response": [] }, { "name": "Create Task (Nested)", "event": [ { "listen": "test", "script": { "exec": [ "if (pm.response.code === 201) {", " const response = pm.response.json();", " pm.collectionVariables.set('taskId', response.id);", " console.log('Task created:', response.id);", "}" ], "type": "text/javascript" } } ], "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"title\": \"Sprint 1 Task (Nested)\",\n \"description\": \"Test task created via nested endpoint\",\n \"priority\": \"Medium\",\n \"estimatedHours\": 6,\n \"assigneeId\": null,\n \"createdBy\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/stories/{{storyId}}/tasks", "host": ["{{baseUrl}}"], "path": ["api", "v1", "stories", "{{storyId}}", "tasks"] }, "description": "Create task using nested endpoint (POST /api/v1/stories/{storyId}/tasks)." }, "response": [] }, { "name": "Get Task", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/tasks/{{taskId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks", "{{taskId}}"] }, "description": "Get task by ID." }, "response": [] }, { "name": "Update Task", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"title\": \"Updated Sprint 1 Task\",\n \"description\": \"Updated task description\",\n \"status\": \"InProgress\",\n \"priority\": \"Critical\",\n \"estimatedHours\": 8,\n \"assigneeId\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/tasks/{{taskId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks", "{{taskId}}"] }, "description": "Update task details." }, "response": [] }, { "name": "Update Task Status (Kanban)", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"newStatus\": \"InProgress\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/tasks/{{taskId}}/status", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks", "{{taskId}}", "status"] }, "description": "Update task status (for Kanban board drag & drop). Status values: Todo, InProgress, Done" }, "response": [] }, { "name": "Delete Task", "request": { "method": "DELETE", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" } ], "url": { "raw": "{{baseUrl}}/api/v1/tasks/{{taskId}}", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks", "{{taskId}}"] }, "description": "Delete a task." }, "response": [] }, { "name": "Assign Task", "request": { "method": "PUT", "header": [ { "key": "Authorization", "value": "Bearer {{accessToken}}", "type": "text" }, { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"assigneeId\": \"{{userId}}\"\n}" }, "url": { "raw": "{{baseUrl}}/api/v1/tasks/{{taskId}}/assign", "host": ["{{baseUrl}}"], "path": ["api", "v1", "tasks", "{{taskId}}", "assign"] }, "description": "Assign task to a user." }, "response": [] } ] } ] }