# Platform Strategy — SAR (Força de Vendas)

**Confirmed:** 2026-05-26
**Step:** 10a — Platform Strategy

> Estratégia de plataforma decorre da STACK.md + Product Concept + Constraints. Esta sessão consolida e abre as decisões de **device strategy** que afetam o MVP.

---

## Plataforma primária — Web SaaS (decisão fixa via STACK.md)

| Camada | Decisão |
|---|---|
| **Tipo** | Web SaaS multi-tenant |
| **Frontend** | React 19.2 SPA via Vite 8 (Rolldown) |
| **Distribuição** | Sem app store; deploy = rolling docker-compose em VMs Proxmox |
| **CDN/edge** | Cloudflare + Nginx para SPA estática |
| **Identidade** | master-login (IdP próprio) OAuth2/OIDC |
| **Multi-tenancy** | BD-por-workspace; workspace resolvido por host/path |

---

## Device strategy por cockpit

### 🟢 Rafael (Rep) — **PWA mobile-first**

| Aspecto | Decisão |
|---|---|
| **Tecnologia** | **Progressive Web App (PWA)** — SPA com Service Worker + Manifest + Web Push |
| **Device-target primário** | **iOS** (gap no mercado; vocês não têm app native iOS) |
| **Device-target secundário** | Android (usuários que preferem PWA ao app legado) |
| **Instalação** | "Adicionar à Tela de Início" no iOS Safari / Android Chrome |
| **Push** | Web Push API via Service Worker (notificações de pedido aprovado, alertas) |
| **Offline** | **Read + Write com sync** (lançamento de pedido offline + reconciliação quando volta sinal) |
| **Native features** | Geolocation (check-in) · Web Push · Share API (compartilhar pedido) |
| **Dark mode** | Desejável (uso noturno em carro/posto) |

### 🟡 Sandra (Supervisora) — Web desktop + mobile-light

| Aspecto | Decisão |
|---|---|
| **Device-target primário** | Desktop (notebook escritório) |
| **Device-target secundário** | Mobile (PWA — consultas rápidas, aprovações via push) |
| **Push** | Web Push para notificar aprovações pendentes |
| **Layout** | Topbar 80px + Sidebar 260px (brand.md) com tabelas/listas densas |

### 🔵 Daniel (Dono) — Desktop + **iPad first-class**

| Aspecto | Decisão |
|---|---|
| **Device-target primário** | Desktop/notebook |
| **Device-target secundário** | **iPad first-class** — testes e ajustes dedicados |
| **Layout** | Visualização-first (gráficos amplos), tom executivo |
| **Modo** | Claro/escuro elegante (uso noturno em casa) |

### 🟣 Alice (Admin) — Desktop-only

| Aspecto | Decisão |
|---|---|
| **Device-target** | Desktop apenas (sem investimento mobile/tablet) |
| **Layout** | Dense forms com assistentes, bulk operations, auditoria visível |

---

## Coexistência com app Android legado

### Decisão estratégica

- **MVP:** SAR PWA + backend SAR construídos do zero. **App Android legado continua intocado** no curto prazo.
- **Pós-MVP (Y1+):** Iniciar **adaptação do app Android legado para consumir backend SAR**, unificando a fonte da verdade.
- **Futuro (Y1-Y2):** Avaliar reescrita do app Android para mobile-native sobre backend SAR (possivelmente Capacitor wrap do PWA ou React Native).

### Modelo evolutivo

```
                  HOJE                       MVP                       Pós-MVP                     Futuro
                  ────                       ───                       ───────                     ──────
Backend           [App Android legado]       [App Android legado]      [App Android adapt.]        [Native iOS]
                       │                          │   [SAR backend]              ▲                 [Native Android]
                       │                          │        │                     │                       │
                  [Backend                   [Backend         ↓                  ▼                       ▼
                   legado]                    legado]    [SAR PWA iOS]      [SAR backend]           [SAR backend]
                                                                              (único)               (único)
```

### Implicação técnica

- **MVP:** SAR é greenfield, sem dependência do Android legado. Reps Android continuam no app legado se já o usam; clientes novos vão direto para SAR PWA.
- **Pós-MVP:** App Android passa a consumir API SAR — necessária camada de compatibilidade temporária (provavelmente adapter no backend para mapear contratos antigos do app).

---

## Offline strategy detalhada (Rafael)

### Nível escolhido: **Read + Write com sync**

| Operação | Online | Offline |
|---|---|---|
| Visualizar catálogo | API + cache | Cache local (IndexedDB) |
| Visualizar clientes | API + cache | Cache local (clientes da carteira do rep) |
| Visualizar últimos pedidos | API + cache | Cache local (últimos N) |
| **Lançar pedido** | API + ack imediato | **IndexedDB queue + Service Worker sync** |
| Editar pedido em rascunho | API + cache | IndexedDB |
| Aprovação de desconto (Sandra) | Real-time | (Não aplicável — Sandra é desktop) |

### Implementação (a detalhar em Phase 3 / 4)

- **Storage local:** IndexedDB para cache + queue de pendentes
- **Sync layer:** Service Worker reage a `online` event; envia queue serialmente
- **Conflict resolution:** Last-write-wins para rascunho; pedido finalizado é imutável depois de submeter
- **UI signaling:** ícone de "modo offline" claro; toast quando sync completa; mostrar status do pedido (`enviando…` → `enviado`)
- **Limites:** offline funciona por até X dias (configurável); depois força login + sync

### Risco a mitigar

- **Pedido duplicado:** rep lança offline, depois online sem perceber sync, lança de novo. Solução: `Idempotency-Key` por pedido (UUID gerado local) — já é padrão STACK.md §05.
- **Catálogo desatualizado:** rep lança pedido com preço/produto que mudou. Solução: validação no sync com `If-Match` ou status `requer_revisao` se preço divergiu.

---

## Native features do MVP

| Feature | Cockpit | Web API | Status MVP |
|---|---|---|---|
| **Geolocation** (check-in agenda) | Rafael | `navigator.geolocation` + permissão | ✅ MVP |
| **Web Push** (aprovação para Sandra; pedido aprovado para Rafael) | Sandra, Rafael | Push API + Service Worker | ✅ MVP (parte do PWA) |
| **Share API** (Rafael compartilha pedido/orçamento via WhatsApp do celular) | Rafael | `navigator.share` | ✅ MVP |
| **Notification API** (desktop) | Sandra | `Notification` | ✅ MVP |
| **Camera** (foto documento/produto) | Rafael, Alice | `<input type="file" capture>` | 🟡 Pós-MVP |
| **File System Access** (Alice import CSV) | Alice | File System API + fallback | 🟡 Pós-MVP |

### Diferença: Share API vs WhatsApp integrado nativo do SAR

- **Share API** (MVP): Rafael toca "Compartilhar pedido" → abre menu nativo do iOS/Android → cliente recebe link/PDF via WhatsApp do celular DELE
- **WhatsApp nativo do SAR** (parcial no MVP): backend envia mensagem programática via WhatsApp Business API quando pedido é aprovado (notificação ao cliente final). Implementação Step 29.

Os dois coexistem. Share API é "rep compartilha como pessoa", WhatsApp nativo é "produto envia em nome do cliente-empresa".

---

## Interaction models

| Modelo | Cockpits | Notas |
|---|---|---|
| **Touch** | Rafael (primário), Sandra/Daniel/Alice (secundário) | Botões 44×44pt mínimo no Rafael |
| **Mouse + teclado** | Sandra, Daniel, Alice | Atalhos de teclado avaliados em Phase 4 (especialmente Alice bulk ops) |
| **Voice commands** | Nenhum no MVP | Possível futuro: Rafael ditando pedido enquanto dirige (risco de segurança rodoviária — descartado por enquanto) |
| **Gesture** | Rafael (swipe entre clientes, pull-to-refresh) | Padrão mobile |
| **Acessibilidade** | Todos | WCAG AA mínimo; screen reader compatível desde MVP |

---

## Implicações de design e desenvolvimento

1. **PWA exige Service Worker robusto** — não é "responsivo com manifest", é arquitetura cliente complexa. Investimento explícito de ~1-2 semanas no MVP.
2. **Web Push exige certificado VAPID + backend para envio** — encaixa com BullMQ jobs já previstos.
3. **Offline write exige UI com estados claros** — `enviando…` `enviado` `falha de sync` `aguardando reconexão` (estados visíveis ao Rafael).
4. **iPad first-class implica testes regulares em iPad Safari** durante Phase 4 — adicionar ao matriz de QA.
5. **Compatibilidade com Android legado é débito conhecido**, não esquecido — pós-MVP terá adapter layer ou contratos compartilhados.

---

## Lacunas conscientemente adiadas

- Native iOS / native Android (Capacitor / React Native) — pós-Y1
- Voice commands para Rafael — descartado por segurança rodoviária
- Acessibilidade avançada (WCAG AAA, switch controls) — manter WCAG AA no MVP
- Camera e File System Access — pós-MVP
- App Smartwatch para alertas Sandra — fora de escopo
