# 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*