Integration testing
Status: canônico · Escopo: Testes de integração, auditoria de colunas, matriz de paths · Atualizado em: 2026-06-14
Além da pirâmide unitária (
coding-standards.md§8). Objetivo: provar caminhos reais (repos + Neon + filas/DO onde couber) e rastrear uso de colunas do schema.
Pirâmide (atual)
Seção intitulada “Pirâmide (atual)”| Nível | Comando | DB | Quando roda |
|---|---|---|---|
| Unit | pnpm test, pnpm py:test | Não | CI quality — sempre |
| Column audit | pnpm schema:columns | Não | CI quality — sempre |
| Schema harness | pnpm schema:validate | Sim (Neon) | CI schema + local |
| Integration | pnpm test:integration | Sim (Neon + seed) | CI schema após harness |
| Worker pool | pnpm test:workers | Sim (DO + Neon opcional) | Local + CI com DATABASE_URL |
Caminhos de integração
Seção intitulada “Caminhos de integração”Matriz versionada: schema/integration-paths.yml.
Cada path lista:
- tabelas tocadas
- testes TS / Python / SQL
- épico (
E2,E5, …)
Paths planned entram na matriz antes da implementação — quando o épico fechar, o path vira obrigatório no CI (pnpm integration:paths).
Matriz atual (integration-paths.yml)
Seção intitulada “Matriz atual (integration-paths.yml)”| ID | Épico | O que prova |
|---|---|---|
inbound-echo-persist | E2/E3 | Inbound → idempotency → messages → observability |
outbound-send-idempotency | E10 | Claim CAS, provider trace, mark sent, retry reclaim |
identity-resolve-inbound | E4 | phone_number_id + wa_id → contact + conversation |
burst-seal-do | E5 | Burst debounce, seal, decision_pending |
state-machine-runtime | E5 | Transições runtime_state (unit + integração inbound/DO) |
llm-call-audit-write | E0/E11 | Persistência llm_calls (Python) |
schema-harness-canonical | E1 | Seed + queries canônicas + invariants |
dependency-graph-boundaries | E0 | dependency-cruiser + import-linter |
web-booking-loop-golden | E31 | Loop book→hold→checkout (unit/golden) |
web-booking-observability | E31 | Timeline + outcome signals no turn web |
web-booking-http | E31/E32 | /book/:slug config + chat com Neon (mock LLM) |
Integração TS worker (requer DATABASE_URL + seed):
apps/api-worker/src/conversation/application/process-inbound.integration.test.tsapps/api-worker/src/identity/application/resolve-inbound-context.integration.test.tsapps/api-worker/src/storage/conversation/message-bursts.repo.integration.test.tsapps/api-worker/src/storage/actions/outbound-deliveries.repo.integration.test.tsapps/api-worker/src/api/handlers/demo-chat.integration.test.ts
Web booking — pirâmide completa (unit → integration → smoke → Playwright futuro): web-booking-test-plan.md.
Rodar local (branch development)
Seção intitulada “Rodar local (branch development)”Scripts schema:* e test:integration carregam .env automaticamente (scripts/with-env.mjs).
pnpm schema:validate # migrate + seed + canonical + invariantspnpm test:integration # TS + Python integrationSem psql ou com TCP :5432 bloqueado (ex.: alguns proxies):
SCHEMA_DRIVER=neon pnpm schema:validatePython integration: usa psycopg (TCP) e faz fallback HTTP se a conexão falhar. Forçar HTTP:
DATABASE_DRIVER=http pnpm py:test:integrationPré-requisito: harness seed (schema/seed.sql) — schema:validate aplica automaticamente.
Só TS worker:
pnpm schema:migrate && pnpm schema:role # imprime DATABASE_URL_RLS — colar no .envpnpm test:integration # owner role (default)DATABASE_URL_RLS='...' pnpm --filter @voltron/api-worker test:integration:rlsSem DATABASE_URL_RLS, integração usa o owner Neon (BYPASSRLS) — testes de row visibility A≠B são skipped com aviso.
Só Python:
DATABASE_URL='...' pnpm py:test:integrationSem DATABASE_URL, testes *.integration.test.ts e @pytest.mark.integration skip — unitários continuam passando.
Auditoria de colunas (360 campos)
Seção intitulada “Auditoria de colunas (360 campos)”Todo table.column do DDL deve estar classificado:
| Status | Significado |
|---|---|
| used | Escrito/lido em runtime (storage/, observability/writer.py, …) — refs[] obrigatório |
| harness | Só schema/seed.sql / queries canônicas — justificativa + refs |
| system | id, created_at, updated_at — PK/timestamp |
| deferred | Ainda não usado — reason + epic obrigatórios em schema/column-usage.yml |
pnpm schema:columns # regenera columns.registry.json + auditaArquivos:
schema/columns.registry.json— gerado das migrations (não editar)schema/column-usage.yml— defaults por tabela + overrides manuaisscripts/schema-column-audit.mjs— gate CI
Ao adicionar coluna na migration: rodar pnpm schema:columns e atualizar column-usage.yml ou refs em código.
Runtime / pacing (E5 — parcial)
Seção intitulada “Runtime / pacing (E5 — parcial)”conversations.runtime_state e pacing_state estão wired no worker (transições em conversation/domain/, callers em application/DO). Path state-machine-runtime cobre unit + integração inbound.
Pendências E5.T7: transições reengage/template/human_active no runtime, mais integração ponta a ponta no DO alarm.
Colunas: reclassificar de deferred → used em column-usage.yml conforme refs forem adicionados ao audit.
Job Schema harness (Neon) (requer secrets — senão falha):
- Branch efêmera (
NEON_API_KEY+NEON_PROJECT_ID) ouDATABASE_URL(development) - Harness níveis 1–3 (
SCHEMA_DRIVER=neonno CI sepsql/TCP falhar) pnpm test:integration
Configure em GitHub → Settings → Secrets → Actions: NEON_API_KEY, NEON_PROJECT_ID (preferido) ou DATABASE_URL.
Job Quality gate:
- Unit +
pnpm schema:columns(sem DB)