# API Design Document

## Base URL

```
Development: http://localhost:8000/api/v1
Production:  https://api.planet.example.com/api/v1
WebSocket:   ws://localhost:8000/ws
```

---

## Authentication

### Login
```http
POST /api/v1/auth/login
Content-Type: application/json

{
    "username": "admin",
    "password": "admin123"
}
```

**Response (200 OK)**
```json
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "bearer",
    "expires_in": 900,
    "user": {
        "id": 1,
        "username": "admin",
        "role": "super_admin"
    }
}
```

**Response (401 Unauthorized)**
```json
{
    "detail": "Invalid credentials"
}
```

### Refresh Token
```http
POST /api/v1/auth/refresh
Authorization: Bearer <refresh_token>
```

**Response (200 OK)**
```json
{
    "access_token": "new_access_token",
    "expires_in": 900
}
```

### Logout
```http
POST /api/v1/auth/logout
Authorization: Bearer <access_token>
```

### Get Current User
```http
GET /api/v1/auth/me
Authorization: Bearer <access_token>
```

**Response (200 OK)**
```json
{
    "id": 1,
    "username": "admin",
    "email": "admin@example.com",
    "role": "super_admin",
    "is_active": true,
    "created_at": "2024-01-15T10:00:00Z"
}
```

---

## Users Management

### List Users
```http
GET /api/v1/users
Authorization: Bearer <token>

Query Parameters:
- page: int (default: 1)
- page_size: int (default: 20, max: 100)
- role: string (optional)
- is_active: boolean (optional)
- search: string (optional)
```

**Response (200 OK)**
```json
{
    "total": 45,
    "page": 1,
    "page_size": 20,
    "data": [
        {
            "id": 1,
            "username": "admin",
            "email": "admin@example.com",
            "role": "super_admin",
            "is_active": true,
            "last_login": "2024-01-20T15:30:00Z",
            "created_at": "2024-01-15T10:00:00Z"
        }
    ]
}
```

### Get User
```http
GET /api/v1/users/{user_id}
Authorization: Bearer <token>
```

### Create User
```http
POST /api/v1/users
Authorization: Bearer <token>
Content-Type: application/json

{
    "username": "newuser",
    "email": "newuser@example.com",
    "password": "securepassword123",
    "role": "operator"
}
```

**Response (201 Created)**
```json
{
    "id": 46,
    "username": "newuser",
    "email": "newuser@example.com",
    "role": "operator",
    "is_active": true,
    "created_at": "2024-01-20T10:00:00Z"
}
```

### Update User
```http
PUT /api/v1/users/{user_id}
Authorization: Bearer <token>
Content-Type: application/json

{
    "email": "updated@example.com",
    "role": "admin",
    "is_active": true
}
```

### Delete User
```http
DELETE /api/v1/users/{user_id}
Authorization: Bearer <token>
```

### Change Password
```http
POST /api/v1/users/{user_id}/change-password
Authorization: Bearer <token>
Content-Type: application/json

{
    "old_password": "oldpassword",
    "new_password": "newpassword123"
}
```

---

## Data Sources

### List Data Sources
```http
GET /api/v1/datasources
Authorization: Bearer <token>

Query Parameters:
- module: string (L1, L2, L3, L4)
- is_active: boolean
- priority: string (P0, P1)
```

**Response (200 OK)**
```json
{
    "total": 9,
    "data": [
        {
            "id": 1,
            "name": "TOP500",
            "module": "L1",
            "priority": "P0",
            "frequency": "4h",
            "is_active": true,
            "last_run": "2024-01-20T08:00:00Z",
            "last_status": "success",
            "next_run": "2024-01-20T12:00:00Z"
        }
    ]
}
```

### Get Data Source
```http
GET /api/v1/datasources/{source_id}
Authorization: Bearer <token>
```

### Create Data Source
```http
POST /api/v1/datasources
Authorization: Bearer <token>
Content-Type: application/json

{
    "name": "New Source",
    "module": "L1",
    "priority": "P1",
    "frequency": "1h",
    "collector_class": "CustomCollector",
    "config": {
        "api_url": "https://api.example.com/data",
        "auth_type": "bearer",
        "api_key": "${env:API_KEY}"
    }
}
```

### Update Data Source
```http
PUT /api/v1/datasources/{source_id}
Authorization: Bearer <token>
Content-Type: application/json

{
    "frequency": "30m",
    "is_active": true
}
```

### Enable/Disable Data Source
```http
POST /api/v1/datasources/{source_id}/enable
POST /api/v1/datasources/{source_id}/disable
Authorization: Bearer <token>
```

### Test Data Source
```http
POST /api/v1/datasources/{source_id}/test
Authorization: Bearer <token>

Response (200 OK)
{
    "status": "success",
    "data_count": 150,
    "execution_time_ms": 1250
}
```

### Get Data Source Logs
```http
GET /api/v1/datasources/{source_id}/logs
Authorization: Bearer <token>

Query Parameters:
- page: int
- page_size: int
- status: string (success, failed, running)
- start_date: datetime
- end_date: datetime
```

---

## Tasks

### List Tasks
```http
GET /api/v1/tasks
Authorization: Bearer <token>

Query Parameters:
- datasource_id: int
- status: string
- start_date: datetime
- end_date: datetime
```

**Response (200 OK)**
```json
{
    "total": 156,
    "data": [
        {
            "id": 1234,
            "datasource_id": 1,
            "datasource_name": "TOP500",
            "status": "success",
            "started_at": "2024-01-20T08:00:00Z",
            "completed_at": "2024-01-20T08:01:15Z",
            "records_processed": 500,
            "error_message": null
        }
    ]
}
```

### Get Task
```http
GET /api/v1/tasks/{task_id}
Authorization: Bearer <token>
```

### Trigger Manual Run
```http
POST /api/v1/datasources/{source_id}/trigger
Authorization: Bearer <token>

Response (202 Accepted)
{
    "task_id": 1567,
    "message": "Task queued successfully"
}
```

### Cancel Running Task
```http
POST /api/v1/tasks/{task_id}/cancel
Authorization: Bearer <token>
```

---

## Dashboard Data

### Overview Stats
```http
GET /api/v1/dashboard/stats
Authorization: Bearer <token>
```

**Response (200 OK)**
```json
{
    "total_datasources": 9,
    "active_datasources": 8,
    "tasks_today": 45,
    "success_rate": 97.8,
    "last_updated": "2024-01-20T10:30:00Z",
    "alerts": {
        "critical": 0,
        "warning": 2,
        "info": 5
    }
}
```

### Data Summary by Module
```http
GET /api/v1/dashboard/summary
Authorization: Bearer <token>
```

**Response (200 OK)**
```json
{
    "L1": {
        "datasources": 5,
        "total_records": 12500,
        "last_updated": "2024-01-20T10:00:00Z"
    },
    "L2": {
        "datasources": 4,
        "total_records": 8300,
        "last_updated": "2024-01-20T09:45:00Z"
    }
}
```

### Recent Activity
```http
GET /api/v1/dashboard/activity
Authorization: Bearer <token>

Query Parameters:
- limit: int (default: 20)
```

---

## GPU Clusters (L1 Data)

### List GPU Clusters
```http
GET /api/v1/data/gpu-clusters
Authorization: Bearer <token>

Query Parameters:
- country: string
- min_gpu_count: int
- order_by: string (gpu_count, flops, rank)
- order: string (asc, desc)
- page: int
- page_size: int
```

**Response (200 OK)**
```json
{
    "total": 1500,
    "page": 1,
    "page_size": 50,
    "data": [
        {
            "id": "epoch-gpu-001",
            "name": "Frontier",
            "country": "US",
            "city": "Oak Ridge, TN",
            "lat": 35.9327,
            "lng": -84.3107,
            "organization": "Oak Ridge National Laboratory",
            "gpu_count": 37888,
            "gpu_type": "AMD MI250X",
            "total_flops": 1.54e9,
            "rank": 1,
            "last_updated": "2024-01-15T00:00:00Z"
        }
    ]
}
```

### Get GPU Cluster Detail
```http
GET /api/v1/data/gpu-clusters/{cluster_id}
Authorization: Bearer <token>
```

### GPU Cluster Statistics
```http
GET /api/v1/data/gpu-clusters/stats
Authorization: Bearer <token>
```

**Response (200 OK)**
```json
{
    "total_clusters": 1500,
    "total_gpu_count": 2500000,
    "by_country": {
        "US": {"count": 800, "gpu_share": 0.45},
        "CN": {"count": 350, "gpu_share": 0.20},
        "EU": {"count": 200, "gpu_share": 0.15}
    },
    "top_10_clusters": [...]
}
```

---

## Submarine Cables (L2 Data)

### List Submarine Cables
```http
GET /api/v1/data/submarine-cables
Authorization: Bearer <token>

Query Parameters:
- status: string (active, planned, decommissioned)
- country: string
```

**Response (200 OK)**
```json
{
    "total": 436,
    "data": [
        {
            "id": "cable-001",
            "name": "FASTER",
            "length_km": 11600,
            "owners": ["Google", "中国移动", "NEC"],
            "capacity_tbps": 60,
            "status": "active",
            "landing_points": [
                {"country": "US", "city": "San Francisco", "lat": 37.7749, "lng": -122.4194},
                {"country": "JP", "city": "Tokyo", "lat": 35.6762, "lng": 139.6503}
            ]
        }
    ]
}
```

---

## IXP Nodes (L2 Data)

### List IXPs
```http
GET /api/v1/data/ixps
Authorization: Bearer <token>

Query Parameters:
- country: string
- region: string
```

**Response (200 OK)**
```json
{
    "total": 1200,
    "data": [
        {
            "id": "ixp-001",
            "name": "Equinix Ashburn",
            "country": "US",
            "city": "Ashburn, VA",
            "member_count": 250,
            "traffic_tbps": 15.5,
            "ixp_db_id": "EQ-AS1"
        }
    ]
}
```

---

## Alerts

### List Alerts
```http
GET /api/v1/alerts
Authorization: Bearer <token>

Query Parameters:
- severity: string (critical, warning, info)
- status: string (active, acknowledged, resolved)
- datasource_id: int
```

**Response (200 OK)**
```json
{
    "total": 12,
    "data": [
        {
            "id": 1,
            "severity": "warning",
            "datasource_id": 2,
            "datasource_name": "Epoch AI",
            "message": "API response time > 30s",
            "status": "active",
            "created_at": "2024-01-20T09:30:00Z",
            "acknowledged_by": null
        }
    ]
}
```

### Acknowledge Alert
```http
POST /api/v1/alerts/{alert_id}/acknowledge
Authorization: Bearer <token>
```

### Resolve Alert
```http
POST /api/v1/alerts/{alert_id}/resolve
Authorization: Bearer <token>
Content-Type: application/json

{
    "resolution": "API rate limit adjusted"
}
```

### Alert Rules Configuration
```http
GET /api/v1/alerts/rules
POST /api/v1/alerts/rules
PUT /api/v1/alerts/rules/{rule_id}
DELETE /api/v1/alerts/rules/{rule_id}
Authorization: Bearer <token>
```

---

## System Configuration

### Get Config
```http
GET /api/v1/config
Authorization: Bearer <token> (admin only)
```

### Update Config
```http
PUT /api/v1/config
Authorization: Bearer <token> (admin only)
Content-Type: application/json

{
    "data_retention_days": 30,
    "refresh_interval": 300,
    "timezone": "Asia/Shanghai"
}
```

---

## Audit Logs

### List Audit Logs
```http
GET /api/v1/audit-logs
Authorization: Bearer <token> (admin only)

Query Parameters:
- user_id: int
- action: string
- resource: string
- start_date: datetime
- end_date: datetime
- page: int
- page_size: int
```

**Response (200 OK)**
```json
{
    "total": 1500,
    "data": [
        {
            "id": 10001,
            "user_id": 1,
            "username": "admin",
            "action": "user.update",
            "resource": "users",
            "resource_id": 5,
            "detail": {"changes": {"role": ["viewer", "operator"]}},
            "ip_address": "192.168.1.100",
            "created_at": "2024-01-20T10:30:00Z"
        }
    ]
}
```

---

## Health Check

### System Health
```http
GET /health
```

**Response (200 OK)**
```json
{
    "status": "healthy",
    "version": "1.0.0",
    "uptime_seconds": 86400,
    "components": {
        "database": "healthy",
        "redis": "healthy",
        "celery": "healthy"
    }
}
```

### Readiness
```http
GET /ready
```

**Response (200 OK)**
```json
{
    "ready": true
}
```

---

## Error Codes

| Code | Description |
|------|-------------|
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Invalid/missing token |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn't exist |
| 422 | Validation Error - Data validation failed |
| 429 | Rate Limited - Too many requests |
| 500 | Internal Server Error |
| 503 | Service Unavailable |
