# ColaFlow API Documentation Ready for Frontend Team **Date**: 2025-11-05 (Day 16) **From**: Backend Team **To**: Frontend Team **Subject**: ProjectManagement API Documentation & Handoff for Day 18 Development --- ## Overview The ProjectManagement API is **production-ready (95%)** and fully documented for frontend integration starting Day 18! All API endpoints are: - Implemented and tested - Multi-tenant secure (100% verified) - JWT authenticated - Fully documented with examples --- ## Documentation Resources ### 1. Interactive API Documentation (RECOMMENDED) **Scalar UI**: http://localhost:5167/scalar/v1 This is the easiest way to explore and test the API: - Browse all endpoints - Try out requests directly in the browser - See request/response examples - Test authentication **How to use**: 1. Open http://localhost:5167/scalar/v1 in your browser 2. Click the "Authenticate" button 3. Enter your JWT token: `Bearer ` 4. Start testing API endpoints ### 2. API Reference Documentation **File**: `docs/api/ProjectManagement-API-Reference.md` Comprehensive reference with: - All ProjectManagement endpoints (Projects, Epics, Stories, Tasks) - Request/response examples - TypeScript interfaces - Error handling - Multi-tenant security explanation - Frontend integration tips - React Query examples ### 3. Quick Reference **File**: `docs/api/API-Endpoints-Summary.md` Quick table of all endpoints: - 68 total API endpoints - 31 ProjectManagement endpoints - 10 Authentication endpoints - 20 Identity & Tenant endpoints - 7 Real-time (SignalR) endpoints ### 4. OpenAPI Specification **File**: `docs/api/openapi.json` **URL**: http://localhost:5167/openapi/v1.json Use this to: - Import into Postman - Generate TypeScript types - Auto-generate API client code --- ## Getting Started (5 Minutes) ### Step 1: Start the API ```bash cd colaflow-api/src/ColaFlow.Api dotnet run ``` The API will be available at: - HTTP: http://localhost:5167 - HTTPS: https://localhost:7295 ### Step 2: Open Scalar UI Navigate to: http://localhost:5167/scalar/v1 ### Step 3: Get a JWT Token First, register a test tenant: ```bash POST http://localhost:5167/api/Tenants/register Content-Type: application/json { "tenantName": "Test Company", "tenantSlug": "test-company", "subscriptionPlan": "Free", "adminEmail": "admin@test.com", "adminPassword": "Password123!", "adminFullName": "Admin User" } ``` Then, log in: ```bash POST http://localhost:5167/api/Auth/login Content-Type: application/json { "tenantSlug": "test-company", "email": "admin@test.com", "password": "Password123!" } ``` **Response**: ```json { "accessToken": "eyJhbGciOiJIUzI1NiIs...", "refreshToken": "def50200...", "expiresIn": 900, "user": { "id": "user-guid", "email": "admin@test.com", "fullName": "Admin User" }, "tenant": { "id": "tenant-guid", "name": "Test Company", "slug": "test-company" } } ``` ### Step 4: Test ProjectManagement API Use the `accessToken` to call ProjectManagement endpoints: ```bash # List all projects GET http://localhost:5167/api/v1/Projects Authorization: Bearer # Create a project POST http://localhost:5167/api/v1/Projects Authorization: Bearer Content-Type: application/json { "name": "My First Project", "key": "FIRST", "description": "Test project", "ownerId": "user-guid-from-login-response" } ``` --- ## Key API Endpoints for Day 18 ### Authentication (CRITICAL - Implement First) 1. **POST /api/Tenants/register** - Register new tenant 2. **POST /api/Auth/login** - User login 3. **GET /api/Auth/me** - Get current user 4. **POST /api/Auth/refresh** - Refresh access token 5. **POST /api/Auth/logout** - Logout ### Projects (HIGH PRIORITY) 1. **GET /api/v1/Projects** - List all projects 2. **GET /api/v1/Projects/{id}** - Get project by ID 3. **POST /api/v1/Projects** - Create project 4. **PUT /api/v1/Projects/{id}** - Update project 5. **DELETE /api/v1/Projects/{id}** - Delete project ### Epics (HIGH PRIORITY) 1. **GET /api/v1/projects/{projectId}/epics** - List epics for a project 2. **POST /api/v1/projects/{projectId}/epics** - Create epic 3. **PUT /api/v1/epics/{id}** - Update epic ### Stories (HIGH PRIORITY) 1. **GET /api/v1/epics/{epicId}/stories** - List stories for an epic 2. **POST /api/v1/epics/{epicId}/stories** - Create story 3. **PUT /api/v1/stories/{id}** - Update story 4. **PUT /api/v1/stories/{id}/assign** - Assign story ### Tasks (HIGH PRIORITY) 1. **GET /api/v1/stories/{storyId}/tasks** - List tasks for a story 2. **GET /api/v1/projects/{projectId}/tasks** - List tasks (with filters) 3. **POST /api/v1/stories/{storyId}/tasks** - Create task 4. **PUT /api/v1/tasks/{id}/status** - Update task status (Kanban board) 5. **PUT /api/v1/tasks/{id}/assign** - Assign task --- ## Frontend Integration Guide ### 1. Generate TypeScript Types Use `openapi-typescript` to auto-generate TypeScript interfaces: ```bash npm install --save-dev openapi-typescript npx openapi-typescript http://localhost:5167/openapi/v1.json --output ./src/types/api.ts ``` This will give you strongly-typed DTOs for all API requests and responses. ### 2. Create API Client Example using `fetch`: ```typescript // src/api/client.ts const BASE_URL = 'http://localhost:5167/api/v1'; export class ApiClient { private token: string; constructor(token: string) { this.token = token; } private async request( endpoint: string, options?: RequestInit ): Promise { const response = await fetch(`${BASE_URL}${endpoint}`, { ...options, headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json', ...options?.headers } }); if (!response.ok) { const error: ProblemDetails = await response.json(); throw new ApiError(error); } if (response.status === 204) { return undefined as T; } return response.json(); } // Projects async getProjects(): Promise { return this.request('/Projects'); } async getProject(id: string): Promise { return this.request(`/Projects/${id}`); } async createProject(data: CreateProjectCommand): Promise { return this.request('/Projects', { method: 'POST', body: JSON.stringify(data) }); } async updateProject(id: string, data: UpdateProjectCommand): Promise { return this.request(`/Projects/${id}`, { method: 'PUT', body: JSON.stringify(data) }); } async deleteProject(id: string): Promise { return this.request(`/Projects/${id}`, { method: 'DELETE' }); } // Epics async getEpics(projectId: string): Promise { return this.request(`/projects/${projectId}/epics`); } async createEpic(projectId: string, data: CreateEpicRequest): Promise { return this.request(`/projects/${projectId}/epics`, { method: 'POST', body: JSON.stringify(data) }); } // Tasks async getTasks(projectId: string, filters?: { status?: string; assigneeId?: string; }): Promise { const query = new URLSearchParams(filters as any).toString(); return this.request(`/projects/${projectId}/tasks?${query}`); } async updateTaskStatus(taskId: string, newStatus: string): Promise { return this.request(`/tasks/${taskId}/status`, { method: 'PUT', body: JSON.stringify({ newStatus }) }); } } ``` ### 3. React Query Hooks Example using React Query: ```typescript // src/hooks/useProjects.ts import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { ApiClient } from '../api/client'; export function useProjects(apiClient: ApiClient) { return useQuery({ queryKey: ['projects'], queryFn: () => apiClient.getProjects() }); } export function useProject(apiClient: ApiClient, projectId: string) { return useQuery({ queryKey: ['projects', projectId], queryFn: () => apiClient.getProject(projectId), enabled: !!projectId }); } export function useCreateProject(apiClient: ApiClient) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (data: CreateProjectCommand) => apiClient.createProject(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['projects'] }); } }); } export function useUpdateProject(apiClient: ApiClient) { const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ id, data }: { id: string; data: UpdateProjectCommand }) => apiClient.updateProject(id, data), onSuccess: (_, { id }) => { queryClient.invalidateQueries({ queryKey: ['projects'] }); queryClient.invalidateQueries({ queryKey: ['projects', id] }); } }); } export function useDeleteProject(apiClient: ApiClient) { const queryClient = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiClient.deleteProject(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['projects'] }); } }); } ``` ### 4. React Component Example ```typescript // src/components/ProjectList.tsx import React from 'react'; import { useProjects, useCreateProject } from '../hooks/useProjects'; export function ProjectList({ apiClient }) { const { data: projects, isLoading, error } = useProjects(apiClient); const createProject = useCreateProject(apiClient); if (isLoading) return
Loading...
; if (error) return
Error: {error.message}
; const handleCreateProject = async () => { try { await createProject.mutateAsync({ name: 'New Project', key: 'NEWP', description: 'Test project', ownerId: 'current-user-id' }); } catch (err) { console.error('Failed to create project:', err); } }; return (

Projects

    {projects?.map(project => (
  • {project.name} ({project.key})

    {project.description}

  • ))}
); } ``` --- ## Important Notes ### Multi-Tenant Security - The `tenantId` is **automatically extracted** from the JWT token - **DO NOT** send `tenantId` in request bodies - All queries are automatically filtered by the current tenant - Cross-tenant access returns `404 Not Found` (not `403 Forbidden`) - This is **production-ready** and verified by 7 integration tests ### Authentication Flow ``` 1. Register tenant (if new) → POST /api/Tenants/register 2. Login → POST /api/Auth/login 3. Store accessToken + refreshToken 4. Use accessToken for all API calls 5. Refresh token before expiry → POST /api/Auth/refresh 6. Logout → POST /api/Auth/logout ``` ### JWT Token Expiry - **Access Token**: Expires in 15 minutes (900 seconds) - **Refresh Token**: Expires in 7 days Your frontend should: 1. Check token expiry before each request 2. Automatically refresh the token if expired 3. Handle 401 Unauthorized errors by refreshing ### Error Handling All errors follow RFC 7807 Problem Details format: ```typescript interface ProblemDetails { type?: string; title?: string; status?: number; detail?: string; instance?: string; } // Example error handling try { const project = await apiClient.getProject(id); } catch (error) { if (error instanceof ApiError) { console.error(`Error ${error.status}: ${error.detail}`); // Handle specific error codes if (error.status === 404) { // Project not found or not accessible } else if (error.status === 401) { // Unauthorized - refresh token } } } ``` --- ## Data Models (TypeScript) ### ProjectDto ```typescript interface ProjectDto { id: string; // Guid name: string; // max 200 key: string; // max 10 description?: string; // max 1000 status: 'Active' | 'Archived' | 'OnHold'; ownerId: string; // Guid createdAt: string; // ISO 8601 updatedAt?: string; // ISO 8601 epics: EpicDto[]; } ``` ### EpicDto ```typescript interface EpicDto { id: string; name: string; description?: string; projectId: string; status: 'Backlog' | 'Todo' | 'InProgress' | 'Done'; priority: 'Low' | 'Medium' | 'High' | 'Critical'; createdBy: string; createdAt: string; updatedAt?: string; stories: StoryDto[]; } ``` ### StoryDto ```typescript interface StoryDto { id: string; title: string; description?: string; epicId: string; status: 'Backlog' | 'Todo' | 'InProgress' | 'Done'; priority: 'Low' | 'Medium' | 'High' | 'Critical'; assigneeId?: string; estimatedHours?: number; actualHours?: number; createdBy: string; createdAt: string; updatedAt?: string; tasks: TaskDto[]; } ``` ### TaskDto ```typescript interface TaskDto { id: string; title: string; description?: string; storyId: string; status: 'Backlog' | 'Todo' | 'InProgress' | 'Done'; priority: 'Low' | 'Medium' | 'High' | 'Critical'; assigneeId?: string; estimatedHours?: number; actualHours?: number; createdBy: string; createdAt: string; updatedAt?: string; } ``` --- ## Real-time Updates (Phase 2) ### SignalR Hubs (WebSocket) - **Project Hub**: `/hubs/project` - Real-time project updates - **Notification Hub**: `/hubs/notification` - User notifications **Note**: SignalR integration is planned for Phase 2 (after basic CRUD). --- ## Testing Checklist for Frontend Team Before Day 18 development, verify: - [ ] API is running at http://localhost:5167 - [ ] Scalar UI is accessible at http://localhost:5167/scalar/v1 - [ ] Can register a new tenant (POST /api/Tenants/register) - [ ] Can log in and get JWT token (POST /api/Auth/login) - [ ] Can list projects with JWT token (GET /api/v1/Projects) - [ ] Can create a project (POST /api/v1/Projects) - [ ] Can create an epic under project (POST /api/v1/projects/{id}/epics) - [ ] Can create a story under epic (POST /api/v1/epics/{id}/stories) - [ ] Can create a task under story (POST /api/v1/stories/{id}/tasks) - [ ] Can update task status (PUT /api/v1/tasks/{id}/status) --- ## Support & Questions If you have any questions or issues: 1. **Check the documentation**: - `docs/api/ProjectManagement-API-Reference.md` (detailed) - `docs/api/API-Endpoints-Summary.md` (quick reference) 2. **Try Scalar UI**: http://localhost:5167/scalar/v1 3. **Contact Backend Team**: We're here to help! --- ## Next Steps for Frontend Team ### Day 18 Sprint Plan: **Phase 1: Authentication & Setup (2-3 hours)** 1. Set up API client with JWT authentication 2. Generate TypeScript types from OpenAPI spec 3. Implement login/logout flow 4. Create authentication context/hooks **Phase 2: Projects CRUD (3-4 hours)** 1. Project list page 2. Create project form 3. Edit project 4. Delete project **Phase 3: Epics & Stories (4-5 hours)** 1. Epic list under project 2. Create/edit epic 3. Story list under epic 4. Create/edit story **Phase 4: Kanban Board (5-6 hours)** 1. Task board view 2. Drag-and-drop task status updates 3. Task assignment 4. Filters (status, assignee) **Phase 5: Polish & Testing (2-3 hours)** 1. Error handling 2. Loading states 3. Validation 4. End-to-end testing --- ## Summary You now have: - **68 fully documented API endpoints** - **Interactive API documentation** (Scalar UI) - **Detailed API reference** with examples - **OpenAPI spec** for code generation - **TypeScript interfaces** and examples - **React Query hooks** examples - **Multi-tenant security** (production-ready) - **Backend support** for any questions **The backend is ready. Let's build an amazing frontend!** --- **Generated**: 2025-11-05 (Day 16) **Backend Status**: Production Ready (95%) **Backend Team**: Ready to support Day 18 frontend development