# Como Medir KPIs

Tudo que skill mede + onde busca + como interpreta.

## KPIs basicos (calculados pelo runtime)

### Completion rate
```sql
SELECT
  CAST(SUM(status='completed') AS REAL) / COUNT(*) * 100 as completion_rate
FROM sessions
WHERE started_at >= date('now', '-30 days');
```

### Tempo medio sessao
```sql
SELECT AVG(
  julianday(completed_at) - julianday(started_at)
) * 86400 as avg_seconds
FROM sessions
WHERE status = 'completed' AND started_at >= date('now', '-30 days');
```

### Drop-off por bloco
```sql
SELECT
  block_id,
  SUM(CASE WHEN type='block_viewed' THEN 1 ELSE 0 END) as views,
  SUM(CASE WHEN type='block_answered' THEN 1 ELSE 0 END) as answers,
  ROUND(
    (1.0 - CAST(SUM(CASE WHEN type='block_answered' THEN 1.0 ELSE 0 END)
     / NULLIF(SUM(CASE WHEN type='block_viewed' THEN 1.0 ELSE 0 END), 0))) * 100, 1
  ) as drop_off_pct
FROM events
WHERE block_id IS NOT NULL
GROUP BY block_id
ORDER BY drop_off_pct DESC;
```

### AI block — turns medio
```sql
SELECT
  block_id,
  AVG(turns) as avg_turns
FROM (
  SELECT
    block_id, session_id,
    COUNT(*) as turns
  FROM messages
  WHERE role = 'user' AND block_id IN (SELECT id FROM ai_blocks_view)
  GROUP BY block_id, session_id
)
GROUP BY block_id;
```

### Conversao por caminho
```sql
SELECT
  utm_content,
  COUNT(*) as sessoes,
  ROUND(CAST(COUNT(*) AS REAL) /
    (SELECT COUNT(*) FROM sessions WHERE status='completed') * 100, 1) as pct
FROM sessions
WHERE status='completed' AND utm_content IS NOT NULL
GROUP BY utm_content;
```

## KPIs externos (mentorada coleta)

### Show rate em call
Comparacao manual:
- N agendamentos no Calendly em janela X
- N pessoas que apareceram

Skill nao mede automatic. Mentorada cola numero em `06-kpis-tracking.md`.

### Fechamento na call
Manual. Mentorada registra apos cada call.

### Show rate em visita / avaliacao
Manual.

### MRR (SaaS) / AOV (e-com)
Vem do sistema de pagamento (Stripe, Eduzz, Hotmart).

## Endpoints da API

Bot expoe via `routes/analytics.ts`:

```
GET /api/analytics/summary
  → { total_sessions, completed_sessions, sessions_today, completion_rate }

GET /api/analytics/funnel
  → array<{ block_id, views, answers, drop_off_rate }>

GET /api/analytics/sessions?limit=50
  → ultimas N sessoes

GET /api/analytics/conversion-by-path
  → conversao por utm_content
```

## Dashboard externo (opcional)

### Looker Studio
Conector SQLite via Google Sheets — skill exporta planilha modelo.

### Metabase / Grafana
Conexao direta ao SQLite via plugin.

## Frequencia de medicao

| Frequencia | KPIs |
|---|---|
| Tempo real | sessoes ativas (count) |
| Diario | completion rate, drop-off, calls do dia |
| Semanal | A/B test, AI block performance |
| Mensal | otimizacao-mensal completa |
| Trimestral | calibragem profunda |

## Alertas (opcional)

Configurar via cron + email/Slack:

```bash
# 7 dias com 0 sessoes = bot caiu
* */1 * * * /usr/bin/node check-bot.js {BOT_SLUG}
```

```js
// check-bot.js
const sessions = await db.prepare(
  "SELECT COUNT(*) as c FROM sessions WHERE started_at >= datetime('now', '-7 days')"
).get();
if (sessions.c === 0) sendAlert("Bot {BOT_SLUG} sem sessoes ha 7 dias");
```

## Privacidade

Banco local SQLite — dados nao saem da VPS da mentorada.
LGPD: variaveis com email/telefone tem retencao de 24 meses default.

Pra apagar dados de visitante:
```sql
DELETE FROM sessions WHERE id = '{session_id}';
-- CASCADE remove session_vars + messages + events
```
