From 2807a9d9dd8f4fea2d4c9e9380b27b594f17b7fa Mon Sep 17 00:00:00 2001 From: Jonas Pacheco Date: Thu, 9 Apr 2026 10:12:46 -0300 Subject: [PATCH] =?UTF-8?q?chore:=20remove=20planos=20SOE=20duplicados=20e?= =?UTF-8?q?=20renomeia=20para=20vers=C3=A3o=20=C3=BAnica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove arquivos duplicados/confusos: - PLANO_SOE_CENTRAL.md (duplicado) - PLANO_SOE_CENTRAL-ignorar.md (duplicado) - PLANO_SOE_CENTRAL_v2-concluido-testar.md (duplicado) Renomeia: - PLANO_SOE_CENTRAL_v2.md → PLANO_SOE.md (único arquivo oficial) Evita confusão da IA no futuro - Single Source of Truth para plano SOE. --- .../{PLANO_SOE_CENTRAL_v2.md => PLANO_SOE.md} | 0 docs/PLANO_SOE_CENTRAL-ignorar.md | 733 ------------------ docs/PLANO_SOE_CENTRAL.md | 733 ------------------ docs/PLANO_SOE_CENTRAL_v2-concluido-testar.md | 666 ---------------- 4 files changed, 2132 deletions(-) rename docs/{PLANO_SOE_CENTRAL_v2.md => PLANO_SOE.md} (100%) delete mode 100644 docs/PLANO_SOE_CENTRAL-ignorar.md delete mode 100644 docs/PLANO_SOE_CENTRAL.md delete mode 100644 docs/PLANO_SOE_CENTRAL_v2-concluido-testar.md diff --git a/docs/PLANO_SOE_CENTRAL_v2.md b/docs/PLANO_SOE.md similarity index 100% rename from docs/PLANO_SOE_CENTRAL_v2.md rename to docs/PLANO_SOE.md diff --git a/docs/PLANO_SOE_CENTRAL-ignorar.md b/docs/PLANO_SOE_CENTRAL-ignorar.md deleted file mode 100644 index 921b731..0000000 --- a/docs/PLANO_SOE_CENTRAL-ignorar.md +++ /dev/null @@ -1,733 +0,0 @@ -# PLANO SOE CENTRAL — Arcádia Suite -## Orquestração Inteligente: Plus + ERPNext invisíveis, Central visível -### Versão 1.0 — Março 2026 - ---- - -## 1. ONDE ESTAMOS (Orientação Geral) - -### O Projeto nasceu no Replit como… -- Uma plataforma de **escritório empresarial com IA central** (Manus Agent) -- Com proxy para o **Arcádia Plus** (Laravel/PHP, porta 8080) — ERP fiscal completo -- Com integração ao **ERPNext/Frappe** via API -- Stack principal: **React 18 + Express.js + PostgreSQL + FastAPI (Python)** - -### O que JÁ existe e funciona: -| Componente | Status | Onde vive | -|---|---|---| -| Manus Agent (IA, 30+ tools) | ✅ Funcionando | `server/manus/` | -| Arcádia Plus (Laravel ERP) | ✅ Funcionando | `plus/` → porta 8080 | -| SSO Plus ↔ Suite | ✅ Funcionando | `server/plus/` | -| Motor Fiscal (nfelib) | ✅ Funcionando | `server/python/` → porta 8002 | -| Motor Contábil | ✅ Funcionando | `server/python/` → porta 8003 | -| Motor BI | ✅ Funcionando | `server/python/` → porta 8004 | -| Motor Automação | ✅ Funcionando | `server/python/` → porta 8005 | -| Motor Comunicação (Comm) | ✅ Funcionando | porta 8006 | -| Dev Center XOS (6 agentes) | ✅ Funcionando | `server/blackboard/` | -| LiteLLM Gateway | ✅ Configurado | porta 4000 | -| CRM, WhatsApp, Chat | ✅ Funcionando | `server/crm/`, `server/whatsapp/` | -| ERPNext integração | ⚠️ Parcial | `server/erp/routes.ts` | - -### O que FALTA para o plano atual: -| Componente | Status | -|---|---| -| **SOE Central (Regras Unificadas)** | ❌ Não existe — este é o plano | -| Fiscal rules centralizadas (acima do Plus) | ❌ Dispersas no Plus | -| ERPNext rules centralizadas | ❌ Não existe camada de abstração | -| Contábil Avançado (lançamentos automáticos) | ❌ Motor existe, regras não | -| Financeiro Avançado (previsão, DRE automático) | ❌ Motor existe, regras não | -| Testes automatizados / CI-CD | ❌ | -| Monitoramento (APM, Sentry) | ❌ | - ---- - -## 2. O PROBLEMA QUE VAMOS RESOLVER - -### Situação Atual (problemática) -``` -Usuário → Arcádia Suite - ├── /plus → acessa Laravel diretamente (usuário VÊ o Plus) - ├── /erp → acessa ERPNext diretamente (usuário VÊ o ERPNext) - └── Regras fiscais ficam dentro do Plus - Regras contábeis ficam no Motor 8003 - Regras ERP ficam no ERPNext - → Fragmentado, sem governança central -``` - -### Situação Desejada (SOE Central) -``` -Usuário → Arcádia Suite (SOE) - │ - ▼ [Central de Regras SOE] - ├── Fiscal: regras unificadas (CFOP, NCM, tributação, NF-e, CT-e...) - ├── ERP: regras de negócio (pedidos, estoque, compras...) - ├── Contábil: regras de lançamentos, plano de contas, DRE... - └── Financeiro: regras de fluxo, provisões, conciliação... - │ - ▼ [Execução invisível] - ├── Plus → emite documentos, registra no banco - └── ERPNext → executa operações, registra no banco - - O usuário NUNCA VÊ o Plus nem o ERPNext. - Só vê a Central SOE do Arcádia. -``` - ---- - -## 3. ARQUITETURA SOE CENTRAL - -### 3.1 Diagrama Completo - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ ARCÁDIA SUITE (Frontend React) │ -│ /financeiro /contabil /fisco /erp /people /production /bi │ -│ Usuário nunca acessa /plus ou ERPNext diretamente │ -└───────────────────────────────┬─────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ SOE — SISTEMA OPERACIONAL EMPRESARIAL (Nova Camada) │ -│ Express.js / porta 5000 / server/soe/ │ -│ │ -│ ┌──────────────────────┐ ┌──────────────────────┐ │ -│ │ CENTRAL FISCAL │ │ CENTRAL ERP │ │ -│ │ server/soe/fiscal/ │ │ server/soe/erp/ │ │ -│ │ │ │ │ │ -│ │ • Regras NCM/CFOP │ │ • Regras de pedidos │ │ -│ │ • Políticas tribut. │ │ • Regras de estoque │ │ -│ │ • Emissão NF-e/NFC-e │ │ • Regras de compras │ │ -│ │ • Cancelamento │ │ • Regras de pessoas │ │ -│ │ • SPED/SINTEGRA │ │ • Integrações ext. │ │ -│ └──────────┬───────────┘ └──────────┬─────────────┘ │ -│ │ │ │ -│ ┌──────────────────────┐ ┌──────────────────────┐ │ -│ │ CENTRAL CONTÁBIL │ │ CENTRAL FINANCEIRO │ │ -│ │ server/soe/contabil/│ │ server/soe/financ/ │ │ -│ │ │ │ │ │ -│ │ • Plano de contas │ │ • Fluxo de caixa │ │ -│ │ • Regras de lanç. │ │ • Contas a P/R │ │ -│ │ • DRE automático │ │ • Conciliação │ │ -│ │ • Balancete │ │ • Previsão (IA) │ │ -│ │ • Fechamento │ │ • Impostos │ │ -│ └──────────┬───────────┘ └──────────┬─────────────┘ │ -│ │ │ │ -│ └────────────┬─────────────┘ │ -│ ▼ │ -│ ┌─────────────────────────────────┐ │ -│ │ SOE RULE ENGINE (Núcleo) │ │ -│ │ server/soe/rule-engine.ts │ │ -│ │ │ │ -│ │ • Resolução de conflitos │ │ -│ │ • Aplicação de políticas XOS │ │ -│ │ • Audit trail de todas regras │ │ -│ │ • Manus consulta este engine │ │ -│ └─────────────────┬───────────────┘ │ -└────────────────────────────┼────────────────────────────────────────────┘ - │ - ┌──────────────┼───────────────┐ - ▼ ▼ ▼ -┌─────────────────┐ ┌──────────────┐ ┌──────────────────┐ -│ ARCÁDIA PLUS │ │ ERPNEXT │ │ MOTORES PYTHON │ -│ Laravel :8080 │ │ Frappe : │ │ 8002 Fiscal │ -│ (invisível) │ │ (invisível) │ │ 8003 Contábil │ -│ │ │ │ │ 8004 BI │ -│ Emite docs │ │ Executa ERP │ │ 8005 Automação │ -│ fiscais │ │ operacional │ │ │ -└─────────────────┘ └──────────────┘ └──────────────────┘ -``` - ---- - -## 4. CENTRAL FISCAL — Detalhamento - -### 4.1 O que ela resolve -O Plus tem **376 controllers** e **1.546 rotas** — tudo fiscal/operacional. A Central Fiscal **não substitui** o Plus, ela **orquestra** o Plus com regras definidas no SOE. - -### 4.2 Regras que vão para a Central (tiradas do Plus) - -```typescript -// server/soe/fiscal/rules.ts — Exemplo de estrutura - -interface FiscalRule { - id: string - nome: string - trigger: 'pre_emissao' | 'pos_emissao' | 'cancelamento' | 'validacao' - condicao: FiscalCondition - acao: FiscalAction - prioridade: number - ativo: boolean -} - -// Exemplos de regras: -const REGRAS_FISCAIS: FiscalRule[] = [ - { - id: 'NFE_CFOP_INTERESTADUAL', - nome: 'Ajusta CFOP para operação interestadual', - trigger: 'pre_emissao', - condicao: { uf_emitente: '!=', uf_destinatario: true }, - acao: { ajustar_cfop: 'interestadual' }, - prioridade: 1, - ativo: true - }, - { - id: 'NFE_SIMPLES_NACIONAL', - nome: 'Aplica tributação Simples Nacional', - trigger: 'pre_emissao', - condicao: { regime_tributario: 'simples_nacional' }, - acao: { aplicar_cst: 'tabela_simples', remover_pis_cofins: true }, - prioridade: 2, - ativo: true - }, - { - id: 'NFE_VALIDACAO_NCM', - nome: 'Valida NCM obrigatório para NF-e', - trigger: 'validacao', - condicao: { tipo_documento: 'nfe' }, - acao: { validar_campo: 'ncm', obrigatorio: true }, - prioridade: 1, - ativo: true - } -] -``` - -### 4.3 Fluxo de Emissão via SOE Central - -``` -Usuário clica "Emitir NF-e" no Arcádia - │ - ▼ -POST /api/soe/fiscal/emitir-nfe - │ - ▼ -SOE Rule Engine: aplica REGRAS_FISCAIS (pre_emissao) - • Verifica regime tributário - • Aplica CFOP correto - • Calcula impostos (ICMS, PIS, COFINS, IPI) - • Valida NCM obrigatório - • Adiciona dados da empresa emitente - │ - ▼ -SOE envia para Plus via API interna (invisível) - POST http://plus:8080/api/nfe/emitir - + token SSO automático - │ - ▼ -Plus emite via Cloud-DFE → SEFAZ - │ - ▼ -SOE recebe retorno - • Registra no banco SOE (tabela soe_fiscal_eventos) - • Dispara lançamento contábil automático - • Notifica via WebSocket o frontend - │ - ▼ -Usuário vê resultado no Arcádia (nunca soube do Plus) -``` - -### 4.4 Tabelas SOE para Fiscal - -```sql --- Tabelas a criar no schema Arcádia (PostgreSQL) - -CREATE TABLE soe_fiscal_regras ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nome VARCHAR(200) NOT NULL, - trigger VARCHAR(50) NOT NULL, - condicao JSONB NOT NULL, - acao JSONB NOT NULL, - prioridade INTEGER DEFAULT 10, - ativo BOOLEAN DEFAULT true, - created_at TIMESTAMP DEFAULT NOW() -); - -CREATE TABLE soe_fiscal_eventos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - tipo VARCHAR(50) NOT NULL, -- 'emissao_nfe', 'cancelamento', etc. - empresa_id INTEGER NOT NULL, - documento_chave VARCHAR(100), - regras_aplicadas JSONB, -- quais regras foram aplicadas - payload_enviado JSONB, -- o que foi enviado ao Plus - payload_retorno JSONB, -- o que o Plus/SEFAZ respondeu - status VARCHAR(50) NOT NULL, - created_at TIMESTAMP DEFAULT NOW() -); - -CREATE TABLE soe_fiscal_configuracoes ( - empresa_id INTEGER PRIMARY KEY, - regime_tributario VARCHAR(50), -- simples, lucro_presumido, lucro_real - uf VARCHAR(2), - cnpj VARCHAR(18), - certificado_tipo VARCHAR(20), - aliquotas JSONB, -- alíquotas padrão por operação - cfops_padrao JSONB, -- CFOPs padrão por tipo de operação - created_at TIMESTAMP DEFAULT NOW() -); -``` - ---- - -## 5. CENTRAL ERP (ERPNext/Frappe) — Detalhamento - -### 5.1 O que ela resolve -O ERPNext tem **APIs complexas**. A Central ERP abstrai tudo isso em operações simples que o Arcádia entende. - -### 5.2 Adapter Layer ERPNext - -```typescript -// server/soe/erp/frappe-adapter.ts - -interface ERPAdapter { - // Produtos - criarProduto(data: ProdutoSOE): Promise - buscarProduto(codigo: string): Promise - atualizarEstoque(movimentacao: MovimentacaoEstoque): Promise - - // Pedidos - criarPedidoVenda(pedido: PedidoSOE): Promise - aprovarPedido(id: string): Promise - faturarPedido(id: string): Promise - - // Financeiro - criarLancamento(lancamento: LancamentoSOE): Promise - buscarPlanoContas(): Promise - - // Compras - criarPedidoCompra(data: PedidoCompraSOE): Promise - receberMercadoria(data: RecebimentoSOE): Promise -} - -// As regras ficam no SOE, o adapter só traduz -class FrappeAdapter implements ERPAdapter { - private baseUrl: string - private apiKey: string - - async criarPedidoVenda(pedido: PedidoSOE): Promise { - // Traduz do modelo SOE para o modelo Frappe - const frappePedido = this.traduzirParaFrappe(pedido) - - // Envia para ERPNext (invisível para o usuário) - const response = await fetch(`${this.baseUrl}/api/resource/Sales Order`, { - method: 'POST', - headers: { 'Authorization': `token ${this.apiKey}` }, - body: JSON.stringify(frappePedido) - }) - - // Traduz retorno de volta para modelo SOE - return this.traduzirDeVoltaSOE(await response.json()) - } -} -``` - -### 5.3 Regras de Negócio ERP no SOE - -```typescript -// server/soe/erp/rules.ts - -const REGRAS_ERP = [ - { - id: 'PEDIDO_APROVACAO_AUTOMATICA', - nome: 'Aprovação automática até R$ 5.000', - trigger: 'pre_aprovacao_pedido', - condicao: { valor_total: { menor_que: 5000 } }, - acao: { aprovar_automaticamente: true } - }, - { - id: 'ESTOQUE_RESERVA_VENDA', - nome: 'Reservar estoque ao confirmar venda', - trigger: 'pos_confirmacao_venda', - condicao: { status: 'confirmado' }, - acao: { reservar_estoque: true, gerar_separacao: true } - }, - { - id: 'NF_AUTOMATICA_FATURAMENTO', - nome: 'Emite NF-e automaticamente ao faturar', - trigger: 'pos_faturamento', - condicao: { tipo_cliente: ['pj', 'pf_contribuinte'] }, - acao: { emitir_nfe: true, via_soe_fiscal: true } - } -] -``` - ---- - -## 6. CENTRAL CONTÁBIL AVANÇADA - -### 6.1 Motor Atual (porta 8003) + Regras SOE - -O Motor Contábil Python já faz DRE e Balancete. O que falta é **alimentação automática**. - -### 6.2 Lançamentos Automáticos (grande salto) - -```typescript -// server/soe/contabil/auto-lancamentos.ts - -interface RegrasLancamentoAuto { - gatilho: string - debito: string // Conta contábil - credito: string // Conta contábil - historico: string - formula: string // Como calcular o valor -} - -const LANCAMENTOS_AUTOMATICOS: RegrasLancamentoAuto[] = [ - // Quando emite NF-e de venda - { - gatilho: 'emissao_nfe_venda', - debito: '1.1.3.01', // Clientes - credito: '3.1.1.01', // Receita Bruta de Vendas - historico: 'Venda conforme NF-e {numero}', - formula: 'valor_total_nota' - }, - { - gatilho: 'emissao_nfe_venda', - debito: '3.1.2.01', // Dedução de Receita (ICMS) - credito: '2.1.2.01', // ICMS a Recolher - historico: 'ICMS s/ Venda NF-e {numero}', - formula: 'valor_icms' - }, - // Quando paga conta - { - gatilho: 'pagamento_conta', - debito: '2.1.1.{categoria}', // Conta a Pagar específica - credito: '1.1.1.01', // Banco/Caixa - historico: 'Pagamento: {descricao}', - formula: 'valor_pago' - }, - // Quando recebe pagamento - { - gatilho: 'recebimento', - debito: '1.1.1.01', // Banco/Caixa - credito: '1.1.3.01', // Clientes - historico: 'Recebimento: {descricao}', - formula: 'valor_recebido' - }, - // Compra de mercadoria - { - gatilho: 'entrada_nfe_compra', - debito: '1.1.4.01', // Estoque - credito: '2.1.1.01', // Fornecedores - historico: 'Compra conforme NF-e {numero} / {fornecedor}', - formula: 'valor_mercadorias' - } -] -``` - -### 6.3 DRE Automático via SOE - -``` -Usuário pede DRE do mês - │ - ▼ -SOE Contábil consulta: - 1. Todos lançamentos do período (tabela soe_lancamentos) - 2. Agrupa por conta contábil - 3. Aplica estrutura DRE configurada - 4. Envia para Motor Python 8003 para cálculos - 5. Retorna DRE formatado - │ - ▼ -Usuário vê DRE no /contabil do Arcádia -(Nunca soube que teve lançamentos automáticos de NF-e, pagamentos, etc.) -``` - ---- - -## 7. CENTRAL FINANCEIRO AVANÇADO - -### 7.1 Regras Financeiras no SOE - -```typescript -// server/soe/financeiro/rules.ts - -const REGRAS_FINANCEIRO = [ - { - id: 'BOLETO_AUTO_VENCIMENTO', - nome: 'Gerar boleto automático para vendas a prazo', - trigger: 'pos_confirmacao_venda_prazo', - acao: { gerar_boleto: true, via: 'asaas', vencimento: '+{prazo}_dias' } - }, - { - id: 'ALERTA_VENCIMENTO_3DIAS', - nome: 'Alerta de vencimento 3 dias antes', - trigger: 'cron_diario', - condicao: { vencimento_em: 3 }, - acao: { notificar: ['whatsapp', 'email'], via_manus: true } - }, - { - id: 'PROVISAO_IMPOSTOS', - nome: 'Provisão mensal de impostos', - trigger: 'cron_mensal', - acao: { calcular_provisao: ['icms', 'pis', 'cofins', 'csll', 'irpj'], registrar_lancamento: true } - }, - { - id: 'CONCILIACAO_AUTO', - nome: 'Conciliação bancária automática via OFX', - trigger: 'importacao_ofx', - acao: { tentar_conciliar: true, confianca_minima: 0.85, pendentes_para_revisao: true } - } -] -``` - ---- - -## 8. MANUS AGENT + SOE CENTRAL - -### 8.1 O Manus consulta a Central - -``` -Pergunta: "Qual foi o resultado do mês passado?" - │ - ▼ -Manus → SOE Central - • GET /api/soe/contabil/dre?periodo=2026-02 - • GET /api/soe/financeiro/fluxo?periodo=2026-02 - • GET /api/soe/fiscal/resumo?periodo=2026-02 - │ - ▼ -SOE agrega dados dos motores (Python) + Plus + ERPNext - │ - ▼ -Manus recebe contexto completo e responde: - "Faturamento: R$ 120.000 - Deduções (impostos): R$ 18.000 - Receita Líquida: R$ 102.000 - Custo das mercadorias: R$ 65.000 - Lucro Bruto: R$ 37.000 - ..." -``` - -### 8.2 Tools do Manus para o SOE - -```typescript -// Novas tools do Manus que consultam o SOE Central - -{ - name: 'consultar_situacao_fiscal', - description: 'Consulta situação fiscal da empresa (NFs pendentes, impostos, SPED)', - endpoint: 'GET /api/soe/fiscal/situacao' -}, -{ - name: 'emitir_documento_fiscal', - description: 'Emite NF-e, NFC-e, CT-e ou MDF-e', - endpoint: 'POST /api/soe/fiscal/emitir' -}, -{ - name: 'consultar_dre', - description: 'Gera DRE de qualquer período', - endpoint: 'GET /api/soe/contabil/dre' -}, -{ - name: 'consultar_fluxo_caixa', - description: 'Consulta fluxo de caixa e previsões', - endpoint: 'GET /api/soe/financeiro/fluxo' -}, -{ - name: 'registrar_lancamento_contabil', - description: 'Registra lançamento contábil manualmente', - endpoint: 'POST /api/soe/contabil/lancamento' -} -``` - ---- - -## 9. ESTRUTURA DE PASTAS A CRIAR - -``` -server/ -└── soe/ ← Nova pasta (Central SOE) - ├── index.ts ← Router principal do SOE - ├── rule-engine.ts ← Motor de regras central - │ - ├── fiscal/ - │ ├── routes.ts ← GET/POST /api/soe/fiscal/* - │ ├── rules.ts ← Regras fiscais (CFOP, NCM, tributação) - │ ├── emissao.ts ← Orquestração de emissão (→ Plus) - │ ├── plus-adapter.ts ← Adaptador para o Plus (invisível) - │ └── sefaz-adapter.ts ← Comunicação direta SEFAZ (via Python 8002) - │ - ├── erp/ - │ ├── routes.ts ← GET/POST /api/soe/erp/* - │ ├── rules.ts ← Regras de negócio ERP - │ ├── frappe-adapter.ts ← Adaptador ERPNext (invisível) - │ └── plus-erp-adapter.ts ← Adaptador Plus-ERP (para dados de venda) - │ - ├── contabil/ - │ ├── routes.ts ← GET/POST /api/soe/contabil/* - │ ├── rules.ts ← Regras contábeis - │ ├── auto-lancamentos.ts ← Lançamentos automáticos - │ ├── plano-contas.ts ← Plano de contas SOE - │ └── python-adapter.ts ← Adaptador Motor Python 8003 - │ - ├── financeiro/ - │ ├── routes.ts ← GET/POST /api/soe/financeiro/* - │ ├── rules.ts ← Regras financeiras - │ ├── previsao.ts ← Previsão com IA - │ └── conciliacao.ts ← Conciliação bancária - │ - └── shared/ - ├── types.ts ← Tipos SOE compartilhados - ├── audit.ts ← Registro de todas as operações - └── event-bus.ts ← Eventos entre Centrais -``` - ---- - -## 10. TABELAS DO BANCO A CRIAR (Drizzle ORM) - -```typescript -// shared/schema.ts — Adicionar: - -// Configuração da empresa no SOE -export const soeEmpresaConfig = pgTable('soe_empresa_config', { - id: serial('id').primaryKey(), - empresaId: integer('empresa_id').notNull(), - regimeTributario: varchar('regime_tributario', { length: 50 }), // simples, presumido, real - uf: varchar('uf', { length: 2 }), - cnpj: varchar('cnpj', { length: 18 }), - planoContasId: integer('plano_contas_id'), - configFiscal: jsonb('config_fiscal'), // alíquotas, CFOPs padrão - configErp: jsonb('config_erp'), // qual ERP: plus, erpnext, ambos - createdAt: timestamp('created_at').defaultNow(), -}) - -// Regras configuráveis (editáveis pelo usuário) -export const soeRegras = pgTable('soe_regras', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id'), // null = regra global - dominio: varchar('dominio', { length: 50 }).notNull(), // 'fiscal', 'erp', 'contabil', 'financeiro' - nome: varchar('nome', { length: 200 }).notNull(), - trigger: varchar('trigger', { length: 100 }).notNull(), - condicao: jsonb('condicao').notNull(), - acao: jsonb('acao').notNull(), - prioridade: integer('prioridade').default(10), - ativo: boolean('ativo').default(true), - createdAt: timestamp('created_at').defaultNow(), -}) - -// Log de todas as operações SOE (audit trail) -export const soeEventos = pgTable('soe_eventos', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id').notNull(), - dominio: varchar('dominio', { length: 50 }).notNull(), - tipo: varchar('tipo', { length: 100 }).notNull(), - regraIds: jsonb('regra_ids'), // regras aplicadas - payloadEntrada: jsonb('payload_entrada'), - payloadSaida: jsonb('payload_saida'), - erp: varchar('erp', { length: 50 }), // 'plus', 'erpnext', 'python_8003', etc. - status: varchar('status', { length: 50 }).notNull(), - duracao: integer('duracao'), // ms - createdAt: timestamp('created_at').defaultNow(), -}) - -// Lançamentos contábeis centralizados -export const soeLancamentos = pgTable('soe_lancamentos', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id').notNull(), - data: date('data').notNull(), - contaDebito: varchar('conta_debito', { length: 30 }).notNull(), - contaCredito: varchar('conta_credito', { length: 30 }).notNull(), - valor: numeric('valor', { precision: 15, scale: 2 }).notNull(), - historico: text('historico').notNull(), - origem: varchar('origem', { length: 100 }), // 'emissao_nfe', 'pagamento', etc. - origemId: varchar('origem_id', { length: 100 }), - period: varchar('period', { length: 7 }), // '2026-03' - createdAt: timestamp('created_at').defaultNow(), -}) -``` - ---- - -## 11. ROADMAP DE IMPLEMENTAÇÃO - -### Fase 1 — Fundação (2–3 semanas) -``` -[ ] 1. Criar server/soe/ com estrutura básica -[ ] 2. Criar tabelas: soe_empresa_config, soe_regras, soe_eventos, soe_lancamentos -[ ] 3. Implementar Plus Adapter (encapsula chamadas ao Laravel) -[ ] 4. Implementar Frappe Adapter (encapsula chamadas ao ERPNext) -[ ] 5. Endpoint GET /api/soe/status (health check de todos os motores) -[ ] 6. Migrar /api/fisco/* para passar pelo SOE -``` - -### Fase 2 — Central Fiscal (2–3 semanas) -``` -[ ] 7. Implementar Rule Engine para fiscal -[ ] 8. Criar regras fiscais base (NCM, CFOP, tributação por regime) -[ ] 9. POST /api/soe/fiscal/emitir-nfe → Plus (invisível) -[ ] 10. POST /api/soe/fiscal/cancelar-nfe → Plus (invisível) -[ ] 11. GET /api/soe/fiscal/situacao → agrega Plus + Python 8002 -[ ] 12. Atualizar frontend /fisco para usar /api/soe/fiscal/* -``` - -### Fase 3 — Central Contábil (2 semanas) -``` -[ ] 13. Implementar auto-lancamentos para eventos fiscais -[ ] 14. Integrar Motor Python 8003 via SOE -[ ] 15. GET /api/soe/contabil/dre → resultado automático -[ ] 16. GET /api/soe/contabil/balancete → atualizado em tempo real -[ ] 17. Atualizar frontend /contabil para usar /api/soe/contabil/* -``` - -### Fase 4 — Central Financeiro (2 semanas) -``` -[ ] 18. Regras de boleto automático (via Asaas) -[ ] 19. Alertas de vencimento (via Manus/WhatsApp) -[ ] 20. Conciliação bancária semi-automática -[ ] 21. Previsão financeira com IA (Motor Python 8003 + Manus) -[ ] 22. Atualizar frontend /financeiro para usar /api/soe/financeiro/* -``` - -### Fase 5 — Manus + SOE (1 semana) -``` -[ ] 23. Registrar novas tools Manus apontando para SOE -[ ] 24. Manus usa SOE para responder perguntas de negócio -[ ] 25. Dashboard SOE: visão geral de todos os eventos -``` - -### Fase 6 — Central ERP (3 semanas) -``` -[ ] 26. Frappe Adapter completo (produtos, pedidos, estoque, compras) -[ ] 27. Regras de negócio ERP no SOE -[ ] 28. Sincronização bidirecional SOE ↔ ERPNext (via eventos) -[ ] 29. Atualizar /erp para usar /api/soe/erp/* -``` - ---- - -## 12. RESULTADO FINAL — O QUE O USUÁRIO EXPERIMENTA - -``` -Antes (fragmentado): - Usuário → /plus → vê Laravel diretamente - Usuário → /erp → vê ERPNext diretamente - Regras fiscais só no Plus - Contabilidade manual - Financeiro sem automação - -Depois (SOE Central): - Usuário → /fisco → emite NF-e, Plus executa invisível - Usuário → /contabil → vê DRE gerado automaticamente - Usuário → /financeiro → vê fluxo, previsões, alertas automáticos - Usuário → Manus → pergunta "qual meu resultado?" → resposta completa - - Plus e ERPNext: INVISÍVEIS, executando em background - Regras: CENTRALIZADAS no SOE, editáveis - Lançamentos: AUTOMÁTICOS baseados em eventos (NF-e, pagamentos, etc.) - Auditoria: TOTAL de todas as operações -``` - ---- - -## 13. PRINCÍPIO ORIENTADOR - -> **"O usuário não sabe o que está por trás. Ele só sabe que funciona."** -> -> O Arcádia Suite é o **Sistema Operacional** da empresa. -> O Plus e o ERPNext são **drivers de hardware** — poderosos, mas invisíveis. -> O SOE Central é o **kernel** que os orquestra com regras e inteligência. - ---- - -*PLANO_SOE_CENTRAL.md — Arcádia Suite v3.0* -*Gerado em: 2026-03-16* diff --git a/docs/PLANO_SOE_CENTRAL.md b/docs/PLANO_SOE_CENTRAL.md deleted file mode 100644 index 921b731..0000000 --- a/docs/PLANO_SOE_CENTRAL.md +++ /dev/null @@ -1,733 +0,0 @@ -# PLANO SOE CENTRAL — Arcádia Suite -## Orquestração Inteligente: Plus + ERPNext invisíveis, Central visível -### Versão 1.0 — Março 2026 - ---- - -## 1. ONDE ESTAMOS (Orientação Geral) - -### O Projeto nasceu no Replit como… -- Uma plataforma de **escritório empresarial com IA central** (Manus Agent) -- Com proxy para o **Arcádia Plus** (Laravel/PHP, porta 8080) — ERP fiscal completo -- Com integração ao **ERPNext/Frappe** via API -- Stack principal: **React 18 + Express.js + PostgreSQL + FastAPI (Python)** - -### O que JÁ existe e funciona: -| Componente | Status | Onde vive | -|---|---|---| -| Manus Agent (IA, 30+ tools) | ✅ Funcionando | `server/manus/` | -| Arcádia Plus (Laravel ERP) | ✅ Funcionando | `plus/` → porta 8080 | -| SSO Plus ↔ Suite | ✅ Funcionando | `server/plus/` | -| Motor Fiscal (nfelib) | ✅ Funcionando | `server/python/` → porta 8002 | -| Motor Contábil | ✅ Funcionando | `server/python/` → porta 8003 | -| Motor BI | ✅ Funcionando | `server/python/` → porta 8004 | -| Motor Automação | ✅ Funcionando | `server/python/` → porta 8005 | -| Motor Comunicação (Comm) | ✅ Funcionando | porta 8006 | -| Dev Center XOS (6 agentes) | ✅ Funcionando | `server/blackboard/` | -| LiteLLM Gateway | ✅ Configurado | porta 4000 | -| CRM, WhatsApp, Chat | ✅ Funcionando | `server/crm/`, `server/whatsapp/` | -| ERPNext integração | ⚠️ Parcial | `server/erp/routes.ts` | - -### O que FALTA para o plano atual: -| Componente | Status | -|---|---| -| **SOE Central (Regras Unificadas)** | ❌ Não existe — este é o plano | -| Fiscal rules centralizadas (acima do Plus) | ❌ Dispersas no Plus | -| ERPNext rules centralizadas | ❌ Não existe camada de abstração | -| Contábil Avançado (lançamentos automáticos) | ❌ Motor existe, regras não | -| Financeiro Avançado (previsão, DRE automático) | ❌ Motor existe, regras não | -| Testes automatizados / CI-CD | ❌ | -| Monitoramento (APM, Sentry) | ❌ | - ---- - -## 2. O PROBLEMA QUE VAMOS RESOLVER - -### Situação Atual (problemática) -``` -Usuário → Arcádia Suite - ├── /plus → acessa Laravel diretamente (usuário VÊ o Plus) - ├── /erp → acessa ERPNext diretamente (usuário VÊ o ERPNext) - └── Regras fiscais ficam dentro do Plus - Regras contábeis ficam no Motor 8003 - Regras ERP ficam no ERPNext - → Fragmentado, sem governança central -``` - -### Situação Desejada (SOE Central) -``` -Usuário → Arcádia Suite (SOE) - │ - ▼ [Central de Regras SOE] - ├── Fiscal: regras unificadas (CFOP, NCM, tributação, NF-e, CT-e...) - ├── ERP: regras de negócio (pedidos, estoque, compras...) - ├── Contábil: regras de lançamentos, plano de contas, DRE... - └── Financeiro: regras de fluxo, provisões, conciliação... - │ - ▼ [Execução invisível] - ├── Plus → emite documentos, registra no banco - └── ERPNext → executa operações, registra no banco - - O usuário NUNCA VÊ o Plus nem o ERPNext. - Só vê a Central SOE do Arcádia. -``` - ---- - -## 3. ARQUITETURA SOE CENTRAL - -### 3.1 Diagrama Completo - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ ARCÁDIA SUITE (Frontend React) │ -│ /financeiro /contabil /fisco /erp /people /production /bi │ -│ Usuário nunca acessa /plus ou ERPNext diretamente │ -└───────────────────────────────┬─────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ SOE — SISTEMA OPERACIONAL EMPRESARIAL (Nova Camada) │ -│ Express.js / porta 5000 / server/soe/ │ -│ │ -│ ┌──────────────────────┐ ┌──────────────────────┐ │ -│ │ CENTRAL FISCAL │ │ CENTRAL ERP │ │ -│ │ server/soe/fiscal/ │ │ server/soe/erp/ │ │ -│ │ │ │ │ │ -│ │ • Regras NCM/CFOP │ │ • Regras de pedidos │ │ -│ │ • Políticas tribut. │ │ • Regras de estoque │ │ -│ │ • Emissão NF-e/NFC-e │ │ • Regras de compras │ │ -│ │ • Cancelamento │ │ • Regras de pessoas │ │ -│ │ • SPED/SINTEGRA │ │ • Integrações ext. │ │ -│ └──────────┬───────────┘ └──────────┬─────────────┘ │ -│ │ │ │ -│ ┌──────────────────────┐ ┌──────────────────────┐ │ -│ │ CENTRAL CONTÁBIL │ │ CENTRAL FINANCEIRO │ │ -│ │ server/soe/contabil/│ │ server/soe/financ/ │ │ -│ │ │ │ │ │ -│ │ • Plano de contas │ │ • Fluxo de caixa │ │ -│ │ • Regras de lanç. │ │ • Contas a P/R │ │ -│ │ • DRE automático │ │ • Conciliação │ │ -│ │ • Balancete │ │ • Previsão (IA) │ │ -│ │ • Fechamento │ │ • Impostos │ │ -│ └──────────┬───────────┘ └──────────┬─────────────┘ │ -│ │ │ │ -│ └────────────┬─────────────┘ │ -│ ▼ │ -│ ┌─────────────────────────────────┐ │ -│ │ SOE RULE ENGINE (Núcleo) │ │ -│ │ server/soe/rule-engine.ts │ │ -│ │ │ │ -│ │ • Resolução de conflitos │ │ -│ │ • Aplicação de políticas XOS │ │ -│ │ • Audit trail de todas regras │ │ -│ │ • Manus consulta este engine │ │ -│ └─────────────────┬───────────────┘ │ -└────────────────────────────┼────────────────────────────────────────────┘ - │ - ┌──────────────┼───────────────┐ - ▼ ▼ ▼ -┌─────────────────┐ ┌──────────────┐ ┌──────────────────┐ -│ ARCÁDIA PLUS │ │ ERPNEXT │ │ MOTORES PYTHON │ -│ Laravel :8080 │ │ Frappe : │ │ 8002 Fiscal │ -│ (invisível) │ │ (invisível) │ │ 8003 Contábil │ -│ │ │ │ │ 8004 BI │ -│ Emite docs │ │ Executa ERP │ │ 8005 Automação │ -│ fiscais │ │ operacional │ │ │ -└─────────────────┘ └──────────────┘ └──────────────────┘ -``` - ---- - -## 4. CENTRAL FISCAL — Detalhamento - -### 4.1 O que ela resolve -O Plus tem **376 controllers** e **1.546 rotas** — tudo fiscal/operacional. A Central Fiscal **não substitui** o Plus, ela **orquestra** o Plus com regras definidas no SOE. - -### 4.2 Regras que vão para a Central (tiradas do Plus) - -```typescript -// server/soe/fiscal/rules.ts — Exemplo de estrutura - -interface FiscalRule { - id: string - nome: string - trigger: 'pre_emissao' | 'pos_emissao' | 'cancelamento' | 'validacao' - condicao: FiscalCondition - acao: FiscalAction - prioridade: number - ativo: boolean -} - -// Exemplos de regras: -const REGRAS_FISCAIS: FiscalRule[] = [ - { - id: 'NFE_CFOP_INTERESTADUAL', - nome: 'Ajusta CFOP para operação interestadual', - trigger: 'pre_emissao', - condicao: { uf_emitente: '!=', uf_destinatario: true }, - acao: { ajustar_cfop: 'interestadual' }, - prioridade: 1, - ativo: true - }, - { - id: 'NFE_SIMPLES_NACIONAL', - nome: 'Aplica tributação Simples Nacional', - trigger: 'pre_emissao', - condicao: { regime_tributario: 'simples_nacional' }, - acao: { aplicar_cst: 'tabela_simples', remover_pis_cofins: true }, - prioridade: 2, - ativo: true - }, - { - id: 'NFE_VALIDACAO_NCM', - nome: 'Valida NCM obrigatório para NF-e', - trigger: 'validacao', - condicao: { tipo_documento: 'nfe' }, - acao: { validar_campo: 'ncm', obrigatorio: true }, - prioridade: 1, - ativo: true - } -] -``` - -### 4.3 Fluxo de Emissão via SOE Central - -``` -Usuário clica "Emitir NF-e" no Arcádia - │ - ▼ -POST /api/soe/fiscal/emitir-nfe - │ - ▼ -SOE Rule Engine: aplica REGRAS_FISCAIS (pre_emissao) - • Verifica regime tributário - • Aplica CFOP correto - • Calcula impostos (ICMS, PIS, COFINS, IPI) - • Valida NCM obrigatório - • Adiciona dados da empresa emitente - │ - ▼ -SOE envia para Plus via API interna (invisível) - POST http://plus:8080/api/nfe/emitir - + token SSO automático - │ - ▼ -Plus emite via Cloud-DFE → SEFAZ - │ - ▼ -SOE recebe retorno - • Registra no banco SOE (tabela soe_fiscal_eventos) - • Dispara lançamento contábil automático - • Notifica via WebSocket o frontend - │ - ▼ -Usuário vê resultado no Arcádia (nunca soube do Plus) -``` - -### 4.4 Tabelas SOE para Fiscal - -```sql --- Tabelas a criar no schema Arcádia (PostgreSQL) - -CREATE TABLE soe_fiscal_regras ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - nome VARCHAR(200) NOT NULL, - trigger VARCHAR(50) NOT NULL, - condicao JSONB NOT NULL, - acao JSONB NOT NULL, - prioridade INTEGER DEFAULT 10, - ativo BOOLEAN DEFAULT true, - created_at TIMESTAMP DEFAULT NOW() -); - -CREATE TABLE soe_fiscal_eventos ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - tipo VARCHAR(50) NOT NULL, -- 'emissao_nfe', 'cancelamento', etc. - empresa_id INTEGER NOT NULL, - documento_chave VARCHAR(100), - regras_aplicadas JSONB, -- quais regras foram aplicadas - payload_enviado JSONB, -- o que foi enviado ao Plus - payload_retorno JSONB, -- o que o Plus/SEFAZ respondeu - status VARCHAR(50) NOT NULL, - created_at TIMESTAMP DEFAULT NOW() -); - -CREATE TABLE soe_fiscal_configuracoes ( - empresa_id INTEGER PRIMARY KEY, - regime_tributario VARCHAR(50), -- simples, lucro_presumido, lucro_real - uf VARCHAR(2), - cnpj VARCHAR(18), - certificado_tipo VARCHAR(20), - aliquotas JSONB, -- alíquotas padrão por operação - cfops_padrao JSONB, -- CFOPs padrão por tipo de operação - created_at TIMESTAMP DEFAULT NOW() -); -``` - ---- - -## 5. CENTRAL ERP (ERPNext/Frappe) — Detalhamento - -### 5.1 O que ela resolve -O ERPNext tem **APIs complexas**. A Central ERP abstrai tudo isso em operações simples que o Arcádia entende. - -### 5.2 Adapter Layer ERPNext - -```typescript -// server/soe/erp/frappe-adapter.ts - -interface ERPAdapter { - // Produtos - criarProduto(data: ProdutoSOE): Promise - buscarProduto(codigo: string): Promise - atualizarEstoque(movimentacao: MovimentacaoEstoque): Promise - - // Pedidos - criarPedidoVenda(pedido: PedidoSOE): Promise - aprovarPedido(id: string): Promise - faturarPedido(id: string): Promise - - // Financeiro - criarLancamento(lancamento: LancamentoSOE): Promise - buscarPlanoContas(): Promise - - // Compras - criarPedidoCompra(data: PedidoCompraSOE): Promise - receberMercadoria(data: RecebimentoSOE): Promise -} - -// As regras ficam no SOE, o adapter só traduz -class FrappeAdapter implements ERPAdapter { - private baseUrl: string - private apiKey: string - - async criarPedidoVenda(pedido: PedidoSOE): Promise { - // Traduz do modelo SOE para o modelo Frappe - const frappePedido = this.traduzirParaFrappe(pedido) - - // Envia para ERPNext (invisível para o usuário) - const response = await fetch(`${this.baseUrl}/api/resource/Sales Order`, { - method: 'POST', - headers: { 'Authorization': `token ${this.apiKey}` }, - body: JSON.stringify(frappePedido) - }) - - // Traduz retorno de volta para modelo SOE - return this.traduzirDeVoltaSOE(await response.json()) - } -} -``` - -### 5.3 Regras de Negócio ERP no SOE - -```typescript -// server/soe/erp/rules.ts - -const REGRAS_ERP = [ - { - id: 'PEDIDO_APROVACAO_AUTOMATICA', - nome: 'Aprovação automática até R$ 5.000', - trigger: 'pre_aprovacao_pedido', - condicao: { valor_total: { menor_que: 5000 } }, - acao: { aprovar_automaticamente: true } - }, - { - id: 'ESTOQUE_RESERVA_VENDA', - nome: 'Reservar estoque ao confirmar venda', - trigger: 'pos_confirmacao_venda', - condicao: { status: 'confirmado' }, - acao: { reservar_estoque: true, gerar_separacao: true } - }, - { - id: 'NF_AUTOMATICA_FATURAMENTO', - nome: 'Emite NF-e automaticamente ao faturar', - trigger: 'pos_faturamento', - condicao: { tipo_cliente: ['pj', 'pf_contribuinte'] }, - acao: { emitir_nfe: true, via_soe_fiscal: true } - } -] -``` - ---- - -## 6. CENTRAL CONTÁBIL AVANÇADA - -### 6.1 Motor Atual (porta 8003) + Regras SOE - -O Motor Contábil Python já faz DRE e Balancete. O que falta é **alimentação automática**. - -### 6.2 Lançamentos Automáticos (grande salto) - -```typescript -// server/soe/contabil/auto-lancamentos.ts - -interface RegrasLancamentoAuto { - gatilho: string - debito: string // Conta contábil - credito: string // Conta contábil - historico: string - formula: string // Como calcular o valor -} - -const LANCAMENTOS_AUTOMATICOS: RegrasLancamentoAuto[] = [ - // Quando emite NF-e de venda - { - gatilho: 'emissao_nfe_venda', - debito: '1.1.3.01', // Clientes - credito: '3.1.1.01', // Receita Bruta de Vendas - historico: 'Venda conforme NF-e {numero}', - formula: 'valor_total_nota' - }, - { - gatilho: 'emissao_nfe_venda', - debito: '3.1.2.01', // Dedução de Receita (ICMS) - credito: '2.1.2.01', // ICMS a Recolher - historico: 'ICMS s/ Venda NF-e {numero}', - formula: 'valor_icms' - }, - // Quando paga conta - { - gatilho: 'pagamento_conta', - debito: '2.1.1.{categoria}', // Conta a Pagar específica - credito: '1.1.1.01', // Banco/Caixa - historico: 'Pagamento: {descricao}', - formula: 'valor_pago' - }, - // Quando recebe pagamento - { - gatilho: 'recebimento', - debito: '1.1.1.01', // Banco/Caixa - credito: '1.1.3.01', // Clientes - historico: 'Recebimento: {descricao}', - formula: 'valor_recebido' - }, - // Compra de mercadoria - { - gatilho: 'entrada_nfe_compra', - debito: '1.1.4.01', // Estoque - credito: '2.1.1.01', // Fornecedores - historico: 'Compra conforme NF-e {numero} / {fornecedor}', - formula: 'valor_mercadorias' - } -] -``` - -### 6.3 DRE Automático via SOE - -``` -Usuário pede DRE do mês - │ - ▼ -SOE Contábil consulta: - 1. Todos lançamentos do período (tabela soe_lancamentos) - 2. Agrupa por conta contábil - 3. Aplica estrutura DRE configurada - 4. Envia para Motor Python 8003 para cálculos - 5. Retorna DRE formatado - │ - ▼ -Usuário vê DRE no /contabil do Arcádia -(Nunca soube que teve lançamentos automáticos de NF-e, pagamentos, etc.) -``` - ---- - -## 7. CENTRAL FINANCEIRO AVANÇADO - -### 7.1 Regras Financeiras no SOE - -```typescript -// server/soe/financeiro/rules.ts - -const REGRAS_FINANCEIRO = [ - { - id: 'BOLETO_AUTO_VENCIMENTO', - nome: 'Gerar boleto automático para vendas a prazo', - trigger: 'pos_confirmacao_venda_prazo', - acao: { gerar_boleto: true, via: 'asaas', vencimento: '+{prazo}_dias' } - }, - { - id: 'ALERTA_VENCIMENTO_3DIAS', - nome: 'Alerta de vencimento 3 dias antes', - trigger: 'cron_diario', - condicao: { vencimento_em: 3 }, - acao: { notificar: ['whatsapp', 'email'], via_manus: true } - }, - { - id: 'PROVISAO_IMPOSTOS', - nome: 'Provisão mensal de impostos', - trigger: 'cron_mensal', - acao: { calcular_provisao: ['icms', 'pis', 'cofins', 'csll', 'irpj'], registrar_lancamento: true } - }, - { - id: 'CONCILIACAO_AUTO', - nome: 'Conciliação bancária automática via OFX', - trigger: 'importacao_ofx', - acao: { tentar_conciliar: true, confianca_minima: 0.85, pendentes_para_revisao: true } - } -] -``` - ---- - -## 8. MANUS AGENT + SOE CENTRAL - -### 8.1 O Manus consulta a Central - -``` -Pergunta: "Qual foi o resultado do mês passado?" - │ - ▼ -Manus → SOE Central - • GET /api/soe/contabil/dre?periodo=2026-02 - • GET /api/soe/financeiro/fluxo?periodo=2026-02 - • GET /api/soe/fiscal/resumo?periodo=2026-02 - │ - ▼ -SOE agrega dados dos motores (Python) + Plus + ERPNext - │ - ▼ -Manus recebe contexto completo e responde: - "Faturamento: R$ 120.000 - Deduções (impostos): R$ 18.000 - Receita Líquida: R$ 102.000 - Custo das mercadorias: R$ 65.000 - Lucro Bruto: R$ 37.000 - ..." -``` - -### 8.2 Tools do Manus para o SOE - -```typescript -// Novas tools do Manus que consultam o SOE Central - -{ - name: 'consultar_situacao_fiscal', - description: 'Consulta situação fiscal da empresa (NFs pendentes, impostos, SPED)', - endpoint: 'GET /api/soe/fiscal/situacao' -}, -{ - name: 'emitir_documento_fiscal', - description: 'Emite NF-e, NFC-e, CT-e ou MDF-e', - endpoint: 'POST /api/soe/fiscal/emitir' -}, -{ - name: 'consultar_dre', - description: 'Gera DRE de qualquer período', - endpoint: 'GET /api/soe/contabil/dre' -}, -{ - name: 'consultar_fluxo_caixa', - description: 'Consulta fluxo de caixa e previsões', - endpoint: 'GET /api/soe/financeiro/fluxo' -}, -{ - name: 'registrar_lancamento_contabil', - description: 'Registra lançamento contábil manualmente', - endpoint: 'POST /api/soe/contabil/lancamento' -} -``` - ---- - -## 9. ESTRUTURA DE PASTAS A CRIAR - -``` -server/ -└── soe/ ← Nova pasta (Central SOE) - ├── index.ts ← Router principal do SOE - ├── rule-engine.ts ← Motor de regras central - │ - ├── fiscal/ - │ ├── routes.ts ← GET/POST /api/soe/fiscal/* - │ ├── rules.ts ← Regras fiscais (CFOP, NCM, tributação) - │ ├── emissao.ts ← Orquestração de emissão (→ Plus) - │ ├── plus-adapter.ts ← Adaptador para o Plus (invisível) - │ └── sefaz-adapter.ts ← Comunicação direta SEFAZ (via Python 8002) - │ - ├── erp/ - │ ├── routes.ts ← GET/POST /api/soe/erp/* - │ ├── rules.ts ← Regras de negócio ERP - │ ├── frappe-adapter.ts ← Adaptador ERPNext (invisível) - │ └── plus-erp-adapter.ts ← Adaptador Plus-ERP (para dados de venda) - │ - ├── contabil/ - │ ├── routes.ts ← GET/POST /api/soe/contabil/* - │ ├── rules.ts ← Regras contábeis - │ ├── auto-lancamentos.ts ← Lançamentos automáticos - │ ├── plano-contas.ts ← Plano de contas SOE - │ └── python-adapter.ts ← Adaptador Motor Python 8003 - │ - ├── financeiro/ - │ ├── routes.ts ← GET/POST /api/soe/financeiro/* - │ ├── rules.ts ← Regras financeiras - │ ├── previsao.ts ← Previsão com IA - │ └── conciliacao.ts ← Conciliação bancária - │ - └── shared/ - ├── types.ts ← Tipos SOE compartilhados - ├── audit.ts ← Registro de todas as operações - └── event-bus.ts ← Eventos entre Centrais -``` - ---- - -## 10. TABELAS DO BANCO A CRIAR (Drizzle ORM) - -```typescript -// shared/schema.ts — Adicionar: - -// Configuração da empresa no SOE -export const soeEmpresaConfig = pgTable('soe_empresa_config', { - id: serial('id').primaryKey(), - empresaId: integer('empresa_id').notNull(), - regimeTributario: varchar('regime_tributario', { length: 50 }), // simples, presumido, real - uf: varchar('uf', { length: 2 }), - cnpj: varchar('cnpj', { length: 18 }), - planoContasId: integer('plano_contas_id'), - configFiscal: jsonb('config_fiscal'), // alíquotas, CFOPs padrão - configErp: jsonb('config_erp'), // qual ERP: plus, erpnext, ambos - createdAt: timestamp('created_at').defaultNow(), -}) - -// Regras configuráveis (editáveis pelo usuário) -export const soeRegras = pgTable('soe_regras', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id'), // null = regra global - dominio: varchar('dominio', { length: 50 }).notNull(), // 'fiscal', 'erp', 'contabil', 'financeiro' - nome: varchar('nome', { length: 200 }).notNull(), - trigger: varchar('trigger', { length: 100 }).notNull(), - condicao: jsonb('condicao').notNull(), - acao: jsonb('acao').notNull(), - prioridade: integer('prioridade').default(10), - ativo: boolean('ativo').default(true), - createdAt: timestamp('created_at').defaultNow(), -}) - -// Log de todas as operações SOE (audit trail) -export const soeEventos = pgTable('soe_eventos', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id').notNull(), - dominio: varchar('dominio', { length: 50 }).notNull(), - tipo: varchar('tipo', { length: 100 }).notNull(), - regraIds: jsonb('regra_ids'), // regras aplicadas - payloadEntrada: jsonb('payload_entrada'), - payloadSaida: jsonb('payload_saida'), - erp: varchar('erp', { length: 50 }), // 'plus', 'erpnext', 'python_8003', etc. - status: varchar('status', { length: 50 }).notNull(), - duracao: integer('duracao'), // ms - createdAt: timestamp('created_at').defaultNow(), -}) - -// Lançamentos contábeis centralizados -export const soeLancamentos = pgTable('soe_lancamentos', { - id: uuid('id').primaryKey().defaultRandom(), - empresaId: integer('empresa_id').notNull(), - data: date('data').notNull(), - contaDebito: varchar('conta_debito', { length: 30 }).notNull(), - contaCredito: varchar('conta_credito', { length: 30 }).notNull(), - valor: numeric('valor', { precision: 15, scale: 2 }).notNull(), - historico: text('historico').notNull(), - origem: varchar('origem', { length: 100 }), // 'emissao_nfe', 'pagamento', etc. - origemId: varchar('origem_id', { length: 100 }), - period: varchar('period', { length: 7 }), // '2026-03' - createdAt: timestamp('created_at').defaultNow(), -}) -``` - ---- - -## 11. ROADMAP DE IMPLEMENTAÇÃO - -### Fase 1 — Fundação (2–3 semanas) -``` -[ ] 1. Criar server/soe/ com estrutura básica -[ ] 2. Criar tabelas: soe_empresa_config, soe_regras, soe_eventos, soe_lancamentos -[ ] 3. Implementar Plus Adapter (encapsula chamadas ao Laravel) -[ ] 4. Implementar Frappe Adapter (encapsula chamadas ao ERPNext) -[ ] 5. Endpoint GET /api/soe/status (health check de todos os motores) -[ ] 6. Migrar /api/fisco/* para passar pelo SOE -``` - -### Fase 2 — Central Fiscal (2–3 semanas) -``` -[ ] 7. Implementar Rule Engine para fiscal -[ ] 8. Criar regras fiscais base (NCM, CFOP, tributação por regime) -[ ] 9. POST /api/soe/fiscal/emitir-nfe → Plus (invisível) -[ ] 10. POST /api/soe/fiscal/cancelar-nfe → Plus (invisível) -[ ] 11. GET /api/soe/fiscal/situacao → agrega Plus + Python 8002 -[ ] 12. Atualizar frontend /fisco para usar /api/soe/fiscal/* -``` - -### Fase 3 — Central Contábil (2 semanas) -``` -[ ] 13. Implementar auto-lancamentos para eventos fiscais -[ ] 14. Integrar Motor Python 8003 via SOE -[ ] 15. GET /api/soe/contabil/dre → resultado automático -[ ] 16. GET /api/soe/contabil/balancete → atualizado em tempo real -[ ] 17. Atualizar frontend /contabil para usar /api/soe/contabil/* -``` - -### Fase 4 — Central Financeiro (2 semanas) -``` -[ ] 18. Regras de boleto automático (via Asaas) -[ ] 19. Alertas de vencimento (via Manus/WhatsApp) -[ ] 20. Conciliação bancária semi-automática -[ ] 21. Previsão financeira com IA (Motor Python 8003 + Manus) -[ ] 22. Atualizar frontend /financeiro para usar /api/soe/financeiro/* -``` - -### Fase 5 — Manus + SOE (1 semana) -``` -[ ] 23. Registrar novas tools Manus apontando para SOE -[ ] 24. Manus usa SOE para responder perguntas de negócio -[ ] 25. Dashboard SOE: visão geral de todos os eventos -``` - -### Fase 6 — Central ERP (3 semanas) -``` -[ ] 26. Frappe Adapter completo (produtos, pedidos, estoque, compras) -[ ] 27. Regras de negócio ERP no SOE -[ ] 28. Sincronização bidirecional SOE ↔ ERPNext (via eventos) -[ ] 29. Atualizar /erp para usar /api/soe/erp/* -``` - ---- - -## 12. RESULTADO FINAL — O QUE O USUÁRIO EXPERIMENTA - -``` -Antes (fragmentado): - Usuário → /plus → vê Laravel diretamente - Usuário → /erp → vê ERPNext diretamente - Regras fiscais só no Plus - Contabilidade manual - Financeiro sem automação - -Depois (SOE Central): - Usuário → /fisco → emite NF-e, Plus executa invisível - Usuário → /contabil → vê DRE gerado automaticamente - Usuário → /financeiro → vê fluxo, previsões, alertas automáticos - Usuário → Manus → pergunta "qual meu resultado?" → resposta completa - - Plus e ERPNext: INVISÍVEIS, executando em background - Regras: CENTRALIZADAS no SOE, editáveis - Lançamentos: AUTOMÁTICOS baseados em eventos (NF-e, pagamentos, etc.) - Auditoria: TOTAL de todas as operações -``` - ---- - -## 13. PRINCÍPIO ORIENTADOR - -> **"O usuário não sabe o que está por trás. Ele só sabe que funciona."** -> -> O Arcádia Suite é o **Sistema Operacional** da empresa. -> O Plus e o ERPNext são **drivers de hardware** — poderosos, mas invisíveis. -> O SOE Central é o **kernel** que os orquestra com regras e inteligência. - ---- - -*PLANO_SOE_CENTRAL.md — Arcádia Suite v3.0* -*Gerado em: 2026-03-16* diff --git a/docs/PLANO_SOE_CENTRAL_v2-concluido-testar.md b/docs/PLANO_SOE_CENTRAL_v2-concluido-testar.md deleted file mode 100644 index f75aa8b..0000000 --- a/docs/PLANO_SOE_CENTRAL_v2-concluido-testar.md +++ /dev/null @@ -1,666 +0,0 @@ -# PLANO SOE CENTRAL v2 — Análise Real + Evolução -## Baseado no MAPA_SOE_ARCADIA.md (Replit) + Auditoria do Código -### Versão 2.0 — Março 2026 - ---- - -## 1. DIAGNÓSTICO — O QUE JÁ EXISTE (e o plano v1 não sabia) - -O MAPA_SOE_ARCADIA.md do Replit revelou que **o SOE já é uma realidade arquitetural robusta**, não apenas um conceito. Antes de planejar qualquer coisa, é crítico entender o que já funciona. - -### 1.1 O que já está construído e funcionando - -| Componente | Status | Localização | -|---|---|---| -| `SOE.tsx` | ✅ 2.414 linhas — UI completa com 9 tabs | `client/src/pages/SOE.tsx` | -| `SoeMotorContext.tsx` | ✅ Seletor de motor (plus/erpnext) | `client/src/contexts/` | -| `ErpApiClient` (interface) | ✅ Interface unificada definida | `server/erp/index.ts` | -| `ArcadiaPlusClient` | ✅ Adaptador HTTP → Plus:8080 | `server/erp/index.ts` | -| `ArcadiaNextClient` | ✅ Adaptador HTTP → ERPNext API | `server/erp/index.ts` | -| `registerSoeRoutes()` | ✅ 60+ endpoints em /api/soe/* | `server/erp/routes.ts` | -| `server/plus/proxy.ts` | ✅ Proxy reverso para Plus | `server/plus/` | -| `server/plus/sso.ts` | ✅ SSO automático Plus ↔ Suite | `server/plus/` | -| `server/plus/launcher.ts` | ✅ Lança PHP artisan serve | `server/plus/` | -| Módulo de Pessoas unificado | ✅ `persons` + `person_roles` | Schema PostgreSQL | -| Módulo de Produtos | ✅ Com NCM, CST, CFOP, IMEI | Schema PostgreSQL | -| Módulo Financeiro | ✅ Contas a P/R + transações | Schema PostgreSQL | -| Motor Fisco (:8002) | ✅ NF-e/NFC-e via nfelib | `server/python/` | -| Motor Contábil (:8003) | ✅ DRE, Balanço, SPED | `server/python/` | -| Sistema de módulos por tenant | ✅ `tenants.features` (JSONB) | Schema PostgreSQL | -| Middleware de gating | ✅ `requireModule()` | `server/` | - -### 1.2 Bancos de Dados por Motor (detalhe crítico) - -``` -Arcádia Suite → PostgreSQL 16 (dados do SOE, pessoas, produtos, vendas...) -Arcádia Plus → MySQL 8.0 (dados do Laravel — vendas, estoque, NF-e...) -ERPNext → MariaDB (dados do Frappe — CRM, HR, projetos...) -Motor Fisco → sem banco (só processa, retorna resultado) -Motor Contábil → sem banco (só processa, retorna resultado) -``` - -**Implicação:** Não há sincronização automática entre esses bancos. Um pedido criado no SOE (PostgreSQL) não aparece no Plus (MySQL) automaticamente — e vice-versa. - -### 1.3 O padrão motor/adaptador atual - -``` -Request do usuário - │ - ▼ -/api/soe/sales-orders (POST) - │ - ▼ -Verifica motor ativo (localStorage: arcadia_soe_motor) - │ - ├── motor = "local" → INSERT direto no PostgreSQL - ├── motor = "plus" → POST → Plus:8080 → MySQL - └── motor = "erpnext" → POST → ERPNext API → MariaDB -``` - ---- - -## 2. O PROBLEMA REAL — Onde o SOE atual para - -O SOE atual é um **roteador inteligente**: recebe o request, decide para qual motor enviar, e despacha. Ele **não tem inteligência própria**. - -### 2.1 O que falta (lacuna real) - -``` -Situação atual: - -SOE.tsx → /api/soe/* ────────────────────────────► Plus/ERPNext - (sem regras, sem processamento) - Regras ficam DENTRO do Plus - Regras ficam DENTRO do ERPNext - -Situação desejada: - -SOE.tsx → /api/soe/* → [RULE ENGINE SOE] ──────► Plus/ERPNext - │ (só executa) - ├── Regras Fiscais - ├── Regras Contábeis - ├── Regras Financeiras - └── Regras de Negócio -``` - -### 2.2 Problemas concretos hoje - -| Problema | Impacto | -|---|---| -| Fiscal rules dentro do Plus | Se trocar de motor (Plus→ERPNext), perde todas as regras | -| Nenhum lançamento contábil automático | DRE fica vazio, contabilidade manual | -| Motor Contábil (:8003) existe mas nada alimenta ele | 0 lançamentos automáticos | -| Plus tem UI própria (/plus) | Usuário pode bypassar o SOE e ir direto ao Plus | -| Sem event bus entre motores | Uma NF-e emitida no Plus não dispara nada no SOE | -| 25 conectores ERP definidos, zero chamadas reais | Integração existe no papel, não funciona | - -### 2.3 O que o usuário vê hoje vs o que deveria ver - -``` -Hoje: - /soe → UI do SOE (tabs: dashboard, pessoas, produtos, vendas...) - /plus → UI do Plus (Laravel) — direto, sem passar pelo SOE - /erp → UI do ERP legado - (usuário VÊ o Plus se quiser) - -Desejado: - /soe → UI do SOE (mesma, mas com inteligência) - /plus → BLOQUEADO ou redirecionado para /soe - /erp → BLOQUEADO ou redirecionado para /soe - (Plus e ERPNext = invisíveis, executando em background) -``` - ---- - -## 3. ARQUITETURA EVOLUÍDA — SOE com Rule Engine - -### 3.1 O que muda (e o que fica igual) - -**NÃO MUDA:** -- `SOE.tsx` — a UI continua a mesma (só ganha funcionalidades) -- `SoeMotorContext.tsx` — seleção de motor continua existindo -- `ArcadiaPlusClient` / `ArcadiaNextClient` — adaptadores continuam -- Todas as rotas `/api/soe/*` — continuam funcionando -- Todos os bancos — PostgreSQL, MySQL, MariaDB — continuam separados - -**MUDA / ADICIONA:** -- Uma **camada de Rule Engine** entre as rotas e os adaptadores -- **Event Bus SOE** que dispara lançamentos contábeis automaticamente -- **Ocultação do Plus** — `/plus` passa a ser controlado pelo SOE -- **Regras fiscais** saem do Plus e entram no SOE - -### 3.2 Diagrama completo com Rule Engine - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ ARCÁDIA SUITE — CAMADA DE APRESENTAÇÃO │ -│ │ -│ SOE.tsx (2.414+ linhas) │ -│ Tabs: Dashboard | Pessoas | Produtos | Vendas | Compras │ -│ Financeiro | CRM | Sincronização | Config │ -│ │ -│ SoeMotorContext.tsx → motor = "plus" | "erpnext" | "local" │ -└───────────────────────────────┬─────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ /api/soe/* — CAMADA DE API (já existe) │ -│ registerSoeRoutes() em server/erp/routes.ts │ -│ requireAuth + requireModule middleware │ -└───────────────────────────────┬─────────────────────────────────────┘ - │ - ▼ ◄── INSERIR AQUI (novo) -┌─────────────────────────────────────────────────────────────────────┐ -│ SOE RULE ENGINE (NOVO) │ -│ server/soe/rule-engine/ │ -│ │ -│ Antes de despachar para o motor, o Rule Engine: │ -│ │ -│ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 1. FISCAL RULES (server/soe/rule-engine/fiscal.ts) │ │ -│ │ • Resolve CFOP correto (intra/interestadual) │ │ -│ │ • Aplica tributação por regime (Simples/Presumido/Real) │ │ -│ │ • Valida NCM obrigatório │ │ -│ │ • Define CST/CSOSN automático │ │ -│ └─────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 2. BUSINESS RULES (server/soe/rule-engine/business.ts) │ │ -│ │ • Aprovação automática de pedidos < R$ X │ │ -│ │ • Reserva de estoque ao confirmar venda │ │ -│ │ • Trigger de NF-e ao faturar pedido │ │ -│ └─────────────────────────────────────────────────────────────┘ │ -│ │ -│ ┌─────────────────────────────────────────────────────────────┐ │ -│ │ 3. ACCOUNTING RULES (server/soe/rule-engine/accounting.ts) │ │ -│ │ • Emitiu NF-e → lançamento automático D: Clientes │ │ -│ │ C: Receita │ │ -│ │ • Pagou conta → lançamento automático D: Fornecedor │ │ -│ │ C: Banco │ │ -│ └─────────────────────────────────────────────────────────────┘ │ -└───────────────────────────────┬─────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ DESPACHADOR DE MOTOR (já existe, aprimorado) │ -│ createErpClient(connection) em server/erp/index.ts │ -│ │ -│ motor = "local" → INSERT PostgreSQL │ -│ motor = "plus" → ArcadiaPlusClient → Plus:8080 → MySQL │ -│ motor = "erpnext" → ArcadiaNextClient → ERPNext API → MariaDB │ -└───────────────────────────────┬─────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ SOE EVENT BUS (NOVO) │ -│ server/soe/event-bus.ts │ -│ │ -│ Depois que o motor executa, o Event Bus dispara: │ -│ │ -│ evento: "nfe_emitida" → Motor Contábil (lançamento auto) │ -│ evento: "venda_confirmada" → Reserva estoque + alerta WhatsApp │ -│ evento: "pagamento_feito" → Baixa C/P + lançamento contábil │ -│ evento: "recebimento" → Baixa C/R + lançamento contábil │ -└─────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 4. O QUE CONSTRUIR — Detalhamento por Módulo - -### 4.1 SOE Rule Engine (PRIORIDADE MÁXIMA) - -**Localização:** `server/soe/rule-engine/` - -Este é o coração da evolução. É um middleware que intercepta as chamadas às rotas SOE **antes** de despachar para o motor. - -#### Como funciona na prática - -```typescript -// server/erp/routes.ts — modificação cirúrgica - -// ANTES (atual): -app.post("/api/soe/sales-orders", requireAuth, async (req, res) => { - const client = getActiveClient(req) // pega Plus ou ERPNext - const result = await client.createSalesOrder(req.body) // despacha direto - res.json(result) -}) - -// DEPOIS (com Rule Engine): -app.post("/api/soe/sales-orders", requireAuth, async (req, res) => { - // 1. Aplica regras ANTES de despachar - const enriched = await ruleEngine.apply('pre_sales_order', req.body, req.user) - - // 2. Despacha para o motor com dados enriquecidos - const client = getActiveClient(req) - const result = await client.createSalesOrder(enriched.payload) - - // 3. Dispara eventos DEPOIS da execução - await eventBus.emit('sales_order_created', { result, rules: enriched.appliedRules }) - - res.json(result) -}) -``` - -#### Estrutura do Rule Engine - -```typescript -// server/soe/rule-engine/index.ts - -interface SoeRule { - id: string - dominio: 'fiscal' | 'business' | 'accounting' | 'financial' - trigger: string // ex: 'pre_sales_order', 'post_nfe_emitida' - condicao: RuleCondition // quando esta regra se aplica - acao: RuleAction // o que ela faz ao payload - prioridade: number - ativo: boolean - empresaId?: number // null = regra global de todos os tenants -} - -class SoeRuleEngine { - async apply(trigger: string, payload: any, context: RuleContext): Promise { - // 1. Busca regras ativas para este trigger (do banco + defaults hardcoded) - const rules = await this.getActiveRules(trigger, context.tenantId) - - // 2. Filtra regras cuja condição se aplica ao payload - const applicable = rules.filter(r => this.avaliarCondicao(r.condicao, payload, context)) - - // 3. Aplica cada regra em ordem de prioridade - let enriched = { ...payload } - const applied: string[] = [] - for (const rule of applicable.sort((a, b) => a.prioridade - b.prioridade)) { - enriched = await this.aplicarAcao(rule.acao, enriched, context) - applied.push(rule.id) - } - - return { payload: enriched, appliedRules: applied } - } -} -``` - -### 4.2 Regras Fiscais no SOE - -Estas regras **hoje vivem dentro do Plus** (Laravel controllers). A ideia é trazê-las para o SOE. - -**Nota importante:** Não é mover o código PHP para TypeScript. É criar regras **declarativas** no SOE que enriquecem o payload **antes** de enviar ao Plus. O Plus ainda processa e emite — mas recebe o payload já correto. - -```typescript -// server/soe/rule-engine/fiscal-rules.ts - -export const FISCAL_RULES_PADRAO: SoeRule[] = [ - - // CFOP — resolve automaticamente por operação - { - id: 'CFOP_VENDA_DENTRO_ESTADO', - dominio: 'fiscal', - trigger: 'pre_sales_order', - condicao: { uf_emitente: '==', uf_destinatario: true, tipo_op: 'venda_produto' }, - acao: { set: { 'items[*].cfop': '5.102' } }, - prioridade: 10, ativo: true - }, - { - id: 'CFOP_VENDA_OUTRO_ESTADO', - dominio: 'fiscal', - trigger: 'pre_sales_order', - condicao: { uf_emitente: '!=', uf_destinatario: true, tipo_op: 'venda_produto' }, - acao: { set: { 'items[*].cfop': '6.102' } }, - prioridade: 10, ativo: true - }, - - // Tributação por Regime - { - id: 'CST_SIMPLES_NACIONAL', - dominio: 'fiscal', - trigger: 'pre_nfe_emissao', - condicao: { regime_tributario: 'simples_nacional' }, - acao: { - set: { 'items[*].cst_icms': '400', 'items[*].pis': null, 'items[*].cofins': null }, - // No Simples Nacional: CSOSN 400 = tributado, sem destaque PIS/COFINS - }, - prioridade: 5, ativo: true - }, - { - id: 'CST_LUCRO_PRESUMIDO', - dominio: 'fiscal', - trigger: 'pre_nfe_emissao', - condicao: { regime_tributario: 'lucro_presumido' }, - acao: { set: { 'items[*].cst_pis': '01', 'items[*].cst_cofins': '01' } }, - prioridade: 5, ativo: true - }, - - // Validações obrigatórias - { - id: 'VALIDAR_NCM_NFE', - dominio: 'fiscal', - trigger: 'pre_nfe_emissao', - condicao: { tipo_documento: ['nfe', 'nfce'] }, - acao: { validar: { campo: 'items[*].ncm', obrigatorio: true, formato: /^\d{8}$/ } }, - prioridade: 1, ativo: true - }, -] -``` - -### 4.3 SOE Event Bus — Lançamentos Contábeis Automáticos - -Este é o **maior salto de valor**. Hoje o Motor Contábil (:8003) existe mas nada o alimenta automaticamente. - -```typescript -// server/soe/event-bus.ts - -type SoeEvent = - | 'nfe_emitida' - | 'nfe_cancelada' - | 'venda_confirmada' - | 'compra_recebida' - | 'pagamento_realizado' - | 'recebimento_realizado' - | 'boleto_gerado' - -interface SoeEventPayload { - empresaId: number - tenantId: number - evento: SoeEvent - dados: Record - motorOrigem: 'plus' | 'erpnext' | 'local' -} - -class SoeEventBus { - async emit(evento: SoeEvent, payload: SoeEventPayload) { - // Registra no banco (audit trail) - await db.insert(soeEventos).values({ ...payload, createdAt: new Date() }) - - // Dispara handlers - await Promise.allSettled( - this.getHandlers(evento).map(h => h(payload)) - ) - } - - // Handlers por evento - private handlers: Record = { - 'nfe_emitida': [ - contabilHandler.lancamentoVenda, // D: Clientes / C: Receita Bruta - contabilHandler.lancamentoImpostos, // D: Impostos / C: ICMS/PIS/COFINS a Recolher - financialHandler.gerarRecebivel, // Cria C/R automaticamente - ], - 'pagamento_realizado': [ - contabilHandler.lancamentoPagamento, // D: Fornecedores / C: Banco - financialHandler.baixarContaPagar, // Baixa C/P - ], - 'recebimento_realizado': [ - contabilHandler.lancamentoRecebimento, // D: Banco / C: Clientes - financialHandler.baixarContaReceber, // Baixa C/R - ], - 'compra_recebida': [ - contabilHandler.lancamentoCompra, // D: Estoque / C: Fornecedores - ], - } -} -``` - -#### Lançamentos automáticos para cada evento - -``` -NF-e emitida (venda): - D: 1.1.3.01 — Clientes (valor total da nota) - C: 3.1.1.01 — Receita Bruta de Vendas - - D: 3.1.2.01 — Deduções (ICMS) - C: 2.1.2.01 — ICMS a Recolher - - D: 3.1.2.02 — Deduções (PIS) - C: 2.1.2.02 — PIS a Recolher - - D: 3.1.2.03 — Deduções (COFINS) - C: 2.1.2.03 — COFINS a Recolher - -Pagamento de fornecedor: - D: 2.1.1.{categoria} — Fornecedores - C: 1.1.1.01 — Banco (conta configurada) - -Recebimento de cliente: - D: 1.1.1.01 — Banco - C: 1.1.3.01 — Clientes - -Compra recebida (NF-e entrada): - D: 1.1.4.01 — Estoque / Mercadorias - C: 2.1.1.01 — Fornecedores -``` - -### 4.4 Ocultação do Plus e ERPNext - -O Plus tem página própria em `/plus` (client/src/pages/Plus.tsx). O usuário pode acessá-la diretamente. Precisamos de 3 mudanças: - -#### a) Redirecionar `/plus` para `/soe` - -```typescript -// client/src/App.tsx — modificação simples -// Trocar: -// Por: } /> -``` - -**Mas manter o proxy reverso Plus ativo** — o Plus continua funcionando em background, só não fica visível como página separada. - -#### b) Ocultar o seletor de motor do usuário final - -```typescript -// client/src/contexts/SoeMotorContext.tsx -// O seletor fica SOMENTE na tab Config do SOE, e somente para admins - -// A tab Config na SOE.tsx — adicionar role check: -{user?.role === 'admin' && Config} -``` - -#### c) Na tab Config (admin), o label muda - -``` -Antes: "Selecione o motor: Plus | ERPNext" -Depois: "Motor de execução: Plus | ERPNext | Local" -(invisível para usuário final, só admin de tenant vê) -``` - ---- - -## 5. TABELAS A CRIAR (complemento ao schema existente) - -As tabelas canônicas do SOE já existem. Precisamos adicionar apenas as tabelas do Rule Engine. - -```typescript -// shared/schema.ts — adicionar ao final - -// Regras do SOE — configuráveis por tenant -export const soeRegras = pgTable('soe_regras', { - id: uuid('id').primaryKey().defaultRandom(), - tenantId: integer('tenant_id'), // null = regra global (todas as empresas) - empresaId: integer('empresa_id'), // null = todas as empresas do tenant - dominio: varchar('dominio', { length: 50 }).notNull(), - trigger: varchar('trigger', { length: 100 }).notNull(), - nome: varchar('nome', { length: 200 }).notNull(), - condicao: jsonb('condicao').notNull(), - acao: jsonb('acao').notNull(), - prioridade: integer('prioridade').default(10), - ativo: boolean('ativo').default(true), - origemPadrao: boolean('origem_padrao').default(false), // true = regra default do sistema - createdAt: timestamp('created_at').defaultNow(), - updatedAt: timestamp('updated_at').defaultNow(), -}) - -// Log de todos os eventos SOE (audit trail completo) -export const soeEventos = pgTable('soe_eventos', { - id: uuid('id').primaryKey().defaultRandom(), - tenantId: integer('tenant_id').notNull(), - empresaId: integer('empresa_id'), - evento: varchar('evento', { length: 100 }).notNull(), - motorOrigem: varchar('motor_origem', { length: 50 }), // 'plus', 'erpnext', 'local' - regraIds: jsonb('regra_ids'), // regras aplicadas - payloadEntrada: jsonb('payload_entrada'), - payloadSaida: jsonb('payload_saida'), - status: varchar('status', { length: 50 }).notNull(), - duracaoMs: integer('duracao_ms'), - erro: text('erro'), - createdAt: timestamp('created_at').defaultNow(), -}) - -// Lançamentos contábeis automáticos do SOE -export const soeLancamentos = pgTable('soe_lancamentos', { - id: uuid('id').primaryKey().defaultRandom(), - tenantId: integer('tenant_id').notNull(), - empresaId: integer('empresa_id').notNull(), - data: date('data').notNull(), - contaDebito: varchar('conta_debito', { length: 30 }).notNull(), - contaCredito: varchar('conta_credito', { length: 30 }).notNull(), - valor: numeric('valor', { precision: 15, scale: 2 }).notNull(), - historico: text('historico').notNull(), - origemEvento: varchar('origem_evento', { length: 100 }), // 'nfe_emitida', etc. - origemEventoId: uuid('origem_evento_id'), // FK para soe_eventos - periodo: varchar('periodo', { length: 7 }), // '2026-03' - enviado8003: boolean('enviado_8003').default(false), // sincronizado com Motor Contábil - createdAt: timestamp('created_at').defaultNow(), -}) -``` - ---- - -## 6. ESTRUTURA DE PASTAS (Novo código a criar) - -``` -server/ -└── soe/ ← NOVA PASTA - ├── rule-engine/ - │ ├── index.ts ← SoeRuleEngine class - │ ├── fiscal-rules.ts ← Regras fiscais padrão - │ ├── business-rules.ts ← Regras de negócio - │ └── accounting-rules.ts ← Regras de lançamento contábil - │ - ├── event-bus.ts ← SoeEventBus class - │ - ├── handlers/ - │ ├── contabil-handler.ts ← Lançamentos automáticos - │ └── financial-handler.ts ← Automação financeira - │ - └── fiscal/ - └── cfop-resolver.ts ← Resolução de CFOP (lógica complexa) -``` - -**Modificações em arquivos existentes:** -``` -server/erp/routes.ts ← Inserir ruleEngine.apply() antes do dispatch -client/src/App.tsx ← Redirecionar /plus para /soe -client/src/pages/SOE.tsx ← Ocultar Config tab para não-admins -``` - ---- - -## 7. ROADMAP — Fases de Implementação - -### Fase 1 — Rule Engine Básico ✅ CONCLUÍDA (2026-03-19) — João -``` -[x] Criar server/soe/rule-engine/index.ts (SoeRuleEngine) — já existia | João | 2026-03-19 -[x] Criar tabelas soe_regras e soe_eventos (drizzle push) — já existiam no schema | João | 2026-03-19 -[x] Inserir ruleEngine.apply() em 3 rotas críticas: - - POST /api/soe/sales-orders ✅ plugado | João | 2026-03-19 - - POST /api/soe/sales-orders/:id/generate-nfe ✅ plugado | João | 2026-03-19 - - POST /api/soe/purchase-orders ✅ plugado | João | 2026-03-19 -[x] Seed das regras fiscais padrão (CFOP, CST, validações NCM) — fiscal-rules.ts hardcoded | João | 2026-03-19 -[ ] Testar: criar pedido → verificar que payload está sendo enriquecido -``` - -### Fase 2 — Event Bus + Contabilidade Automática ✅ CONCLUÍDA (2026-03-19) — João -``` -[x] Criar server/soe/event-bus.ts — já existia | João | 2026-03-19 -[x] Criar tabela soe_lancamentos (drizzle push) — já existia no schema | João | 2026-03-19 -[x] Criar handlers: contabil-handler.ts + financial-handler.ts — já existiam | João | 2026-03-19 -[x] Conectar: POST generate-nfe → emit('nfe_emitida') → lançamentos ✅ plugado | João | 2026-03-19 -[ ] Conectar: pagamento/recebimento → emit() → lançamentos -[ ] Criar endpoint: GET /api/soe/contabil/lancamentos?periodo=YYYY-MM -[ ] DRE: agora tem dados reais (via soe_lancamentos → Motor :8003) -``` - -### Fase 3 — Ocultar Plus/ERPNext ✅ CONCLUÍDA (2026-03-19) — João -``` -[x] client/src/App.tsx: /plus → redirect para /soe ✅ | João | 2026-03-19 -[x] client/src/pages/SOE.tsx: Config tab só para admins ✅ | João | 2026-03-19 -[x] Manter proxy Plus funcionando (invisível) — proxy já existia, não alterado | João | 2026-03-19 -[ ] Testar: fluxo completo sem nenhum acesso direto ao Plus UI -``` - -### Fase 4 — Regras Configuráveis pelo Usuário (1 semana) -``` -[ ] UI na tab Config do SOE: "Regras de Negócio" -[ ] CRUD de regras via /api/soe/rules -[ ] Admin pode criar regras custom sem código -[ ] Exemplo: "Pedidos acima de R$10.000 requerem aprovação manual" -``` - -### Fase 5 — Financeiro Avançado (2 semanas) -``` -[ ] Auto-boleto ao confirmar venda (Asaas API) -[ ] Alertas de vencimento (Manus → WhatsApp) -[ ] Conciliação bancária OFX semi-automática -[ ] Previsão financeira (Motor BI :8004 + histórico soe_lancamentos) -``` - -### Fase 6 — Contábil Avançado (2 semanas) -``` -[ ] DRE automático mensal (100% alimentado pelo Event Bus) -[ ] Balanço Patrimonial automático -[ ] Fechamento contábil mensal -[ ] SPED ECD/ECF alimentado por soe_lancamentos -[ ] Exportação para escritório contábil (OFX, Excel, PDF) -``` - ---- - -## 8. COMPARAÇÃO: PLANO v1 vs PLANO v2 - -| Aspecto | Plano v1 (antes do Replit .md) | Plano v2 (com conhecimento real) | -|---|---|---| -| Adaptadores Plus/ERPNext | "Precisam ser criados" | Já existem — não tocar | -| SOE Routes | "Precisam ser criadas" | 60+ endpoints já existem | -| SOE.tsx | "Precisa ser construída" | 2.414 linhas — já funciona | -| Onde adicionar código | server/soe/ do zero | Middleware nas rotas existentes | -| Esforço estimado | Alto (refatoração total) | Médio (adição cirúrgica) | -| Risco de quebrar | Alto | Baixo (adição, não substituição) | -| Banco Plus | Ignorado | MySQL — separado, nunca tocar direto | - ---- - -## 9. PRINCÍPIO ORIENTADOR (REVISADO) - -> O SOE já é o roteador certo. Agora vamos torná-lo o **árbitro de regras**. -> -> O padrão motor/adaptador está perfeito. O que falta é a **inteligência entre a rota e o adaptador**. -> -> Plus e ERPNext continuam existindo e funcionando — só que o usuário final não sabe. -> Ele só vê a Central SOE. O restante é infraestrutura. - ---- - -## 10. RESUMO EXECUTIVO — O que fazer agora - -**1 ação que entrega valor imediato:** -``` -Criar o SoeRuleEngine e plugar nas rotas de venda/NF-e. -Resultado: Ao emitir uma NF-e, o CFOP correto é calculado -automaticamente pelo SOE — sem o usuário saber que o Plus está -sendo chamado por baixo. -``` - -**1 ação que entrega valor a médio prazo:** -``` -Criar o Event Bus com o handler de contabilidade. -Resultado: Cada NF-e emitida gera lançamentos contábeis -automaticamente. O DRE do mês é gerado sem entrada manual de dados. -``` - -**1 ação que fecha o conceito:** -``` -Redirecionar /plus → /soe. -Resultado: O usuário não tem mais acesso ao Plus diretamente. -Ele só vê o Arcádia. O Plus é infraestrutura invisível. -``` - ---- - -*PLANO_SOE_CENTRAL_v2.md — Arcádia Suite v3.0* -*Gerado em: 2026-03-16 — Baseado na análise real do MAPA_SOE_ARCADIA.md (Replit)*