Skip to content

Exemplos de Bundles OKF

Três bundles completos pra você copiar, adaptar e sair usando. Nada de “hello world” — são exemplos com cross-links, frontmatter real e estrutura de pastas que funciona em produção.

Opinião: bundle bom é bundle que alguém abre o index.md e entende o domínio em 30 segundos. Se precisa de manual pra navegar, a estrutura tá errada.


1. E-commerce Analytics

Bundle de um time de dados que documenta tabelas, métricas e dashboards de um e-commerce. Caso clássico: o analista novo chega e precisa saber onde fica o que.

Estrutura de pastas

ecommerce-analytics/
├── index.md
├── tables/
│   ├── index.md
│   ├── pedidos.md
│   └── clientes.md
├── metrics/
│   ├── index.md
│   └── receita-bruta.md
└── log.md

index.md

# E-commerce Analytics

Bundle de conhecimento do domínio analytics do e-commerce Acme.

# Tabelas

* [Pedidos](tables/pedidos.md) - uma linha por pedido finalizado
* [Clientes](tables/clientes.md) - cadastro de clientes com segmentação

# Métricas

* [Receita Bruta](metrics/receita-bruta.md) - GMV sem descontos e devoluções

tables/pedidos.md

---
type: BigQuery Table
title: Pedidos
description: Uma linha por pedido finalizado em qualquer canal (app, web, marketplace).
resource: https://console.cloud.google.com/bigquery?p=acme-prod&d=ecommerce&t=pedidos
tags: [vendas, core, receita]
timestamp: 2026-06-10T14:00:00Z
owner: time-dados
sla_freshness: 30min
---

Tabela principal de faturamento. Toda métrica de receita começa aqui.

# Schema

| Coluna | Tipo | Descrição |
|-----------------|-----------|--------------------------------------------------|
| `pedido_id` | STRING | UUID do pedido. PK. |
| `cliente_id` | STRING | FK → [clientes](/tables/clientes.md). |
| `total_brl` | NUMERIC | Valor total em BRL (com impostos, sem frete). |
| `status` | STRING | `paid`, `refunded`, `cancelled`. |
| `canal` | STRING | `app`, `web`, `marketplace`. |
| `criado_em` | TIMESTAMP | Quando o pedido foi submetido. |
| `atualizado_em` | TIMESTAMP | Última mudança de status. |

# Joins

- [clientes](/tables/clientes.md) via `cliente_id`
- Usado pela métrica [Receita Bruta](/metrics/receita-bruta.md)

# Notas

- Pedidos com `status = cancelled` **não entram** no cálculo de receita.
- Particionado por `criado_em` (DAY). Queries sem filtro de data = conta alta.

# Citations

[1] [Documentação do pipeline de ingestão](https://wiki.acme.internal/data/pipeline-pedidos)

tables/clientes.md

---
type: BigQuery Table
title: Clientes
description: Cadastro unificado de clientes com segmentação RFM e lifecycle.
resource: https://console.cloud.google.com/bigquery?p=acme-prod&d=ecommerce&t=clientes
tags: [clientes, segmentacao, core]
timestamp: 2026-06-08T10:00:00Z
owner: time-dados
---

Base canônica de clientes. Toda análise de cohort ou segmentação parte daqui.

# Schema

| Coluna | Tipo | Descrição |
|-------------------|-----------|---------------------------------------------|
| `cliente_id` | STRING | UUID. PK. |
| `email` | STRING | Email principal (PII — acesso restrito). |
| `segmento_rfm` | STRING | `champions`, `at_risk`, `hibernating`, etc. |
| `primeiro_pedido` | TIMESTAMP | Data do primeiro pedido. |
| `ltv_brl` | NUMERIC | Lifetime value acumulado. |
| `criado_em` | TIMESTAMP | Data de cadastro. |

# Joins

- [pedidos](/tables/pedidos.md) via `cliente_id`

# Notas

- Atualizado diariamente pelo job de segmentação RFM (6h UTC).
- `email` requer role `pii-reader` — não exponha em dashboards públicos.

metrics/receita-bruta.md

---
type: Metric
title: Receita Bruta (GMV)
description: Soma de total_brl de pedidos pagos, sem descontar devoluções.
tags: [receita, kpi, finance]
timestamp: 2026-06-10T14:00:00Z
owner: time-finance
granularity: daily
---

KPI primário do negócio. Reportado no board mensal.

# Definição

```sql
SELECT
  DATE(criado_em) AS dia,
  SUM(total_brl) AS receita_bruta
FROM `acme-prod.ecommerce.pedidos`
WHERE status = 'paid'
GROUP BY 1

Fonte de dados

Calculada a partir da tabela pedidos, filtrando status = 'paid'.

Cuidados

  • Não inclui pedidos refunded ou cancelled.
  • Não desconta devoluções parciais (ver métrica receita-liquida quando existir).
  • Frete não está incluído no total_brl.

Citations

[1] Definição aprovada pelo CFO — Confluence


---

## 2. SaaS Incident Playbooks

Bundle de um time de SRE/platform que documenta runbooks, alertas e processo de escalation. O cenário: são 3h da manhã, o PagerDuty tocou, e o engenheiro de plantão precisa saber o que fazer sem acordar ninguém (ainda).

### Estrutura de pastas

incident-playbooks/ ├── index.md ├── alerts/ │ ├── index.md │ ├── api-latency-p99.md │ └── db-connections-exhausted.md ├── runbooks/ │ ├── index.md │ └── escalar-incidente.md └── log.md


### `index.md`

```markdown
# Incident Playbooks

Conhecimento operacional do time Platform. Se o pager tocou, comece aqui.

# Alertas

* [API Latency P99](alerts/api-latency-p99.md) - latência acima do SLO no gateway
* [DB Connections Exhausted](alerts/db-connections-exhausted.md) - pool de conexões esgotado

# Runbooks

* [Escalar Incidente](runbooks/escalar-incidente.md) - quando e como escalar pra liderança

alerts/api-latency-p99.md

---
type: Alert
title: API Latency P99 > 2s
description: Dispara quando a latência P99 do API Gateway ultrapassa 2 segundos por 5 minutos.
tags: [oncall, api, latencia, sev2]
timestamp: 2026-05-20T09:00:00Z
owner: time-platform
severity: SEV2
slo: 99.5% requests < 2s
---

# Trigger

Prometheus alert rule:

```yaml
- alert: APILatencyP99High
  expr: histogram_quantile(0.99, rate(http_duration_seconds_bucket[5m])) > 2
  for: 5m
  labels:
    severity: sev2

Diagnóstico

  1. Abra o Grafana — API Latency Dashboard.
  2. Verifique se é um endpoint específico ou generalizado.
  3. Cheque o pool de conexões — se esgotado, veja DB Connections Exhausted.
  4. Verifique deploys recentes: kubectl rollout history deploy/api-gateway -n production.

Mitigação

  • Se um endpoint específico: habilite circuit breaker via feature flag cb_{endpoint}.
  • Se generalizado: escale pods kubectl scale deploy/api-gateway --replicas=10 -n production.
  • Se persistir > 15min: siga Escalar Incidente.

Falsos positivos conhecidos

  • Batch de reconciliação financeira (todo dia 2h UTC) causa spike de 3-4min. Ignore se resolver sozinho.

Citations

[1] SLO definition — internal wiki


### `alerts/db-connections-exhausted.md`

```markdown
---
type: Alert
title: DB Connections Exhausted
description: Pool de conexões PostgreSQL atingiu 95% da capacidade.
tags: [oncall, database, postgres, sev1]
timestamp: 2026-06-01T11:00:00Z
owner: time-platform
severity: SEV1
---

# Trigger

```yaml
- alert: DBConnectionPoolExhausted
  expr: pg_stat_activity_count / pg_settings_max_connections > 0.95
  for: 2m
  labels:
    severity: sev1

Diagnóstico

  1. Identifique queries longas: SELECT pid, now() - pg_stat_activity.query_start AS duration, query FROM pg_stat_activity WHERE state != 'idle' ORDER BY duration DESC;
  2. Verifique se há leak de conexão (app não fechando connections).
  3. Cheque se API Latency P99 também disparou (efeito cascata comum).

Mitigação imediata

  1. Mate queries > 5min: SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE duration > interval '5 minutes';
  2. Se não resolver: restart do PgBouncer systemctl restart pgbouncer.
  3. Não faça restart do Postgres sem escalar antes — veja Escalar Incidente.

Root causes comuns

  • Deploy com migration pesada sem statement_timeout.
  • Cronjob de relatório sem connection pooling.
  • N+1 query em endpoint novo.

### `runbooks/escalar-incidente.md`

```markdown
---
type: Runbook
title: Escalar Incidente
description: Processo de escalation — quando sair do diagnóstico solo e acionar reforços.
tags: [oncall, processo, escalation]
timestamp: 2026-05-15T08:00:00Z
owner: time-platform
---

# Quando escalar

Escale **imediatamente** se:

- SEV1 sem mitigação após 10 minutos.
- SEV2 sem mitigação após 30 minutos.
- Qualquer incidente com impacto financeiro visível (pedidos falhando).
- Você não entende o que está acontecendo (isso é válido, não é vergonha).

# Como escalar

| Passo | Ação | Contato |
|-------|------|---------|
| 1 | Declare incidente no Slack `#incidents` | `@oncall-platform` |
| 2 | Acione engineering manager | PagerDuty escalation policy `platform-em` |
| 3 | Se impacto em clientes > 5min | Acione `@oncall-cs` para comunicação |
| 4 | Se revenue impactada | Acione `@oncall-finance` |

# Template de declaração

🚨 INCIDENTE DECLARADO Severidade: SEV{1|2} Alerta: {link para o alerta que disparou} Impacto: {o que o usuário está vendo} Status: Investigando / Mitigando / Resolvido IC: @{seu-nome}


# Pós-incidente

- Postmortem obrigatório para SEV1, opcional para SEV2.
- Prazo: 48h após resolução.
- Template: [Confluence — Postmortem Template](https://wiki.acme.internal/templates/postmortem).

# Links relacionados

- [API Latency P99](/alerts/api-latency-p99.md) — alerta mais comum que gera escalation.
- [DB Connections Exhausted](/alerts/db-connections-exhausted.md) — segundo mais comum.

3. API Documentation

Bundle pra documentar uma API REST. Diferente do OpenAPI (que é spec de contrato), aqui o foco é conhecimento contextual: por que o endpoint existe, cuidados de uso, rate limits, exemplos que de fato funcionam.

Estrutura de pastas

api-docs/
├── index.md
├── auth/
│   ├── index.md
│   └── oauth2-flow.md
├── endpoints/
│   ├── index.md
│   ├── criar-pedido.md
│   └── listar-clientes.md
├── policies/
│   ├── index.md
│   └── rate-limits.md
└── log.md

index.md

# API Docs — Acme Commerce API

Documentação contextual da API pública v2. Para a spec OpenAPI crua, veja o [Swagger UI](https://api.acme.com/docs).

# Autenticação

* [OAuth2 Flow](auth/oauth2-flow.md) - como obter e renovar tokens

# Endpoints

* [Criar Pedido](endpoints/criar-pedido.md) - POST /v2/orders
* [Listar Clientes](endpoints/listar-clientes.md) - GET /v2/customers

# Políticas

* [Rate Limits](policies/rate-limits.md) - limites por plano e headers de controle

auth/oauth2-flow.md

---
type: Auth Flow
title: OAuth2 Client Credentials
description: Fluxo de autenticação machine-to-machine para a API Acme.
resource: https://api.acme.com/oauth/token
tags: [auth, oauth2, seguranca]
timestamp: 2026-06-05T16:00:00Z
owner: time-api
---

# Fluxo

```bash
curl -X POST https://api.acme.com/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET \
  -d scope="orders:write customers:read"

Resposta:

{
  "access_token": "eyJhbGci...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "orders:write customers:read"
}

Uso

Envie o token no header de todos os requests:

Authorization: Bearer {access_token}

Scopes disponíveis

ScopePermite
orders:readConsultar pedidos
orders:writeCriar e atualizar pedidos
customers:readListar e buscar clientes
customers:writeCriar e atualizar clientes

Cuidados

  • Token expira em 1 hora. Implemente refresh antes da expiração.
  • Rate limit do endpoint /oauth/token: 10 req/min por client_id — não peça token novo a cada request.
  • Respeite os rate limits gerais após autenticado.

Citations

[1] RFC 6749 — OAuth 2.0 Client Credentials


### `endpoints/criar-pedido.md`

```markdown
---
type: API Endpoint
title: Criar Pedido
description: Cria um novo pedido no sistema. Requer scope orders:write.
resource: https://api.acme.com/v2/orders
tags: [orders, write, core]
timestamp: 2026-06-10T10:00:00Z
owner: time-api
method: POST
path: /v2/orders
auth_scope: orders:write
---

# Request

```bash
curl -X POST https://api.acme.com/v2/orders \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_abc123",
    "items": [
      {"sku": "WIDGET-01", "quantity": 2, "unit_price_brl": 49.90}
    ],
    "shipping_address_id": "addr_xyz789"
  }'

Response (201 Created)

{
  "order_id": "ord_def456",
  "status": "pending_payment",
  "total_brl": 99.80,
  "created_at": "2026-06-10T10:30:00Z"
}

Erros comuns

StatusCódigoCausaFix
400invalid_skuSKU não existe no catálogoValide antes via GET /v2/products
401token_expiredToken expiradoRenove via OAuth2 flow
429rate_limitedExcedeu rate limitVeja Rate Limits
422insufficient_stockSem estoqueReduza quantidade ou aguarde reposição

Idempotência

Envie Idempotency-Key: {uuid} no header para garantir que retries não dupliquem pedidos.

Notas

  • O total_brl é calculado server-side. Não confie no valor que você calcula client-side.
  • Pedidos ficam pending_payment por 30min. Após isso, cancelamento automático.
  • Este endpoint alimenta a tabela documentada em contexto de dados — não é OKF linkável diretamente, mas é a mesma entidade.

### `policies/rate-limits.md`

```markdown
---
type: Policy
title: Rate Limits
description: Limites de requisição por plano, headers de controle e comportamento em throttle.
tags: [api, rate-limit, policy, infra]
timestamp: 2026-06-01T09:00:00Z
owner: time-api
---

# Limites por plano

| Plano | Requests/min | Requests/dia | Burst |
|------------|--------------|--------------|-------|
| Free | 60 | 10.000 | 10 |
| Pro | 600 | 100.000 | 50 |
| Enterprise | 6.000 | 1.000.000 | 200 |

# Headers de resposta

Toda response inclui:

X-RateLimit-Limit: 600 X-RateLimit-Remaining: 584 X-RateLimit-Reset: 1718020800


- `X-RateLimit-Reset` é Unix timestamp de quando o bucket reseta.

# Comportamento quando throttled

Response `429 Too Many Requests`:

```json
{
  "error": "rate_limited",
  "message": "Rate limit exceeded. Retry after 12 seconds.",
  "retry_after": 12
}

Implemente exponential backoff. Não fique em loop martelando a API — clientes que fazem isso são bloqueados por 24h.

Endpoints com limites especiais

EndpointLimiteMotivo
POST /oauth/token10/minPrevenir brute force
POST /v2/orders30/minPrevenir spam de pedidos
GET /v2/reports/*5/minQueries pesadas

Boas práticas

  1. Cache agressivo em GETs que não mudam frequentemente (clientes, produtos).
  2. Batch quando possívelPOST /v2/orders/batch aceita até 50 pedidos por request.
  3. Monitore o header X-RateLimit-Remaining e diminua throughput antes de bater no limite.
  4. Precisa de mais? Fale com vendas ou veja o plano Enterprise.

Links

  • OAuth2 Flow — rate limit específico do endpoint de token.
  • Criar Pedido — endpoint com limite especial de 30/min.

Citations

[1] IETF RFC 6585 — 429 Too Many Requests [2] API Design Guidelines — interno


---

## Padrões que você vai notar nos 3 exemplos

1. **`type` é semântico pro domínio.** Não tem lista fixa. Use `BigQuery Table`, `Alert`, `Runbook`, `API Endpoint`, `Policy`, `Metric` — o que fizer sentido pro seu time.

2. **Cross-links são generosos.** Se um conceito referencia outro, linka. É barato e torna o bundle navegável como wiki.

3. **`index.md` é mapa, não lixeira.** Uma frase por item, link direto, sem enrolação.

4. **Campos extras no frontmatter? Pode meter.** A spec aceita qualquer chave adicional. `owner`, `severity`, `sla_freshness`, `method`, `auth_scope` — bota o que o consumidor (humano ou agente) precisa pra filtrar e rotear.

5. **`# Citations` no final.** Links externos que validam o conteúdo. Agentes usam pra checar claims.

6. **Body estruturado.** Headings, tabelas, code blocks. Quanto mais structure, melhor a retrieval por agentes. Textão de prosa corrida = ruído.