# API Documentation

Complete GraphQL API documentation for Sankofa Phoenix.

## Base URL

- **Production**: `https://api.sankofa.nexus/graphql`
- **Development**: `http://localhost:4000/graphql`

## Authentication

All requests (except health check) require authentication via JWT token:

```http
Authorization: Bearer <token>
```

Tokens are obtained via Keycloak OIDC authentication.

## Queries

### Health Check

Check API health status.

```graphql
query {
  health {
    status
    timestamp
    version
  }
}
```

**Response:**
```json
{
  "data": {
    "health": {
      "status": "ok",
      "timestamp": "2024-01-01T00:00:00Z",
      "version": "1.0.0"
    }
  }
}
```

### Resources

Query resources with optional filtering.

```graphql
query {
  resources(filter: {
    type: VM
    status: RUNNING
    siteId: "site-1"
  }) {
    id
    name
    type
    status
    site {
      id
      name
      region
    }
    metadata
    createdAt
    updatedAt
  }
}
```

**Filter Options:**
- `type`: Resource type (VM, CONTAINER, STORAGE, NETWORK)
- `status`: Resource status (RUNNING, STOPPED, PENDING, ERROR)
- `siteId`: Filter by site ID
- `tenantId`: Filter by tenant ID (admin only)

### Resource

Get a single resource by ID.

```graphql
query {
  resource(id: "resource-id") {
    id
    name
    type
    status
    site {
      id
      name
    }
    metadata
  }
}
```

### Sites

List all accessible sites.

```graphql
query {
  sites {
    id
    name
    region
    status
    metadata
  }
}
```

### Tenants

List all tenants (admin only).

```graphql
query {
  tenants {
    id
    name
    domain
    status
    tier
    quotaLimits {
      compute {
        vcpu
        memory
        instances
      }
      storage {
        total
      }
    }
    createdAt
  }
}
```

### Tenant

Get tenant details.

```graphql
query {
  tenant(id: "tenant-id") {
    id
    name
    status
    resources {
      id
      name
      type
    }
    usage {
      totalCost
      byResource {
        resourceId
        cost
      }
    }
  }
}
```

### Usage Report

Get usage report for a tenant.

```graphql
query {
  usage(
    tenantId: "tenant-id"
    timeRange: {
      start: "2024-01-01T00:00:00Z"
      end: "2024-01-31T23:59:59Z"
    }
    granularity: DAY
  ) {
    totalCost
    currency
    byResource {
      resourceId
      resourceName
      cost
      quantity
    }
    byMetric {
      metricType
      cost
      quantity
    }
  }
}
```

### Invoices

List invoices for a tenant.

```graphql
query {
  invoices(
    tenantId: "tenant-id"
    filter: {
      status: PAID
      startDate: "2024-01-01"
      endDate: "2024-01-31"
    }
  ) {
    invoices {
      id
      invoiceNumber
      billingPeriodStart
      billingPeriodEnd
      total
      currency
      status
      lineItems {
        description
        quantity
        unitPrice
        total
      }
    }
  }
}
```

### Budgets

Get budgets for a tenant.

```graphql
query {
  budgets(tenantId: "tenant-id") {
    id
    name
    amount
    currency
    period
    currentSpend
    remaining
    alertThresholds
  }
}
```

### Billing Alerts

Get billing alerts for a tenant.

```graphql
query {
  billingAlerts(tenantId: "tenant-id") {
    id
    name
    alertType
    threshold
    enabled
    lastTriggeredAt
  }
}
```

## Mutations

### Create Resource

Create a new resource.

```graphql
mutation {
  createResource(input: {
    name: "my-vm"
    type: VM
    siteId: "site-1"
    metadata: {
      cpu: 4
      memory: "8Gi"
      disk: "100Gi"
    }
  }) {
    id
    name
    status
  }
}
```

### Update Resource

Update an existing resource.

```graphql
mutation {
  updateResource(
    id: "resource-id"
    input: {
      name: "updated-name"
      metadata: {
        cpu: 8
      }
    }
  ) {
    id
    name
    metadata
  }
}
```

### Delete Resource

Delete a resource.

```graphql
mutation {
  deleteResource(id: "resource-id")
}
```

### Create Tenant

Create a new tenant (admin only).

```graphql
mutation {
  createTenant(input: {
    name: "New Tenant"
    domain: "tenant.example.com"
    tier: STANDARD
    quotaLimits: {
      compute: {
        vcpu: 16
        memory: 64
        instances: 10
      }
      storage: {
        total: 1000
      }
    }
  }) {
    id
    name
    status
  }
}
```

### Share Resource Across Tenants

Share a resource with other tenants.

```graphql
mutation {
  shareResourceAcrossTenants(
    resourceId: "resource-id"
    sourceTenantId: "tenant-1"
    targetTenants: ["tenant-2", "tenant-3"]
  )
}
```

### Create Invoice

Generate an invoice for a tenant (admin only).

```graphql
mutation {
  createInvoice(
    tenantId: "tenant-id"
    billingPeriodStart: "2024-01-01T00:00:00Z"
    billingPeriodEnd: "2024-01-31T23:59:59Z"
  ) {
    id
    invoiceNumber
    total
    status
  }
}
```

### Create Budget

Create a budget for a tenant.

```graphql
mutation {
  createBudget(
    tenantId: "tenant-id"
    budget: {
      name: "Monthly Budget"
      amount: 1000
      currency: USD
      period: MONTHLY
      startDate: "2024-01-01T00:00:00Z"
      alertThresholds: [0.5, 0.75, 0.9]
    }
  ) {
    id
    name
    amount
    currentSpend
    remaining
  }
}
```

### Create Billing Alert

Create a billing alert.

```graphql
mutation {
  createBillingAlert(
    tenantId: "tenant-id"
    alert: {
      name: "Budget Warning"
      alertType: BUDGET
      threshold: 0.8
      condition: {
        budgetId: "budget-id"
      }
    }
  ) {
    id
    name
    enabled
  }
}
```

## Error Handling

All errors follow GraphQL error format:

```json
{
  "errors": [
    {
      "message": "Error message",
      "extensions": {
        "code": "ERROR_CODE",
        "field": "fieldName"
      }
    }
  ]
}
```

### Error Codes

- `UNAUTHENTICATED`: Authentication required
- `FORBIDDEN`: Insufficient permissions
- `NOT_FOUND`: Resource not found
- `VALIDATION_ERROR`: Input validation failed
- `INTERNAL_ERROR`: Server error
- `QUOTA_EXCEEDED`: Tenant quota exceeded

## Rate Limiting

- **Default**: 100 requests per minute per user
- **Admin**: 1000 requests per minute
- **Service Accounts**: 5000 requests per minute

Rate limit headers:
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
```

## Pagination

List queries support pagination:

```graphql
query {
  resources(filter: {}, limit: 10, offset: 0) {
    id
    name
  }
}
```

## Subscriptions

Real-time updates via GraphQL subscriptions:

```graphql
subscription {
  resourceUpdated(resourceId: "resource-id") {
    id
    status
    metadata
  }
}
```

Available subscriptions:
- `resourceCreated`
- `resourceUpdated`
- `resourceDeleted`
- `billingAlertTriggered`
- `incidentDetected`

## Examples

### Complete Resource Lifecycle

```graphql
# 1. Create resource
mutation {
  createResource(input: {
    name: "web-server"
    type: VM
    siteId: "site-1"
    metadata: { cpu: 4, memory: "8Gi" }
  }) {
    id
    status
  }
}

# 2. Query resource
query {
  resource(id: "resource-id") {
    id
    name
    status
    site {
      name
      region
    }
  }
}

# 3. Update resource
mutation {
  updateResource(
    id: "resource-id"
    input: { metadata: { cpu: 8 } }
  ) {
    id
    metadata
  }
}

# 4. Delete resource
mutation {
  deleteResource(id: "resource-id")
}
```

### Billing Workflow

```graphql
# 1. Check usage
query {
  usage(
    tenantId: "tenant-id"
    timeRange: { start: "...", end: "..." }
    granularity: DAY
  ) {
    totalCost
    byResource {
      resourceId
      cost
    }
  }
}

# 2. Create budget
mutation {
  createBudget(
    tenantId: "tenant-id"
    budget: {
      name: "Monthly"
      amount: 1000
      period: MONTHLY
    }
  ) {
    id
  }
}

# 3. Create alert
mutation {
  createBillingAlert(
    tenantId: "tenant-id"
    alert: {
      name: "Budget Warning"
      alertType: BUDGET
      threshold: 0.8
    }
  ) {
    id
  }
}

# 4. Generate invoice
mutation {
  createInvoice(
    tenantId: "tenant-id"
    billingPeriodStart: "..."
    billingPeriodEnd: "..."
  ) {
    id
    invoiceNumber
    total
  }
}
```

## SDK Examples

### JavaScript/TypeScript

```typescript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'

const client = new ApolloClient({
  uri: 'https://api.sankofa.nexus/graphql',
  cache: new InMemoryCache(),
  headers: {
    Authorization: `Bearer ${token}`
  }
})

const GET_RESOURCES = gql`
  query {
    resources {
      id
      name
      type
    }
  }
`

const { data } = await client.query({ query: GET_RESOURCES })
```

### Python

```python
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport

transport = RequestsHTTPTransport(
    url="https://api.sankofa.nexus/graphql",
    headers={"Authorization": f"Bearer {token}"}
)

client = Client(transport=transport, fetch_schema_from_transport=True)

query = gql("""
    query {
        resources {
            id
            name
            type
        }
    }
""")

result = client.execute(query)
```

## References

- GraphQL Specification: https://graphql.org/learn/
- Apollo Server: https://www.apollographql.com/docs/apollo-server/
- Schema Definition: `api/src/schema/typeDefs.ts`

