# Plano de Migração — Modelo de Dados Canônico SAR

**Data:** 2026-06-22
**Autor:** Julian (Product Owner SAR)
**Status:** Proposta para avaliação

---

## 1. Contexto e Problema

### Situação atual

O SAR foi iniciado consultando diretamente as **views do ERP JCS** (`vw_clientes`, `vw_pedidos_erp`, `vw_produtos`, etc.) que existem dentro do banco de dados do cliente (`libreplast@192.168.0.43`). Isso funcionou para o cliente piloto, mas cria uma dependência estrutural que inviabiliza a expansão do produto.

### Problema identificado

| Sintoma | Consequência |
|---|---|
| SAR acessa views do ERP via SQL raw | Cada novo ERP exige reescrever queries |
| Schema `sar` vive *dentro* do banco ERP | Sem isolamento; SAR depende de acesso ao servidor do cliente |
| Views são específicas do ERP JCS | ERP diferente = produto diferente |
| Sem camada de abstração | Impossível oferecer o SAR como SaaS multi-tenant real |

### Diagnóstico técnico (levantamento 2026-06-22)

```
Módulos 100% acoplados ao ERP:   auth, catalog, clients
Módulos parcialmente acoplados:  orders (leitura), dashboard
Módulos já independentes:        notifications, workspace
Views ERP consumidas:            11 views + 1 tabela direta
Tabelas próprias SAR existentes: 6 models Prisma
```

---

## 2. Solução Proposta

### Modelo Canônico + Connectors

```
┌─────────────────────────────────────────────────────┐
│                    APP SAR                          │
│         (frontend + API NestJS)                     │
│    Lê APENAS tabelas próprias do SAR                │
└──────────────────────┬──────────────────────────────┘
                       │ Prisma ORM
                       ▼
┌─────────────────────────────────────────────────────┐
│              Banco de Dados SAR                     │
│         (PostgreSQL isolado por workspace)          │
│  tabelas canônicas: clientes, produtos, pedidos...  │
└──────────┬──────────────────────┬───────────────────┘
           │                      │
           ▼                      ▼
┌──────────────────┐   ┌──────────────────────────────┐
│  Connector       │   │  Connector                   │
│  ERP JCS         │   │  ERP X (futuro)              │
│  (PostgreSQL)    │   │  (REST API / CSV / outro)    │
└──────────────────┘   └──────────────────────────────┘
```

**Princípio:** O ERP é uma **fonte de dados**, não o sistema de registro do SAR. Cada cliente tem um connector específico para seu ERP. O SAR opera exclusivamente sobre seu próprio modelo de dados.

### O que não muda

Os dados transacionais do SAR já estão corretos e **permanecem sem alteração**:
- `pedidos`, `pedido_itens`, `historico_pedido`
- `alcada_desconto`, `meta_representante`
- `push_subscription`

---

## 3. Tabelas Canônicas a Criar

### 3.1 Entidades mestres (sincronizadas do ERP)

| Tabela SAR | Substitui | Campos principais |
|---|---|---|
| `sar.clientes` | `vw_clientes` | codigo, razao_social, nome_fantasia, cnpj, cidade, uf, ativo, representante_codigo |
| `sar.representantes` | `vw_representantes` | codigo, nome, email, senha_hash, tipo (rep/supervisor), ativo |
| `sar.produtos` | `vw_produtos` | codigo, descricao, unidade, ncm, ativo |
| `sar.estoques` | `vw_estoque` | produto_codigo, deposito, saldo (snapshot com timestamp) |
| `sar.pautas` | `vw_pautas` | codigo, descricao, ativa |
| `sar.pauta_produtos` | `vw_pauta_produtos` | pauta_codigo, produto_codigo, preco, desconto_max |
| `sar.formas_pagamento` | `vw_formas_pagamento` | codigo, descricao, parcelas, ativa |
| `sar.municipios` | `vw_municipios` | ibge, nome, uf |
| `sar.empresa` | `gestao.empresa` | cnpj, razao_social, nome_fantasia, endereco, logo_url |

### 3.2 Histórico ERP (read-only, sincronizado)

| Tabela SAR | Substitui | Propósito |
|---|---|---|
| `sar.pedidos_erp` | `vw_pedidos_erp` | Histórico de pedidos anteriores ao SAR |
| `sar.pedido_itens_erp` | `vw_peditens_erp` | Itens dos pedidos ERP |

### 3.3 Controle de sincronização

| Tabela SAR | Propósito |
|---|---|
| `sar.sync_log` | Registro de cada execução de sync (início, fim, erros, registros processados) |
| `sar.sync_config` | Configuração do connector por workspace (tipo ERP, credenciais, frequência) |

---

## 4. Plano de Execução por Fases

### Fase 0 — Banco de Dados Isolado `[Fundação]`

**Objetivo:** Separar o banco SAR do banco ERP do cliente.

**Ações:**
- Provisionar banco PostgreSQL exclusivo para o SAR (`sar_db`)
- Configurar variável `DATABASE_URL` apontando para o novo banco
- Manter `ERP_DB_*` apenas no connector (não no app principal)
- Estrutura multi-tenant: um schema por workspace ou banco por workspace (já previsto na stack)

**Resultado:** SAR pode funcionar mesmo sem acesso ao ERP; connector roda separado.

**Estimativa:** 2–3 dias

---

### Fase 1 — Schema Canônico `[Estrutura]`

**Objetivo:** Criar todos os models Prisma das tabelas canônicas.

**Ações:**
- Adicionar 11 models ao `schema.prisma` (seção 3.1 e 3.2)
- Adicionar 2 models de controle de sync (seção 3.3)
- Gerar e aplicar migrations
- Nenhuma mudança no código da API ainda

**Resultado:** Tabelas existem no banco, prontas para receber dados.

**Estimativa:** 3–4 dias

---

### Fase 2 — Sync Service (Connector ERP JCS) `[Motor]`

**Objetivo:** Criar a camada que lê o ERP e popula as tabelas canônicas.

**Ações:**
- Criar módulo `SyncModule` no NestJS
- Implementar `ErpJcsConnector` com leitura das 11 views existentes
- Sync completo na inicialização do workspace
- Sync incremental por cron (ex: a cada 5 minutos para estoque, 30 min para cadastros)
- Registrar execuções em `sync_log`
- Endpoint admin `/api/v1/sync/trigger` para forçar sync manual

**Estratégia de sync:**

```
┌────────────────────────────────────────────────────┐
│  Frequências recomendadas                          │
│                                                    │
│  A cada 5 min:   estoques (alta volatilidade)      │
│  A cada 30 min:  produtos, pautas, preços          │
│  A cada 60 min:  clientes, representantes          │
│  A cada 6h:      pedidos_erp (histórico)           │
│  1x por dia:     municipios, empresa, formas_pgto  │
└────────────────────────────────────────────────────┘
```

**Resultado:** Tabelas SAR ficam populadas e atualizadas automaticamente.

**Estimativa:** 5–8 dias

---

### Fase 3 — Migração dos Módulos `[Execução]`

**Objetivo:** Substituir todos os `$queryRaw` por queries Prisma nas tabelas canônicas.

**Prioridade e ordem:**

| Ordem | Módulo | Complexidade | Motivo da prioridade |
|---|---|---|---|
| 1 | `catalog` | Baixa | Somente leitura, sem lógica de negócio complexa |
| 2 | `clients` | Média | Base do dashboard e pedidos |
| 3 | `auth` | Baixa | Bem delimitado; lê apenas `representantes` |
| 4 | `dashboard` | Média | Depende de clients migrado |
| 5 | `orders` (leitura) | Média | Parte escrita já usa Prisma corretamente |

**Processo por módulo:**
1. Com o sync rodando, os dados já estão nas tabelas canônicas
2. Substituir `$queryRaw` por `prisma.cliente.findMany(...)` etc.
3. Manter o contrato de resposta da API (frontend não muda)
4. Teste comparativo: mesmo resultado via ERP vs. via tabela SAR
5. Remover a query antiga após validação

**Resultado:** Zero dependência de views ERP no código da API.

**Estimativa:** 5–8 dias

---

### Fase 4 — Segundo Connector (Validação da Abstração) `[Prova]`

**Objetivo:** Onboarding de um cliente com ERP diferente do JCS.

**Ações:**
- Identificar segundo ERP (ex: TOTVS, Sankhya, outro)
- Criar `ErpXConnector` implementando a mesma interface do `ErpJcsConnector`
- Mapear campos do ERP X para o schema canônico SAR
- Sem nenhuma mudança no app SAR

**Resultado:** Prova de conceito real de que a arquitetura é ERP-agnóstica.

**Estimativa:** 4–6 dias (variável conforme ERP)

---

## 5. Cronograma Estimado

```
Semana 1:  Fase 0 (banco isolado) + Fase 1 (schema Prisma)
Semana 2:  Fase 2 (Sync Service — maior esforço)
Semana 3:  Fase 3 (migração dos módulos)
Semana 4:  Fase 4 (segundo connector) + testes + documentação

Total estimado: 4 semanas (19–25 dias úteis)
```

---

## 6. Riscos e Mitigações

| Risco | Probabilidade | Impacto | Mitigação |
|---|---|---|---|
| Divergência de dados entre ERP e tabela SAR durante sync | Médio | Alto | Sync comparativo com log de diferenças; alertas |
| Latência do sync afeta experiência do rep | Baixo | Médio | Sync de estoque a cada 5 min é suficiente para força de vendas |
| ERP do cliente sem conectividade temporária | Médio | Baixo | SAR continua funcionando com dados do último sync |
| Campos do segundo ERP sem equivalência no schema canônico | Médio | Médio | Schema canônico flexível com campo `metadata jsonb` por entidade |
| Custo de manutenção de dois bancos | Baixo | Baixo | Banco SAR é pequeno; ERP continua como está |

---

## 7. Benefícios Esperados

| Benefício | Impacto |
|---|---|
| **Multi-ERP real** | Onboarding de qualquer cliente independente do ERP |
| **Isolamento de falhas** | Queda do ERP não derruba o SAR |
| **Performance** | Queries no banco SAR são mais rápidas (schema otimizado) |
| **Funciona offline** | Rep consulta dados mesmo sem VPN/internet no cliente |
| **Multi-tenant limpo** | Banco SAR separado por workspace desde o início |
| **Evolução independente** | SAR pode adicionar campos sem depender do ERP |

---

## 8. Decisão

O projeto SAR **não precisa ser refeito do zero**. A infraestrutura (NestJS, autenticação, frontend React, ciclo de pedidos, alçadas, metas, push notifications) está correta e é reaproveitada integralmente.

A mudança é **cirúrgica e incremental**:
- Adicionar banco e tabelas canônicas (Fases 0 e 1)
- Construir o motor de sync (Fase 2)
- Substituir queries raw módulo a módulo (Fase 3)

O risco de **não fazer** essa migração agora é maior: quanto mais o produto crescer sobre as views do ERP JCS, mais caro fica refatorar depois.

---

*Documento gerado em 2026-06-22. Para dúvidas: jcsinfo@gmail.com*
