> ## Documentation Index
> Fetch the complete documentation index at: https://lifters.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tipos de Condição de Alerta

> Detalhes técnicos de no_data, byte_threshold, rate_drop e lag_high com exemplos de uso.

# Tipos de Condição

A v1 suporta 4 tipos de condição. Cada um avalia um aspecto diferente da ingestão.

## `no_data` — Ausência de dados

Match se `now - last_ingest_at > threshold_seconds` para o escopo da regra.

**Quando usar:** detectar integração quebrada, fonte parou de enviar, ClickPipes pausado.

**Campos:**

| Campo               | Tipo    | Obrigatório |
| ------------------- | ------- | ----------- |
| `threshold_seconds` | int > 0 | Sim         |

**Exemplo:**

```json theme={null}
{
  "name": "Bet placed parou",
  "domain": "sportsbook",
  "event": "bet_placed",
  "condition_type": "no_data",
  "threshold_seconds": 300,
  "severity": "critical"
}
```

**Caso especial:** se o heartbeat para a chave **não existe** (a fonte nunca enviou dados), a regra dispara — assume integração broken.

## `lag_high` — Atraso entre evento e ingestão

Match se `last_ingest_at - last_event_at > threshold_seconds`.

**Quando usar:** detectar Kafka backlog, ClickPipes lento, DLQ acumulando.

**Diferença de `no_data`:** o evento *está chegando*, mas com atraso (timestamp do evento muito mais antigo que ingest).

**Exemplo:**

```json theme={null}
{
  "name": "Lag de ingestão > 2min",
  "domain": "transaction",
  "condition_type": "lag_high",
  "threshold_seconds": 120,
  "severity": "warning"
}
```

## `byte_threshold` — Volume acima de limite

Match se `sum(bytes_uncompressed)` na janela > `threshold_bytes`.

**Quando usar:** alerta de quota de plano, detecção de spike anômalo (ex: 10× volume normal indica bug no operador).

**Campos:**

| Campo             | Tipo  | Default     |
| ----------------- | ----- | ----------- |
| `threshold_bytes` | int64 | obrigatório |
| `window_seconds`  | int   | 300         |

**Exemplo:**

```json theme={null}
{
  "name": "Spike de bytes > 100MB/min",
  "condition_type": "byte_threshold",
  "threshold_bytes": 104857600,
  "window_seconds": 60,
  "severity": "warning"
}
```

## `rate_drop` — Queda vs baseline

Compara `rows_count` na janela atual com a média de janelas equivalentes nos últimos `baseline_window_days` dias.

Match se `(1 - current/baseline) * 100 >= threshold_percent`.

**Quando usar:** detectar degradação parcial sem que a fonte fique 100% silenciosa (`no_data` não pegaria).

**Campos:**

| Campo                  | Tipo          | Default     |
| ---------------------- | ------------- | ----------- |
| `threshold_percent`    | float (0-100) | obrigatório |
| `window_seconds`       | int           | 300         |
| `baseline_window_days` | int           | 7           |

**Exemplo:**

```json theme={null}
{
  "name": "Queda > 50% vs baseline 7d",
  "domain": "sportsbook",
  "condition_type": "rate_drop",
  "threshold_percent": 50,
  "window_seconds": 600,
  "baseline_window_days": 7,
  "severity": "warning"
}
```

**Caso especial:** se a fonte é nova (sem baseline >= 1 dia de histórico), a regra **não dispara** (`metric_payload.note = "insufficient_baseline"`).

## Comparação

| Detecta            | `no_data` | `lag_high` | `byte_threshold` | `rate_drop`          |
| ------------------ | --------- | ---------- | ---------------- | -------------------- |
| Fonte 100% parada  | ✓         | ✗          | ✗                | ✓ (após queda total) |
| Lag de pipeline    | ✗         | ✓          | ✗                | ✗                    |
| Spike anômalo      | ✗         | ✗          | ✓                | ✗                    |
| Degradação parcial | ✗         | ✗          | ✗                | ✓                    |
| Quota / cobrança   | ✗         | ✗          | ✓                | ✗                    |

**Recomendação:** combine **`no_data`** (5 min) + **`rate_drop`** (50% queda em 10 min) para cobrir tanto silêncio total quanto degradação.

## Avaliação

Tudo roda no `alert_runner`, worker em goroutine no backend (Go). Tick de 30s:

1. Lista regras enabled (1 query PG)
2. Avalia em batch via `AlertEvaluator` (1 query CH por strategy)
3. Para cada match em estado `ok|resolved` + cooldown ok: cria `alert_event`, dispara canais, marca `firing`
4. Para cada não-match em estado `firing`: cria `alert_event`, dispara resolve, marca `resolved`

Falhas de despacho (Slack down, etc) são gravadas em `alert_events.delivery_status` mas **não bloqueiam** outros canais nem a transição de estado.
