Files
sar/design-artifacts/A-Product-Brief/dialog/platform-strategy.md
julian 17c08e6392 chore: initial monorepo scaffold + WDS Phase 1+2 artifacts
- Nx 22.7 monorepo (pnpm 11.1, TypeScript 5.9, Node 24)
- apps/api: NestJS 11 (CJS conforme CODING-RULES.md PGD-DB-004)
- apps/web: React 19 + Vite 8 (ESM)
- libs/shared/api-interface: Zod contract base
- Docker Compose dev: Postgres 18, Valkey 8, MinIO, Mailpit
- WDS artifacts:
  - design-artifacts/A-Product-Brief/ (5 docs canônicos + 16 dialogs)
  - design-artifacts/B-Trigger-Map/ (hub + 4 personas + feature impact)
- Stack canon: STACK.md v2.2 + CODING-RULES.md v2.0 + brand.md
- AGENTS.md + README.md como entrada para devs/agentes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:34:20 +00:00

170 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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