# 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).**
