# API Contracts: Migration UI Improvements

**Date**: 2025-12-27 | **Status**: Implemented

## Overview

This document defines the API contracts for the Migration UI Improvements feature. All endpoints follow RESTful conventions and use standard HTTP status codes.

## Base URL

`/api/` - All endpoints are relative to the API base URL

## Authentication

All endpoints require authentication using the existing session mechanism.

## Endpoints

### 1. List Migration Tasks

**Endpoint**: `GET /api/tasks`

**Purpose**: Retrieve a paginated list of migration tasks

**Parameters**:
```
limit: integer (query, optional) - Number of tasks to return (default: 10, max: 50)
offset: integer (query, optional) - Pagination offset (default: 0)
status: string (query, optional) - Filter by task status (PENDING, RUNNING, SUCCESS, FAILED, AWAITING_INPUT, AWAITING_MAPPING)
```

**Response**: `200 OK`

**Content-Type**: `application/json`

**Response Body**:
```json
{
  "tasks": [
    {
      "id": "string (uuid)",
      "type": "string",
      "status": "string (enum)",
      "start_time": "string (iso8601)",
      "end_time": "string (iso8601) | null",
      "requires_input": "boolean"
    }
  ],
  "total": "integer",
  "limit": "integer",
  "offset": "integer"
}
```

**Example Request**:
```
GET /api/tasks?limit=5&offset=0
```

**Example Response**:
```json
{
  "tasks": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "migration",
      "status": "RUNNING",
      "start_time": "2025-12-27T09:47:12.000Z",
      "end_time": null,
      "requires_input": false
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "type": "migration",
      "status": "AWAITING_INPUT",
      "start_time": "2025-12-27T09:45:00.000Z",
      "end_time": null,
      "requires_input": true
    }
  ],
  "total": 2,
  "limit": 5,
  "offset": 0
}
```

**Error Responses**:
- `401 Unauthorized` - Authentication required
- `400 Bad Request` - Invalid parameters

### 2. Get Task Logs

**Endpoint**: `GET /tasks/{task_id}/logs`

**Purpose**: Retrieve detailed logs for a specific task

**Parameters**: None

**Response**: `200 OK`

**Content-Type**: `application/json`

**Response Body**:
```json
{
  "task_id": "string (uuid)",
  "status": "string (enum)",
  "logs": [
    {
      "timestamp": "string (iso8601)",
      "level": "string",
      "message": "string",
      "context": "object | null"
    }
  ]
}
```

**Example Request**:
```
GET /api/tasks/550e8400-e29b-41d4-a716-446655440001/logs
```

**Example Response**:
```json
{
  "task_id": "550e8400-e29b-41d4-a716-446655440001",
  "status": "AWAITING_INPUT",
  "logs": [
    {
      "timestamp": "2025-12-27T09:45:00.000Z",
      "level": "INFO",
      "message": "Starting migration",
      "context": null
    },
    {
      "timestamp": "2025-12-27T09:47:12.000Z",
      "level": "ERROR",
      "message": "API error during upload",
      "context": {
        "error": "Must provide a password for the database",
        "database": "PostgreSQL"
      }
    }
  ]
}
```

**Error Responses**:
- `401 Unauthorized` - Authentication required
- `404 Not Found` - Task not found
- `403 Forbidden` - Access denied to this task

### 3. Resume Task with Input

**Endpoint**: `POST /tasks/{task_id}/resume`

**Purpose**: Provide required input and resume a paused task

**Request Body**:
```json
{
  "passwords": {
    "database_name": "password"
  }
}
```

**Response**: `200 OK`

**Content-Type**: `application/json`

**Response Body**:
```json
{
  "success": true,
  "message": "Task resumed successfully"
}
```

**Example Request**:
```
POST /api/tasks/550e8400-e29b-41d4-a716-446655440001/resume
Content-Type: application/json

{
  "passwords": {
    "PostgreSQL": "securepassword123"
  }
}
```

**Example Response**:
```json
{
  "success": true,
  "message": "Task resumed successfully"
}
```

**Error Responses**:
- `401 Unauthorized` - Authentication required
- `404 Not Found` - Task not found
- `400 Bad Request` - Invalid request body or missing required fields
- `409 Conflict` - Task not in AWAITING_INPUT state or already completed
- `422 Unprocessable Entity` - Invalid password provided

### 4. Get Task Details (Optional)

**Endpoint**: `GET /tasks/{task_id}`

**Purpose**: Get detailed information about a specific task

**Parameters**: None

**Response**: `200 OK`

**Content-Type**: `application/json`

**Response Body**:
```json
{
  "id": "string (uuid)",
  "type": "string",
  "status": "string (enum)",
  "start_time": "string (iso8601)",
  "end_time": "string (iso8601) | null",
  "requires_input": "boolean",
  "input_request": "object | null"
}
```

**Example Response**:
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "type": "migration",
  "status": "AWAITING_INPUT",
  "start_time": "2025-12-27T09:45:00.000Z",
  "end_time": null,
  "requires_input": true,
  "input_request": {
    "type": "database_password",
    "databases": ["PostgreSQL"],
    "error_message": "Must provide a password for the database"
  }
}
```

## Data Types

### TaskStatus Enum

```
PENDING
RUNNING
SUCCESS
FAILED
AWAITING_INPUT
```

### LogLevel Enum

```
INFO
WARNING
ERROR
DEBUG
```

## Error Handling

### Standard Error Format

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "details": "object | null"
  }
}
```

### Common Error Codes

- `invalid_task_id`: Task ID is invalid or not found
- `task_not_awaiting_input`: Task is not in AWAITING_INPUT state
- `invalid_password`: Provided password is invalid
- `unauthorized`: Authentication required
- `bad_request`: Invalid request parameters

## WebSocket Integration

### Task Status Updates

**Channel**: `/ws/tasks/{task_id}/status`

**Message Format**:
```json
{
  "event": "status_update",
  "task_id": "string (uuid)",
  "status": "string (enum)",
  "timestamp": "string (iso8601)"
}
```

### Task Log Updates

**Channel**: `/ws/tasks/{task_id}/logs`

**Message Format**:
```json
{
  "event": "log_update",
  "task_id": "string (uuid)",
  "log": {
    "timestamp": "string (iso8601)",
    "level": "string",
    "message": "string",
    "context": "object | null"
  }
}
```

## Rate Limiting

- Maximum 10 requests per minute per user for task list endpoint
- Maximum 30 requests per minute per user for task details/logs endpoints
- No rate limiting for WebSocket connections

## Versioning

All endpoints are versioned using the `Accept` header:
- `Accept: application/vnd.api.v1+json` - Current version

## Security Considerations

1. **Authentication**: All endpoints require valid session authentication
2. **Authorization**: Users can only access their own tasks
3. **Password Handling**: Passwords are not stored permanently, only used for immediate task resumption
4. **Input Validation**: All inputs are validated according to defined schemas
5. **Rate Limiting**: Prevents abuse of API endpoints

## Implementation Notes

1. **Pagination**: Default limit of 10 tasks, maximum of 50
2. **Sorting**: Tasks are sorted by start_time descending by default
3. **Caching**: Task list responses can be cached for 5 seconds
4. **WebSocket**: Use existing WebSocket infrastructure for real-time updates
5. **Error Recovery**: Failed task resumptions can be retried with corrected input

## OpenAPI Specification

A complete OpenAPI 3.0 specification is available in the repository at `specs/008-migration-ui-improvements/contracts/openapi.yaml`.