12 KiB
EDEN — Progresso
Fase 0 — Descoberta e Arquitetura: CONCLUÍDA
Data: 2026-09-03.
Entregáveis
docs/project-inventory.md,docs/glossary.md,docs/architecture.md,docs/assumptions.md,docs/security/threat-model.md,docs/implementation-plan.md,docs/progress.md(este arquivo).- 12 ADRs em
docs/adr/(0001–0012), cobrindo: modular monolith, topologia de containers (Postgres isolado + eden-core/parceiros/assinante em containers/portas distintas — decisão explícita do operador), auth/sessões, modelo de permissões, criptografia/segredos, contrato first-class, stock ledger, separação billing/finance/fiscal, outbox transacional, adapter SaperX, adapter Focus NFe, três apps com identidade compartilhada. - 14 subagentes em
.claude/agents/: eden-architect, eden-database, eden-security, eden-commercial, eden-finance, eden-fiscal, eden-inventory, eden-telecom, eden-support, eden-hr-timeclock, eden-frontend, eden-api-integrations, eden-qa, eden-code-reviewer. - 7 skills em
.claude/skills/: eden-domain, eden-security, eden-finance, eden-fiscal, eden-inventory, eden-telecom, eden-timeclock — cada uma comSKILL.md+references/. - Hooks em
.claude/settings.json+.claude/hooks/*:PreToolUse(guarda de comandos Bash destrutivos/externos e de acesso a arquivo fora do projeto/.ssh//etc/segredo),PostToolUse(lint/typecheck incremental, fail-open enquanto pnpm não existir),Stop(checagem advisória de segredo/TODO crítico no diff, silenciosa até existir repositório git). Testados via pipe com payloads sintéticos — todos os cenários (allow/ask/deny/fail-open) se comportaram como esperado.
Revisão cruzada (self-review contra os critérios dos agentes eden-architect / eden-security / eden-database, criados nesta mesma fase)
eden-architect: bounded contexts (docs/architecture.md §2) têm direção de dependência consistente (nenhum ciclo); HR/Timeclock corretamente isolado; candidatos a extração futura (Billing, Fiscal) identificados sem extração prematura. Nenhuma feature de negócio foi implementada antes deste gate — consistente com o Master Prompt §18.
eden-security: threat model cobre as superfícies do legado (rotas públicas, auth, autorização, integrações, upload, PDF, auditoria, infraestrutura) mais os invariantes de teste obrigatórios (§15.3). Hooks PreToolUse já impõem, a nível de ferramenta, várias regras de §2.1/§2.2 (fora do projeto, .ssh//etc, impressão de .env, SSH/SCP externo, remoção ampla de volume/prune). Pendência real registrada (não bloqueante): política de retenção/eliminação LGPD ainda não definida pela Handix (docs/assumptions.md #1).
eden-database: princípios de modelagem (§11) já refletidos nas ADRs de contrato/estoque/billing (nunca saldo editável, nunca CASCADE indiscriminado, JSONB só para snapshot/metadata). Nenhum schema físico foi criado ainda nesta fase — corretamente adiado para a Fase 1, quando o Postgres 18 realmente subir.
Nota: esta revisão foi feita pela própria sessão orquestradora aplicando os critérios definidos nos arquivos de agente recém-criados. Os subagentes dedicados (eden-architect, eden-security, eden-database) ficam disponíveis para revisões reais em sessões futuras assim que o Claude Code os carregar como subagent types.
Pendências não bloqueantes (ver docs/assumptions.md)
- Política de retenção/eliminação de dados pessoais (LGPD) — Handix ainda não definiu.
- Docker/Node/pnpm precisam ser provisionados no ambiente antes da Fase 1.
- Portas dos containers definidas via
.env(não fixas) — ver ADR-0002. - Git ainda não iniciado no projeto — planejado para o início da Fase 1.
- Inventário fino do
tema_do_Eden.zip(extração de componentes) adiado para o início deeden-frontend.
Gate de saída da Fase 0: VERDE
Todos os itens do checklist da seção 22 do Master Prompt (“Primeira Execução”) estão completos.
Fase 1 — Plataforma: EM ANDAMENTO
Data de início: 2026-09-03.
Ambiente provisionado
- Docker CE 29.7.2 + Compose v5.5.0 (repositório oficial Docker, não o
docker.iodo Debian) instalados via apt. - Node.js 22.23.2 LTS (NodeSource) + pnpm 11.25.0 (via corepack).
- Git 2.47.3. Repositório inicializado (
main), remotoorigin=https://git.falehandix.com.br/Matheus/eden.git(nenhum push feito ainda).
Monorepo
- pnpm workspaces + Turborepo. 5 apps (
api,worker,core-web,reseller-web,subscriber-web) + 9 packages, todos compackage.json/tsconfig.jsonválidos. pnpm install,pnpm turbo run typecheckepnpm turbo run buildpassam 100% (15/15 e 14/14 tarefas, respectivamente) em todo o monorepo.apps/api: NestJS mínimo com/health/livee/health/ready(este último checando Postgres de verdade via@eden/database).apps/worker: placeholder que confirma conectividade com o banco; sem BullMQ/Redis ainda (conforme ADR-0002 — só entra quando houver job real).apps/core-web,apps/reseller-web,apps/subscriber-web: Vite + React + TS + Tailwind, cada um com favicon oficial do EDEN.packages/database: migrations vianode-pg-migrate(formato.cjs), client de query (pgPool).
Banco de dados
- Migration baseline aplicada com sucesso contra Postgres 18.6 real (container
eden-postgres):roles,role_permissions,applications,users,user_applications,sessions,audit_log— cobrindo Identity & Access (ADR-0003/ADR-0004) e um audit log append-only com hash-chain (testado:UPDATE/DELETEsão efetivamente bloqueados pelo trigger, só liberados viaSET LOCAL eden.allow_audit_mutation). - Seeds: 4 papéis do sistema (pesos idênticos ao legado) + as 3 aplicações (
core/reseller/subscriber). - Organization (empresas/entidades legais), Commercial e demais bounded contexts ainda não têm migration — ficam para quando cada fase começar, por design (ver ADR-0001).
Docker Compose — topologia ADR-0002 validada de ponta a ponta
docker compose --env-file .env up -d sobe os 6 serviços com sucesso:
| Serviço | Status observado |
|---|---|
eden-postgres |
healthy — porta dev 55432, nunca 5432 direto |
eden-api |
healthy — único serviço com DATABASE_URL; /health/ready confirma Postgres via rede interna |
eden-worker |
up — conecta ao Postgres, sem porta exposta |
eden-core (:3001) |
healthy — HTTP 200 |
eden-parceiros (:3002) |
healthy — HTTP 200 |
eden-assinante (:3003) |
healthy — HTTP 200 |
Bugs de bootstrap corrigidos nesta sessão (documentados aqui para não se repetirem):
- Imagem oficial
postgres:18-alpinemudou o layout do volume — precisa montar/var/lib/postgresql(não.../data). apps/api/package.jsontinha"type": "module"incompatível com otsconfig(saída CommonJS) — Node falhava comexports is not defined.node-pg-migrate --envPathnão carregava o.envcorretamente nesta versão — trocado porbash -c 'source .env; ...'nos scriptsmigrate:up/migrate:down.- Healthcheck dos 3 frontends usava
wget http://localhost/..., que resolve para::1(IPv6) dentro do container — nginx só escuta IPv4; trocado para127.0.0.1.
Auth, permissões, Companies e OpenAPI — implementados e testados ao vivo
- Auth (
apps/api/src/auth/): Argon2id (parâmetros versionados, ADR-0005), JWT de acesso de 15 min, refresh token opaco (256 bits) com rotação e detecção de replay (reuso de token já rotacionado revoga toda a cadeia de sessões do usuário). EndpointsPOST /api/v1/auth/{login,refresh,logout}eGET /api/v1/auth/me. - Permissões (
apps/api/src/auth/permissions.ts,permission.guard.ts): resource+action+scope (ADR-0004),super_admincom bypass hardcoded (nunca consultarole_permissions, espelhando a trava também existente no banco). Guard resolve permissões do banco a cada request (nunca cacheado no JWT) — mudança de papel tem efeito imediato, mesma filosofia do legado. - Companies (
apps/api/src/companies/+ migration1788437478189_companies): CRUD com leitura aberta a qualquer autenticado e escrita restrita acompanies:manage; validação de CNPJ (dígito verificador,packages/domain-shared) testada com CNPJ válido/inválido conhecidos. - Seed automático:
SeedServicecria o primeirosuper_admina partir deEDEN_SUPERADMIN_EMAIL/PASSWORDsó quandousersestá vazia — testado (logsuper_admin inicial criado). - OpenAPI/Swagger:
/api/docs(UI) e/api/docs-json, cobrindo todos os endpoints atuais. - Validação/segurança de request:
ValidationPipeglobal comwhitelist+forbidNonWhitelisted(proteção contra mass-assignment) — testado (id/isActiveextras num POST de company são rejeitados com 400).
Testes manuais realizados contra a stack real (não só typecheck): login com senha errada → 401 genérico; refresh rotaciona e o token antigo some; reuso do token antigo → 401 + toda a cadeia revogada; logout revoga e é idempotente; audit log com a sequência completa de eventos (auth.login, auth.refresh, auth.refresh_replay_detected, company.created).
CRUD de Usuários/Papéis, Products, Resellers, adapters S3/SMTP — implementados via 4 subagentes especializados em paralelo (worktrees isolados) + trabalho direto
Estratégia: 4 subagentes (general-purpose, atuando com a persona eden-commercial/eden-api-integrations definida em .claude/agents/, já que os subagent types customizados ainda não carregaram nesta sessão) rodaram em paralelo, cada um em git worktree isolado, enquanto o CRUD de Usuários/Papéis foi feito diretamente (por tocar peso hierárquico e segurança). Cada agente foi instruído a não editar app.module.ts nem packages/database/src/index.ts — a integração final (merge das branches, wiring, resolução de conflitos, rebuild, teste ao vivo) foi feita manualmente.
- Users/Roles (
apps/api/src/users/,apps/api/src/roles/): convite com senha temporária, troca de senha self-service, reset administrativo, grant/revoke de aplicação — tudo com checagem de peso hierárquico (assertCanAssignRole/assertCanActOnUser, eden.md §1.6). CRUD de papéis erole_permissionsexclusivosuper_admin(SuperAdminGuard), deliberadamente não generalizado para o modelo de permissão (raiz do próprio sistema de autorização). - Products (
apps/api/src/products/+ migrationproducts): catálogo com as 5 faixas de preço fixas,product_codesequencial, flags de rastreamento (estoque/serial/patrimônio/MAC). Leitura aberta, escrita viaproducts:edit. - Resellers (
apps/api/src/resellers/+ migrationresellers): CRUD operacional + vínculo usuário↔revenda (users.reseller_id). Leitura aberta, escrita viaresellers:edit— desvio deliberado do legado (que travava emrequireAdmin), documentado em comentário. - Adapters S3/SMTP (
packages/integrations/): portados fielmente do legado — S3 falha alto (erro claro se não configurado), SMTP falha silencioso (nunca quebra um fluxo de negócio por causa de e-mail).
2 bugs reais encontrados em teste manual e corrigidos antes do commit final:
assertCanAssignRole/assertCanActOnUserpulavam a validação de existência do papel quando o ator erasuper_admin(o bypass de peso pulava a checagem inteira) — convidar usuário comrole_keyinexistente estourava a constraint FK do banco como 500 não tratado em vez de 400 claro.PATCH /v1/resellers/:id/assign-useraceitava umresellerIddiferente no corpo, que na prática era o valor usado — o:idda URL virava só uma checagem de existência, não o alvo real da atribuição. Corrigido para o:idda URL ser a única fonte de verdade; desatribuição virou endpoint próprio (POST /v1/resellers/unassign-user).
Todos os módulos testados ao vivo contra a stack real (não só typecheck): convite de usuário, papel inexistente (400 após o fix), CRUD de produto com preços NUMERIC corretos, CRUD de revenda, atribuição/desatribuição de usuário à revenda.
Pendências da Fase 1 (não iniciadas)
- MFA/TOTP (schema já existe —
users.mfa_*— endpoint ainda não implementado). - Extração do Design System a partir do tema DreamsERP (
packages/uiainda é placeholder). - Wiring dos adapters S3/SMTP em algum módulo consumidor real (hoje só existem como biblioteca em
packages/integrations, nada os chama ainda). - Nota de dado de teste: a empresa "Handix Telecom LTDA" e a revenda "Handix (revenda própria)" criadas durante os testes usam dados de exemplo, não os dados reais da Handix — substituir/remover antes de qualquer ambiente que não seja dev local.