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>
103 lines
8.4 KiB
Markdown
103 lines
8.4 KiB
Markdown
# 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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 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:
|
|
1. **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.
|
|
2. **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`), nunca `5432:5432` direto.
|
|
3. **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.
|
|
4. **Build multi-stage por app** (`infra/docker/Dockerfile.api`, `Dockerfile.web` parametrizado por app via build-arg) — imagens enxutas, sem devDependencies em produção.
|
|
5. **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.
|
|
6. **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 via `pg_dump` streaming para S3, Master Prompt §6.15, roda **de dentro** do container/worker, não do host).
|
|
7. 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.md`
|
|
- `docs/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)
|