prisma: modelo Client + migração 20260527225728_add_client + seed dev (10 clientes)
api: GET /clients (list, busca, filtro atividade/financeiro, paginação) + GET /clients/:id
rep vê carteira própria; supervisor/admin vê tudo; activityStatus calculado de lastOrderAt
@sar/api-interface: ClientSummarySchema, ClientDetailSchema, ClientListResponseSchema
web: ClientsPage (tabela AntD, busca, filtro), DevLogin (token dev), authStore, Bearer no apiFetch
oq-4 resolvida: creditLimit gerenciado no SAR
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
37 KiB
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 emfrontend/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-briefcom Saga
2026-05-26 — Phase 1 Steps 1, 1a, 2 concluídos
- Step 1 (Init): materiais adicionais identificados — mockup SPA legado (
index.html2251 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 201-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.exampletemplate 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/sarconfigurado (push diferido) - Próximos passos sugeridos:
- Criar repo no Gitea e fazer push (
git push -u origin main) - Subir Docker Compose dev (
pnpm dev:up) - Implementar master-login stub (auth real virá depois)
- Implementar multi-tenant BD-por-workspace via Prisma factory + cls
- Primeira tela viva: login + painel Rafael (vazio)
- Criar repo no Gitea e fazer push (
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 envmain.ts— helmet · CORS por env · compression · versionamento URI/api/v1· graceful shutdown · Pino logger globalapp/config/— EnvSchema Zod 4 comsuperRefine(fail-fast prod, defaults dev) + EnvModule globalapp/logger/— nestjs-pino com redact*.cpf|*.cardNumber|*.password|authorization|cookie, ignora/health/*, pretty em devapp/filters/problem-details.filter.ts— RFC 9457application/problem+json, Zod → 422 com arrayerrors, type URIs emhttps://docs.sar.jcs.com.br/errors/*app/health/—/health/livee/health/ready(skeleton, K=3 LRU pool placeholder documentado)app/workspace/— ClsModule.forRootAsync comsetuppopulando requestId+workspaceId; idGenerator alinha com pino-http (mesmo UUID header+body)app/ping/—GET /api/v1/pingretornando status+service+version+workspaceId+requestId+uptime+nowapp.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-idpropagado em todas as responses - Hello-world boilerplate removido (app.controller/service/specs)
- Pendente próxima sessão:
- Frente C — Zod contracts compartilhados (
libs/shared/api-interface): primeiro DTO real (createZodDto) consumido por API + Web - Frente D — ESLint boundaries (3 tags Nx canônicas) + Husky+gitleaks
- Web → API integração:
apps/webchamar/api/v1/pingvia TanStack Query (validar fundação ponta-a-ponta no browser) - OpenTelemetry SDK plugar quando entrar em catálogo (stub atual mantém posição correta)
- Master-login + WorkspacePrismaPool (próxima frente arquitetural pesada)
- Docker compose dev: subir e validar healthcheck (
pnpm dev:up)
- Frente C — Zod contracts compartilhados (
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.cssespelhando 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 comstatus: z.literal('ok'),requestId: z.uuid(),now: z.iso.datetime(), etc.) + tipo inferidoPingResponse. 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 paraping.contract. Placeholdersapi-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 + tipoz.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:test6/6 ✅. - Pegadinha Postgres 18+ encontrada e fixada (canon JCS):
pnpm dev:updeu containersar-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/datapara/var/lib/postgresql(dados em subdir18/main) para suportarpg_upgrade --linksem boundary issues. Ref:docker-library/postgres#1259. - Fix:
docker-compose.dev.ymlpostgres.volumes →- sar-postgres-data:/var/lib/postgresql. Comentário inline explicando o porquê. - Volume
sar-postgres-dataremovido (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 deniedno/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).
- Usuário fora do grupo
- Stack dev validada healthy:
sar-postgres(18-alpine) 5432 ✅ — BDssar_master+sar_workspace_dev, extensionspgcrypto+uuid-osspno workspace epgcrypto+plpgsqlno master.sar-valkey(8-alpine) 6379 ✅ —+PONG.sar-minio(latest) 9000+9001 ✅ —/minio/health/liveHTTP 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):
- Web→API integração ponta-a-ponta —
apps/webchama/api/v1/pingvia TanStack Query +PingResponseSchema.parse(...)na response. Fecha o loop B+C; prova que o contrato Zod funciona dos dois lados. - Frente D — ESLint boundaries (tags Nx
scope:* · type:* · domain:*) + Husky + gitleaks. - Phase 3 WDS — PRD via
/bmad-prd createantes de qualquer modelagem de domínio. - Master-login stub + WorkspacePrismaPool (frente arquitetural pesada — depende de #3).
- OpenTelemetry SDK plugar quando entrar em catálogo (stub atual mantém posição).
- Web→API integração ponta-a-ponta —
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 parseiaapplication/problem+json(RFC 9457) emApiErrorestruturado 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. Pulseprocessingno 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/pingvia proxy Vite →200 application/jsoncom payload contratual completo (status=ok,workspaceId=dev-workspace,requestId,uptimeSeconds=144,now)curl :4200/api/v1/nope→404 application/problem+jsoncomtype/title/detail/instance/requestId— prova queApiErrorcaptura 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-interfacesem arrastar nada do Nest.PingResponseSchemaviaja como Zod puro;ApiErrorna Web não conheceHttpExceptiondo Nest — só o contrato HTTP+JSON. Alinhamento com regra "lib stays framework-free" da sessão anterior. - Pegadinhas notadas (não bloquearam):
_sidebarOpenno AppShell ainda temeslint-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):
- Frente D — ESLint boundaries (tags Nx
scope:* · type:* · domain:*) + Husky + gitleaks. Higiene de PR antes de feature pesada. - PRD WDS via
/bmad-prd createantes de modelar domínio. - Master-login stub + WorkspacePrismaPool (frente arquitetural — depende do PRD).
- OpenTelemetry SDK plugar quando entrar no catálogo.
- Frente D — ESLint boundaries (tags Nx
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:sharedadicionadas em todos os 5 projetos (e2e estavam vazios). eslint.config.mjsdepConstraints 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-cacheverde em todos os 3 projetos com as novas regras.
- Tags
- D2 — Husky + lint-staged:
husky 9+lint-staged 17instalados.prepare: "husky"nopackage.json.pre-commit:eslint --max-warnings=0+prettier --checksó nos arquivos staged (rápido, sem varrer repo inteiro).
- D3 — commitlint:
@commitlint/cli+@commitlint/config-conventionalinstalados.commitlint.config.js: tipo obrigatório, subject lowercase, scope enum comowarn(nãoerror— permite escopos novos sem bloquear), body/footer ilimitados.- Hook
commit-msgativo. Smoke test: mensagem inválida → 2 erros; mensagem válida → pass.
- D4 — gitleaks via Docker:
.gitleaks.tomlcriado comuseDefault = 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.jsonautopoluindo scan → excluirtmp/+ 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 dockernão funciona em hooks não-interativos. Solução: fallback comecho+ warning, e usarsudo usermod -aG docker $USER+ logout/login para resolver permanentemente no desktop dev. - Pendente próxima sessão (ordem atualizada):
- PRD WDS via
/bmad-prd createantes de modelar qualquer domínio. Desbloqueia master-login + WorkspacePrismaPool. - Master-login stub + WorkspacePrismaPool (frente arquitetural pesada — depende do PRD).
- OpenTelemetry SDK plugar quando entrar no catálogo.
- PRD WDS via
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):
- OpenTelemetry SDK plugar quando entrar no catálogo.
- 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.tsusadatasource.url(nãomigrate.adapter) — API correta do Prisma 7.prisma migrate deveprisma generatefuncionando. Schema vazio (modelos virão com C2/C3). -
M2 — WorkspacePrismaPool: LRU cache (max 10) de
PrismaClientporworkspaceId.getOrCreate(workspaceId, dbUrl),health(k=3),onModuleDestroy. Usa@prisma/adapter-pg+pg.Poolpor workspace (ADR 0006). -
M3 — JwtAuthGuard: Guard global (
APP_GUARD) comjoseHS256. Valida Bearer token, populareq.usercom{sub, workspace_id, role}. Atualiza CLS comworkspaceId,userIdeprismaapó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. ContratoDevTokenRequestSchema+AuthTokenResponseSchemaem@sar/api-interface. -
M5 — WorkspaceModule: CLS setup simplificado (middleware só define
requestId+workspaceIddefault). Guard sobrescreve workspace real do JWT. Pool não injetado no middleware (limitação do nestjs-clsClsRootModule). -
M6 — Health ready:
WorkspacePoolHealthIndicatoradicionado ao/health/ready. Amostra top-3 LRU — nunca O(N).active: 0quando nenhum workspace criado ainda. -
M7 — Smoke test: API sobe limpo.
/health/live✓,/health/ready✓ (pool ativo=0),/pingpúblico ✓,POST /auth/dev/tokenemite token com claims corretos.
Decisões técnicas:
@prisma/client-runtime-utilsadicionado 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:
- OpenTelemetry SDK plugar quando entrar no catálogo.
- C2 ficha do cliente —
ClientDetailPage(web), endpoint detalhe já existe; precisa de UI. - C3 Consulta de Pedidos Históricos — modelo
Order+OrderItemno 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+ enumFinancialStatus. Migração20260527225728_add_clientaplicada. 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.activityStatuscalculado 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.activityStatuscomputado delastOrderAt(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).DevLoginpara adquirir token em dev.authStore(localStorage dev)./clientese/clientes/:idno router. -
Smoke test:
GET /clientssem token → 401 ✓. Com token rep user-001 → 8 clientes ✓. Filtro?status=inactive→ 1 resultado ✓. Busca?q=padaria→ 1 resultado ✓.
Pendente próxima sessão:
ClientDetailPage— UI da ficha (web); endpoint já existe.- C3 — modelo
Order+OrderItem+ endpointGET /clients/:id/orders. - 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.