---
title: "SAR — Força de Vendas: PRD MVP"
status: final
created: 2026-05-27
updated: 2026-05-27
project: sar
version: "0.1"
---

# SAR — Força de Vendas: PRD MVP

## 1. Visão Geral

**SAR** é uma plataforma SaaS web de força de vendas para PMEs brasileiras com 5–50 Representantes externos. Substitui o app Android/Desktop legado da JCS e resolve a dor central: **donos e supervisores decidem no escuro** enquanto 5–10% da Carteira esfria silenciosamente na rua.

O produto entrega **quatro cockpits especializados** (Representante · Supervisor · Dono · Admin) compartilhando um único dado em tempo real. O MVP valida os dois cockpits de maior impacto operacional imediato: **Rafael** (Rep em campo) e **Sandra** (supervisora que aprova e monitora).

**Por que agora:** janela de mercado de 2–3 anos antes de concorrentes se modernizarem. O primeiro cliente pagante em 3–4 meses valida o modelo e financia as próximas iterações.

---

## 2. Objetivos e Métricas de Sucesso

### North Star
> Primeiro cliente paga e **renova** nos primeiros 3 meses após go-live.

### Métricas de comportamento (MVP)

| Métrica | Alvo MVP | Sinal de problema |
|---------|----------|-------------------|
| Pedidos lançados pelo Rep no SAR vs. total | ≥ 90% | < 70% = adoção baixa |
| Tempo médio de lançamento de Pedido | < 2 min | > 5 min = UX ruim |
| Taxa de sincronização offline bem-sucedida | ≥ 99,5% | < 99% = risco de perda |
| Aprovações respondidas em < 30 min | ≥ 80% | < 60% = gargalo |
| Clientes Inativos >60 d visualizados/semana | ≥ 30% da lista | < 10% = feature ignorada |

### Métricas de negócio JCS (Y1)
- 10–20 clientes pagantes até o mês 12
- ARR R$ 200k–600k
- NPS donos > 50

### Counter-métricas
- Pedidos duplicados por falha de sync → alvo: 0
- Reclamações de dado incorreto no histórico → alvo: < 2/mês/cliente

---

## 3. Personas MVP

### Rafael — Representante *(cockpit primário)*

- **Perfil:** 30–50 anos, vendedor B2B externo, comissionado, atende 50–200 Clientes ativos
- **Device:** Mobile-first · PWA iOS (Android legado continua em paralelo)
- **Contexto de uso:** No carro, no posto, no fundo da loja. Conexão instável 3G/4G. Raramente na mesa.
- **Goals prioritários:**
  - Bater meta mensal sem depender do escritório para informações
  - Ter clareza absoluta da Carteira — saber sem pensar quem comprou, quando e quanto
  - Lançar Pedido em menos de 60 segundos, mesmo sem sinal
- **Frustrações que o produto resolve:**
  - Perde Pedido por bug ou ausência de sinal no app legado
  - Comissão é mistério até o fechamento do mês
  - Não sabe quais Clientes estão esfriando antes que seja tarde demais
  - Precisa ligar para o escritório para consultar histórico de Cliente

### Sandra — Supervisora *(cockpit secundário)*

- **Perfil:** 35–55 anos, gerente comercial, coordena 5–30 Representantes, desktop o dia todo
- **Device:** Desktop-first · PWA mobile-light (Aprovações em reuniões/almoço)
- **Contexto de uso:** Abre o SAR às 8h30. Checagem diária, Aprovações durante reuniões, fechamento de semana.
- **Goals prioritários:**
  - Saber o que está acontecendo na rua sem precisar ligar para os Reps
  - Aprovar descontos com contexto real (histórico, margem, alçada) em segundos
  - Identificar problemas no time antes que virem perda de Cliente
- **Frustrações que o produto resolve:**
  - Aprova desconto no WhatsApp sem nenhum contexto
  - Descobre tarde demais que um Cliente-chave parou de comprar
  - Não tem visão consolidada dos Pedidos do dia em tempo real

---

## 4. Escopo do MVP

### Dentro do escopo

| # | Capacidade | Cockpit |
|---|-----------|---------|
| C1 | Autenticação e acesso por papel | Todos |
| C2 | Consulta de Clientes (lista + ficha) | Rafael |
| C3 | Consulta de Pedidos históricos | Rafael |
| C4 | Lançamento de Pedido novo (online + offline) | Rafael |
| C5 | Fluxo de Aprovação de desconto | Rafael → Sandra |
| C6 | Push notification de Aprovação | Sandra → Rafael |
| C7 | Painel Rafael (meta, KPIs, alertas de Inativo) | Rafael |
| C8 | Painel Sandra (Pedidos do dia, fila de Aprovações) | Sandra |
| C9 | Onboarding de workspace (admin interno JCS) | — |

### Fora do escopo (MVP)

- Cockpit Daniel (BI + IA estratégica) → placeholder de tela apenas
- Cockpit Alice (campanhas, ICMS-ST, pautas) → placeholder de tela apenas
- Editor visual de campanhas no-code
- Assistente IA por NCM/UF para ICMS-ST
- WhatsApp conversacional bidirecional (apenas Share API nativo)
- App nativo iOS/Android
- Integração automática com ERPs externos
- Benchmark cross-tenant
- Agenda + check-in GPS *(desejável; entra se não comprometer prazo)*

---

## 5. Jornadas de Usuário

### UJ-1 — Rafael lança Pedido em campo (fluxo principal)

> Rafael está na frente do comprador na distribuidora. Abre o SAR no celular (4G fraco).

1. Rafael abre a ficha do Cliente pelo nome — vê histórico e limite de crédito disponível
2. Toca em "Novo Pedido" — catálogo carrega do cache offline
3. Adiciona produtos por busca ou lista de favoritos
4. O sistema sugere o desconto máximo dentro da alçada de Rafael
5. Rafael aplica desconto de 8% (dentro da alçada de 10%) — Pedido vai direto para confirmação
6. Rafael confirma — Pedido entra na fila offline com Idempotency-Key
7. Ao recuperar sinal, o Pedido sincroniza automaticamente — Rafael recebe confirmação silenciosa
8. Cliente recebe resumo via Share API (WhatsApp nativo do celular de Rafael)

*Variação offline:* os passos 6 e 7 ocorrem com delay. O Pedido aparece como "pendente sincronização" na lista.

### UJ-2 — Rafael solicita Aprovação de desconto acima da alçada

> Rafael quer dar 15% de desconto; sua alçada é 10%.

1. Rafael digita 15% — o sistema avisa "acima da sua alçada (10%). Enviar para Aprovação?"
2. Rafael confirma — Pedido vai para Sandra com status `aprovação pendente`
3. Sandra recebe push notification com contexto: Cliente, valor, desconto solicitado, histórico
4. Sandra abre a notificação no celular (ou no Painel desktop) — vê histórico do Cliente
5. Sandra aprova ou recusa com um toque, podendo ajustar o percentual
6. Rafael recebe push notification: "Pedido #1234 aprovado — 13%" e o Pedido entra em sincronização

### UJ-3 — Sandra monitora o dia (fluxo diário)

> Sandra chega às 8h30 e abre o SAR no notebook.

1. Painel mostra: Pedidos do dia, fila de Aprovações pendentes, alertas de Inativos por Rep
2. Sandra vê que o Rep Marcos tem 3 Clientes Inativos há mais de 60 dias — acessa a lista
3. Abre a fila de Aprovações: 2 Pedidos aguardando. Resolve os dois com contexto visível
4. À tarde: recebe push no celular durante o almoço — Aprovação urgente. Resolve em segundos

---

## 6. Requisitos Funcionais

### C1 — Autenticação e Acesso

**FR-1.1** O sistema autentica usuários via master-login (IdP OAuth2/OIDC próprio da JCS).

**FR-1.2** Cada usuário tem exatamente um papel no workspace: `representante` · `supervisor` · `dono` · `admin`. O papel define qual cockpit é exibido e quais operações são permitidas.

**FR-1.3** O acesso a workspaces é isolado fisicamente por banco de dados (BD-por-workspace, ADR 0006). Nenhum usuário acessa dados de outro workspace, nem mesmo administradores da JCS.

**FR-1.4** O sistema bloqueia acesso e retorna HTTP 404 (não 403) quando o usuário autenticado não tem permissão sobre um recurso — para não vazar a existência do recurso.

**FR-1.5** [ASSUMPTION] Criação de usuários e workspaces é feita por administrador interno da JCS (não self-service no MVP). Onboarding assistido.

---

### C2 — Consulta de Clientes

**FR-2.1** O Rep lista todos os Clientes da sua Carteira com busca por nome, razão social e CNPJ/CPF.

**FR-2.2** A lista exibe, para cada Cliente: nome, última compra (data + valor), status de atividade (`ativo` · `em alerta` · `inativo`) e se há Pedidos em aberto.

**FR-2.3** O status de atividade é calculado automaticamente: `inativo` = sem Pedido Faturado há mais de 60 dias; `em alerta` = 30–60 dias; `ativo` = menos de 30 dias. [ASSUMPTION] Thresholds configuráveis por workspace pelo admin.

**FR-2.4** Ao abrir a ficha do Cliente, o Rep vê:
- Dados cadastrais: nome, CNPJ/CPF, endereço de entrega, telefone, e-mail
- Situação financeira resumida (`regular` · `atenção` · `bloqueado`) — disponível offline (cacheada)
- Limite de crédito disponível (valor numérico) — **requer conexão**; exibido com disclaimer "dados de até [hora da última sync]" quando offline
- Histórico de inadimplência — **requer conexão**; não cacheado offline
- Últimos 10 Pedidos com status e valor
- Comissão gerada pelo Cliente no mês atual e no mês anterior

**FR-2.5** A lista de Clientes, dados cadastrais, situação financeira resumida e os últimos 10 Pedidos estão disponíveis offline após a última sincronização. Dados financeiros sensíveis (limite de crédito numérico, inadimplência) requerem conexão.

**FR-2.6** [ASSUMPTION] O cadastro de Clientes é sincronizado do ERP legado da empresa. O Rep não cria nem edita Clientes no MVP.

---

### C3 — Consulta de Pedidos Históricos

**FR-3.1** O Rep visualiza todos os Pedidos da sua Carteira com filtros por: Cliente, status, período (padrão: últimos 90 dias) e número do Pedido.

**FR-3.2** Cada Pedido exibe: número, Cliente, data de emissão, status (`orçamento` · `aprovação pendente` · `aprovado` · `faturado` · `cancelado`), valor total e desconto aplicado.

**FR-3.3** Ao abrir um Pedido, o Rep vê: itens (produto, quantidade, preço unitário, desconto, subtotal), status de Aprovação (com quem está e desde quando, se pendente) e histórico de alterações de status.

**FR-3.4** Pedidos com status `aprovação pendente` têm indicador visual destacado na lista.

**FR-3.5** O histórico dos últimos 90 dias está disponível offline após sincronização. Pedidos mais antigos requerem conexão.

---

### C4 — Lançamento de Pedido Novo

**FR-4.1** O Rep inicia um novo Pedido a partir da ficha do Cliente ou da tela inicial.

**FR-4.2** O fluxo de lançamento funciona completamente offline. Pedidos criados sem conexão são enfileirados localmente (IndexedDB) e sincronizados automaticamente quando o sinal é restaurado.

**FR-4.3** Cada Pedido é identificado por um `Idempotency-Key` gerado localmente antes do envio, garantindo que retentativas de sync não criem Pedidos duplicados.

**FR-4.4** O catálogo de produtos (código, descrição, preço de tabela, estoque disponível, foto) fica cacheado localmente para uso offline. [ASSUMPTION] A sincronização do catálogo ocorre ao abrir o app com conexão ativa, com TTL de 4h.

**FR-4.5** O Rep adiciona produtos ao Pedido por: busca por nome/código, lista de favoritos pessoais ou lista dos produtos mais comprados pelo Cliente.

**FR-4.6** Para cada item, o Rep define quantidade e percentual de desconto. O sistema exibe o preço resultante e o subtotal em tempo real.

**FR-4.7** O sistema valida o desconto contra a alçada do Rep **antes** da submissão:
  - Dentro da alçada: Pedido segue direto para confirmação (FR-4.8)
  - Acima da alçada: Pedido entra no fluxo de Aprovação (C5)
  - [OQ-2] Se a alçada variar por linha de produto, a validação ocorre item a item; o Pedido só vai para Aprovação se ao menos um item exceder a alçada da sua linha.

**FR-4.8** Na tela de confirmação, o Rep vê: resumo dos itens, valor total, desconto médio, status do limite de crédito do Cliente e botão "Confirmar Pedido".

**FR-4.9** Após confirmação, o sistema:
  - Registra o Pedido com status `orçamento` (dentro da alçada) ou `aprovação pendente` (acima da alçada)
  - Exibe confirmação imediata ao Rep, mesmo que a sincronização ainda não tenha ocorrido
  - Disponibiliza opção de compartilhar resumo do Pedido via Share API (WhatsApp nativo)

**FR-4.10** O Rep visualiza Pedidos pendentes de sync em uma lista local, com indicação clara de "aguardando conexão".

**FR-4.11** Se o servidor rejeitar um Pedido da fila offline (produto inativo, Cliente bloqueado, pauta vencida), o Pedido retorna ao Rep com status `falha de sync` e motivo legível em linguagem humana. O Pedido nunca é descartado silenciosamente — fica visível na fila com opção de editar e reenviar ou cancelar.

**FR-4.12** [ASSUMPTION] A alçada de desconto é configurada por Rep pelo admin do workspace. Default: 5%.

---

### C5 — Fluxo de Aprovação de Desconto

**FR-5.1** Quando um Pedido exige Aprovação, o supervisor responsável recebe push notification e o Pedido é incluído na fila de Aprovações.

**FR-5.2** A fila de Aprovações exibe, para cada Pedido pendente: Rep, Cliente, valor total, desconto solicitado vs. alçada, tempo aguardando e indicador de urgência (> 2h sem resposta).

**FR-5.3** Ao abrir um Pedido para aprovar, o supervisor vê:
  - Resumo do Pedido (itens, valores, desconto)
  - Histórico do Cliente: últimas compras, inadimplência, volume no período
  - Alçada do Rep e justificativa do desconto (campo livre, opcional)

**FR-5.4** O supervisor pode: **aprovar** (com o desconto solicitado), **aprovar com ajuste** (definir percentual diferente) ou **recusar** (com motivo obrigatório).

**FR-5.5** Após a decisão:
  - O Rep recebe push notification com o resultado
  - O status do Pedido é atualizado em tempo real no Painel de ambos
  - Se aprovado, o Pedido avança para status `aprovado`; se recusado, retorna ao Rep com o motivo

**FR-5.6** [ASSUMPTION] No MVP, qualquer supervisor do workspace pode aprovar qualquer Pedido da sua equipe. Hierarquia de Aprovação com múltiplos níveis é pós-MVP.

---

### C6 — Notificações e Push

**FR-6.1** O sistema envia Web Push Notification para:
  - Sandra: novo Pedido aguardando Aprovação (com preview: Rep, Cliente, valor)
  - Rafael: Aprovação concedida ou recusada (com resultado e eventual ajuste)

**FR-6.2** Notificações push funcionam com o navegador em background (PWA).

**FR-6.3** O sistema exibe um badge de contagem no ícone de notificações na Topbar com o total de itens pendentes de ação.

**FR-6.4** O Rep compartilha o resumo de um Pedido confirmado via Share API do browser (abre o WhatsApp nativo ou qualquer app de mensagens do dispositivo). [ASSUMPTION] O conteúdo compartilhado é texto formatado com os itens e o valor total; link para visualização futura é pós-MVP.

---

### C7 — Painel Rafael

**FR-7.1** O Painel do Rep exibe, ao abrir o app:
  - Saudação com nome e data atual
  - Meta do mês (valor atingido / valor total, percentual e progresso visual)
  - Valor faltante para atingir a meta
  - Comissão acumulada no mês (valor fixo + FLEX, quando aplicável)

**FR-7.2** O Painel lista os Clientes Inativos da Carteira do Rep, ordenados por dias sem compra (decrescente). Clientes com mais de 60 dias têm destaque visual.

**FR-7.3** O Painel exibe os Pedidos recentes (últimos 7 dias) com status e indicação de pendentes de sync.

**FR-7.4** Todos os dados do Painel são acessíveis offline após a última sincronização. A data e hora da última sync são visíveis.

---

### C8 — Painel Sandra

**FR-8.1** O Painel da supervisora exibe, ao abrir o app:
  - Fila de Aprovações pendentes (ordenada por tempo aguardando)
  - Resumo dos Pedidos do dia da equipe: total de Pedidos, valor consolidado e comparativo com a mesma semana do mês anterior
  - Alertas de Clientes Inativos por Rep (top 3 Reps com maior número de Inativos)

**FR-8.2** O Painel atualiza em tempo real via Socket.IO/SSE: novos Pedidos, mudanças de status e novas Aprovações pendentes.

**FR-8.3** [ASSUMPTION] No MVP, Sandra não acessa fichas de Clientes individuais nem histórico de Pedidos por Rep diretamente — apenas o que aparece no Painel e na fila de Aprovações. Drill-down por Rep é próxima iteração.

---

## 7. Requisitos Não-Funcionais

### Performance

**NFR-1.1** Operações CRUD (consulta de Cliente, histórico de Pedidos, confirmação de Pedido): p99 < 800 ms.

**NFR-1.2** Carregamento inicial do Painel (dados do dia): p99 < 2 s com conexão 4G.

**NFR-1.3** Sincronização de Pedido offline pendente após retorno de conexão: início do envio em menos de 5 s.

**NFR-1.4** Atualização em tempo real no Painel da Sandra (novo Pedido aparece): menos de 3 s após o evento.

### Offline (Rafael)

**NFR-2.1** Rafael consulta Clientes, visualiza histórico e lança Pedidos completos sem nenhuma conexão de rede, usando os dados da última sincronização.

**NFR-2.2** Pedidos criados offline são persistidos no IndexedDB com `Idempotency-Key` gerado localmente, garantindo envio único quando a conexão é restaurada.

**NFR-2.3** O app detecta automaticamente a perda e o retorno de conexão e sincroniza a fila sem ação do usuário.

**NFR-2.4** Em nenhuma circunstância um Pedido pode ser perdido silenciosamente. Falhas de sync devem ser exibidas visivelmente para o Rep.

### Segurança e LGPD

**NFR-3.1** PII de Clientes (CPF/CNPJ, telefone, e-mail) é redactada nos logs de aplicação.

**NFR-3.2** Dados de Clientes e Pedidos são fisicamente isolados por workspace (BD-por-workspace, ADR 0006). Nenhuma query atravessa workspaces.

**NFR-3.3** O armazenamento offline (IndexedDB) contém apenas os dados mínimos necessários para o fluxo de lançamento de Pedido. Dados financeiros sensíveis (limite de crédito completo, histórico de inadimplência) requerem conexão.

**NFR-3.4** Tokens JWT são armazenados em memória (nunca em localStorage). Refresh token em cookie `httpOnly; Secure; SameSite=Lax`.

**NFR-3.5** Rate limit em endpoints de autenticação: 5 tentativas/min/IP.

**NFR-3.6** Todo opt-in para Web Push é explícito, com possibilidade de revogar a qualquer momento.

### Acessibilidade

**NFR-4.1** Interfaces seguem WCAG AA para contraste, tamanho de alvo touch (mínimo 44 px) e suporte a leitor de tela.

**NFR-4.2** Score Lighthouse ≥ 90 em Performance, Acessibilidade e Best Practices — gate obrigatório de CI.

### Compatibilidade

**NFR-5.1** Rafael: Safari iOS 17+ e Chrome Android 120+ (PWA com offline, Web Push, Share API, Geolocation).

**NFR-5.2** Sandra: Chrome 120+ e Safari 17+ em desktop. Layout responsivo até 1280 px.

**NFR-5.3** [ASSUMPTION] Sem suporte a IE ou browsers legados.

### Disponibilidade

**NFR-6.1** SLA de disponibilidade: 99,5% em horário comercial (7h–21h BRT, seg–sáb).

**NFR-6.2** Janela de manutenção: domingos das 2h–6h BRT, comunicada com 48h de antecedência.

---

## 8. Integrações

### 8.1 Master-login (IdP JCS) — *Obrigatório*
Autenticação e gestão de usuários/workspaces via OAuth2/OIDC. Usuários e papéis são gerenciados pelo IdP; o SAR atua como resource server.

### 8.2 WhatsApp — *Share API nativa (MVP)*
O compartilhamento de Pedidos usa a Web Share API nativa do device (abre WhatsApp ou qualquer app de mensagens). Nenhuma integração com Meta Cloud API no MVP. [ASSUMPTION] WhatsApp Business API (mensagens programáticas) entra na próxima iteração.

### 8.3 ERP Legado — *Sync via importação*
[ASSUMPTION] Catálogo de produtos, pautas de preço e cadastro de Clientes são importados do ERP legado via arquivo (CSV/JSON) ou endpoint configurável pelo admin. O SAR é o sistema de registro dos Pedidos novos; o ERP continua sendo o sistema de faturamento. Integração bidirecional automática é pós-MVP.

### 8.4 Web Push — *Nativo*
Via Push API do browser + Service Worker. Sem provedor SaaS externo de push no MVP.

---

## 9. Restrições Técnicas e de Design

- **Stack:** STACK.md v2.2 é canônica e imutável sem RFC. Node 24 · Nest 11 · Prisma 7 · React 19.2 · AntD 6.4 · PostgreSQL 18 · multi-tenancy BD-por-workspace.
- **Brand:** `brand.md` é canônico. Paleta JCS Blue `#004a99`, Plus Jakarta Sans, Topbar 80 px + Sidebar 260 px, radius 12/20 px.
- **Vocabulário do produto:** Cliente · Representante/Rep · Orçamento · Pedido · Faturado · Visita · Carteira · Inativo · Painel · Aprovação. Nunca "Lead", "Prospect" ou "Ticket".
- **Infraestrutura:** Proxmox on-prem Brasil. Sem AWS/GCP/Azure. Cloudflare como CDN/proxy.
- **LGPD by design:** datacenter BR, PII criptografada, redact em logs, Art. 18 implementado.
- **Ambiente de desenvolvimento:** Docker Compose dev com Postgres 18, Valkey 8, MinIO e Mailpit — todos com healthcheck validado.

---

## 10. Questões Abertas

| # | Questão | Impacto | Responsável | Prazo |
|---|---------|---------|-------------|-------|
| OQ-1 | Catálogo de produtos e pautas de preço: formato e frequência de importação do ERP legado? | Alto — bloqueia FR-4.4 | Julian + primeiro cliente | Antes do design de C4 |
| OQ-2 | Alçada de desconto: é fixa por Rep ou pode variar por linha de produto? | Médio — impacta FR-4.7 e FR-4.11 | Julian | Antes de C4/C5 |
| OQ-3 | Comissão FLEX: a fórmula de cálculo está documentada? | Médio — impacta FR-7.1 | Julian | Antes de C7 |
| ~~OQ-4~~ | ~~Limite de crédito: é calculado no SAR ou importado do ERP?~~ | ✅ **RESOLVIDO 2026-05-27** — gerenciado no SAR (admin/supervisor define; SAR é fonte da verdade) | Julian | — |
| OQ-5 | Múltiplos supervisores: se houver mais de um no workspace, como se distribui a fila de Aprovações? | Médio — impacta FR-5.1 | Julian | Antes de C5 |
| OQ-6 | Catálogo offline: TTL de 4h é aceitável para o primeiro cliente? Há risco de Rep vender produto fora de pauta? | Médio — impacta FR-4.4 | Julian + primeiro cliente | Antes de C4 |

---

## 11. Fora do Escopo (explícito)

- Cockpit Daniel (dashboard executivo + IA estratégica) — tela placeholder apenas
- Cockpit Alice (campanhas, ICMS-ST, pautas, cadastros) — tela placeholder apenas
- Editor visual de campanhas no-code
- Assistente IA por NCM/UF
- WhatsApp conversacional bidirecional (Meta Cloud API)
- Agenda e roteamento de visitas com GPS
- App nativo iOS ou Android
- Integração automática bidirecional com ERP
- Multi-empresa por workspace (uma empresa por workspace no MVP)
- Benchmark cross-tenant anonimizado
- Dark mode *(desejável, não bloqueante)*
- Relatórios exportáveis (PDF/Excel)

---

*Documento gerado em 2026-05-27 via bmad-prd (Fast Path). Assumptions marcados — revisar com Julian antes do início de C4 e C5.*
