Files
sar/STACK.md
julian 17c08e6392 chore: initial monorepo scaffold + WDS Phase 1+2 artifacts
- Nx 22.7 monorepo (pnpm 11.1, TypeScript 5.9, Node 24)
- apps/api: NestJS 11 (CJS conforme CODING-RULES.md PGD-DB-004)
- apps/web: React 19 + Vite 8 (ESM)
- libs/shared/api-interface: Zod contract base
- Docker Compose dev: Postgres 18, Valkey 8, MinIO, Mailpit
- WDS artifacts:
  - design-artifacts/A-Product-Brief/ (5 docs canônicos + 16 dialogs)
  - design-artifacts/B-Trigger-Map/ (hub + 4 personas + feature impact)
- Stack canon: STACK.md v2.2 + CODING-RULES.md v2.0 + brand.md
- AGENTS.md + README.md como entrada para devs/agentes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:34:20 +00:00

12 KiB

STACK.md — Referência de Tecnologias

Define o que usar: tecnologias, versões, estrutura do monorepo e filosofia arquitetural. Leia antes de decisões de tecnologia ou arquitetura. Para regras de como escrever o código (invariantes + pegadinhas 🔥), consulte CODING-RULES.md. Humano novo? Este arquivo é projetado para consumo por agente de IA. Comece por docs/QUICKSTART.md — 5 min, com TL;DR executável e as 5 decisões arquiteturais-chave.

1. O que é e por quê

Stack full-stack TypeScript para apps internas da empresa (Proxmox on-prem no BR · Docker Compose · MinIO · master-login · Vault · email/CDN via SaaS). Seis decisões que diferenciam de stacks genéricas:

  1. Schemas Zod são o contrato. Tipos derivam de schemas em libs/shared/api-interface; mesmo schema valida no Nest e tipa react-hook-form. → §06
  2. Monorepo Nx · apps/ + libs/<scope>/<type>-<nome> com 3 tags (scope: + type: + domain:) e ESLint boundaries. Um repo por produto, não por serviço. → §02
  3. App stateless · infra stateful self-host no Proxmox. Postgres, Valkey, MinIO, master-login e Vault rodam em VMs/LXC controladas pelo time — nunca em container efêmero da app. Email (Resend) e CDN (Cloudflare) permanecem SaaS por razões de deliverability / borda global. → §03, §11, ADR 0004, ADR 0005
  4. Multi-tenancy via BD-por-workspace. Cada workspace tem cluster PG próprio registrado no master-login; app cliente resolve PrismaClient por request via get_workspace_connection + role app_reader (senha nunca trafega por HTTP). Sem coluna tenantId em modelos; isolamento é físico. → §03.4, §23.4, ADR 0006
  5. Tudo que pode esperar vai pra fila (BullMQ). Email, webhook, processamento, agendado — handler HTTP só faz o mínimo síncrono. Job sempre carrega workspaceId no payload; worker recria o CLS. → §11
  6. LGPD by design. Isolamento físico cross-workspace (cluster PG dedicado por cliente), PII criptografada (MinIO SSE + pgcrypto), redact agressivo em logs, Art. 18 implementado, hash em targeting de flags. Datacenter próprio elimina exposição ao CLOUD Act (US) sobre dados regulados. → §07, §09, §22

Princípios canônicos (11 itens) em docs/README.md → Princípios gerais (TL;DR). Filosofia arquitetural completa em §21.

2. Stack canônica (May 2026)

Tabela completa com colunas Versão/Arquivo em docs/README.md → Tabela canônica. One-liners por camada:

  • Runtime: Node 24 LTS · pnpm 11.1 · TypeScript 5.9 → §01
  • Monorepo: Nx 22.7 → §02
  • Backend: NestJS 11.1 (Express 5) · Prisma 7 · PostgreSQL 18 · nestjs-cls · @nestjs/terminus · @nestjs/throttler + @nest-lab/throttler-storage-redis§03, §20
  • Frontend: React 19.2 + Compiler · Vite 8 (Rolldown) · Ant Design 6.4 · TanStack Query 5.100 · TanStack Router · Zustand 5.0.13+ → §04
  • API: REST + OpenAPI 3.1 + RFC 9457 Problem Details · Zod 4 (pnpm catalog) + nestjs-zod + react-hook-form (zodResolver) → §05, §06
  • Auth: Guards NestJS + jose + master-login (IdP OAuth2/OIDC próprio em VM Proxmox; HS256 hoje → RS256 roadmap) · argon2id centralizado no IdP → §07, ADR 0005
  • Segredos: HashiCorp Vault (KV v2) self-host · Vault Agent injeta env vars no container → §08
  • Observabilidade: Pino + nestjs-pino 10.3 · OpenTelemetry (Traces+Metrics GA; Logs Beta) · Grafana Cloud LGTM · Sentry → §09
  • Flags: OpenFeature SDK + GrowthBook self-host → §10
  • Filas: BullMQ 5.77 + @nestjs/bullmq 11 · Bull Board · Valkey em VM/LXC Proxmox → §11
  • Cache: @nestjs/cache-manager v3 + cache-manager 6 + @keyv/redis + cacheable (L1) — TTL em ms§12
  • Real-time: Socket.IO 4 + @socket.io/redis-adapter · SSE via @Sse() nativo NestJS → §13
  • Uploads: MinIO (S3-compat) presigned POST policy + AWS SDK v3 · Uppy + @uppy/aws-s3 · ClamAV em worker BullMQ · sharp 0.34 → §14
  • Email: Resend (SaaS — não self-host) + React Email via BullMQ → §15
  • Testes: Vitest 4.1 · Testcontainers 12 · Supertest 7.2.2 (encapsulado) · Playwright 1.60 → §16
  • Qualidade: ESLint 10.4 flat · typescript-eslint 8.59 · Prettier 3.8.3 · eslint-plugin-import-x 4.16.2 · Husky 9 + lint-staged 17 · gitleaks§17
  • CI/Deploy: GitHub Actions + Nx Cloud · Trivy gate · pin actions por SHA · Docker multi-stage node:24-alpine · Ansible/SSH para VMs Proxmox com docker-compose rolling (backend) · Cloudflare + Nginx servindo SPA estática (frontend, não containerizar) → §18

3. Quando aplicar este guia

  • Greenfield: obrigatório do dia 0.
  • Brownfield: adoção gradual, tópico a tópico.
  • Spike/POC: livre até 2 semanas — se virar produto, refatora.
  • Fora de escopo (React Native, GraphQL pesado, mobile nativo): exige RFC antes.

4. Filosofia em 5 bullets

Aprofunde em docs/21-filosofia-arquitetural.md.

  1. Monólito modular. Uma única aplicação deployável (apps/api), organizada em um NestJS Module por domínio de negócio (ComprasModule, VendasModule, EstoqueModule, FinanceiroModule).
  2. Dependências apontam para dentro (Clean Architecture). Domínio não conhece framework; módulos não importam domínio alheio direto.
  3. Um domínio = um Module = N libs (domain- / feature- / data-access-). Boundaries enforçadas pelas três tags Nx (ADR 0002).
  4. Cross-domínio via fila, read-model ou ACL. Nunca import direto entre módulos de domínios diferentes. Eventos como substantivo no passado (OrderPlaced, PaymentFailed).
  5. Entidade ≠ model Prisma. Type Prisma é mapeado para entidade em data-access; mapper é o único ponto que conhece Prisma.*. Entidades com construtor private + factories create()/reconstitute(); mutações por métodos de negócio (cancel(), ship()). Side-effects (email, webhook, read-model) sempre após o prisma.$transaction, via BullMQ.

5. Estrutura do monorepo

apps/
  api/          # NestJS HTTP — monólito modular (um Module por domínio)
  api-worker/   # Workers BullMQ (mesma imagem, entrypoint diferente)
  web/          # React + Vite SPA
  web-e2e/      # Playwright
libs/
  shared/<purpose>/                 # usável por api e web
  api/domain-<domínio>/             # entidades, VOs, repositórios abstratos
  api/feature-<domínio>/            # use cases (um arquivo por ação) + Module
  api/data-access-<domínio>/        # Prisma, BullMQ producers, mappers
  api/util-<nome>/                  # utilitários sem regra de negócio
  web/<feature|data-access|ui|util>-<nome>/

Convenções de naming/branching/code review em §19; detalhes de tags Nx e depConstraints em §02 e §21.

6. Onde aprofundar (mapa por intenção)

Para fazer… Vá em
Invariantes e pegadinhas 🔥 (regras de código) CODING-RULES.md
Setup zero (runtime, ESM, tooling) §01
Criar/configurar libs Nx, boundaries, tags §02, ADR 0002
Modelar backend (Module, Prisma, transação) §03, §20
Frontend (componente, query, form, router) §04
Desenhar endpoint REST (paginação, erro, versão) §05
Validar entrada (Zod, DTO, i18n pt-BR) §06
Implementar auth (login, refresh, OAuth/PKCE) §07
Gerir secrets e env vars §08
Logar, tracear, alertar §09
Criar feature flag / experimento §10
Enfileirar job, scheduler, retry, DLQ §11
Cachear (app, HTTP, CDN, stampede) §12
WebSocket / SSE §13
Upload de arquivo / imagem §14
Enviar email / notificação (web push) §15
Escrever teste (unit, integração, E2E) §16
Configurar lint / formatter / hook / gitleaks §17
CI, Docker, deploy Proxmox (Ansible/SSH), rolling §18
Dimensionar VMs Proxmox (sizing, HA, capacity) §24
Naming, branching, code review §19
Padrão Nest universal (DI, ciclo de vida, health) §20
Filosofia arquitetural (DDD, Clean, BC) §21
LGPD (bases legais, retenção, redact, Art. 18, RoPA) §22
Autorização (RBAC + ABAC, BD-por-workspace, anti-IDOR) §23, ADR 0006
Multi-tenancy (factory de PrismaClient, get_workspace_connection, saga de onboarding) §03.4, ADR 0006
SLOs default por tipo de endpoint / job / fluxo ADR 0001
ADRs (decisões fora do escopo deste guia) docs/adr/

Meta-governança

  • Adotar em uma app: copie STACK.md e CODING-RULES.md para a raiz do repo da app + referencie ambos em AGENTS.md. Procedimento completo (cópia, referência, sync, exceções, checklist) em docs/README.md → "Como usar STACK.md em uma app".
  • Sync: PR que altera tabela canônica / princípios em docs/README.md deve atualizar STACK.md no mesmo commit; PR que altera pegadinhas deve atualizar CODING-RULES.md — enforçado por .gitea/workflows/stack-sync-check.yml.
  • Mudanças de stack: ADR em docs/adr/NNN-titulo.md (sequencial; nunca reescrito — Superseded by NNN); RFC via issue com label rfc. Bump trimestral de versões.
  • Mantenedores: time de plataforma; canal #plataforma.

Regra de ouro para o agente: ao propor tecnologia fora desta tabela, pergunte antes e cite a justificativa. Para regras de como escrever o código, consulte CODING-RULES.md.