Files
sar/design-artifacts/A-Product-Brief/04-platform-requirements.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

20 KiB

Platform Requirements: SAR — Força de Vendas

Status: Block D COMPLETO (Steps 27-32) — fast-track via STACK.md v2.2 Cliente: JCS Sistemas Última atualização: 2026-05-27

Este documento é um espelho consolidado de decisões já feitas em STACK.md v2.2, CODING-RULES.md v2.0, ADRs 0001-0006, e Step 10a (Platform Strategy). Não duplica conteúdo — referencia. STACK.md continua sendo source of truth para qualquer decisão técnica.


Stakeholder técnico

Item Valor
Tech Lead Julian (acumulado com PO + Champion — solo founder mode até 1º cliente)
Nível técnico do PO Muito técnico (autor de STACK.md + CODING-RULES.md)
Time de desenvolvimento MVP Apenas Julian até 1º cliente; +1-2 devs depois
Cultura técnica JCS Tech maturity alta — 11-50 pessoas, anos de software profissional

Decisões já feitas (referência cruzada)

Decisão Onde está consolidada
Stack canônica completa STACK.md v2.2 (FONTE DA VERDADE)
Invariantes de código e pegadinhas críticas CODING-RULES.md v2.0
Multi-tenancy BD-por-workspace ADR 0006 (substituiu row-level tenantId)
master-login como IdP ADR 0005 (substituiu Keycloak)
Migração AWS sa-east-1 → Proxmox on-prem BR ADR 0004
SLO defaults por endpoint/job/fluxo ADR 0001
Tags Nx canônicas (scope / type / domain) ADR 0002
PWA mobile-first iOS para Rafael Step 10a
Desktop-first para Sandra/Daniel/Alice Step 10a + brand.md
iPad first-class para Daniel Step 10a
Offline read+write com sync (Rafael) Step 10a
Coexistência com app Android legado Step 10a
Sem app store no MVP Step 10a + STACK.md §18
pt-BR only no MVP, i18n-ready Step 16
LGPD by design STACK.md §22 + CODING-RULES.md
brand.md identidade visual canônica
03-visual-direction.md direção visual completa

Tech Stack (Step 28 — espelho consolidado de STACK.md v2.2)

Camadas principais

Camada Decisão canônica
Runtime Node 24 LTS · pnpm 11.1 · TypeScript 5.9
Monorepo Nx 22.7 (apps/api + apps/api-worker + apps/web + apps/web-e2e + libs/) com 3 tags canônicas (scope / type / domain) — ADR 0002
Backend NestJS 11.1 (Express 5) · Prisma 7 · PostgreSQL 18 · nestjs-cls · @nestjs/terminus · @nestjs/throttler + Valkey storage
Frontend React 19.2 + Compiler · Vite 8 (Rolldown) · Ant Design 6.4 · TanStack Query 5.100 · TanStack Router · Zustand 5
API REST + OpenAPI 3.1 + RFC 9457 Problem Details · Zod 4 (pnpm catalog) + nestjs-zod + react-hook-form (zodResolver)
Auth Guards NestJS + jose + master-login (IdP OAuth2/OIDC próprio em VM Proxmox; HS256→RS256 roadmap) · argon2id no IdP — ADR 0005
Multi-tenancy BD-por-workspace — cluster Postgres dedicado por cliente, resolvido via get_workspace_connection no master-login. Sem coluna tenantId em modelos — isolamento físico — ADR 0006
Secrets HashiCorp Vault (KV v2) self-host · Vault Agent injeta env vars no entrypoint do container
Observabilidade Pino + nestjs-pino 10.3 · OpenTelemetry (Traces/Metrics GA, Logs Beta) · Grafana Cloud LGTM · Sentry
Feature flags OpenFeature SDK + GrowthBook self-host
Filas BullMQ 5.77 + @nestjs/bullmq 11 · Bull Board · Valkey em VM/LXC Proxmox
Cache @nestjs/cache-manager v3 + cache-manager 6 + @keyv/redis + cacheable (L1)
Real-time Socket.IO 4 + @socket.io/redis-adapter (Valkey) · SSE via @Sse() nativo NestJS
Uploads MinIO (S3-compat) presigned POST policy · AWS SDK v3 · Uppy + @uppy/aws-s3 · ClamAV worker BullMQ · sharp 0.34
Email Resend (SaaS — únicas exceções SaaS são email e CDN por questão de deliverability/borda) + React Email via BullMQ
Testes Vitest 4.1 · Testcontainers 12 · Supertest 7.2.2 (encapsulado) · Playwright 1.60
Qualidade ESLint 10.4 flat · typescript-eslint 8.59 · Prettier 3.8.3 · eslint-plugin-importx 4.16.2 · Husky 9 + lint-staged 17 · gitleaks
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)
Infraestrutura Proxmox on-prem BR — substitui AWS sa-east-1 — ADR 0004. Self-host Postgres, Valkey, MinIO, master-login, Vault, GrowthBook, PostHog (novo)

Decisões frontend específicas do SAR (decorrentes de Block C)

  • PWA mobile-first iOS para Rafael — Service Worker + Web Push + manifest + offline read+write
  • Desktop SPA para Sandra/Daniel/Alice (mesmo bundle React, layouts diferentes)
  • iPad first-class para Daniel (testes regulares em iPad Safari)
  • Code-splitting por cockpit (TanStack Router lazy routes)
  • Service Worker crítico para Rafael offline (IndexedDB queue + sync)
  • Plus Jakarta Sans self-host (não Google Fonts CDN — LGPD + performance)
  • Dark mode elegante (especialmente Rafael à noite)
  • Build target: ES2023 (noUncheckedIndexedAccess ON, NodeNext module resolution)

Rationale (curto)

A stack JCS v2.2 foi calibrada para:

  • LGPD by design (datacenter BR, isolamento físico multi-tenant, redact em logs)
  • Velocidade de desenvolvimento (Node/Nest/Prisma stack TypeScript end-to-end)
  • Custo operacional baixo (self-host Proxmox para tudo que não é deliverability/edge)
  • Velocidade de iteração (Nx affected, code-splitting, hot reload Vite Rolldown)
  • Solo founder mode (toolchain conhecido pelo PO, sem learning curve)

Para alterar qualquer decisão fora desta tabela: RFC em docs/adr/NNN-titulo.md.


Integrations (Step 29)

Decisões fechadas

Integração Provider escolhido Por quê Notas
Pagamento Iugu BR-focused, assinaturas recorrentes nativas, boleto/PIX/cartão suportados, ticket B2B BR padrão Webhook handler via NestJS controller + BullMQ para retries. Receita reconhecida no momento do paid event.
WhatsApp Business Oficial Meta (WhatsApp Cloud API) Sem intermediário, templates aprovados direto pela Meta, mais seguro a longo prazo Setup mais burocrático (verificação Business + templates approval). Custo por mensagem. Templates centralizados em libs/shared/whatsapp-templates.
Analytics de produto PostHog self-host (Proxmox) Self-host alinha STACK.md (BR + LGPD). Cobre product analytics, session replay, feature flags. Roda em VM/LXC Proxmox separada. Eventos via SDK no frontend. Dashboards customizados por cockpit.
Email transacional Resend (já em STACK.md §15) Já decidido React Email para templates · BullMQ jobs · DPA assinado
Identidade (IdP) master-login (próprio, JCS) — ADR 0005 Já decidido OAuth2/OIDC, argon2id
Secrets HashiCorp Vault self-host Já decidido KV v2, Vault Agent no container
Object storage MinIO self-host Já decidido S3-compat, presigned POST policy, ClamAV worker
CDN edge Cloudflare Já decidido em STACK.md §18 DNS, edge cache, DDoS, certificados
Logging Grafana Cloud LGTM + Sentry Já decidido OTel + Pino + Sentry
Geolocation (GPS check-in) Browser navigator.geolocation nativo Sem provider externo Web API padrão

⚠️ Decisão aberta: IA generativa

Julian quer estudar todas as opções antes de cravar. Recomendação canônica: abstração multi-provider desde dia 1.

Arquitetura proposta:

  • Camada de abstração: Vercel AI SDK (ai package) ou LiteLLM proxy (Node SDK)
  • Cliente NestJS chama interface única; troca de provider é configuração
  • Providers candidatos a A/B (com critérios de avaliação):
Provider Pros Cons Score qualitativo
Anthropic (Claude) Excelente em raciocínio analítico + pt-BR · JSON estruturado nativo · explicabilidade forte (alinha SAR) Custo médio · ecossistema menor que OpenAI alinhamento com diferencial
OpenAI (GPT) Ecossistema maior · mais SDKs/tools · function calling maduro Drift de qualidade entre versões · custo competitivo
Local/Ollama Sem custo recorrente · máximo controle/privacidade Qualidade inferior · custo de infra Proxmox · velocidade variável para MVP, se LGPD for ultra-rigoroso
Multi-provider (LiteLLM) Hedge total · pode usar local para tarefas simples + cloud para complexas Complexidade de manutenção estratégico

Princípio: estrutura o código para ser provider-agnostic. PR de IA não tem import OpenAI from 'openai' — usa interface JCS.

Marco de decisão: quando 1º cliente fechar e Julian tiver tempo de benchmark dedicado. Até lá, padrão temporário = Anthropic Claude Sonnet/Opus via SDK direto, mas isolado atrás de interface.

Categorias de integração futura (mapa, sem decisão MVP)

Categoria Quando decidir Candidatos
CRM próprio JCS (vender SAR com SAR — dogfood) Y1 O próprio SAR adaptado
Assinatura digital de contratos Y1 DocuSign · ClickSign (BR) · D4Sign (BR)
NFe / NFSe (cobrança JCS para clientes) Y1 quando volume justifica NFe.io · Bling · Iugu pode embutir
CDP / nurturing de leads Y1+ PostHog cobre boa parte; eventualmente HubSpot/RD Station
Helpdesk / suporte ao cliente Pós-MVP Crisp · Zendesk · self-host Cal.com + email
Status page pública Pós-MVP Statuspage.io · Instatus · self-host Cachet

Account ownership (quem cria/gerencia)

Integração Conta de quem Notas
Iugu, Resend, Anthropic/OpenAI, Cloudflare, Meta WhatsApp JCS Sistemas Único proprietário; cobrança vai pra JCS
MinIO, master-login, Vault, GrowthBook, PostHog JCS Sistemas self-host Roda em VMs Proxmox JCS
Google Business Profile (JCS) JCS Sistemas Reivindicar e manter

Contact Strategy (Step 30)

Primary contact method

Form de demo (/contato no site marketing) — alinha com sales-led motion (Step 5).

Campo Obrigatório Por quê
Nome Sim Personalização do follow-up
Email corporativo Sim Canal principal · validador de "B2B real"
Telefone (com DDD) Sim Permite ligação direta · WhatsApp follow-up
Empresa Sim Qualificação inicial
Cargo / função Sim Identifica se é dono/diretor (decisor) ou supervisor (influenciador)
Quantos representantes externos Sim Qualificação principal (sweet spot 5-50)
ERP atual Sim Identifica origem do lead (Grupo 2 da concorrência)
Cidade/UF Sim Roteamento regional eventual
Como nos conheceu Opcional Atribuição de canal (indicação? Google? feira? parceiro?)
Mensagem Opcional Captura intent custom

Channels (canais de contato disponíveis)

Canal Quando aparece Quem responde
Form de demo (CTA principal) Em toda página + header sticky SDR JCS (Julian no início)
Email (contato@sarjcs.com.br ou similar) Footer SDR
Telefone JCS Footer + página /contato SDR (horário comercial BR)
WhatsApp JCS Business Footer + página /contato (clica e abre app) SDR
Página /parceiros Captura indicações de canal Account manager (Julian no início)
Chat ao vivo NÃO no MVP Volta como decisão pós-MVP

Form requirements técnicos

  • Anti-spam: hCaptcha ou Cloudflare Turnstile (não Google reCAPTCHA — LGPD)
  • Validação client-side: Zod schema compartilhado com o backend
  • Submit → cria lead no CRM JCS · dispara notificação Slack/email para SDR · responde "Recebemos seu contato — Julian responde em até 4h úteis"
  • Rate limit: 5 submissions/email/h · 10/IP/h via @nestjs/throttler
  • LGPD: checkbox de consentimento explícito + link para política de privacidade
  • Idempotency: Idempotency-Key header (Zod + nestjs-zod já cobrem)

AI opportunity em contato

Pós-MVP: chatbot pré-qualificador do lead na própria página de contato. Usa o stack de IA generativa (a definir) para responder dúvidas básicas e qualificar antes do SDR atender. Não no MVP — solo founder não vai operar isso bem.

UX implications

  • Form aparece em modal/drawer ao clicar "Agende demo" (não navegação a /contato)
  • Após submit, mensagem clara + próximos passos ("Julian envia uma proposta em até 24h úteis")
  • Email automático imediato confirmando recebimento (Resend + React Email)
  • Lead score automático no CRM (tamanho da equipe + cargo)

Multilingual & SEO (Step 31)

Multilingual (já decidido em Step 16)

  • pt-BR only no MVP · arquitetura i18n-ready (todas strings em pt-BR.json)
  • en preparado no código, sem tradução
  • es (LatAm) fora de escopo (requer adaptação fiscal por país)

URL structure técnica

  • Domínio: sarjcs.com.br (proposta — verificar disponibilidade)
  • pt-BR (default): <dominio>/<slug>
  • en futuro: <dominio>/en/<slug>
  • App produto: app.sarjcs.com.br/ ou <dominio>/app/ (decidir em PRD)
  • Slug: lowercase, hífen, ASCII, sem stopwords desnecessárias

Translation workflow (futuro)

  • Strings vivem em libs/shared/i18n/locales/pt-BR.json (single source)
  • Tradução en.json quando ativar: copy mantido fiel ao tom "consultor sênior" + variantes culturais aplicáveis
  • Sincronização via diff de chaves: CI quebra build se chave faltar em algum locale ativo

Technical SEO requirements (espelha Step 17)

Item Implementação
Meta tags dinâmicas Vite + React Helmet por rota
Sitemap.xml Gerado por script no build · submit Google Search Console
robots.txt Permitir crawling em marketing; noindex em /app/ (produto privado)
Structured data (JSON-LD) Organization (JCS) · SoftwareApplication (SAR home) · Product+Offer (preços) · Article (blog/cases) · FAQPage · BreadcrumbList
Open Graph + Twitter Cards Por rota, com imagem dedicada (screenshot do produto)
hreflang tags Não no MVP (single language); preparado quando i18n ativar
Canonical URLs Em toda página, mesmo o domínio principal
404 customizada Line art mono JCS Blue + "Voltar pra home"
Core Web Vitals Lighthouse > 90 · LCP < 2.5s · CLS < 0.1 · INP < 200ms
Schema.org test Validação no Google Rich Results Test antes de cada deploy

Performance budgets (espelha Step 24)

Métrica Target Bloqueio
Lighthouse Performance (mobile) ≥ 90 CI quebra se < 85
FCP < 1.5s
LCP < 2.5s CI alerta se > 3s
CLS < 0.1
INP < 200ms
Bundle inicial por entry < 200KB gzipped CI alerta se > 250KB
TTI Rafael 3G (PWA) < 3s Validação manual em dispositivo

Maintenance Ownership

MVP (solo founder mode)

Categoria Owner Frequência
Stack updates (npm deps, ADRs, RFC) Julian Trimestral (alinhar com STACK.md cadence)
Deploys (backend + frontend) Julian via Ansible/SSH A cada PR mergeado
Infraestrutura Proxmox (VMs, snapshots, backup) Julian Manutenção mensal, backup diário automatizado
Vault rotation, master-login chaves Julian Trimestral / on-incident
Monitoramento Grafana + Sentry Julian On-call 24/7 (PME pequena)
Integrações (Iugu, Resend, Meta WhatsApp, Cloudflare) Julian On-issue
LGPD ANPD / DPO Julian (com possível advogado externo) On-request
Atualização de templates WhatsApp Meta Julian + revisor de tom On-mudança

Pós-MVP (Y1+)

Categoria Owner futuro
Infraestrutura DevOps/SRE dedicado
Backend dev Time JCS (1-2 devs)
Frontend dev Time JCS (1-2 devs)
QA QA dedicado ou compartilhado com dev
LGPD / Compliance DPO formal (Julian acumula, depois separa)

Risk register

Risco Probabilidade Impacto Mitigação
Meta muda regras WhatsApp Business Média Alto Arquitetura plug-in · alternativa Telegram/SMS no roadmap (Step 9, 10)
Anthropic/OpenAI muda pricing ou política Média Alto Abstração multi-provider (LiteLLM/AI SDK) · capacidade de trocar provider · sempre considerar local fallback
Iugu instabilidade Baixa Alto Multi-provider de pagamento (preparar arquitetura para alternar Pagar.me como backup)
Cloudflare CDN issue Baixa Médio Migrar para AWS CloudFront / Bunny CDN possível em <1 dia
Proxmox failure Baixa Crítico Backup snapshot diário · Plano B: re-provisionamento em outra infra (custo de RTO ~4-8h)
Solo founder ausência prolongada Média Crítico Documentação extensiva em CODING-RULES.md · todos os secrets em Vault recuperável · contratar 1 dev assim que possível

Final synthesis

Visão executiva

O SAR roda na stack canônica JCS v2.2 sem desvios. Decisões de plataforma específicas do produto vivem em Step 10a (Platform Strategy) e neste documento. STACK.md é a fonte da verdade para qualquer questão técnica não específica do SAR.

Tabela síntese (entrar no Brief executivo)

─────────────────────────────────────────────────────────
SAR — Platform Requirements Summary
─────────────────────────────────────────────────────────

Stack:        Node 24 · NestJS 11 · Prisma 7 · PG 18 · React 19 + Vite 8
              + AntD 6.4 · Zod 4 · BullMQ 5.77 · Socket.IO 4 · TanStack
              Query/Router · Zustand
Multi-tenant: BD-por-workspace (cluster PG dedicado/cliente) — ADR 0006
Auth:         master-login (IdP próprio) — ADR 0005
Infra:        Proxmox on-prem BR — ADR 0004
Distribução:  PWA mobile-first iOS · Desktop-first · iPad first-class

Integrations:
  Pagamento:  Iugu (boleto/PIX/cartão + assinaturas recorrentes)
  WhatsApp:   Oficial Meta (Cloud API)
  IA:         Decisão ABERTA — abstração multi-provider (LiteLLM/AI SDK)
              · default temporário: Anthropic Claude
  Analytics:  PostHog self-host (Proxmox)
  Email:      Resend (transacional)
  Storage:    MinIO self-host
  Secrets:    Vault self-host
  CDN:        Cloudflare
  Observ.:    Grafana LGTM + Sentry + OpenTelemetry

Contact:      Form de demo (CTA único) · sem chat ao vivo no MVP
              Anti-spam: hCaptcha/Turnstile · Throttler 5/h por email

Lang:         pt-BR only no MVP · i18n-ready · sem hreflang até ativar en
SEO técnico:  Lighthouse >90 mobile · JSON-LD · sitemap · noindex /app/

Maintenance:  Julian (solo founder mode) até 1º cliente; depois +1-2 devs

─────────────────────────────────────────────────────────

Próximos passos

  • Phase 3 (PRD): detalhar requirements por feature consumindo este doc
  • Phase 4 (UX Specs): cada cockpit referencia constraints de plataforma
  • Phase 5 (Agentic Dev): scaffolding Nx + setup CI/CD via STACK.md

Block D COMPLETO. Próximo: Block E — Wrap-up (Steps 33-36).