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>
8.4 KiB
EDEN — Arquitetura (Fase 0)
1. Estilo arquitetural
Modular monolith em monorepo TypeScript (pnpm workspaces + Turborepo), conforme Master Prompt §4. Um único processo de API (apps/api) organizado por bounded contexts internos, com fronteiras de módulo explícitas e comunicação interna via eventos de domínio (outbox) — nunca chamada direta cross-módulo que quebre a fronteira. Ver ADR-0001.
Motivo de não usar microserviços desde o início: custo operacional de dezenas de serviços não se paga no estágio atual; o modular monolith permite extrair um bounded context para serviço próprio no futuro (ex.: billing/fiscal, que já são os candidatos naturais por volume/isolamento) sem reescrever o domínio.
2. Bounded contexts
| Contexto | Núcleo de dados | Depende de | Agente responsável |
|---|---|---|---|
| Identity & Access | users, roles, permissions, sessions, resellers (vínculo) | — (fundacional) | eden-security |
| Organization | legal entities, companies, branches, warehouses, cost centers | Identity | eden-architect |
| Commercial (CRM) | leads, opportunities, quotes, pricing tiers, approval workflow | Identity, Organization | eden-commercial |
| Customer 360 | client accounts (PF/PJ), reseller accounts, partners/QSA | Commercial | eden-commercial |
| Contracts | contracts, versions, amendments, renewals, status history | Customer 360, Commercial | eden-commercial |
| Documents & E-signature | templates, versions, generations, envelopes, signers, audit hash-chain | Contracts, Organization | eden-frontend (editor) + domínio próprio |
| Inventory & Assets | warehouses, stock ledger, serialized assets, RMA | Contracts (instalação) | eden-inventory |
| Finance (AR/AP) | receivables, boletos, dunning, payables, reconciliation | Contracts, Billing | eden-finance |
| Billing | billing accounts, cycles, subscriptions, invoices, billing runs | Contracts, Inventory (consumo) | eden-finance |
| Fiscal | catálogos fiscais, fiscal profiles, documentos fiscais emitidos | Billing | eden-fiscal |
| Telecom (SaperX) | circuitos, DIDs, consumo/CDR, conciliação | Customer 360, Billing | eden-telecom |
| Support (Service Desk) | tickets, SLA, OS | Customer 360, Contracts, Inventory | eden-support |
| HR/Timeclock | devices, employees, AFD, apuração, banco de horas | Organization (isolado do resto) | eden-hr-timeclock |
| Integrations/Events | outbox, webhooks, API clients, delivery log | transversal | eden-api-integrations |
Regra de dependência: setas só "para trás" na tabela acima (uma linha não depende de uma que a segue) — evita ciclo entre módulos. HR/Timeclock é deliberadamente isolado (só depende de Organization) — pode ser paralelizado/adiado sem travar o núcleo comercial, replicando a recomendação do próprio eden.md.
3. Estrutura do monorepo
Conforme Master Prompt §4.2:
apps/
api/ # API principal (modular monolith)
worker/ # jobs assíncronos (BullMQ)
core-web/ # EDEN Core (ERP interno)
reseller-web/ # EDEN Parceiros
subscriber-web/ # EDEN Assinante
packages/
database/ # schema, migrations, query layer
contracts/ # DTOs/schemas/event contracts compartilhados
ui/ # Design System (derivado do tema DreamsERP)
auth/ # SDK de auth client-side comum às 3 apps
observability/
config/
testing/
integrations/ # adapters Focus NFe, SaperX, Control iD, S3, SMTP
domain-shared/
infra/
docker/
migrations/
docs/
.claude/
4. Topologia de deployment / containers
Decisão explícita solicitada pelo operador: Postgres roda em container próprio, separado dos containers de aplicação; cada uma das três aplicações web roda em seu próprio container, cada uma em porta distinta. Detalhamento completo em docs/adr/0002-container-topology.md. Resumo:
┌─────────────────────────────────────────────────────────────┐
│ docker compose (rede interna "eden_net") │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌─────────────────┐ │
│ │ eden-postgres │ │ eden-redis │ │ eden-api │ │
│ │ :5432 (int) │ │ :6379 (int) │ │ :8080 → host │ │
│ └───────┬───────┘ └───────┬───────┘ └────────┬────────┘ │
│ │ │ │ │
│ └─────────────┬─────┴─────────────────────┘ │
│ │ (api é o único que fala com o banco) │
│ ┌───────────────┐ ┌──▼────────────┐ ┌─────────────────┐ │
│ │ eden-worker │ │ eden-core │ │ eden-parceiros │ │
│ │ (sem porta) │ │ :3001→host │ │ :3002→host │ │
│ └───────────────┘ └───────────────┘ └─────────────────┘ │
│ ┌────────────────┐ │
│ │ eden-assinante │ │
│ │ :3003→host │ │
│ └────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Princípios:
- Nenhuma aplicação web fala direto com o Postgres — todas as 3 (core/parceiros/assinante) consomem exclusivamente a API (
eden-api), que é a única com credencial de banco. Isso preserva o requisito do Master Prompt de "nascer preparado para ser consumido por essas três aplicações" sem triplicar a superfície de acesso a dados. - Postgres nunca expõe porta ao host em produção — só rede interna do compose; em dev, opcionalmente mapeada para uma porta alta não-padrão para acesso de ferramenta local (ex.
55432:5432), nunca5432:5432direto. - Cada app web em porta própria e distinta, definida em
.env(EDEN_CORE_PORT,EDEN_PARCEIROS_PORT,EDEN_ASSINANTE_PORT,EDEN_API_PORT) — nenhuma hardcoded no compose, para permitir múltiplos ambientes na mesma máquina (dev/staging) sem colisão. - Build multi-stage por app (
infra/docker/Dockerfile.api,Dockerfile.webparametrizado por app via build-arg) — imagens enxutas, sem devDependencies em produção. - Healthcheck obrigatório em todo container (Postgres via
pg_isready, API via/health/ready, apps web via HTTP 200 na raiz) —depends_on: condition: service_healthy, não apenas ordem de start. - Volumes nomeados para dados do Postgres (
eden_pgdata) — nunca bind mount direto de dado de produção para o filesystem do host sem estratégia de backup (backup lógico viapg_dumpstreaming para S3, Master Prompt §6.15, roda de dentro do container/worker, não do host). - Redis (cache/fila BullMQ) entra como container próprio (
eden-redis) só quando o primeiro job assíncrono real precisar dele — não subir vazio "por precaução" (Master Prompt §4.1: "somente quando houver benefício real").
5. Identidade compartilhada entre as 3 apps
Uma única API de autenticação/autorização (dentro de eden-api) emite sessão para as 3 aplicações. Uma identidade pode ter acesso a core/reseller/subscriber de forma explícita (tabela de vínculo, não inferida pelo nome do papel) — ver ADR-0012 e Master Prompt §5.1.
6. Próximos documentos
docs/security/threat-model.mddocs/adr/*(decisões referenciadas acima)docs/implementation-plan.md(backlog por fase)docs/data-model/*(ERD por domínio — produzido ao entrar em cada Fase)