Bootstrap EDEN: Fase 0 (arquitetura) e Fase 1 (monorepo + infra)
Fase 0 — descoberta e arquitetura:
- Inventário do projeto, glossário de domínio, arquitetura com bounded
contexts e topologia de containers, threat model inicial.
- 12 ADRs cobrindo modular monolith, topologia de containers (Postgres
isolado + eden-core/parceiros/assinante em containers e portas
distintos), auth/sessões, modelo de permissões, criptografia/segredos,
contrato first-class, stock ledger, separação billing/finance/fiscal,
outbox transacional, adapters SaperX e Focus NFe, e identidade
compartilhada entre as 3 apps.
- 14 subagentes e 7 skills especializados por domínio em .claude/.
- Hooks de segurança (PreToolUse/PostToolUse/Stop) testados via pipe.
Fase 1 — plataforma (em andamento):
- Monorepo pnpm workspaces + Turborepo: apps/{api,worker,core-web,
reseller-web,subscriber-web} + 9 packages compartilhados.
- apps/api: NestJS mínimo com /health/live e /health/ready (checando
Postgres real via @eden/database).
- 3 frontends Vite + React + TypeScript + Tailwind, com o favicon
oficial do EDEN.
- packages/database: migration baseline (node-pg-migrate) criando
roles/role_permissions/applications/users/user_applications/sessions/
audit_log — audit log append-only com hash-chain, testado ao vivo
(UPDATE/DELETE bloqueados pelo trigger).
- compose.yaml implementando a topologia da ADR-0002, validada de ponta
a ponta: os 6 containers sobem e ficam saudáveis com um único
`docker compose up`.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
18
docs/adr/0009-transactional-outbox.md
Normal file
18
docs/adr/0009-transactional-outbox.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# ADR-0009: Outbox transacional para eventos de integração
|
||||
|
||||
## Status
|
||||
Aceito
|
||||
|
||||
## Contexto
|
||||
O EDEN precisa publicar eventos de domínio (`lead.created`, `contract.signed`, `invoice.overdue`, etc. — catálogo no Master Prompt §9.2) para consumo por n8n/webhooks/outros módulos, sem perder evento em caso de falha entre o commit da transação de negócio e a publicação. O legado não tem esse problema porque não publica eventos externos.
|
||||
|
||||
## Decisão
|
||||
Toda operação que precise emitir um evento relevante grava a linha do evento na mesma transação SQL da mudança de negócio, numa tabela `outbox_events` (payload normalizado, tipo do evento, status `pending/delivered/failed`, tentativas, correlation id). Um processo separado (`apps/worker`) lê a outbox e entrega (webhook assinado HMAC, ou fila interna para o próprio módulo consumidor), marcando como entregue só após confirmação — com retry/backoff e dead-letter após esgotar tentativas.
|
||||
|
||||
Consumidores (internos ou externos via n8n) devem ser idempotentes por `event_id` — reentrega nunca duplica efeito.
|
||||
|
||||
## Consequências
|
||||
- Positivo: garante "at-least-once" delivery sem depender de o processo de aplicação sobreviver após o commit (invariante nº9 do Master Prompt §24 — webhook repetido não duplica efeito, aplicado também no sentido saída).
|
||||
- Positivo: replay manual de evento é trivial (reprocessar linha da outbox).
|
||||
- Negativo: exige limpeza/arquivamento periódico da tabela de outbox (retenção configurável) para não crescer indefinidamente.
|
||||
- Negativo: consumidores precisam de lógica de idempotência — custo replicado em cada integração, mitigado por uma camada compartilhada em `packages/integrations`.
|
||||
Reference in New Issue
Block a user