Pular para o conteúdo

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.

NívelComandoDBQuando roda
Unitpnpm test, pnpm py:testNãoCI quality — sempre
Column auditpnpm schema:columnsNãoCI quality — sempre
Schema harnesspnpm schema:validateSim (Neon)CI schema + local
Integrationpnpm test:integrationSim (Neon + seed)CI schema após harness
Worker poolpnpm test:workersSim (DO + Neon opcional)Local + CI com DATABASE_URL

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).

IDÉpicoO que prova
inbound-echo-persistE2/E3Inbound → idempotency → messages → observability
outbound-send-idempotencyE10Claim CAS, provider trace, mark sent, retry reclaim
identity-resolve-inboundE4phone_number_id + wa_id → contact + conversation
burst-seal-doE5Burst debounce, seal, decision_pending
state-machine-runtimeE5Transições runtime_state (unit + integração inbound/DO)
llm-call-audit-writeE0/E11Persistência llm_calls (Python)
schema-harness-canonicalE1Seed + queries canônicas + invariants
dependency-graph-boundariesE0dependency-cruiser + import-linter
web-booking-loop-goldenE31Loop book→hold→checkout (unit/golden)
web-booking-observabilityE31Timeline + outcome signals no turn web
web-booking-httpE31/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.ts
  • apps/api-worker/src/identity/application/resolve-inbound-context.integration.test.ts
  • apps/api-worker/src/storage/conversation/message-bursts.repo.integration.test.ts
  • apps/api-worker/src/storage/actions/outbound-deliveries.repo.integration.test.ts
  • apps/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.

Scripts schema:* e test:integration carregam .env automaticamente (scripts/with-env.mjs).

Terminal window
pnpm schema:validate # migrate + seed + canonical + invariants
pnpm test:integration # TS + Python integration

Sem psql ou com TCP :5432 bloqueado (ex.: alguns proxies):

Terminal window
SCHEMA_DRIVER=neon pnpm schema:validate

Python integration: usa psycopg (TCP) e faz fallback HTTP se a conexão falhar. Forçar HTTP:

Terminal window
DATABASE_DRIVER=http pnpm py:test:integration

Pré-requisito: harness seed (schema/seed.sql) — schema:validate aplica automaticamente.

Só TS worker:

Terminal window
pnpm schema:migrate && pnpm schema:role # imprime DATABASE_URL_RLS — colar no .env
pnpm test:integration # owner role (default)
DATABASE_URL_RLS='...' pnpm --filter @voltron/api-worker test:integration:rls

Sem DATABASE_URL_RLS, integração usa o owner Neon (BYPASSRLS) — testes de row visibility A≠B são skipped com aviso.

Só Python:

Terminal window
DATABASE_URL='...' pnpm py:test:integration

Sem DATABASE_URL, testes *.integration.test.ts e @pytest.mark.integration skip — unitários continuam passando.

Todo table.column do DDL deve estar classificado:

StatusSignificado
usedEscrito/lido em runtime (storage/, observability/writer.py, …) — refs[] obrigatório
harnessschema/seed.sql / queries canônicas — justificativa + refs
systemid, created_at, updated_at — PK/timestamp
deferredAinda não usado — reason + epic obrigatórios em schema/column-usage.yml
Terminal window
pnpm schema:columns # regenera columns.registry.json + audita

Arquivos:

  • schema/columns.registry.json — gerado das migrations (não editar)
  • schema/column-usage.yml — defaults por tabela + overrides manuais
  • scripts/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.

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 deferredused em column-usage.yml conforme refs forem adicionados ao audit.

Job Schema harness (Neon) (requer secrets — senão falha):

  1. Branch efêmera (NEON_API_KEY + NEON_PROJECT_ID) ou DATABASE_URL (development)
  2. Harness níveis 1–3 (SCHEMA_DRIVER=neon no CI se psql/TCP falhar)
  3. 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)