# Referencia de la API

Base URL: `http://localhost:8000/api/v1`

Documentación interactiva (Swagger): `http://localhost:8000/docs`

---

## Autenticación

La API usa un flujo de dos pasos:

1. Intercambiar **API Key** → **JWT** (válido 15 minutos)
2. Usar **JWT** en el header `Authorization: Bearer <token>`

---

## Endpoints

### `GET /health` — Público

Verifica el estado del servicio.

**Response:**
```json
{
  "status": "ok",
  "version": "1.0.0",
  "db": "ok",
  "uptime_s": 142
}
```

---

### `POST /auth/token` — Obtener JWT

**Rate limit:** 10 req/min por cliente

**Request:**
```json
{
  "api_key": "sk_live_..."
}
```

**Response:**
```json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 900,
  "client_id": "uuid-del-cliente"
}
```

**Errores:**
| Código | Motivo |
|---|---|
| 401 | API Key inválida o cliente inactivo |
| 429 | Rate limit excedido |

---

### `POST /convert` — Convertir MT940 a camt.053

**Rate limit:** 100 req/min por cliente

**Headers requeridos:**
```
Authorization: Bearer <jwt_token>
Content-Type: application/json
```

**Request body:**
```json
{
  "message": ":20:STMT001\n:25:ES91...\n...",
  "format": "MT940",
  "options": {
    "include_metadata": false,
    "validate_output": true
  }
}
```

| Campo | Tipo | Descripción |
|---|---|---|
| `message` | string | Mensaje MT940/MT950 completo |
| `format` | "MT940" \| "MT950" | Tipo de mensaje |
| `options.include_metadata` | bool | Incluir metadatos extra (default: false) |
| `options.validate_output` | bool | Validar XML contra XSD (default: true) |

**Response exitosa (200):**
- Content-Type: `application/xml`
- Body: XML camt.053.001.02
- Headers de respuesta:
  - `X-Request-ID`: UUID de la solicitud
  - `X-Client-ID`: UUID del cliente autenticado
  - `X-Conversion-Time-Ms`: duración en milisegundos

**Errores:**
| Código | Motivo |
|---|---|
| 401 | JWT expirado o inválido |
| 422 | Mensaje MT940 malformado o XSD inválido |
| 429 | Rate limit excedido |
| 500 | Error interno del servidor |

---

### `POST /admin/clients` — Crear cliente

**Header:** `X-Admin-Secret: <admin_secret>`

**Request:**
```json
{
  "name": "Mi Empresa SA",
  "email": "admin@empresa.com",
  "rate_limit_per_min": 200,
  "scopes": ["convert"]
}
```

**Response (200)** — devuelve `api_key` solo esta vez:
```json
{
  "id": "uuid",
  "name": "Mi Empresa SA",
  "email": "admin@empresa.com",
  "rate_limit_per_min": 200,
  "scopes": "[\"convert\"]",
  "active": true,
  "created_at": "2024-01-15T10:00:00",
  "api_key": "sk_live_abc123..."
}
```

> ⚠️ El `api_key` solo se muestra una vez. Guárdalo de forma segura.

---

### `GET /admin/clients` — Listar clientes

**Header:** `X-Admin-Secret: <admin_secret>`

Devuelve lista de clientes activos (sin `api_key_hash`).

---

### `GET /admin/clients/{client_id}/logs` — Audit Log

**Header:** `X-Admin-Secret: <admin_secret>`

**Query params:**
- `page` (default: 1)
- `limit` (default: 50)

**Response:**
```json
[
  {
    "id": "uuid",
    "request_id": "uuid",
    "client_id": "uuid",
    "timestamp": "2024-01-15T10:05:00",
    "format_in": "MT940",
    "status": "success",
    "error_detail": null,
    "duration_ms": 47,
    "ip_address": "192.168.1.1"
  }
]
```

---

### `DELETE /admin/clients/{client_id}` — Eliminar cliente (soft)

**Header:** `X-Admin-Secret: <admin_secret>`

Marca el cliente como inactivo (`active=False`, `deleted_at=now`). No elimina registros de BD.

**Response:** 204 No Content
