# API de Status

A Délfica expõe uma família de endpoints de **status público** (sem
autenticação) para que integradores e ferramentas de monitoramento
possam verificar a saúde da API e da SEFAZ sem precisar de uma conta
de serviço.

Para a página visual de status (cards de latência, status e timestamp),
acesse [`/status-api`](../api/pages/api_status.py) no portal ou no link
em `$HOST/status-api`.

## Endpoints

| Método | Rota | Auth | Uso |
|---|---|---|---|
| `GET` | `/api/v1/healthz` | não | Verificação geral (200 se OK). |
| `GET` | `/api/v1/liveness` | não | Liveness probe (Kubernetes). |
| `GET` | `/api/v1/readiness` | não | Readiness probe (PG + Odoo + Pool). |
| `GET` | `/api/v1/public/sefaz-status` | não | Snapshot atual de todas as UFs. |
| `GET` | `/api/v1/public/sefaz-history` | não | Histórico de transições (30 dias). |

## `GET /api/v1/healthz`

Verifica que a API está respondendo. Retorna 200 com JSON mínimo
quando OK. Pode retornar 503 durante inicialização.

```bash
curl -i https://api.delfica.com.br/api/v1/healthz
```

```json
{"status": "ok"}
```

## `GET /api/v1/liveness`

Sempre 200 se o processo Python respondeu. Use em
`livenessProbe` do Kubernetes:

```yaml
livenessProbe:
  httpGet:
    path: /api/v1/liveness
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 30
```

## `GET /api/v1/readiness`

200 se Postgres + Odoo + Pool estão OK; 503 caso contrário. Use em
`readinessProbe` para tirar o pod do balanceador enquanto Odoo reinicia.

```bash
curl -i https://api.delfica.com.br/api/v1/readiness
```

```json
{
  "ready": true,
  "components": {
    "pg": "ok",
    "odoo": "ok",
    "pool": "ok"
  }
}
```

## `GET /api/v1/public/sefaz-status`

Snapshot em tempo real do status da SEFAZ em cada UF. Útil para
**evitar emitir quando a UF está fora** (rejeição 108 — "UF
indisponível").

```bash
curl https://api.delfica.com.br/api/v1/public/sefaz-status
```

```json
{
  "captured_at": "2026-06-14T18:23:11Z",
  "ufs": {
    "SP": {"status": "verde", "since": "2026-06-14T08:00:00Z"},
    "RJ": {"status": "amarelo", "since": "2026-06-14T17:00:00Z"},
    "MG": {"status": "verde", "since": "2026-06-13T22:00:00Z"}
  }
}
```

Possíveis valores de `status`: `verde` (operação normal), `amarelo`
(incidente parcial, contingência FS-DA pode ser necessária), `vermelho`
(UF completamente fora).

## `GET /api/v1/public/sefaz-history`

Histórico das últimas 30 transições em todas as UFs. Use para BI ou
para correlacionar incidentes com rejeições.

```bash
curl "https://api.delfica.com.br/api/v1/public/sefaz-history?uf=SP&days=7"
```

## Implementando retry com backoff

Quando o backend retorna `429`, o cabeçalho `Retry-After` indica quantos
segundos aguardar. Para `502/503` (backend indisponível), implemente
**exponential backoff com jitter**:

```python
import random
import time
import httpx


def get_with_retry(url: str, max_attempts: int = 5) -> dict:
    """GET com backoff exponencial para 502/503 e Retry-After para 429."""
    for attempt in range(max_attempts):
        try:
            r = httpx.get(url, timeout=10)
        except httpx.HTTPError as exc:
            # Erro de rede: tenta de novo
            if attempt == max_attempts - 1:
                raise
            time.sleep(2 ** attempt + random.uniform(0, 1))
            continue

        if r.status_code == 429:
            # Rate limit: respeita Retry-After
            wait = int(r.headers.get("Retry-After", "5"))
            time.sleep(wait)
            continue
        if r.status_code in (502, 503):
            # Backend fora: backoff exponencial + jitter
            if attempt == max_attempts - 1:
                r.raise_for_status()
            time.sleep(2 ** attempt + random.uniform(0, 1))
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError(f"Falhou após {max_attempts} tentativas")
```

## Página visual `/status-api`

A página `/status-api` no portal consome os endpoints acima via fetch
client-side a cada 30s e renderiza cards com:

- Latência por endpoint
- Status atual (`ok`, `degraded`, `down`)
- Timestamp da última consulta
- Histórico SEFAZ por UF

Use-a em janelas de monitoramento ou compartilhe o link com clientes
para autoatendimento durante incidentes.
