Source of truth (fonte única de verdade) para os contratos do ecossistema OpenAudit Brasil.
Este repositório define, valida e versiona:
- OpenAPI dos serviços (ex.:
openaudit-search-api) - JSON Schemas (mensagens, artefatos, auditoria)
- Contratos de observabilidade (logs estruturados e convenções de telemetria)
- Exemplos canônicos validados por CI
- Geração de tipos/modelos para TypeScript (Node) e Python (CLI/pipelines)
Se um serviço/UI não segue estes contratos, ele está fora do padrão do projeto.
"Plug-and-play" só existe quando os contratos são executáveis e testados.
- Objetivo
- O que este repositório é (e não é)
- Melhor stack (tooling)
- Estrutura do repositório
- Contratos incluídos no MVP (Fase 1)
- Exemplos de contrato
- Como executar
- Geração de tipos (TS e Python)
- Cenários de testes
- Diretrizes de desenvolvimento
- Como consumir nos outros repositórios
- Links oficiais
- Licença
Garantir que o ecossistema seja:
- Modular: serviços e ferramentas se encaixam sem acoplamento implícito
- Auditável: contratos forçam presença de metadados essenciais (versões, hashes, proveniência)
- Seguro: contratos impedem/evitam PII por padrão e linguagem acusatória em campos críticos
- Evolutivo: versionamento formal (SemVer) com exemplos e CI impedindo divergência
- Contrato executável (OpenAPI + JSON Schema)
- Biblioteca de modelos gerados (TS/Python) para evitar "JSON de mão"
- Catálogo de convenções (observabilidade: logs/telemetria) com validação
- Base para "plug-ins" futuros (connectors/transformers/IA) via contratos bem definidos
- Serviço HTTP
- Implementação de regras/indicadores
- Camada de persistência
- Observabilidade "rodando" (isso é o repo
openaudit-observability, que implementa libs/middlewares)
Como core-contracts é essencialmente validação + geração, a stack ideal é tooling em Node:
- Node.js 22+
- pnpm (ou npm/yarn)
- TypeScript (para scripts/geração)
- AJV para validar JSON Schema (runtime e testes)
- OpenAPI linter (ex.:
@redocly/cli) para validar OpenAPI - openapi-typescript para gerar tipos TS a partir do OpenAPI
- datamodel-code-generator (Python) para gerar modelos Pydantic a partir de JSON Schema/OpenAPI
Observação: os repositórios consumidores podem ser Node, Python, Rust etc.
O "source of truth" aqui é OpenAPI/JSON Schema. As linguagens consomem via geração.
Estrutura:
.
├─ openapi/
│ └─ search-api.yaml
├─ schemas/
│ ├─ common/
│ │ ├─ confidence.enum.json
│ │ ├─ severity.enum.json
│ │ ├─ stage.enum.json
│ │ └─ ids.schema.json
│ ├─ search/
│ │ ├─ candidate.schema.json
│ │ └─ search_response.schema.json
│ ├─ catalog/
│ │ └─ catalog_meta.schema.json
│ └─ observability/
│ ├─ log_event.schema.json
│ └─ error_event.schema.json
├─ observability/
│ ├─ metrics_registry.yaml
│ └─ span_names.yaml
├─ examples/
│ ├─ search/
│ │ └─ search_response.json
│ ├─ catalog/
│ │ └─ catalog_meta.json
│ └─ logs/
│ └─ search_log_event.json
├─ packages/
│ ├─ typescript/ # gerado (não editar à mão)
│ └─ python/ # gerado (não editar à mão)
├─ scripts/
│ ├─ validate_schemas.ts
│ ├─ validate_openapi.ts
│ ├─ validate_examples.ts
│ └─ generate.ts
├─ CHANGELOG.md
├─ package.json
└─ README.md- OpenAPI:
GET /health,GET /search - JSON Schema:
SearchResponse,Candidate, enums comuns
- JSON Schema do
catalog_meta.json(proveniência e versão do catálogo)
- JSON Schema:
LogEventeErrorEvent - Registry: nomes de métricas e spans (catálogo de convenções)
Trecho ilustrativo:
openapi: 3.0.3
info:
title: openaudit-search-api
version: 0.1.0
paths:
/search:
get:
summary: Search candidates in entity catalog
parameters:
- in: query
name: q
required: true
schema: { type: string, minLength: 1 }
- in: query
name: limit
schema: { type: integer, minimum: 1, maximum: 25, default: 10 }
- in: query
name: offset
schema: { type: integer, minimum: 0, default: 0 }
responses:
"200":
description: OK
headers:
X-Request-Id:
schema: { type: string }
X-Catalog-Version:
schema: { type: string }
X-Cache:
schema: { type: string, enum: [HIT, MISS] }
content:
application/json:
schema:
$ref: "../schemas/search/search_response.schema.json"Trecho ilustrativo (resumo):
{
"$id": "schemas/search/search_response.schema.json",
"type": "object",
"required": ["query", "catalog", "candidates"],
"properties": {
"query": {
"type": "object",
"required": ["normalized", "hash"],
"properties": {
"normalized": { "type": "string", "minLength": 1 },
"hash": { "type": "string", "pattern": "^sha256:" }
}
},
"catalog": {
"type": "object",
"required": ["name", "version", "snapshot_id", "source"],
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"snapshot_id": { "type": "string" },
"source": { "type": "string" }
}
},
"candidates": {
"type": "array",
"items": { "$ref": "./candidate.schema.json" }
}
}
}Esse arquivo é produzido pelo openaudit-entity-catalog (Python CLI) e consumido pelo search-api.
Exemplo:
{
"name": "openaudit-entity-catalog",
"catalog_version": "2026-02-28",
"snapshot_id": "cat:2026-02-28T03:00:00Z",
"schema_version": "1.0.0",
"build_version": "0.1.0",
"collected_at": "2026-02-28T03:00:00Z",
"sources": [
{
"name": "TSE",
"dataset": "candidaturas",
"source_url": "https://dadosabertos.tse.jus.br/",
"collected_at": "2026-02-28T02:40:00Z",
"hash": "sha256:..."
}
],
"artifacts": [
{ "file": "catalog.sqlite", "hash": "sha256:...", "rows": 123456 }
],
"qa": {
"report_file": "qa_report.json",
"passed": true,
"checks_failed": 0
}
}Por que aqui? Porque observabilidade também é contrato. Se cada serviço loga de um jeito, você perde rastreabilidade.
Regras essenciais:
- não logar
qbruto - não logar CPF/PII por padrão
- campos para correlação (
request_id,run_id) obrigatórios conforme contexto
Exemplo de evento:
{
"timestamp": "2026-02-28T20:10:00Z",
"level": "info",
"service": { "name": "openaudit-search-api", "version": "0.1.0" },
"env": "dev",
"event": { "name": "catalog.search" },
"correlation": { "request_id": "req_123", "run_id": null },
"data": {
"query_hash": "sha256:...",
"catalog_version": "2026-02-28",
"limit": 10,
"offset": 0,
"result_count": 8,
"cache_hit": false
},
"duration_ms": 21,
"status": "success"
}Implementação para emitir isso fica no repo
openaudit-observability. Aqui, a gente só define e valida o contrato.
- Node.js 22+
- pnpm (recomendado) ou npm
pnpm installpnpm validatepnpm generatepnpm testOs comandos acima são o "contrato operacional" do repo.
Gera tipos TS para consumo nos serviços Node/UI:
- saída:
packages/typescript/
Exemplos de geradores comuns:
openapi-typescript(OpenAPI → TS)json-schema-to-typescript(JSON Schema → TS)
Gera modelos Pydantic para consumo em CLIs/pipelines:
- saída:
packages/python/
Gerador recomendado:
datamodel-code-generator(JSON Schema/OpenAPI → Pydantic)
Regra:
packages/*é gerado. Não editar manualmente.
O CI deve cobrir, no mínimo:
-
Schema lint/parse
- todos os JSON Schemas devem ser válidos
-
OpenAPI lint/parse
- OpenAPI válido e consistente
-
Exemplos validados
- todo JSON em
examples/deve validar contra seu schema correspondente
- todo JSON em
-
Geração reprodutível
pnpm generatenão pode gerar diffs não commitados (enforced)
-
Breaking change guard (recomendado)
- mudanças incompatíveis exigem bump de versão MAJOR e changelog
Checklist obrigatório:
-
Atualize o arquivo em
openapi/ouschemas/ -
Atualize/adicione exemplo em
examples/ -
Rode:
pnpm validatepnpm testpnpm generate
-
Atualize
CHANGELOG.md -
Se for breaking change, atualize versão (SemVer)
- MAJOR: breaking changes (remove/muda tipo/muda semântica/torna obrigatório)
- MINOR: adiciona campo opcional, novo endpoint compatível
- PATCH: correção de docs/descrições/examples sem alterar contrato
Consideramos breaking change:
- remover campo
- mudar tipo
- mudar enum permitido
- mudar significado semântico (mesmo mantendo tipo)
- mudar contrato de observabilidade (campos obrigatórios), sem bump major
- Dependência:
@openaudit/core-contracts(quando publicado) ou via git/tag - Use os tipos gerados + validação runtime opcional (AJV)
- Dependência:
openaudit_core_contracts(quando publicado) ou via git/tag - Use os modelos Pydantic para validar
catalog_meta.jsone outros artefatos
Mesmo antes de publicar em registries, vocês podem versionar por Git tags e usar
git+https.
Documentação normativa do projeto (fonte de verdade):
Roadmap:
- Licença oficial: https://github.com/OpenAudit-Brasil/About/blob/main/LICENSE