# Design Log

**Project:** SAR — Força de Vendas
**Started:** 2026-05-26
**Method:** Whiteport Design Studio (WDS)

---

## Backlog

> Business-value items. Add links to detail files if needed.

- [ ] Complete product brief — Phase 1 (`A-Product-Brief/`)
- [ ] Define trigger map — Phase 2 (`B-Trigger-Map/`) — 3 personas hipotéticas: rep externo, supervisor, admin
- [ ] Create user scenarios — Phase 3 (`C-UX-Scenarios/`)
- [ ] Page specifications — Phase 4 (`C-UX-Scenarios/<scenario>/<page>/`)
- [ ] Design System overlay sobre AntD 6.4 — Phase 6 (`D-Design-System/`)
- [ ] Agentic development — Phase 5 (`E-Development/`)

---

## Current

| Task | Started | Agent |
|------|---------|-------|
| Phase 0 setup | 2026-05-26 | wds-0-project-setup |

**Rules:** Mark what you start. Complete it when done (move to Log). One task at a time per agent.

---

## Design Loop Status

> Per-page design progress. Updated by agents at every design transition.

| Scenario | Step | Page | Status | Updated |
|----------|------|------|--------|---------|

**Status values:** `discussed` → `wireframed` → `specified` → `explored` → `building` → `built` → `approved` | `removed`

---

## Log

### 2026-05-26 — Project initialized (Phase 0)
- Type: greenfield
- Complexity: complex (Web Application, SaaS B2B multi-tenant)
- Tech stack: STACK.md JCS v2.2 — React 19.2 + Vite 8 + Ant Design 6.4 / NestJS 11.1 + Prisma 7 + PostgreSQL 18 / Proxmox on-prem
- Existing materials: `brand.md`, `STACK.md`, `CODING-RULES.md`, logos em `frontend/img/`
- Strategic analysis: full (Phase 2 habilitada)
- Brief level: complete
- Stakes: small-business (JCS Sistemas)
- Active agents: Saga (estratégia), Freya (design)
- **Next:** `skill:wds-1-project-brief` com Saga

### 2026-05-26 — Phase 1 Steps 1, 1a, 2 concluídos
- **Step 1 (Init):** materiais adicionais identificados — mockup SPA legado (`index.html` 2251 linhas, 9 telas, login excluído).
- **Step 1a (Client Profile):** JCS = PME software house 11-50p, tech maturity alta + design iniciante. Julian acumula PO + Tech Lead + único Champion, autonomia total. Cultura fast-individual. SAR é upgrade-de-tier para SaaS web vendável (não conserto de legado).
- **Step 2 (Vision):** SAR oferece 3 experiências distintas (rep operacional / supervisor tático / dono estratégico+IA). 6 diferenciais explícitos: inteligência de carteira, WhatsApp nativo, metas gamificadas, camadas por papel, IA estratégica, SaaS web distribuível.

### 2026-05-26 — Phase 1 Step 3 (Positioning) concluído
- **Target:** Distribuidoras / indústrias / RCAs / PMEs com 5-50 reps externos (sweet spot mid-SMB).
- **Dor central:** Donos e supervisores decidem no escuro — falta visibilidade em tempo real do que acontece na rua.
- **Concorrência:** Apps verticais (Mercos/Promosoft/MaxFV/Workforce/Mobits), módulos de ERP (TOTVS/Sankhya/Senior), stack improvisado (Excel+WhatsApp+ERP), apps caseiros.
- **Estratégia:** Coexistência com ERPs (não migração total) — multi-tenancy BD-por-workspace facilita integração heterogênea. WhatsApp+IA no MVP, não em roadmap.
- **Próximo:** Step 5 — Business Model.

### 2026-05-26 — Phase 1 Step 5 (Business Model) concluído
- **Modelo:** B2B SaaS per-seat, sales-led, trial 14-30 dias, contrato híbrido mensal/anual.
- **Ticket médio:** R$ 750-7.500/mês (porte pequeno a médio alto).
- **Implicações técnicas:** active rep counter no produto; provisioning automatizado de workspace para trial; billing suporta cobrança mensal recorrente + anual única; reusa BD-por-workspace (ADR 0006) para sandbox.
- **Implicações marketing:** CTA "Agende demo", trial gated por SDR, pricing page no site.
- **Próximo:** Step 6 — Business Customers.

### 2026-05-26 — Phase 1 Step 6 (Business Customers) concluído
- **Buyer persona:** "Dono Empresário B2B" — 35-60 anos, sócio-fundador, decide na fé+demo+boca-a-boca.
- **Decisão:** dono OU diretor comercial. Influenciadores chave: supervisor + reps. **Ausentes: financeiro, TI, jurídico** (venda operacional-emocional).
- **Canais:** indicação + SEO + feiras + parceiros (todos os 4 ativos).
- **Ciclo:** 2-4 semanas (pequeno) → 2-4 meses (médio alto).
- **Implicações chave:** site precisa 3 páginas por papel, comparativos diretos com concorrentes, demo-friendliness obrigatória, JCS precisa de CRM próprio (possível dogfood).
- **Próximo:** Step 7 — Target Users (3 user personas: rep / supervisor / dono).

### 2026-05-26 — Phase 1 Step 7 (Target Users) concluído
- **4 personas confirmados:** Rafael (Rep — PRIMÁRIA, mobile-first), Sandra (Supervisora), Daniel (Dono+IA), **Alice (Admin — nova)** com responsabilidade por campanhas/promoções, pautas e tributação.
- **Decisão crítica de design:** mobile-first para Rafael, desktop-first para os outros 3. SAR são 2 paradigmas de UI no mesmo produto.
- **Diferenciais reforçados:** editor de campanhas no-code (Alice), assistente ICMS-ST (Alice), auditoria de pautas (Alice+regulatório), comissão em tempo real (Rafael), IA explicável (Daniel).
- **Insight de venda:** demo precisa brilhar para Sandra, vender para Daniel, encantar Rafael. Alice é benefício, não argumento.
- **Próximo:** Step 7a — Product Concept.

### 2026-05-26 — Phase 1 Step 7a (Product Concept) concluído
- **Concept canônico:** "SAR é uma plataforma de 4 cockpits especializados (Rep / Supervisor / Dono / Admin) compartilhando um dado único em tempo real, atravessado por WhatsApp nativo e IA contextual."
- **Metáfora:** equipe de Fórmula 1 — cada papel tem seu próprio dashboard sobre o mesmo carro em telemetria real.
- **4 princípios:** cada cockpit com UX/device próprios; tempo real (Socket.IO/SSE); WhatsApp+IA como fios horizontais; multi-tenancy BD-por-workspace.
- **Tensões aceitas:** 4 paradigmas UX vs 1 responsivo; tempo real obrigatório; WhatsApp/IA pilares desde MVP.
- **Implicação:** Phase 6 (Design System) deixa de ser opcional — tokens compartilhados + variantes por cockpit.
- **Próximo:** Step 8 — Success Criteria.

### 2026-05-26 — Phase 1 Step 8 (Success Criteria) concluído
- **North star MVP:** 1º cliente paga e renova nos primeiros 3 meses após go-live.
- **Y1:** 10-20 clientes (conservador) · NPS donos > 50 · ARR R$ 200k-600k.
- **Timeline:** MVP em 3-4 meses → cliente renova em mês 6-7 → 10 clientes pagantes em mês 12.
- **Métricas em 4 camadas:** negócio JCS · cliente · comportamento usuário · qualidade técnica.
- **Implicação:** instrumentação de produto (OTel/Grafana/analytics/NPS) no MVP, não em roadmap.
- **Próximo:** Step 9 — Competitive Landscape.

### 2026-05-26 — Phase 1 Step 9 (Competitive Landscape) concluído
- **5 grupos analisados:** apps verticais (Mercos+), ERPs com módulo (TOTVS+), stack improvisado, apps caseiros, **do-nothing** (50%+ dos prospects).
- **5 unfair advantages estruturais:** 4 cockpits + multi-tenancy BD-por-workspace + stack moderna + IA estrutural + velocidade JCS.
- **Posição alvo:** vendas-first + baixo atrito de implantação.
- **Estratégia de venda:** demo ataca do-nothing primeiro (urgência), coexistência com ERPs para Grupo 2.
- **Janela de mercado:** 2-3 anos para entrincheirar; velocidade MVP é decisão estratégica.
- **Próximo:** Step 10 — Constraints.

### 2026-05-26 — Phase 1 Step 10 (Constraints) concluído
- **Tensão estratégica flagueada:** concept ambicioso + 3-4 meses + **solo founder mode** não comportam concept completo no MVP.
- **Resolução proposta:** MVP mínimo defensível = Rafael + Sandra completos + Daniel/Alice simplificados + WhatsApp básico (sem IA). IA + editor no-code entram pós-MVP.
- **Premissa:** 1º cliente é referência/parceiro, aceita limitações; quando renova, Julian contrata 1-2 devs e completa.
- **Constraints fixos:** STACK.md v2.2, brand.md, LGPD by design, Proxmox on-prem BR, multi-tenancy BD-por-workspace.
- **Flexível:** providers (pagamento, IA, WhatsApp), analytics, dark mode.
- **Próximo:** Step 10a — Platform Strategy.

### 2026-05-26 — Phase 1 Step 10a (Platform Strategy) concluído
- **Plataforma primária:** Web SaaS (React SPA + Cloudflare + Nginx).
- **Rafael:** **PWA mobile-first com foco iOS** (Android continua com app legado por enquanto).
- **Sandra:** Desktop + PWA mobile-light.
- **Daniel:** Desktop + iPad first-class.
- **Alice:** Desktop-only.
- **Coexistência:** Android legado intocado no MVP; pós-MVP adapta para consumir backend SAR; futuro avalia native iOS+Android sobre SAR.
- **Offline:** Read + Write com sync (IndexedDB + Service Worker) para Rafael.
- **Native features MVP:** Geolocation, Web Push, Share API, Notification API. Camera/File API pós-MVP.
- **Acessibilidade:** WCAG AA desde MVP.
- **Próximo:** Step 11 — Tone of Voice.

### 2026-05-26 — Phase 1 Step 11 (Tone of Voice) concluído
- **5 atributos canônicos:** Direto · Profissional sem ser frio · Confiante · Específico · Empático nos momentos difíceis.
- **Variações por cockpit:** Rafael (informal/curto), Sandra (decisivo), Daniel (executivo), Alice (técnico-preciso).
- **Vocabulário canônico:** Cliente · Rep · Orçamento · Pedido · Faturado · Visita · Carteira · Inativo · Painel · Aprovação.
- **Don'ts:** emoji em produção, caps lock erros, burocratês, anglicismos desnecessários, frases dúbias.
- **Implicação:** vocabulário vira tokens i18n; Phase 6 inclui guia microcopy; prompt de IA generativa precisa carregar atributos + vocabulário.
- **Próximo:** Step 12 — Create Product Brief (consolidação dos Steps 1-11 num documento canônico).

### 2026-05-26 — Phase 1 BLOCK A (Product Brief) CONCLUÍDO ✅
- **Brief canônico gerado:** `design-artifacts/A-Product-Brief/01-product-brief.md`
- **14 steps concluídos** (1, 1a, 2, 3, 5, 6, 7, 7a, 8, 9, 10, 10a, 11, 12)
- **Tempo decorrido:** ~2-3h em uma sessão
- **Confirmação:** narrativa estratégica apresentada e confirmada sem ajustes
- **Próximo:** Block B (Content & Language) — Steps 13-18.

### 2026-05-27 — Phase 1 BLOCK B (Content & Language) CONCLUÍDO ✅
- **Documento canônico gerado:** `design-artifacts/A-Product-Brief/02-content-language.md`
- **7 steps concluídos** (13, 14, 15, 16, 17, 17a, 18)
- **Personality:** "Consultor sênior brasileiro de vendas B2B" (5 atributos)
- **Tone spectrums:** Formality 3 · Mood 2 · Complexity 3 · Energy 2
- **Languages:** pt-BR only no MVP, i18n-ready
- **SEO:** 6 intents de keywords · sitemap robusto · structured data plan · page-keyword map top 10
- **Content Structure:** 10 princípios site + 11 princípios produto + 8 exclusões explícitas
- **Content guidelines:** UI/Marketing/Info/Email/WhatsApp/IA + ownership + checklist 13 itens
- **Próximo:** Block C (Visual Direction) — fast-track via brand.md.

### 2026-05-27 — Phase 1 Step 19 (Inspiration Workshop) concluído
- **🌟 Insight estratégico:** "Não acho nada no mercado de identidade como inspirador — uma das coisas que nos trouxe para esse projeto" → **estética moderna é parte do diferencial fundacional do SAR**, adicionar como 6º unfair advantage no Brief.
- **4 referências externas:** Apple iCloud · Linear · Stripe Dashboard · Notion (todas fora do setor B2B força de vendas BR, propositalmente).
- **7 padrões destilados:** sidebar fixa + tipografia hierarquia + único accent JCS + densidade respirável + animações sutis + dark mode + empty states informativos.
- **Referências por cockpit** mapeadas para alimentar Phase 4.
- **Próximo:** Step 20 — Visual Init.

### 2026-05-27 — Phase 1 BLOCK C (Visual Direction) CONCLUÍDO ✅
- **Documento canônico:** `design-artifacts/A-Product-Brief/03-visual-direction.md`
- **8 steps concluídos** (19, 20, 21, 22, 23, 24, 25, 26)
- **Insight estratégico:** estética moderna é parte do diferencial fundacional do SAR (6º unfair advantage)
- **Visual DNA:** Modern Flat + Minimal · JCS Blue mono + accents · Plus Jakarta Geometric Humanist · Clean/Confident/Specific/Serene/Modern · split hero + cockpits diferenciados · effects sutis · screenshots-only Apple-style
- **Próximo:** Block D (Platform Requirements) — fast-track via STACK.md.

### 2026-05-27 — Phase 1 BLOCK D (Platform Requirements) CONCLUÍDO ✅
- **Documento canônico:** `design-artifacts/A-Product-Brief/04-platform-requirements.md`
- **6 steps concluídos** (27, 28, 29, 30, 31, 32) — batched após Step 27
- **Tech Stack:** espelho de STACK.md v2.2 (Node 24 + Nest 11 + Prisma 7 + React 19 + AntD 6.4 + multi-tenant BD-por-workspace ADR 0006 + Proxmox on-prem ADR 0004)
- **Integrações fechadas:** Iugu (pagamento) · Meta Cloud API oficial (WhatsApp) · PostHog self-host (analytics)
- **Integração ABERTA:** IA generativa — abstração multi-provider (Vercel AI SDK/LiteLLM) com default temporário Anthropic Claude
- **Contact strategy:** Form de demo como único CTA; sem chat ao vivo no MVP
- **Multilingual:** pt-BR only, i18n-ready · Lighthouse > 90 como CI gate
- **Maintenance:** solo founder mode até 1º cliente
- **Próximo:** Block E (Wrap-up) — Steps 33-36.

### 2026-05-27 — Phase 1 BLOCK E (Wrap-up) CONCLUÍDO ✅ — PHASE 1 INTEIRA COMPLETA 🎉

**Steps concluídos:** 33 (Analyze), 34 (Summary), 35 (Update Design Log), 36 (Provide Activation Phase 2).

**Handover document:** `design-artifacts/A-Product-Brief/00-handover-summary.md`

**Artefatos canônicos finais (todos em `design-artifacts/A-Product-Brief/`):**
- `00-handover-summary.md` ⭐ entrada para Phase 2
- `01-product-brief.md` ⭐ brief estratégico (Block A)
- `02-content-language.md` (Block B)
- `03-visual-direction.md` (Block C)
- `04-platform-requirements.md` (Block D)
- `dialog/` (16 documentos de histórico detalhado)

**Tempo total Phase 1:** ~6-8 horas em 2 dias (2026-05-26 + 2026-05-27).

**Steps completados:** 36/36 ✅

**Decisões abertas conscientemente:**
- Provider de IA generativa (resolver pré-feature IA)
- Preço per-seat exato (validar com primeiras vendas)
- Setup fee, add-ons premium, contratações futuras, JCS team photos

**Tensão estratégica documentada:**
- Solo founder + 3-4 meses + concept ambicioso → MVP minimalista (Rafael+Sandra completos; Daniel+Alice simplificados; IA+editor no-code pós-MVP).

**Próximo:** Phase 2 — Trigger Mapping (skill `wds-2-trigger-mapping` com Saga). 5 workshops sequenciais. Output em `design-artifacts/B-Trigger-Map/`.

### 2026-05-27 — Phase 2 (Trigger Mapping) CONCLUÍDA ✅ (Dream mode)
- **7 documentos gerados** em `design-artifacts/B-Trigger-Map/`:
  - `00-trigger-map.md` (hub + mermaid diagram + síntese + priorização MVP)
  - `01-business-goals.md` (5 BGs refinados do Brief)
  - `personas/02-rafael-representante.md` (PRIMARY MVP)
  - `personas/03-sandra-supervisora.md` (influenciadora compra)
  - `personas/04-daniel-dono.md` (IA + buyer overlap)
  - `personas/05-alice-admin.md` (operacional)
  - `06-feature-impact-analysis.md` (matrix Features × Forças × Personas)
- **Session log:** `_progress/agent-experiences/2026-05-27-trigger-map-D.md`
- **Modo:** Dream (autonomous) com self-review
- **Tempo total:** ~15-20 min de geração
- **5 business goals canônicos:** BG-1 PMF · BG-2 Referenciabilidade · BG-3 Modernidade · BG-4 Coexistência ERPs · BG-5 Fundação técnica
- **Driving forces por persona:** 5-7 por persona, mix positivo+negativo, scored Freq×Int×Fit
- **Tensões críticas resolvidas:** R-7↔S+6 (vigia↔talento) · D+4↔D-6 (IA↔black-box) · Sandra ops↔Daniel estratégico · concept↔solo founder
- **Priorização MVP fechada:** P0 (lançamento offline, multi-tenant, real-time, 0 pedidos perdidos) → MVP core → MVP-light → pós-MVP
- **Próximo:** Phase 3 — UX Scenarios (skill `wds-3-scenarios`).

### 2026-05-27 — Phase 3 pausada em Step 2 (decisão estratégica de paralelizar com setup)
- **Step 1+2 concluídos:** site type = Mixed, 65 páginas inventariadas, **7 scenarios MVP aprovados** (Marketing→Demo · Trial Onboarding · 4 cockpits · Cross-cockpit Real-Time Flow)
- **Decisão pragmática (escolha Julian):** pausar detalhamento dos outlines em Phase 3 e **começar setup do monorepo HOJE em paralelo**. Phase 4 page specs serão feitas just-in-time por feature, junto com o PR de implementação.
- **Outlines Phase 3 detalhados (Steps 5+):** retomar quando primeiro cockpit precisar ser implementado.
- **Próximo:** **Setup do monorepo SAR** — pnpm + Nx + Nest + Prisma + Vite + React + Docker Compose + git Gitea.

### 2026-05-27 — Setup do monorepo SAR CONCLUÍDO ✅ (Fases 1-9)
- **Commit inicial:** `17c08e6 chore: initial monorepo scaffold + WDS Phase 1+2 artifacts` (3.631 arquivos, local, sem push)
- **Stack ativa:** pnpm 11.1.0 · Node 24.15.0 · Nx 22.7.4 · TypeScript 5.9.3 · Prettier 3.8.3
- **5 projetos Nx:** api · api-e2e · web · web-e2e · api-interface
- **Build geral:** ✅ todos os 3 projetos buildáveis passam
- **Docker Compose dev** criado (Postgres 18 · Valkey 8 · MinIO · Mailpit) — não iniciado ainda
- **`.env.example`** template completo com todas as variáveis críticas
- **README.md + AGENTS.md** criados como entrada para devs/agentes
- **Git remote:** `https://git.jcsinformatica.com.br/Julian/sar` configurado (push diferido)
- **Próximos passos sugeridos:**
  1. Criar repo no Gitea e fazer push (`git push -u origin main`)
  2. Subir Docker Compose dev (`pnpm dev:up`)
  3. Implementar master-login stub (auth real virá depois)
  4. Implementar multi-tenant BD-por-workspace via Prisma factory + cls
  5. Primeira tela viva: login + painel Rafael (vazio)

### 2026-05-27 — Foundation API (Frente A) CONCLUÍDA ✅
- **10 tarefas executadas (A1-A10):** tsconfig hardening · tracing stub · Zod env · Pino+redact LGPD · main.ts hardening · RFC 9457 filter · health endpoints · CLS workspace · /api/v1/ping · build+lint+smoke
- **Estrutura `apps/api/src/`:**
  - `tracing.ts` — primeiro import (PGD-OBS-001), OTel SDK ativável por env
  - `main.ts` — helmet · CORS por env · compression · versionamento URI `/api/v1` · graceful shutdown · Pino logger global
  - `app/config/` — EnvSchema Zod 4 com `superRefine` (fail-fast prod, defaults dev) + EnvModule global
  - `app/logger/` — nestjs-pino com redact `*.cpf|*.cardNumber|*.password|authorization|cookie`, ignora `/health/*`, pretty em dev
  - `app/filters/problem-details.filter.ts` — RFC 9457 `application/problem+json`, Zod → 422 com array `errors`, type URIs em `https://docs.sar.jcs.com.br/errors/*`
  - `app/health/` — `/health/live` e `/health/ready` (skeleton, K=3 LRU pool placeholder documentado)
  - `app/workspace/` — ClsModule.forRootAsync com `setup` populando requestId+workspaceId; idGenerator alinha com pino-http (mesmo UUID header+body)
  - `app/ping/` — `GET /api/v1/ping` retornando status+service+version+workspaceId+requestId+uptime+now
  - `app.module.ts` — APP_PIPE: ZodValidationPipe (nestjs-zod) · APP_FILTER: ProblemDetailsFilter
- **Dependências instaladas (root):** @nestjs/config 4.0 · @nestjs/terminus 11.1 · nestjs-pino 4.6 · pino 9.14 · pino-http 10.5 · pino-pretty 13.1 · nestjs-zod 4.3 · nestjs-cls 5.4 · helmet 8.2 · compression 1.8 · zod (catalog) · @types/express · @types/compression
- **Smoke test verde:** `GET /api/v1/ping` → 200 com workspaceId+requestId · `/health/live` + `/health/ready` → 200 (heap OK) · `/api/v1/nope` → 404 application/problem+json · CORS preflight: localhost:4200 permitido, evil.com bloqueado · helmet headers todos presentes (HSTS, X-CTO, X-Frame-Options, etc.) · `x-request-id` propagado em todas as responses
- **Hello-world boilerplate removido** (app.controller/service/specs)
- **Pendente próxima sessão:**
  1. **Frente C — Zod contracts compartilhados** (`libs/shared/api-interface`): primeiro DTO real (createZodDto) consumido por API + Web
  2. **Frente D — ESLint boundaries** (3 tags Nx canônicas) + Husky+gitleaks
  3. **Web → API integração:** `apps/web` chamar `/api/v1/ping` via TanStack Query (validar fundação ponta-a-ponta no browser)
  4. **OpenTelemetry SDK** plugar quando entrar em catálogo (stub atual mantém posição correta)
  5. **Master-login + WorkspacePrismaPool** (próxima frente arquitetural pesada)
  6. **Docker compose dev**: subir e validar healthcheck (`pnpm dev:up`)

### 2026-05-27 — Foundation Web (Frente B) CONCLUÍDA ✅
- **Commit:** `3a42723 feat(web): foundation com brand JCS + AntD theme + Rafael painel placeholder`
- **Tokens CSS** em `apps/web/src/styles/tokens.css` espelhando brand.md (paleta, tipografia, layout, motion, spacing, type scale)
- **Plus Jakarta Sans Variable** self-host via `@fontsource-variable/plus-jakarta-sans` (LGPD + performance)
- **AntD ConfigProvider tema JCS** em `apps/web/src/lib/theme.ts` — colorPrimary #004a99, radius 12/20, sombra canon, motion sutil
- **TanStack Query + Router** setup com defaults conservadores (no refetchOnFocus, retry 5xx, no mutation retry — Idempotency-Key cobre)
- **Layout shell:** Topbar 80px + Sidebar 260px com 9 itens cockpit Rafael (FA outline icons)
- **RafaelPainel placeholder** com copy canônica + mock data:
  - "Bom dia, Rafael" + agenda do dia
  - Meta de maio (R$ 47.600 / R$ 60.000 = 79%) com Progress JCS Blue
  - "Pedidos no mês" (28, +18% vs abril) · "Comissão" (R$ 2.540, FLEX R$ 380)
  - "Clientes esfriando" — OPENFRIOS 47 dias, etc. — vocabulário canon
  - "Próxima visita" OPENFRIOS 14:30
- **Build OK:** 878KB JS (~250KB gzip) — vai code-splitar quando cockpits virarem rotas separadas
- **Dev server:** http://localhost:4200/ servindo com title, theme-color, lang pt-BR corretos
- **Pendentes próxima sessão:** Frente A (API foundation), C (Zod contracts), D (ESLint+boundaries), Docker permissions, **abrir browser e validar visualmente**

### 2026-05-27 — Frente C (Zod contracts shared) + Docker dev healthy CONCLUÍDA ✅
- **Escopo da sessão:** 1+2 do roadmap pendente — subir compose dev + criar primeiro contrato Zod compartilhado API↔Web.
- **`libs/shared/api-interface/` reescrita:**
  - `src/lib/ping.contract.ts` — `PingResponseSchema` (z.object com `status: z.literal('ok')`, `requestId: z.uuid()`, `now: z.iso.datetime()`, etc.) + tipo inferido `PingResponse`. Comentário registra a decisão arquitetural abaixo.
  - `src/lib/ping.contract.spec.ts` — 6 testes vitest (1 happy + 5 rejeições: status, uuid, uptime negativo, datetime inválido, workspaceId vazio).
  - `src/index.ts` — reaponta para `ping.contract`. Placeholders `api-interface.{ts,spec.ts}` deletados.
  - `package.json` — `+zod: catalog:` (sai do dependency-checks do Nx limpo).
- **Decisão arquitetural — lib stays framework-free:** `createZodDto` (nestjs-zod) **NÃO** vai pra `@sar/api-interface`. A Web vai consumir essa mesma lib e não pode arrastar dependência de framework backend. A lib carrega só Zod schema + tipo `z.infer`; quando precisar de DTO-class pro pipe, fica na camada API (`apps/api`). Alinha com CODING-RULES §06 ("schema é o contrato; DTO é a classe que o expõe").
- **`apps/api/src/app/ping/ping.controller.ts`** — `import type { PingResponse } from '@sar/api-interface'`, interface inline removida. Comportamento idêntico (CLS, uptime, version).
- **Validação:** `nx run-many -t lint build -p api,api-interface` ✅ · `nx run api-interface:test` 6/6 ✅.
- **Pegadinha Postgres 18+ encontrada e fixada (canon JCS):**
  - `pnpm dev:up` deu container `sar-postgres Restarting (1)` com erro "in 18+, these Docker images are configured to store database data in a format which is compatible with pg_ctlcluster (specifically, using major-version-specific directory names). Counter to that, there appears to be PostgreSQL data in: /var/lib/postgresql/data (unused mount/volume)".
  - Causa: Postgres 18+ mudou o layout do mount canônico de `/var/lib/postgresql/data` para `/var/lib/postgresql` (dados em subdir `18/main`) para suportar `pg_upgrade --link` sem boundary issues. Ref: `docker-library/postgres#1259`.
  - Fix: `docker-compose.dev.yml` postgres.volumes → `- sar-postgres-data:/var/lib/postgresql`. Comentário inline explicando o porquê.
  - Volume `sar-postgres-data` removido (`docker volume rm`) e compose religado limpo. Sem perda de dados (era primeiro boot).
- **Pegadinha permissão Docker (registro pra próximas máquinas dev):**
  - Usuário fora do grupo `docker` → `permission denied` no `/var/run/docker.sock`. Fix: `sudo usermod -aG docker $USER` + `newgrp docker` (efeito imediato na sub-shell) ou logout/login para fixar em todos terminais novos. Aceitável em desktop dev pessoal; em servidor compartilhado, **não** (grupo docker ≡ root local).
- **Stack dev validada healthy:**
  - `sar-postgres` (18-alpine) 5432 ✅ — BDs `sar_master` + `sar_workspace_dev`, extensions `pgcrypto`+`uuid-ossp` no workspace e `pgcrypto`+`plpgsql` no master.
  - `sar-valkey` (8-alpine) 6379 ✅ — `+PONG`.
  - `sar-minio` (latest) 9000+9001 ✅ — `/minio/health/live` HTTP 200; console UI em http://localhost:9001.
  - `sar-mailpit` (latest) 1025+8025 ✅ — web UI em http://localhost:8025.
- **Pendente próxima sessão (em ordem recomendada):**
  1. **Web→API integração ponta-a-ponta** — `apps/web` chama `/api/v1/ping` via TanStack Query + `PingResponseSchema.parse(...)` na response. Fecha o loop B+C; prova que o contrato Zod funciona dos dois lados.
  2. **Frente D — ESLint boundaries** (tags Nx `scope:* · type:* · domain:*`) + Husky + gitleaks.
  3. **Phase 3 WDS — PRD** via `/bmad-prd create` antes de qualquer modelagem de domínio.
  4. **Master-login stub + WorkspacePrismaPool** (frente arquitetural pesada — depende de #3).
  5. **OpenTelemetry SDK** plugar quando entrar em catálogo (stub atual mantém posição).

### 2026-05-27 — Web→API ponta-a-ponta (loop B+C fechado) CONCLUÍDO ✅
- **Escopo da sessão:** Pendência #1 do roadmap — provar que `@sar/api-interface` é honrado pelos dois lados em runtime, não só em build time. Loop B (Web foundation) + C (Zod contracts) fechado.
- **Arquivos novos:**
  - `apps/web/src/lib/api-client.ts` — fetch wrapper que parseia `application/problem+json` (RFC 9457) em `ApiError` estruturado carregando status+type+title+detail+requestId+errors[]. Sem validação Zod aqui — responsabilidade do caller (CODING-RULES §05).
  - `apps/web/src/lib/queries/ping.ts` — `useApiPing()` TanStack Query chamando `/api/v1/ping` + `PingResponseSchema.parse(...)`. Drift servidor falha alto **antes** de chegar nos componentes. `refetchInterval: 30s` (Visual DNA "sereno").
  - `apps/web/src/components/layout/FoundationStatus.tsx` — pill discreto na Topbar (verde/vermelho/cinza) com Tooltip detalhando service+version+workspaceId+requestId+uptime. Pulse `processing` no refetch silencioso. Conscientemente temporário — quando produto entrar em normal, vira indicador só em `/health`.
- **Modificados:**
  - `apps/web/vite.config.mts` — `server.proxy['/api']: http://localhost:3000`. Evita CORS em dev e mantém URL relativa no código da Web; em produção, Nginx roteia mesmo origin. `changeOrigin: false` (mesma host).
  - `apps/web/src/components/layout/Topbar.tsx` — `<FoundationStatus />` antes do sino.
- **Validação ponta-a-ponta:**
  - `nx run web:lint` ✅ · `nx run web:build` ✅ (821ms, 309KB gzip)
  - `curl :4200/api/v1/ping` via proxy Vite → `200 application/json` com payload contratual completo (`status=ok`, `workspaceId=dev-workspace`, `requestId`, `uptimeSeconds=144`, `now`)
  - `curl :4200/api/v1/nope` → `404 application/problem+json` com `type/title/detail/instance/requestId` — prova que `ApiError` captura erro estruturado quando servidor falhar
  - Headers helmet, x-request-id, CORS expose-headers passam pelo proxy intactos
- **Decisão arquitetural confirmada:** Web consome lib `@sar/api-interface` sem arrastar nada do Nest. `PingResponseSchema` viaja como Zod puro; `ApiError` na Web não conhece `HttpException` do Nest — só o contrato HTTP+JSON. Alinhamento com regra "lib stays framework-free" da sessão anterior.
- **Pegadinhas notadas (não bloquearam):**
  - `_sidebarOpen` no AppShell ainda tem `eslint-disable` — fica pra Frente D ou primeiro responsivo mobile.
  - Bundle Web 976KB (309KB gzip) — code-splitting esperado quando rotas de cockpit virarem separadas (TanStack Router suporta nativo). Não age agora.
- **Pendente próxima sessão (ordem atualizada):**
  1. **Frente D — ESLint boundaries** (tags Nx `scope:* · type:* · domain:*`) + Husky + gitleaks. Higiene de PR antes de feature pesada.
  2. **PRD WDS** via `/bmad-prd create` antes de modelar domínio.
  3. **Master-login stub + WorkspacePrismaPool** (frente arquitetural — depende do PRD).
  4. **OpenTelemetry SDK** plugar quando entrar no catálogo.

### 2026-05-27 — Frente D (ESLint boundaries + Husky + commitlint + gitleaks) CONCLUÍDA ✅
- **Escopo da sessão:** Higiene de PR — guardrails de qualidade antes da primeira feature de domínio.
- **D1 — Tags Nx + depConstraints:**
  - Tags `scope:api|web|shared`, `type:app|e2e|util`, `domain:shared` adicionadas em todos os 5 projetos (e2e estavam vazios).
  - `eslint.config.mjs` depConstraints substituído por regras explícitas em 3 eixos:
    - `scope`: api só usa api+shared; web só usa web+shared; shared não importa código de app-scope.
    - `type`: apps dependem só de libs (feature/util/data); e2e só do seu app-par + utils; utils são folha.
  - `nx run-many --skip-nx-cache` verde em todos os 3 projetos com as novas regras.
- **D2 — Husky + lint-staged:**
  - `husky 9` + `lint-staged 17` instalados. `prepare: "husky"` no `package.json`.
  - `pre-commit`: `eslint --max-warnings=0` + `prettier --check` só nos arquivos staged (rápido, sem varrer repo inteiro).
- **D3 — commitlint:**
  - `@commitlint/cli` + `@commitlint/config-conventional` instalados.
  - `commitlint.config.js`: tipo obrigatório, subject lowercase, scope enum como `warn` (não `error` — permite escopos novos sem bloquear), body/footer ilimitados.
  - Hook `commit-msg` ativo. Smoke test: mensagem inválida → 2 erros; mensagem válida → pass.
- **D4 — gitleaks via Docker:**
  - `.gitleaks.toml` criado com `useDefault = true` + allowlist para `.agents/`, `.claude/`, `tmp/`, `.env.example`, `pnpm-lock.yaml`.
  - Iteração em 3 rodadas para zerar falsos positivos: (1) JWTs de exemplo em BMad skills → excluir `.agents/` e `.claude/`; (2) `tmp/gitleaks-report.json` autopoluindo scan → excluir `tmp/` + adicionar ao `.gitignore`; (3) zero leaks no tree completo.
  - Pre-commit roda via `docker run --rm -v ... zricethezav/gitleaks:latest`; fallback silencioso se Docker indisponível (socket sem permissão no contexto do hook — comportamento correto; CI usa binário nativo).
- **Pegadinha do commit-msg:** subject-case do commitlint rejeita "F" maiúsculo em "Frente D" — subject deve ser lowercase. Corrigido na mensagem de commit.
- **Pegadinha Docker no hook:** `sg docker` não funciona em hooks não-interativos. Solução: fallback com `echo` + warning, e usar `sudo usermod -aG docker $USER` + logout/login para resolver permanentemente no desktop dev.
- **Pendente próxima sessão (ordem atualizada):**
  1. **PRD WDS** via `/bmad-prd create` antes de modelar qualquer domínio. Desbloqueia master-login + WorkspacePrismaPool.
  2. **Master-login stub + WorkspacePrismaPool** (frente arquitetural pesada — depende do PRD).
  3. **OpenTelemetry SDK** plugar quando entrar no catálogo.

### 2026-05-27 — PRD MVP FINALIZADO ✅ (`status: final`)
- **Workspace:** `_bmad-output/planning-artifacts/prds/prd-sar-2026-05-27/`
- **Artefatos:** `prd.md` (final) + `.decision-log.md` (8 decisões registradas)
- **Working mode:** Fast Path — Julian definiu escopo em uma frase; documentos Phase 1+2 foram fonte de verdade via extração por subagentes.
- **Escopo MVP fechado:** 9 capacidades (C1–C9) · 45 FRs · 3 jornadas de usuário · 6 NFRs — cockpits Rafael + Sandra.
- **Cockpits fora do MVP:** Daniel e Alice → telas placeholder apenas.
- **Decisões chave:**
  - WhatsApp = Share API nativa (sem Meta Cloud API no MVP)
  - ERP = importação manual (CSV/JSON); sem integração automática
  - Aprovação de desconto inclusa no MVP (confirmado explicitamente)
  - Limite de crédito numérico e inadimplência requerem conexão (não cacheados offline)
  - Falha de sync: Pedido retorna com status `falha de sync` + motivo; nunca descartado silenciosamente
- **OQs abertas (6):** OQ-1/OQ-4 são phase-blockers para C2/C4 — dependem do primeiro cliente. OQ-3/OQ-6 são non-blockers.
- **Reviewer gate:** 1 revisor subagente — veredito "Aprovado com Ressalvas"; 3 achados incorporados antes do `final`.
- **Pendente próxima sessão (ordem atualizada):**
  1. **OpenTelemetry SDK** plugar quando entrar no catálogo.
  2. **Design C2/C4** (Consulta de Clientes + Lançamento de Pedido) — após resolver OQ-1 e OQ-4 com o primeiro cliente.

### 2026-05-27 — Master-login stub + WorkspacePrismaPool COMPLETO ✅

**Entregas (M1–M7):**

- **M1 — Prisma 7 config corrigida:** `prisma.config.ts` usa `datasource.url` (não `migrate.adapter`) — API correta do Prisma 7. `prisma migrate dev` e `prisma generate` funcionando. Schema vazio (modelos virão com C2/C3).

- **M2 — WorkspacePrismaPool:** LRU cache (max 10) de `PrismaClient` por `workspaceId`. `getOrCreate(workspaceId, dbUrl)`, `health(k=3)`, `onModuleDestroy`. Usa `@prisma/adapter-pg` + `pg.Pool` por workspace (ADR 0006).

- **M3 — JwtAuthGuard:** Guard global (`APP_GUARD`) com `jose` HS256. Valida Bearer token, popula `req.user` com `{sub, workspace_id, role}`. Atualiza CLS com `workspaceId`, `userId` e `prisma` após validação. `@Public()` decorator para ping/health/dev-auth.

- **M4 — Auth dev stub:** `POST /api/v1/auth/dev/token` — emite JWT HS256 com claims `{sub, workspace_id, role}`. Retorna 404 em produção. Contrato `DevTokenRequestSchema` + `AuthTokenResponseSchema` em `@sar/api-interface`.

- **M5 — WorkspaceModule:** CLS setup simplificado (middleware só define `requestId` + `workspaceId` default). Guard sobrescreve workspace real do JWT. Pool não injetado no middleware (limitação do nestjs-cls `ClsRootModule`).

- **M6 — Health ready:** `WorkspacePoolHealthIndicator` adicionado ao `/health/ready`. Amostra top-3 LRU — nunca O(N). `active: 0` quando nenhum workspace criado ainda.

- **M7 — Smoke test:** API sobe limpo. `/health/live` ✓, `/health/ready` ✓ (pool ativo=0), `/ping` público ✓, `POST /auth/dev/token` emite token com claims corretos.

**Decisões técnicas:**
- `@prisma/client-runtime-utils` adicionado como dependência direta no workspace root (pnpm isolated mode não o hoista automaticamente).
- Guard atualiza CLS depois do middleware (ordem correta NestJS: middleware → guard → handler).
- Pool não injetado no ClsRootAsync devido a limitação de DI do nestjs-cls; guard faz a resolução.

**Pendente próxima sessão:**
1. **OpenTelemetry SDK** plugar quando entrar no catálogo.
2. **C2 ficha do cliente** — `ClientDetailPage` (web), endpoint detalhe já existe; precisa de UI.
3. **C3 Consulta de Pedidos Históricos** — modelo `Order` + `OrderItem` no Prisma + endpoint.

### 2026-05-27 — C2 Consulta de Clientes COMPLETO ✅

**OQ-4 resolvida:** Limite de crédito gerenciado no SAR (admin/supervisor define; SAR é fonte da verdade).

**Entregas:**

- **Prisma schema:** modelo `Client` + enum `FinancialStatus`. Migração `20260527225728_add_client` aplicada.
  Campos: taxId (unique), endereço (JSON), creditLimit (Decimal, null = não definido), repId, lastOrderAt/Value (desnorm. de Orders), openOrdersCount, erpCode, syncedAt, deletedAt (soft delete).

- **Contratos Zod:** `@sar/api-interface` — `ClientSummarySchema`, `ClientDetailSchema`, `ClientListResponseSchema`, `ClientListQuerySchema`. `activityStatus` calculado em runtime (não persiste — evita drift).

- **API:** `ClientsModule` — `GET /api/v1/clients` (list, search, paginação, filtro atividade) + `GET /api/v1/clients/:id`. Rep vê só carteira (`repId = userId`); supervisor/manager/admin vê tudo. `activityStatus` computado de `lastOrderAt` (thresholds: 30d alert, 60d inactive — FR-2.3).

- **Seed dev:** 10 clientes fictícios brasileiros (8 do user-001, 2 do user-002) com dados variados de atividade e situação financeira.

- **Web:** `ClientsPage` (Rafael cockpit) com tabela AntD (busca, filtro atividade, paginação). `DevLogin` para adquirir token em dev. `authStore` (localStorage dev). `/clientes` e `/clientes/:id` no router.

- **Smoke test:** `GET /clients` sem token → 401 ✓. Com token rep user-001 → 8 clientes ✓. Filtro `?status=inactive` → 1 resultado ✓. Busca `?q=padaria` → 1 resultado ✓.

**Pendente próxima sessão:**
1. `ClientDetailPage` — UI da ficha (web); endpoint já existe.
2. C3 — modelo `Order` + `OrderItem` + endpoint `GET /clients/:id/orders`.
3. OpenTelemetry SDK.

---

## About This Folder

- **This file** — Single source of truth for project progress
- **agent-experiences/** — Compressed insights from design discussions (dated files)
- **wds-project-outline.yaml** — Project configuration from Phase 0 setup

**Do not modify `wds-project-outline.yaml`** — it is the source of truth for project configuration.
