Skip to content

Latest commit

Β 

History

History
959 lines (755 loc) Β· 17.4 KB

File metadata and controls

959 lines (755 loc) Β· 17.4 KB

TeamHub API Documentation

πŸ“š Table of Contents


🌐 Overview

The TeamHub API is a RESTful API built with Django REST Framework. It provides programmatic access to all TeamHub features including teams, projects, tasks, and user management.

API Version: v1
Protocol: HTTP/HTTPS
Data Format: JSON


πŸ” Authentication

JWT Authentication

All protected endpoints require a JWT (JSON Web Token) in the Authorization header:

Authorization: Bearer <your-access-token>

Getting a Token

Method 1: Username/Password

POST /api/token/
Content-Type: application/json

{
  "username": "john_doe",
  "password": "secure_password"
}

Response:

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Method 2: Google OAuth

GET /api/auth/google/login/?redirect=http://localhost:3000

This redirects to Google OAuth flow and returns a JWT token upon successful authentication.

Refreshing Tokens

POST /api/token/refresh
Content-Type: application/json

{
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Response:

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Token Lifetime

  • Access Token: 60 minutes
  • Refresh Token: 24 hours (sliding)

🌍 Base URL

Development: http://localhost:8000/api
Production: https://api.teamhub.com/api


πŸ“¦ Response Format

Success Response

{
  "id": 1,
  "name": "Project Name",
  "created_at": "2026-01-15T10:30:00Z"
}

List Response

[
  {
    "id": 1,
    "name": "Item 1"
  },
  {
    "id": 2,
    "name": "Item 2"
  }
]

Error Response

{
  "error": "Error message describing what went wrong"
}

⚠️ Error Handling

HTTP Status Codes

Code Description
200 OK Request successful
201 Created Resource created successfully
400 Bad Request Invalid request parameters
401 Unauthorized Missing or invalid authentication
403 Forbidden Insufficient permissions
404 Not Found Resource not found
500 Internal Server Error Server error

Common Error Responses

401 Unauthorized:

{
  "detail": "Authentication credentials were not provided."
}

403 Forbidden:

{
  "error": "Only higher staff can create teams"
}

404 Not Found:

{
  "error": "Task not found"
}

πŸ“‹ Endpoints

Authentication Endpoints

1. Obtain JWT Token

POST /api/token/

Request Body:

{
  "username": "john_doe",
  "password": "secure_password123"
}

Response: 200 OK

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}

2. Refresh JWT Token

POST /api/token/refresh

Request Body:

{
  "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}

Response: 200 OK

{
  "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}

3. Google OAuth Login

GET /api/auth/google/login/

Query Parameters:

  • redirect (optional): URL to redirect after authentication

Response: Redirects to Google OAuth consent screen, then back to your redirect URL with token.


4. Google OAuth Callback

GET /api/auth/google/callback/custom/

Query Parameters:

  • code: Authorization code from Google

Response: Redirects to frontend with JWT token in URL parameters.


User Endpoints

1. List All Users

GET /api/users/

Headers:

Authorization: Bearer <token>

Response: 200 OK

[
  {
    "id": 1,
    "username": "john_doe",
    "email": "john@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "is_staff": true
  },
  {
    "id": 2,
    "username": "jane_smith",
    "email": "jane@example.com",
    "first_name": "Jane",
    "last_name": "Smith",
    "is_staff": false
  }
]

Team Endpoints

1. List User's Teams

GET /api/teams/

Headers:

Authorization: Bearer <token>

Description: Returns all teams where the user is either a member or owner.

Response: 200 OK

[
  {
    "id": 1,
    "name": "Development Team",
    "owner": 1,
    "owner_username": "john_doe",
    "member_count": 5,
    "created_at": "2026-01-10T08:00:00Z"
  },
  {
    "id": 2,
    "name": "Design Team",
    "owner": 3,
    "owner_username": "alice_wonder",
    "member_count": 3,
    "created_at": "2026-01-12T10:30:00Z"
  }
]

2. Create Team (Staff Only)

POST /api/teams/create/

Headers:

Authorization: Bearer <token>

Permissions: User must have is_staff = true

Request Body:

{
  "name": "Backend Team",
  "member_ids": [2, 3, 4]
}

Request Fields:

  • name (string, required): Team name
  • member_ids (array, optional): Array of user IDs to add as members

Response: 201 Created

{
  "id": 3,
  "name": "Backend Team",
  "owner": 1,
  "owner_username": "john_doe",
  "member_count": 3,
  "created_at": "2026-02-10T14:25:00Z"
}

Error Response: 403 Forbidden

{
  "error": "Only higher staff can create teams"
}

Project Endpoints

1. List User's Projects

GET /api/projects/

Headers:

Authorization: Bearer <token>

Description: Returns all projects where the user is a member.

Response: 200 OK

[
  {
    "id": 1,
    "name": "Website Redesign",
    "team": 1,
    "team_name": "Development Team",
    "join_code": "a3f7b9c2",
    "member_count": 5,
    "members_list": [
      {
        "id": 1,
        "username": "john_doe",
        "email": "john@example.com"
      },
      {
        "id": 2,
        "username": "jane_smith",
        "email": "jane@example.com"
      }
    ],
    "created_at": "2026-01-15T09:00:00Z"
  }
]

2. Create Project

POST /api/projects/create/

Headers:

Authorization: Bearer <token>

Permissions: User must be a member or owner of the team.

Request Body:

{
  "name": "Mobile App Development",
  "team_id": 1
}

Request Fields:

  • name (string, required): Project name
  • team_id (integer, required): ID of the team this project belongs to

Response: 201 Created

{
  "id": 2,
  "name": "Mobile App Development",
  "team": 1,
  "team_name": "Development Team",
  "join_code": "e8d4c1f9",
  "member_count": 5,
  "members_list": [
    {
      "id": 1,
      "username": "john_doe",
      "email": "john@example.com"
    }
  ],
  "created_at": "2026-02-10T15:00:00Z"
}

Note: All team members (including owner) are automatically added to the project.

Error Responses:

400 Bad Request

{
  "error": "team_id and name are required"
}

403 Forbidden

{
  "error": "You are not a member of this team"
}

404 Not Found

{
  "error": "Team not found"
}

3. Join Project by Code

POST /api/projects/join/

Headers:

Authorization: Bearer <token>

Request Body:

{
  "join_code": "a3f7b9c2"
}

Request Fields:

  • join_code (string, required): Unique 8-character project code

Response: 200 OK

{
  "message": "Joined project successfully",
  "project": {
    "id": 1,
    "name": "Website Redesign"
  }
}

Error Responses:

400 Bad Request

{
  "error": "join_code is required"
}

404 Not Found

{
  "error": "Invalid project code"
}

Task Endpoints

1. List User's Tasks

GET /api/tasks/

Headers:

Authorization: Bearer <token>

Description: Returns all tasks from projects where the user is a member.

Response: 200 OK

[
  {
    "id": 1,
    "title": "Design homepage mockup",
    "description": "Create initial design concepts for the new homepage",
    "status": "doing",
    "assigned_to": 2,
    "assigned_to_username": "jane_smith",
    "project": 1,
    "project_name": "Website Redesign",
    "created_at": "2026-02-08T10:00:00Z"
  },
  {
    "id": 2,
    "title": "Set up database schema",
    "description": "Create models for user, team, and project",
    "status": "done",
    "assigned_to": 1,
    "assigned_to_username": "john_doe",
    "project": 1,
    "project_name": "Website Redesign",
    "created_at": "2026-02-07T14:30:00Z"
  }
]

2. Create Task

POST /api/tasks/

Headers:

Authorization: Bearer <token>

Permissions: User must be a member of the project.

Request Body:

{
  "title": "Implement user authentication",
  "description": "Add JWT-based authentication with Google OAuth",
  "project": 1,
  "assigned_to": 2,
  "status": "todo"
}

Request Fields:

  • title (string, required): Task title
  • description (string, optional): Detailed task description
  • project (integer, required): Project ID
  • assigned_to (integer, optional): User ID to assign task to
  • status (string, optional): Task status - todo (default), doing, or done

Response: 201 Created

{
  "id": 3,
  "title": "Implement user authentication",
  "description": "Add JWT-based authentication with Google OAuth",
  "status": "todo",
  "assigned_to": 2,
  "assigned_to_username": "jane_smith",
  "project": 1,
  "project_name": "Website Redesign",
  "created_at": "2026-02-10T16:00:00Z"
}

Error Response: 403 Forbidden

{
  "error": "You are not a member of this project"
}

3. Update Task Status

PATCH /api/tasks/<task_id>/

Headers:

Authorization: Bearer <token>

Permissions: Only the assigned user can update task status.

Request Body:

{
  "status": "doing"
}

Request Fields:

  • status (string, required): New status - todo, doing, or done

Example:

PATCH /api/tasks/1/
Content-Type: application/json
Authorization: Bearer <token>

{
  "status": "done"
}

Response: 200 OK

{
  "id": 1,
  "title": "Design homepage mockup",
  "description": "Create initial design concepts for the new homepage",
  "status": "done",
  "assigned_to": 2,
  "assigned_to_username": "jane_smith",
  "project": 1,
  "project_name": "Website Redesign",
  "created_at": "2026-02-08T10:00:00Z"
}

Error Responses:

400 Bad Request

{
  "error": "Invalid status. Must be 'todo', 'doing', or 'done'"
}

403 Forbidden

{
  "error": "You are not assigned to this task"
}

404 Not Found

{
  "error": "Task not found"
}

πŸ“Š Models

User Model

{
  "id": Integer,
  "username": String,
  "email": String,
  "first_name": String,
  "last_name": String,
  "is_staff": Boolean
}

Team Model

{
  "id": Integer,
  "name": String,
  "owner": Integer (User ID),
  "owner_username": String (read-only),
  "member_count": Integer (computed),
  "created_at": DateTime
}

Relationships:

  • owner: One-to-Many with User
  • members: Many-to-Many with User

Project Model

{
  "id": Integer,
  "name": String,
  "team": Integer (Team ID),
  "team_name": String (read-only),
  "join_code": String (8 chars, auto-generated),
  "member_count": Integer (computed),
  "members_list": Array[User] (read-only),
  "created_at": DateTime
}

Relationships:

  • team: Many-to-One with Team
  • members: Many-to-Many with User (auto-populated from team)

Task Model

{
  "id": Integer,
  "title": String,
  "description": String,
  "status": String ("todo" | "doing" | "done"),
  "assigned_to": Integer (User ID, nullable),
  "assigned_to_username": String (read-only),
  "project": Integer (Project ID),
  "project_name": String (read-only),
  "created_at": DateTime
}

Relationships:

  • project: Many-to-One with Project
  • assigned_to: Many-to-One with User (optional)

πŸ”’ Permissions

Permission Matrix

Endpoint Anonymous Authenticated Staff Only
POST /api/token/ βœ… βœ… βœ…
GET /api/users/ ❌ βœ… βœ…
GET /api/teams/ ❌ βœ… βœ…
POST /api/teams/create/ ❌ ❌ βœ…
GET /api/projects/ ❌ βœ… βœ…
POST /api/projects/create/ ❌ βœ…* βœ…
POST /api/projects/join/ ❌ βœ… βœ…
GET /api/tasks/ ❌ βœ… βœ…
POST /api/tasks/ ❌ βœ…* βœ…
PATCH /api/tasks/<id>/ ❌ βœ…** βœ…

Legend:

  • βœ… Allowed
  • ❌ Forbidden
  • βœ…* Allowed if user is team member
  • βœ…** Allowed if user is assigned to task

Custom Permission Rules

  1. Team Creation: Only users with is_staff=true
  2. Project Creation: User must be member or owner of the team
  3. Task Creation: User must be member of the project
  4. Task Status Update: User must be assigned to the task
  5. Project Join: Any authenticated user with valid join code

⏱️ Rate Limiting

Currently, no rate limiting is implemented. Consider implementing rate limiting in production:

Recommended Limits:

  • Authentication endpoints: 5 requests/minute
  • Read endpoints: 100 requests/minute
  • Write endpoints: 30 requests/minute

πŸ”„ Automatic Synchronization

Team Member Sync

When team members are added or removed, they are automatically synchronized to all projects in that team:

Example:

  1. User jane_smith is added to "Development Team"
  2. Automatically added to all existing projects in "Development Team"
  3. Can immediately create tasks in those projects

Project Member Initialization

When a project is created, all team members are automatically added:

Example:

  1. Create project "Mobile App" for "Development Team" (5 members)
  2. All 5 team members automatically become project members
  3. No manual member addition required

πŸ“ Usage Examples

Complete Workflow Example

# 1. Login and get token
curl -X POST http://localhost:8000/api/token/ \
  -H "Content-Type: application/json" \
  -d '{"username": "john_doe", "password": "password123"}'

# Response: {"access": "eyJ0...", "refresh": "eyJ0..."}

# 2. Create a team (staff only)
curl -X POST http://localhost:8000/api/teams/create/ \
  -H "Authorization: Bearer eyJ0..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Dev Team", "member_ids": [2, 3]}'

# 3. Create a project
curl -X POST http://localhost:8000/api/projects/create/ \
  -H "Authorization: Bearer eyJ0..." \
  -H "Content-Type: application/json" \
  -d '{"name": "Website Redesign", "team_id": 1}'

# 4. Create a task
curl -X POST http://localhost:8000/api/tasks/ \
  -H "Authorization: Bearer eyJ0..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Design homepage",
    "description": "Create mockups",
    "project": 1,
    "assigned_to": 2,
    "status": "todo"
  }'

# 5. Update task status
curl -X PATCH http://localhost:8000/api/tasks/1/ \
  -H "Authorization: Bearer eyJ0..." \
  -H "Content-Type: application/json" \
  -d '{"status": "done"}'

# 6. List all tasks
curl -X GET http://localhost:8000/api/tasks/ \
  -H "Authorization: Bearer eyJ0..."

πŸ› Debugging

Enable Detailed Logging

Add to backend/teamhub/settings.py:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

Common Issues

401 Unauthorized:

  • Token expired (refresh it)
  • Missing Authorization header
  • Invalid token format

403 Forbidden:

  • Insufficient permissions
  • Not a member of team/project
  • Not assigned to task

CORS Errors:

  • Check CORS_ALLOWED_ORIGINS in settings
  • Ensure frontend URL is whitelisted

πŸ“š Additional Resources


Last Updated: February 10, 2026
API Version: 1.0