TaskFlow / API_DOCUMENTATION.md
BilalCode's picture
taskflow todo app
310260a
# KIro Todo API Documentation
**Version**: 1.0.0
**Base URL**: `http://localhost:8001`
**Authentication**: JWT Bearer Token
---
## Table of Contents
1. [Overview](#overview)
2. [Authentication](#authentication)
3. [Task Management](#task-management)
4. [Data Models](#data-models)
5. [Error Handling](#error-handling)
6. [Security](#security)
7. [Examples](#examples)
---
## Overview
The KIro Todo API is a RESTful API built with FastAPI that provides secure, multi-user task management with complete data isolation. Each user can only access their own tasks, enforced through JWT authentication and database-level filtering.
**Key Features:**
- JWT-based authentication
- User-scoped data isolation
- Complete CRUD operations for tasks
- Task completion tracking
- Comprehensive error handling
- Automatic timestamp management
---
## Authentication
All task endpoints require a valid JWT token in the `Authorization` header.
### User Signup
Create a new user account.
**Endpoint:** `POST /api/auth/signup`
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123"
}
```
**Response:** `201 Created`
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"user": {
"id": 1,
"email": "user@example.com"
}
}
```
**Validation Rules:**
- Email must be valid format
- Password minimum 8 characters
- Password must contain: uppercase, lowercase, number
- Email must be unique
**Error Responses:**
- `400 Bad Request` - Invalid email format or weak password
- `409 Conflict` - Email already exists
---
### User Signin
Authenticate an existing user.
**Endpoint:** `POST /api/auth/signin`
**Request Body:**
```json
{
"email": "user@example.com",
"password": "SecurePass123"
}
```
**Response:** `200 OK`
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"user": {
"id": 1,
"email": "user@example.com"
}
}
```
**Error Responses:**
- `401 Unauthorized` - Invalid credentials
---
## Task Management
All task endpoints require authentication via JWT token.
**Authentication Header:**
```
Authorization: Bearer <your_jwt_token>
```
---
### List All Tasks
Retrieve all tasks for the authenticated user.
**Endpoint:** `GET /api/tasks`
**Headers:**
```
Authorization: Bearer <token>
```
**Response:** `200 OK`
```json
[
{
"id": 1,
"title": "Complete project documentation",
"description": "Write comprehensive API docs",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T10:30:00Z",
"updated_at": "2026-02-03T10:30:00Z"
},
{
"id": 2,
"title": "Review pull requests",
"description": null,
"completed": true,
"user_id": 1,
"created_at": "2026-02-03T09:15:00Z",
"updated_at": "2026-02-03T11:45:00Z"
}
]
```
**Query Parameters:** None
**Notes:**
- Returns only tasks owned by authenticated user
- Ordered by creation date (newest first)
- Empty array if user has no tasks
---
### Create Task
Create a new task for the authenticated user.
**Endpoint:** `POST /api/tasks`
**Headers:**
```
Authorization: Bearer <token>
Content-Type: application/json
```
**Request Body:**
```json
{
"title": "Buy groceries",
"description": "Milk, eggs, bread, and coffee"
}
```
**Response:** `201 Created`
```json
{
"id": 3,
"title": "Buy groceries",
"description": "Milk, eggs, bread, and coffee",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T12:00:00Z",
"updated_at": "2026-02-03T12:00:00Z"
}
```
**Field Requirements:**
- `title` (required): 1-200 characters, cannot be empty or whitespace
- `description` (optional): 0-2000 characters, can be null
**Error Responses:**
- `400 Bad Request` - Missing or empty title
- `401 Unauthorized` - Invalid or missing token
**Notes:**
- `user_id` is automatically set from JWT token
- `completed` defaults to `false`
- Timestamps are automatically generated
---
### Get Single Task
Retrieve a specific task by ID.
**Endpoint:** `GET /api/tasks/{task_id}`
**Headers:**
```
Authorization: Bearer <token>
```
**Path Parameters:**
- `task_id` (integer): The task ID
**Response:** `200 OK`
```json
{
"id": 1,
"title": "Complete project documentation",
"description": "Write comprehensive API docs",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T10:30:00Z",
"updated_at": "2026-02-03T10:30:00Z"
}
```
**Error Responses:**
- `401 Unauthorized` - Invalid or missing token
- `403 Forbidden` - Task belongs to another user
- `404 Not Found` - Task does not exist
**Security:**
- Ownership is verified before returning task
- Users cannot access other users' tasks
---
### Update Task
Update an existing task's title and/or description.
**Endpoint:** `PUT /api/tasks/{task_id}`
**Headers:**
```
Authorization: Bearer <token>
Content-Type: application/json
```
**Path Parameters:**
- `task_id` (integer): The task ID
**Request Body:**
```json
{
"title": "Complete project documentation (Updated)",
"description": "Write comprehensive API docs with examples"
}
```
**Partial Update Supported:**
```json
{
"title": "New title only"
}
```
**Response:** `200 OK`
```json
{
"id": 1,
"title": "Complete project documentation (Updated)",
"description": "Write comprehensive API docs with examples",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T10:30:00Z",
"updated_at": "2026-02-03T12:30:00Z"
}
```
**Field Requirements:**
- `title` (optional): If provided, 1-200 characters, cannot be empty
- `description` (optional): If provided, 0-2000 characters
**Error Responses:**
- `400 Bad Request` - Empty title provided
- `401 Unauthorized` - Invalid or missing token
- `403 Forbidden` - Task belongs to another user
- `404 Not Found` - Task does not exist
**Notes:**
- Only provided fields are updated
- `updated_at` timestamp is automatically updated
- Ownership is verified before update
---
### Delete Task
Permanently delete a task.
**Endpoint:** `DELETE /api/tasks/{task_id}`
**Headers:**
```
Authorization: Bearer <token>
```
**Path Parameters:**
- `task_id` (integer): The task ID
**Response:** `200 OK`
```json
{
"message": "Task deleted successfully"
}
```
**Error Responses:**
- `401 Unauthorized` - Invalid or missing token
- `403 Forbidden` - Task belongs to another user
- `404 Not Found` - Task does not exist
**Notes:**
- Deletion is permanent (no soft delete)
- Ownership is verified before deletion
---
### Toggle Task Completion
Toggle a task's completion status (complete ↔ incomplete).
**Endpoint:** `PATCH /api/tasks/{task_id}/complete`
**Headers:**
```
Authorization: Bearer <token>
```
**Path Parameters:**
- `task_id` (integer): The task ID
**Request Body:** None
**Response:** `200 OK`
```json
{
"id": 1,
"title": "Complete project documentation",
"description": "Write comprehensive API docs",
"completed": true,
"user_id": 1,
"created_at": "2026-02-03T10:30:00Z",
"updated_at": "2026-02-03T13:00:00Z"
}
```
**Behavior:**
- `completed: false``completed: true`
- `completed: true``completed: false`
**Error Responses:**
- `401 Unauthorized` - Invalid or missing token
- `403 Forbidden` - Task belongs to another user
- `404 Not Found` - Task does not exist
**Notes:**
- `updated_at` timestamp is automatically updated
- Ownership is verified before toggle
---
## Data Models
### User
```typescript
{
id: number; // Auto-generated primary key
email: string; // Unique, valid email format
password_hash: string; // Bcrypt hashed password (never exposed in API)
created_at: datetime; // Auto-generated timestamp
}
```
### Task
```typescript
{
id: number; // Auto-generated primary key
title: string; // Required, 1-200 characters
description: string | null; // Optional, 0-2000 characters
completed: boolean; // Default: false
user_id: number; // Foreign key to User (from JWT)
created_at: datetime; // Auto-generated timestamp
updated_at: datetime; // Auto-updated on changes
}
```
### JWT Token Payload
```typescript
{
user_id: number; // User's database ID
email: string; // User's email
exp: number; // Token expiration timestamp
iat: number; // Token issued at timestamp
}
```
---
## Error Handling
All errors follow a consistent format:
```json
{
"error": "Detailed error message",
"message": "User-friendly message",
"details": null
}
```
### HTTP Status Codes
| Code | Meaning | When Used |
|------|---------|-----------|
| `200` | OK | Successful GET, PUT, PATCH, DELETE |
| `201` | Created | Successful POST (resource created) |
| `400` | Bad Request | Invalid input, validation failure |
| `401` | Unauthorized | Missing or invalid JWT token |
| `403` | Forbidden | Valid token but insufficient permissions |
| `404` | Not Found | Resource does not exist |
| `409` | Conflict | Resource already exists (e.g., duplicate email) |
| `500` | Internal Server Error | Unexpected server error |
### Common Error Scenarios
**Missing Authentication:**
```json
{
"error": "Not authenticated",
"message": "Authentication is required to access this resource",
"details": null
}
```
**Invalid Token:**
```json
{
"error": "Invalid token",
"message": "Authentication is required to access this resource",
"details": null
}
```
**Accessing Another User's Task:**
```json
{
"error": "You do not have permission to access this task",
"message": "You do not have permission to access this resource",
"details": null
}
```
**Task Not Found:**
```json
{
"error": "Task not found",
"message": "The requested resource was not found",
"details": null
}
```
**Validation Error:**
```json
{
"error": "Title is required and cannot be empty",
"message": "The request contains invalid data",
"details": null
}
```
---
## Security
### Authentication Flow
1. **User Registration/Login:**
- User provides email and password
- Backend validates credentials
- Backend generates JWT token with user_id
- Token returned to client
2. **Authenticated Requests:**
- Client includes token in `Authorization: Bearer <token>` header
- Backend verifies token signature
- Backend extracts `user_id` from token payload
- Backend uses `user_id` for all database queries
### Security Guarantees
**User Identity from JWT Only:**
- User ID is NEVER accepted from client input
- All user identification comes from verified JWT token
- Prevents user impersonation attacks
**Complete Data Isolation:**
- All database queries filtered by authenticated `user_id`
- Users cannot view, edit, or delete other users' tasks
- Ownership verified on every operation
**Password Security:**
- Passwords hashed with bcrypt before storage
- Plain-text passwords never stored
- Password hashes never exposed in API responses
**SQL Injection Prevention:**
- All queries use SQLModel ORM with parameterization
- No raw SQL with string concatenation
**CORS Protection:**
- CORS middleware configured with allowed origins
- Prevents unauthorized cross-origin requests
### Token Management
**Token Expiration:** 7 days (168 hours)
**Token Format:**
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5jb20iLCJleHAiOjE3MDcwNTI4MDB9.signature
```
**Token Verification:**
- Signature verified using `JWT_SECRET`
- Expiration checked on every request
- Invalid tokens rejected with 401 Unauthorized
---
## Examples
### Complete Workflow Example
#### 1. Create Account
```bash
curl -X POST http://localhost:8001/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "SecurePass123"
}'
```
**Response:**
```json
{
"access_token": "eyJhbGc...",
"token_type": "bearer",
"user": {
"id": 1,
"email": "john@example.com"
}
}
```
#### 2. Create Task
```bash
curl -X POST http://localhost:8001/api/tasks \
-H "Authorization: Bearer eyJhbGc..." \
-H "Content-Type: application/json" \
-d '{
"title": "Learn FastAPI",
"description": "Build a REST API with authentication"
}'
```
**Response:**
```json
{
"id": 1,
"title": "Learn FastAPI",
"description": "Build a REST API with authentication",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T14:00:00Z",
"updated_at": "2026-02-03T14:00:00Z"
}
```
#### 3. List Tasks
```bash
curl -X GET http://localhost:8001/api/tasks \
-H "Authorization: Bearer eyJhbGc..."
```
**Response:**
```json
[
{
"id": 1,
"title": "Learn FastAPI",
"description": "Build a REST API with authentication",
"completed": false,
"user_id": 1,
"created_at": "2026-02-03T14:00:00Z",
"updated_at": "2026-02-03T14:00:00Z"
}
]
```
#### 4. Mark Task Complete
```bash
curl -X PATCH http://localhost:8001/api/tasks/1/complete \
-H "Authorization: Bearer eyJhbGc..."
```
**Response:**
```json
{
"id": 1,
"title": "Learn FastAPI",
"description": "Build a REST API with authentication",
"completed": true,
"user_id": 1,
"created_at": "2026-02-03T14:00:00Z",
"updated_at": "2026-02-03T14:30:00Z"
}
```
#### 5. Update Task
```bash
curl -X PUT http://localhost:8001/api/tasks/1 \
-H "Authorization: Bearer eyJhbGc..." \
-H "Content-Type: application/json" \
-d '{
"title": "Master FastAPI",
"description": "Build production-ready APIs"
}'
```
#### 6. Delete Task
```bash
curl -X DELETE http://localhost:8001/api/tasks/1 \
-H "Authorization: Bearer eyJhbGc..."
```
**Response:**
```json
{
"message": "Task deleted successfully"
}
```
---
### JavaScript/TypeScript Example
```typescript
// API Client Configuration
const API_BASE_URL = 'http://localhost:8001';
let authToken: string | null = null;
// Signup
async function signup(email: string, password: string) {
const response = await fetch(`${API_BASE_URL}/api/auth/signup`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const data = await response.json();
authToken = data.access_token;
return data;
}
// Create Task
async function createTask(title: string, description?: string) {
const response = await fetch(`${API_BASE_URL}/api/tasks`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`
},
body: JSON.stringify({ title, description })
});
return response.json();
}
// List Tasks
async function listTasks() {
const response = await fetch(`${API_BASE_URL}/api/tasks`, {
headers: {
'Authorization': `Bearer ${authToken}`
}
});
return response.json();
}
// Toggle Task Completion
async function toggleTaskComplete(taskId: number) {
const response = await fetch(`${API_BASE_URL}/api/tasks/${taskId}/complete`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${authToken}`
}
});
return response.json();
}
// Delete Task
async function deleteTask(taskId: number) {
const response = await fetch(`${API_BASE_URL}/api/tasks/${taskId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${authToken}`
}
});
return response.json();
}
```
---
## Testing the API
### Using Swagger UI
FastAPI provides interactive API documentation:
1. Start the backend server
2. Open browser to: http://localhost:8001/docs
3. Click "Authorize" button
4. Enter JWT token from signup/signin response
5. Test endpoints interactively
### Using Postman
1. Import the API endpoints
2. Set `Authorization` header: `Bearer <token>`
3. Set `Content-Type` header: `application/json`
4. Test each endpoint
### Using curl
See examples above for complete curl commands.
---
## Rate Limiting & Performance
**Current Implementation:**
- No rate limiting (suitable for development/hackathon)
- Database connection pooling via Neon PostgreSQL
- Async/await for non-blocking I/O
**Production Recommendations:**
- Add rate limiting middleware
- Implement request caching
- Add database query optimization
- Monitor API performance metrics
---
## Support & Troubleshooting
**Common Issues:**
1. **401 Unauthorized on all requests**
- Check token is included in Authorization header
- Verify token format: `Bearer <token>`
- Ensure JWT_SECRET matches between backend and frontend
2. **403 Forbidden when accessing task**
- Task belongs to another user
- Verify you're using correct user's token
3. **CORS errors from frontend**
- Check CORS_ORIGINS in backend .env
- Ensure frontend URL is in allowed origins list
4. **Database connection errors**
- Verify DATABASE_URL in .env
- Check Neon PostgreSQL is accessible
- Test connection with database client
---
## API Versioning
**Current Version:** v1.0.0
**Endpoint Prefix:** `/api/`
**Future Versioning Strategy:**
- Breaking changes will use new prefix: `/api/v2/`
- Current endpoints will remain stable
- Deprecation notices will be provided in advance
---
## Changelog
### v1.0.0 (2026-02-03)
- Initial release
- User authentication (signup, signin)
- Task CRUD operations
- Task completion tracking
- JWT-based security
- Complete data isolation
---
**Last Updated:** 2026-02-03
**Maintained By:** KIro Todo Development Team