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>
This commit is contained in:
2026-05-27 14:34:20 +00:00
commit 17c08e6392
3631 changed files with 855518 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
# 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