Simjob Platform
Plataforma industrial unificada — MES, WMS, APS, Customs com IA, Visão Computacional e o produto AURA MESH para analytics e IA generativa, instalada dentro da fábrica.
O que é o Simjob Platform?
O Simjob Platform é um sistema operacional industrial de ponta a ponta desenhado para conectar equipamentos físicos (máquinas, PLCs, CLPs, sensores IoT) a sistemas de gestão, painéis de análise e agentes de inteligência artificial — tudo em tempo real.
A plataforma opera com filosofia Edge-first: toda a coleta, processamento e persistência de dados acontece localmente na planta industrial, garantindo operação autônoma mesmo sem conectividade com a nuvem. A sincronização com destinos de nuvem (Simjob Cloud, Google BigTable, Alibaba TableStore) ocorre de forma assíncrona, com fila de até 100.000 eventos e retry automático.
Princípios de Design
| Princípio | Implementação |
|---|---|
| Edge-first | Processamento local, operação offline garantida, sync assíncrono |
| Cloud-ready | Sync nativo para Simjob Cloud, Google BigTable, Alibaba TableStore |
| AI-native | IA integrada nos módulos do MES, WMS, APS, ASAP, Customs e no AURA MESH |
| Multi-tenant | Isolamento por tenant ID em todas as entidades e APIs |
| Protocolo aberto | REST, WebSocket, gRPC, MQTT, MCP (Model Context Protocol) |
| Plugin system | Edge carrega módulos MES/WMS/APS como plugins Go em tempo de execução |
Arquitetura da Plataforma
A plataforma é composta por múltiplos serviços independentes que se comunicam via REST, WebSocket, gRPC, MQTT e Redis Pub/Sub.
Fluxo de Dados
Coleta e Ingestão IoT
Consumo em Tempo Real
Pipeline de IA
Inspeção Visual
Edge Monitor — Painel de Saúde da Plataforma
Tela inicial ao acessar o servidor Simjob da fábrica. Reúne em um único painel a saúde de todos os módulos, o consumo de recursos, a disponibilidade dos serviços e o status da integração com os equipamentos. Foi pensada para que o time de TI / manutenção da planta tenha resposta rápida a qualquer parada ou degradação — sem precisar abrir terminais ou ferramentas externas.
O que aparece na tela
Status agregado
Indicador único de saúde geral, com semáforo verde/amarelo/vermelho, tempo on-line desde a última partida e versão atual instalada.
Uso de recursos
Gráficos de retenção de dados, ocupação de armazenamento, memória cache e percentual livre — atualizados em tempo real.
Serviços disponíveis
Atalhos para MES Manager, WMS Manager, APS Manager, Customs Admin e demais painéis, com indicador de online/offline por serviço.
Integração com equipamentos
Quantidade de máquinas conectadas, eventos por minuto, fila pendente e taxa de sincronização com a nuvem (quando aplicável).
Alertas ativos
Lista de avisos abertos no momento — falhas de coleta, certificados expirando, retenção próxima do limite, problemas de integração.
Configuração rápida
Ajuste de retenção de dados, limite de armazenamento e identificação do tenant ativo, sem necessidade de SSH ou edição de arquivos.
Tela de exemplo
Configuração disponível
- Ajuste de período de retenção dos dados operacionais.
- Definição do limite máximo de armazenamento, com alerta antecipado.
- Ativação ou pausa de sincronização com nuvem / AURA MESH.
- Identificação visual do tenant ativo (ambiente).
- Acesso direto às demais telas da plataforma — sem novo login.
Terminal de Chão de Fábrica
Nova tela voltada ao operador, projetada para rodar em terminal industrial fixo na máquina (touchscreen, monitor industrial ou tablet). Substitui apontamentos em papel ou em planilhas — o operador escolhe a máquina e seu nome uma única vez, e a tela passa a refletir, em tempo real, o estado da ordem em execução e os eventos do equipamento.
O que o operador faz na tela
Iniciar e concluir ordens
Lista de ordens disponíveis para a máquina; o operador inicia, pausa, retoma e conclui em poucos toques.
Registrar paradas
Botão grande para classificar a parada (preventiva, corretiva, troca de ferramenta, falta de material) com motivos pré-cadastrados.
Apontar refugo
Registro de quantidade rejeitada e motivo (qualidade, dimensão, defeito visual) — alimenta indicadores de qualidade do OEE.
Setup e troca
Marcação clara dos tempos de setup separados do tempo produtivo, base para análise de eficiência e melhoria contínua.
Detalhes do produto
Painel com especificações, instruções de trabalho e capacidades exigidas — sempre disponível ao operador no momento certo.
Indicadores em tempo real
Anel de progresso, ritmo de produção contra meta, peças produzidas vs planejadas e visualização do turno em andamento.
Ergonomia industrial
- Sessão persistente — após escolher máquina e operador, um F5 acidental no chão de fábrica não derruba a tela.
- Modo tela cheia para uso em monitor industrial sem distração.
- Login simplificado por crachá / código curto, sem necessidade de teclado completo.
- Trocar máquina ou operador é um botão único — útil em turnos compartilhados.
- Continua funcionando se a conexão oscilar — eventos são sincronizados quando a rede volta.
Configuração de Customs — Tela e IA
Tela de administração onde o cliente registra, ativa, desativa e revisa os customs — telas, relatórios e jobs sob medida que rodam dentro do MES, do WMS ou do painel de fábrica (DS). Inclui um recurso de IA assistente que transforma um briefing (PDF, e-mail, descrição em texto) em um rascunho funcional pronto para revisão e publicação.
Como o cliente configura — passo a passo
- Listar customs existentes — visão geral por host (MES, WMS, painel), com status (rascunho, publicado, desativado) e filtros.
- Criar novo custom — informa título, host de montagem, slug e perfis de acesso autorizados.
- Gerar rascunho com IA (opcional) — anexa o material do cliente (PDF da especificação, modelo de relatório, e-mail descritivo) e o assistente devolve um rascunho com manifesto, código e README.
- Iterar sobre o resultado — comandos em linguagem natural ("adicione tooltip nos códigos", "trave a ordenação por nome") refinam o rascunho.
- Pré-visualizar — abre a tela diretamente no host destino antes de publicar; nada vai para o usuário final ainda.
- Habilitar / desabilitar — alterna o custom entre publicado e oculto sem reinício de serviço.
- Permissões por perfil — cada custom pode ser restrito a perfis específicos do tenant.
Por que isso é diferente
IA encurta o caminho
Materiais de cliente — geralmente em PDF, e-mail ou planilha — viram um primeiro rascunho funcional em minutos. A revisão humana foca no que importa, não na digitação.
Segurança por perfil
Cada custom carrega seus perfis exigidos. O servidor verifica o usuário antes de entregar a tela — sem perfil, o custom simplesmente não aparece.
Isolamento por cliente
Customs de um cliente nunca aparecem para outro. Um mesmo servidor pode hospedar vários ambientes simultaneamente sem mistura.
Jobs agendados
Customs do tipo relatório podem ser agendados para rodar em horários definidos e enviar o resultado por e-mail automaticamente — sem operação manual.
Soberania da geração por IA
O cliente decide o modo de operação da IA assistente:
- Cloud — usa modelos hospedados por provedores de IA, ideal para velocidade e qualidade máxima.
- Híbrido — pode optar entre cloud ou on-premises caso a caso.
- On-premises — restringe a geração a um modelo local rodando dentro da própria infra do cliente; nada sai da rede da fábrica.
A escolha não muda nada para quem usa a tela — apenas para quem instala e opera. A configuração é feita pelo time de implantação Simjob junto com o cliente.
Edge Server — Núcleo Industrial
É o servidor central da plataforma instalado dentro da fábrica. Concentra a coleta de dados de máquinas, sensores e CLPs, executa a lógica do MES, WMS, APS e Customs, e expõe as telas para operação. Foi projetado para continuar funcionando mesmo se a internet cair — eventos ficam em fila local e sincronizam automaticamente quando a conexão volta.
O que ele faz
Coleta de equipamentos
Conecta-se a máquinas, sensores e CLPs por múltiplos protocolos industriais; recebe o dado bruto e o transforma em informação utilizável.
Cálculo de OEE em tempo real
Disponibilidade, performance e qualidade são consolidados continuamente, sem necessidade de batch ou intervenção manual.
Regras de negócio
Roda as regras de MES, WMS e APS em um único processo, garantindo consistência e baixíssima latência.
Sincronização com nuvem
Envia eventos para destinos de nuvem ou para o AURA MESH de forma assíncrona e resiliente, com fila local que segura picos e quedas de rede.
Segurança e auditoria
Autenticação por usuário/perfil, isolamento por tenant e log de operações sensíveis para conformidade.
Customs nativo
Aceita extensões do cliente (telas, jobs e relatórios) sem alterar o produto e sem reinício.
Protocolos e integrações suportados
MQTT, REST, WebSocket, gRPC e integração com sistemas externos (ERP, SAP, TOTVS, sistemas legados) por API de integração simplificada. Detalhes técnicos para integradores estão na seção API de Integração.
MES Manager — Execução da Manufatura
Interface web para a área de produção. Concentra ordens, apontamentos, paradas, qualidade, configuração de OEE e relatórios — alimentando indicadores em tempo real para gestores e operadores.
Funcionalidades principais
| Área | O que oferece |
|---|---|
| Painel de OEE | Disponibilidade, performance, qualidade e OEE consolidado, atualizados continuamente. |
| Ordens de produção | Cadastro, programação, sequenciamento e acompanhamento por status, com priorização e visão por máquina. |
| Terminal (Dispatch) | Tela do operador para iniciar, pausar, concluir ordens e registrar paradas/refugo direto da máquina. |
| Configuração de OEE | Mapeamento dos motivos de parada nas categorias de perda — base do cálculo de OEE confiável. |
| Ocorrências | Tipos de evento, motivos de parada e refugo administrados pelo cliente, com função vinculada à operação. |
| Turnos e calendários | Jornadas, feriados e calendários produtivos por máquina ou centro de trabalho. |
| Hierarquia ISA-95 | Empresa → Site → Área → Centro de Trabalho → Máquina, com filtros consistentes em toda a aplicação. |
| Especificações e instruções | Roteiros, capacidades exigidas e instruções de trabalho disponíveis ao operador no momento certo. |
| Rastreabilidade | Histórico de lote, operador, máquina e turno por ordem. |
| Relatórios nativos R1–R4 | Produção, OEE, material e estoque — pré-prontos, parametrizáveis, com exportação para PDF e planilha. |
| Customs do cliente | Telas e relatórios sob medida convivem no mesmo menu, isolados por perfil. |
WMS Manager — Gestão de Armazém
Gestão completa do armazém — recebimento, armazenagem, picking, expedição, inventário e transformações. Adapta-se ao segmento da operação (hospitalar, fábricas, armazéns 3PL, distribuidor farmacêutico, food & beverage, e-commerce) ativando funcionalidades específicas conforme o site cadastrado.
Funcionalidades universais
| Área | O que oferece |
|---|---|
| Endereçamento | Zonas dedicadas (recebimento, armazenagem, picking, expedição, qualidade, quarentena, devoluções, frio) com hierarquia de corredor, estante, nível e posição. |
| Recebimento | Contra pedido de compra, com nota fiscal, lote, validade, embalagem (LPN) e custo unitário. |
| Picking | Estratégias FIFO, FEFO e LIFO com priorização e otimização de rota dentro do armazém. |
| Expedição | Acompanhamento do pedido em fila, alocação, separação, conferência e despacho. |
| Inventário cíclico | Multi-contagem com tolerâncias, equipes e aprovação com ajuste automático. |
| Rastreabilidade | Por lote, número de série e embalagem, com trilha de auditoria preparada para órgãos reguladores. |
| Transformações | Kits, fracionamento, reembalagem e composição multinível com apuração de custos. |
| Reposição | Automática por demanda, por estoque mínimo ou manual. |
| Voice Picking | Operador conduzido por comandos de voz em português, mãos livres. |
| Indicadores | Giro de estoque, DIO, acuracidade, fill rate e produtividade de picking. |
WMS — Segmentação por Indústria
O segmento de cada operação é definido no cadastro do Site (hierarquia ISA-95). Ao alternar de site, o sistema mostra automaticamente as funcionalidades aplicáveis àquela realidade — sem reinstalação, sem build separado, sem licenças adicionais.
Hospitalar
Dispensação por paciente/leito, medicamentos controlados, OPME e consignação, farmácias satélite, estoques de emergência, antimicrobianos e cadeia de frio.
Fábricas
Consumo por ordem de produção, kanban de linha, controle de material em processo, ferramental e moldes, lista de materiais multinível, rastreabilidade reversa.
Armazéns / 3PL
Multi-cliente, agendamento de docas, gestão de pátio, transportadoras, ondas de separação e SLA por cliente.
Distribuidor Farmacêutico
Rastreabilidade ANVISA, controle de licenças, mapa de distribuição por lote e conformidade com normas de boas práticas.
Food & Beverage
Multi-zona de temperatura, gestão de alérgenos, quarentena microbiológica, shelf life dinâmico e registro fiscal sanitário.
E-commerce
Múltiplas transportadoras, integração com marketplaces, devoluções, separação otimizada, divisão de pedido e backorder.
WMS Hospitalar — Detalhamento
Conjunto de funcionalidades específicas para a operação hospitalar e farmacêutica, ativadas automaticamente quando o site é classificado como hospitalar.
Módulos hospitalares
| Módulo | O que oferece |
|---|---|
| Dispensação por paciente | Vinculada à prescrição médica. Fluxo de validação farmacêutica → separação por validade (FEFO) → entrega → administração, com baixa real do estoque. |
| Medicamentos controlados | Classificação por lista (A1 a C5), escrituração com dupla conferência e contagem obrigatória de troca de turno com testemunha. |
| OPME e consignação | Estoque do fornecedor mantido no hospital, com aprovação técnica/clínica antes do uso e cobrança automática quando consumido. |
| Farmácias satélite | Sub-estoques em UTI, centro cirúrgico e pronto-socorro com níveis-alvo por produto e reposição automática. |
| Estoques de emergência | Carros de parada e kits de código azul com lacre, verificação periódica e reposição automática ao romper. |
| Antimicrobianos | Autorização por infectologista com prazo de validade e alerta para renovação. |
O que o gestor vê
- Dashboard com dispensações por status, farmácias satélite com nível baixo e excursões de temperatura ativas.
- Escrituração de controlados pronta para auditoria.
- Relatórios de itens vencendo, com destaque para controlados.
- Resumo de dispensação por unidade assistencial.
- Alertas automáticos: nível baixo, vencimento próximo, autorizações expirando, lacres rompidos sem reposição.
Monitoramento de Temperatura — Cadeia de Frio
Funcionalidade compartilhada — disponível para hospitalar, food & beverage, distribuidor farmacêutico e fábricas. Os sensores enviam leituras de temperatura e umidade continuamente, o sistema compara com a faixa permitida da zona e cria automaticamente uma excursão sempre que algum valor sai do limite.
O que o cliente recebe
- Painel com todas as zonas refrigeradas, leitura atual e status (dentro da faixa, próximo do limite, em excursão).
- Histórico completo de leituras por zona, com gráficos de tendência.
- Lista de excursões ativas — quando começou, duração, valor de pico — com botão para registrar a ação tomada.
- Resumo executivo: zonas com mais incidência, tempo total fora da faixa e zonas críticas.
- Integração com fluxos de qualidade: produtos da zona em excursão podem ser automaticamente movidos para quarentena.
Tipos de zona suportados
| Tipo | Faixa | Uso |
|---|---|---|
| AMBIENT | 15°C a 30°C | Medicamentos gerais, insumos |
| REFRIGERATED | 2°C a 8°C | Vacinas, insulinas, hemoderivados |
| FROZEN | -25°C a -15°C | Reagentes, alimentos congelados |
| ULTRA_FROZEN | -90°C a -60°C | Vacinas mRNA, amostras biológicas |
Lógica de Excursão
- Temperatura fora da faixa → cria excursão com severidade WARNING
- Desvio > 5°C → severidade CRITICAL
- Duração > 30 minutos → escalação automática para CRITICAL
- Temperatura volta à faixa → excursão auto-resolvida
- Eventos publicados no EventBus → WebSocket → frontend em tempo real
APS Manager — Planejamento e Sequenciamento
Módulo de planejamento avançado para indústrias, armazéns e operações hospitalares. Gera planos considerando capacidade finita, prazos, prioridades e restrições reais do chão de fábrica. A escolha do motor de otimização é feita conforme a natureza do problema:
Determinístico
Para regras claras e cenários bem definidos. Gera planos consistentes e reproduzíveis com alta precisão.
Heurístico
Para problemas grandes e combinatórios; entrega bons planos rapidamente, mesmo com muitas restrições simultâneas.
Assistido por IA
Para regras descritas em texto livre — útil quando a lógica de planejamento ainda está sendo formalizada.
Capacidades para o cliente
- Sequenciamento de ordens respeitando turnos, capacidades e setups.
- Acompanhamento da aderência ao plano em tempo real.
- Comparativo entre cenários antes de publicar o plano.
- Indicadores de qualidade do plano (estabilidade, makespan, índice de mudanças).
SimJob Lens — Motor de KPIs e Indicadores
Motor de análises da plataforma que transforma os dados operacionais (apontamentos, paradas, sensores e ordens) em indicadores padronizados de OEE, qualidade, manutenção, planejamento, estoque, segurança e ESG. Os indicadores são calculados automaticamente e ficam disponíveis no MES, no AURA MESH e em painéis para gestores.
Pacotes de indicadores disponíveis
| Pacote | Foco | O que entrega |
|---|---|---|
| OEE Essencial | Produção | OEE, disponibilidade, performance, qualidade, TEEP, NEE, FTT e produtividade. |
| Qualidade 360 | Produção | Refugo, retrabalho, RTY, DPMO, nível Sigma e custo da não-qualidade. |
| SPC Essencial / Avançado | Qualidade | Cp, Cpk, Pp, Ppk, EWMA, CUSUM e regras de Nelson para controle estatístico. |
| Manutenção | Confiabilidade | MTBF, MTTR, MTTA, MTTF e taxa de falhas por equipamento. |
| Lean / Fluxo | Eficiência | Takt time, tempo de ciclo, throughput, material em processo, tempo de troca. |
| Energia & ESG | Sustentabilidade | Energia por unidade, CO₂ por unidade, água, intensidade de resíduos. |
| Mão de obra | Pessoas | Eficiência, utilização e absenteísmo da equipe operacional. |
| Segurança / EHS | Pessoas | TRIR, LTIR, DART, quase-acidentes e índice 5S. |
| Execução de plano | Planejamento | Aderência ao plano, on-time delivery, on-time start. |
| Qualidade do plano | Planejamento | Estabilidade do plano, makespan, índice de mudanças, gap do solver. |
| Estoque | WMS | Giro, acuracidade, ruptura. |
| Atendimento | WMS | Pedido perfeito, on-time, fill rate. |
| Picking | WMS | Acuracidade e produtividade de separação e armazenagem. |
| Financeiro de operação | Cross | Custo por unidade, custo de parada, valor de throughput. |
| ESG multi | Cross | Pontuação ESG, energia equivalente, % de insumo reciclado. |
| MSA | Qualidade | Gage R&R e número de categorias distintas. |
Como o cliente ativa
- Escolhe pacotes de indicadores conforme a estratégia da operação — não precisa contratar todos.
- Indica como cada equipamento/sinal alimenta os indicadores (configuração feita junto com o time Simjob).
- A partir da ativação, os indicadores aparecem nos painéis do MES, em widgets configuráveis e no AURA MESH.
- Histórico é mantido para análises de tendência e comparativos.
Camada de IA — capacidades para o cliente
A plataforma oferece um conjunto de capacidades de IA que ficam disponíveis dentro do MES, do WMS e do AURA MESH, sem necessidade de instalar nada extra para o usuário final:
| Capacidade | O que faz |
|---|---|
| Consulta de produção em linguagem natural | "Quantas ordens fechei na sexta?", "qual máquina mais parou em março?" — sem precisar saber consultar bancos. |
| Consulta de armazém em linguagem natural | Posição de estoque, movimentações, vencimentos e endereços respondidos em texto. |
| Análise de documentos | Carrega PDF, Excel ou CSV e responde perguntas sobre o conteúdo (procedimentos, especificações, e-mails do cliente). |
| Geração de relatório por demanda | Cria relatórios pontuais a partir de uma descrição em texto. |
| Análise de alertas | Sugere ações corretivas ao receber alertas operacionais. |
| Detecção de anomalias | Identifica padrões fora do esperado nos dados de sensores e OEE. |
A IA consulta sempre o banco central da plataforma e o Data Lake do AURA MESH — não há banco documental separado, e nenhum dado precisa sair da fábrica para o serviço funcionar.
AURA MESH — Plataforma de Dados e IA Industrial
O AURA MESH é o produto de inteligência analítica e IA generativa da Simjob, agora separado da plataforma operacional e instalado em servidor próprio dentro da fábrica. Substitui o antigo módulo Aura embutido no monolito — consumindo eventos do Edge e mantendo todo o conhecimento histórico em um Data Lake local.
O que ele entrega ao cliente
Análise de OEE histórica
Comparativos por máquina, turno, produto e período sobre meses ou anos de dados consolidados, sem onerar o banco operacional.
Detecção de anomalias
Identificação automática de comportamento fora do padrão em sensores, ciclos e indicadores — com alertas direcionados ao time de operação.
Root Cause via IA
Correlação entre paradas e leituras de sensores para indicar a causa mais provável de cada interrupção, com explicação em linguagem natural.
Pergunte aos seus dados
Interface conversacional: "qual máquina mais parou em março?", "quais lotes tiveram refugo acima de 3%?". Respostas sustentadas no Data Lake da própria fábrica.
Soberania de dados
Roda 100% on-premises. O cliente decide o que vai para a nuvem (e se vai). Dados sensíveis ficam dentro da planta industrial.
Integração Edge ↔ Mesh
O Edge envia eventos em fluxo contínuo; o AURA MESH consolida, analisa e devolve insights consumíveis pelo MES/WMS/APS e pelos relatórios da plataforma.
Como o cliente usa
- Painéis prontos de OEE, paradas e qualidade alimentados pelo histórico longo prazo.
- Interface de perguntas em linguagem natural para gerentes e diretores industriais.
- Integração transparente com os módulos da Simjob — não exige nova autenticação para o usuário final.
- Configuração e instalação são feitas em conjunto com o time de implantação Simjob.
Vision — Visão Computacional Industrial
Sistema de visão computacional para inspeção de qualidade, monitoramento de linhas e análise de câmeras industriais. Recebe imagens e vídeo das câmeras instaladas na fábrica, processa em tempo real e devolve classificações, contagens e alertas para os módulos da plataforma.
O que ele faz
- Inspeção automática de produtos (presença/ausência, dimensões, defeitos visíveis).
- Contagem de peças em esteira e linhas.
- Monitoramento de áreas críticas (uso de EPI, presença em zonas restritas).
- Gravação de evidência em armazenamento próprio para auditoria posterior.
- Acionamento de alertas no MES quando padrões anômalos são detectados.
ASAP — Comunicação Omnicanal com IA
Plataforma de atendimento omnicanal com assistente de IA para suporte industrial. Integra WhatsApp, chat web, e-mail e notificações em tempo real, e pode consultar o MES/WMS para responder dúvidas operacionais com base em dados reais.
Casos de uso típicos
- Atendimento ao operador: tira-dúvidas sobre procedimentos, motivos de parada e alertas ativos.
- Notificação de eventos críticos por WhatsApp/e-mail (parada longa, ruptura de estoque, excursão de temperatura).
- Canal direto entre operação e supervisão sem trocar de aplicativo.
Outros Módulos
Digital Signage
Painéis visuais para TVs e monitores instalados no chão de fábrica, com indicadores em tempo real, status das ordens em execução e visão de turno.
Workflow / Automação
Editor visual para automatizar processos industriais — disparo de notificações, aprovação de eventos, integração com sistemas externos a partir de gatilhos do MES e WMS.
Object Storage
Repositório interno para imagens, relatórios PDF e arquivos gerados pela plataforma — gerenciado pelo próprio servidor Simjob, sem dependência de nuvem externa.
App Mobile
App multi-plataforma (Android, iOS e web) para apontamento de produção, picking de WMS e consultas — pensado para uso em equipamentos de mão.
Camada de IA unificada
Camada interna que conecta a plataforma a diferentes provedores de IA (em nuvem ou local) e cuida de limites, segurança e métricas — transparente para o usuário final.
Sincronização Edge ↔ Mesh
Mecanismo de sincronização incremental que mantém o AURA MESH e instâncias auxiliares atualizadas com o estado operacional, sem onerar o banco principal.
🧩 Customs — Visão Geral
O módulo Customs é o sistema de extensibilidade da plataforma SimJob. Permite que cada cliente desenvolva telas, relatórios e fluxos customizados em React que rodam dentro dos hosts oficiais (DS, WMS, MES) sem tocar no código-fonte da plataforma.
O código-fonte do custom vive fora do repositório SimJob — no workspace do próprio
cliente. Apenas o bundle compilado é enviado ao edge via CLI/API, ficando servido
em /customs/<tenant>/<slug>/index.js com gate de autenticação e de perfis.
3 Hosts de Montagem
Um custom roda em DS (Digital Signage), WMS ou MES. O runtime é carregado via import() dinâmico; o host injeta window.__SIMJOB_RUNTIME__ antes da montagem.
Gate por Perfil
Cada custom declara required_roles. O serve do bundle checa o JWT do usuário e os perfis (access_profiles.name ou .level) antes de entregar o JS.
Multi-Tenant
Chave (tenant, slug) na tabela customs_registry; arquivos isolados por tenant em customs/<tenant>/<slug>/. Header X-Tenant resolve por request.
Gerador por IA
Endpoint POST /api/v1/customs/generate transforma PDFs/e-mails em rascunhos React via LLM (DashScope hoje, Qwen local amanhã).
Jobs Agendados
Cron → render → e-mail. Tabelas customs_jobs e customs_job_runs + runner Go em background. Usa net/smtp com STARTTLS.
CLI Completo
@simjob/customs-cli: init · gen · dev · build · doctor · publish · login · status · list · enable · disable · rm · jobs.
Arquitetura
┌───────────────────────────── Máquina do cliente ─────────────────────────────┐
│ my-customs/ │
│ └─ rel-extrusoras/ │
│ ├─ src/index.jsx ← React + @simjob/customs-sdk │
│ ├─ manifest.json ← slug, host, menu, required_roles │
│ └─ dist/index.js ← ESM compilado (externals: react, sdk) │
│ │
│ $ simjob-customs build → dist/index.js │
│ $ simjob-customs publish → POST multipart ao edge │
└──────────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────── Edge do cliente ───────────────────────────────┐
│ │
│ POST /api/v1/customs/:slug/upload │
│ └─ grava CUSTOMS_ROOT/<tenant>/<slug>/index.js (tmp+rename+sha256) │
│ └─ upserta customs_registry (PostgreSQL) │
│ │
│ GET /customs/:tenant/:slug/index.js │
│ ├─ checa enabled + status=enabled (ou ?preview=1) │
│ ├─ checa required_roles vs perfis do JWT │
│ └─ serve ESM (ETag=sha256) │
│ │
│ GET /api/v1/customs?host=mes │
│ └─ shells consomem para montar itens de menu dinâmicos │
│ │
│ Runner interno: │
│ loop 60s → ListDue() → executa cron jobs → render → smtp/webhook │
└──────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────── Host shell (DS/WMS/MES) ──────────────────────────┐
│ 1. <script type="importmap"> resolve react / @simjob/customs-sdk │
│ 2. window.__SIMJOB_RUNTIME__ = { edgeUrl, user, tenant, host, params, ... } │
│ 3. import(bundleUrl) → monta <Component/> dentro de ErrorBoundary │
└──────────────────────────────────────────────────────────────────────────────┘
Tabela customs_registry
| Coluna | Tipo | Descrição |
|---|---|---|
id | BIGSERIAL | PK |
tenant | VARCHAR(64) | Tenant owner (default = "default") |
slug | VARCHAR(128) | Identificador único dentro do tenant |
title, description | TEXT | Exibição humana |
host | VARCHAR(16) | ds | wms | mes |
menu_section, menu_label, menu_icon, menu_order | VARCHAR/INT | Posicionamento no menu do host |
required_roles | JSONB | Array de nomes ou níveis de perfil; vazio = qualquer autenticado |
entry | VARCHAR(128) | Nome do arquivo entry dentro do bundle (default: index.js) |
params_schema, params_default | JSONB | JSON Schema dos params + valores default |
version | VARCHAR(32) | SemVer |
enabled | BOOLEAN | true = visível nos menus; false = escondido |
status | VARCHAR(16) | draft | enabled | disabled |
bundle_path, bundle_size, bundle_hash | TEXT/BIGINT | Metadados do arquivo em disco |
author | VARCHAR(200) | Quem publicou |
created_at, updated_at | TIMESTAMPTZ | Auditoria |
Migração: edge/migrations/customs/001_customs_registry.sql (idêntica embed em
edge/internal/customs/migrations/ para deploys sem filesystem).
API REST do módulo Customs
Registry
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/v1/customs?host=mes&enabled=1 | Lista; enabled=1 retorna só publicados |
| GET | /api/v1/customs/{slug} | Metadata de um custom |
| POST | /api/v1/customs | Upsert de metadados (body = Manifest) |
| PUT | /api/v1/customs/{slug} | Idem, slug pelo path |
| DELETE | /api/v1/customs/{slug} | Remove registry + pasta de bundle em disco |
| POST | /api/v1/customs/{slug}/enable | enabled=true, status=enabled |
| POST | /api/v1/customs/{slug}/disable | enabled=false, status=disabled |
| POST | /api/v1/customs/{slug}/upload | Multipart: campos manifest (JSON) + bundle (arquivo) |
Serve do bundle
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /customs/{tenant}/{slug}/{file} | Bundle/sourcemap. 404 se disabled ou draft; 403 se required_roles não bate com o usuário. ?preview=1 ignora o gate de enabled (usado pela tela admin) |
Jobs
| Método | Endpoint | Descrição |
|---|---|---|
| GET | /api/v1/customs/jobs | Lista jobs |
| POST | /api/v1/customs/jobs | Upsert |
| PUT/DELETE | /api/v1/customs/jobs/{slug} | Editar/remover |
| POST | /api/v1/customs/jobs/{slug}/enable | Cron passa a disparar |
| POST | /api/v1/customs/jobs/{slug}/disable | Pausa cron |
| POST | /api/v1/customs/jobs/{slug}/run | Dispara job SINCRONAMENTE (smoke test) |
Gerador
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /api/v1/customs/generate | Recebe {tenant, slug, host, kind, briefing_dir, iterate, model}; retorna {manifest_json, index_js, diagnostics, provider, tokens_in, tokens_out, ...} |
Multi-tenant
Todo request resolve o tenant via (precedência): header X-Tenant → query ?tenant= → default "default".
SDK React — @simjob/customs-sdk
Pacote npm que o cliente consome para autor de customs. Instala como
devDependency; em produção é external no bundle e resolvido
via import map do host.
Hooks disponíveis
| Hook | Retorna | Uso típico |
|---|---|---|
useEdgeApi() | (path, init) => Promise<Response> | Fetch autenticado com JWT + X-API-Key + X-Tenant injetados; prefixa URL relativa com edgeUrl |
useEdgeJSON(path, opts) | {data, error, loading} | Polling JSON; opts.refreshMs para auto-refresh; opts.params vira querystring |
useCurrentUser() | {id, username, fullName, roles, ...} \| null | Filtros per-user, menções |
useCustomParams() | Record<string, unknown> | Params configurados pelo admin (merge com params_default) |
useHost() | 'ds' | 'wms' | 'mes' | Variações per-host do mesmo bundle |
useTenant() | string | Branding e segmentação |
useLocale() | 'pt-BR' default | Formatadores |
useEdgeBaseUrl() | string | Links absolutos |
Protocolo de runtime
O host popula window.__SIMJOB_RUNTIME__ antes de chamar
import(), em uma forma tipada como SimJobRuntime:
interface SimJobRuntime {
edgeUrl: string;
tenant: string;
host: 'ds' | 'wms' | 'mes';
authToken?: string;
apiKey?: string;
user?: {
id: number | string;
username: string;
fullName?: string;
roles: string[];
locale?: string;
} | null;
params?: Record<string, unknown>;
locale?: string;
}
Exemplo mínimo de custom
import React from 'react';
import { useEdgeJSON, useCurrentUser, useCustomParams } from '@simjob/customs-sdk';
export default function MeuRelatorio() {
const user = useCurrentUser();
const params = useCustomParams();
const { data, loading } = useEdgeJSON(
'/api/v1/mes/reports/production',
{ params, refreshMs: 60_000 }
);
if (loading) return <p>Carregando…</p>;
return <div>
<h1>Produção — {user?.fullName}</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>;
}
CLI — @simjob/customs-cli
Tooling completo de autoria. Roteador simjob-customs <comando> com lazy import dos módulos para que --help, login, init rodem sem npm install.
Resolução de credenciais
Toda chamada ao edge resolve credenciais nesta ordem:
- Flag explícita:
--edge=…,--token=…,--apiKey=…,--tenant=… - Env var:
SIMJOB_EDGE,SIMJOB_TOKEN,SIMJOB_API_KEY,SIMJOB_TENANT - Arquivo:
~/.simjob/config.jsongerado porsimjob-customs login(chmod 600)
Comandos
| Comando | O que faz |
|---|---|
init <slug> [--host=…] [--title=…] | Scaffold em ./<slug>/ |
gen --slug=… --host=… --kind=report | IA gera custom a partir de briefing (veja Gerador) |
dev [--port=5173] [--mock] | Vite dev server com HMR + shell + import map + runtime mockada |
build [--root=.] | Vite library mode → dist/index.js ESM (react, react-dom, SDK externos) |
doctor | Valida manifest, slug, bundle, default export; exit 1 em erro |
login | Interativo; chama /api/v1/auth/login, grava JWT |
logout | Limpa ~/.simjob/config.json |
status | Mostra edge/tenant/user + probe do endpoint |
list [--host=…] [--enabled] | Tabela ASCII com todos os customs |
publish [--root=.] | Upload multipart de dist/index.js + manifest.json |
enable <slug> / disable <slug> | Publica / esconde |
rm <slug> [--yes] | Remove do registry e do disco |
jobs <subcomando> | Gerenciar jobs agendados (ver seção Jobs) |
Fluxo típico (desenvolvedor)
simjob-customs login # 1x/máquina
simjob-customs init meu-relatorio --host=mes
cd meu-relatorio
npm install
simjob-customs dev # HMR contra edge real (ou --mock offline)
simjob-customs doctor # valida
simjob-customs build
simjob-customs publish
simjob-customs enable meu-relatorio
Comando dev — detalhes
Gera .simjob/dev-index.html (adicionado ao .gitignore) com:
- Import map apontando
react,react-dom,react/jsx-runtime,@simjob/customs-sdkpara esm.sh — instância ÚNICA de React (evita a armadilha de "Invalid hook call") window.__SIMJOB_RUNTIME__populada com edge real (do login) + usuário fake admin/manager/operator- Barra superior de desenvolvimento
[DEV][LIVE|MOCK] host · tenant · user - Flag
--mockinterceptafetch('/api/*')com JSON canned (production report,storage status) optimizeDeps.include: ['react', 'react-dom', 'react/jsx-runtime']força pre-bundle no Vite
Integração nos Hosts
MES Manager (Next.js)
7 pontos de integração:
| Arquivo | Responsabilidade |
|---|---|
src/app/layout.tsx | <script type="importmap"> no <head> — resolve react/jsx-runtime/customs-sdk via esm.sh |
src/lib/customsClient.ts | Cliente HTTP tipado: Custom, CustomManifest, CustomsClient; resolveCreds() lê do localStorage; parseRoles() normaliza JSON ou array |
src/components/customs/CustomRuntime.tsx | Dynamic import + injeção de window.__SIMJOB_RUNTIME__ + ErrorBoundary classe |
src/app/customs/page.tsx | Tela admin /mes/customs: lista, filtro por host, criar/editar/upload/publicar/desativar/preview |
src/app/custom/[slug]/page.tsx | Rota dinâmica /mes/custom/<slug> — resolve e monta |
src/components/layout/Sidebar.tsx | Item fixo "Customs" + merge dinâmico buscando /api/v1/customs?host=mes&enabled=1, agrupado por menu_section |
DS (Digital Signage, Vite)
| Arquivo | Responsabilidade |
|---|---|
ds/index.html | Import map na raiz HTML |
ds/public/vendor/simjob-customs-sdk.js | Cópia do SDK servida estaticamente pelo Vite |
src/components/customs/*.jsx | CustomsAdminPage, CustomRuntime, customsService |
src/App.jsx | Botão 🧩 flutuante + rotas por hash: #customs abre admin, #custom/<slug> monta custom |
Import map (compartilhado)
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18",
"react-dom": "https://esm.sh/react-dom@18",
"react-dom/client": "https://esm.sh/react-dom@18/client",
"react/jsx-runtime": "https://esm.sh/react@18/jsx-runtime",
"react/jsx-dev-runtime": "https://esm.sh/react@18/jsx-dev-runtime",
"@simjob/customs-sdk": "/vendor/simjob-customs-sdk.js"
}
}
</script>
Decisão arquitetural: o custom renderiza em sua própria instância de React (esm.sh) — isola o host do estado e do runtime de React do custom. Hooks funcionam dentro do custom; o host só vê o subtree renderizado. Zero risco de React duplicado quebrar o shell.
⏰ Jobs Agendados
Um job é uma entrega recorrente que dispara em cron, busca dados em um endpoint, renderiza via template HTML e entrega via canal configurado (e-mail, webhook, noop). Cobre o caso "enviar o relatório X por e-mail todo dia às 07:00".
Schema — tabelas novas
customs_jobs:
| Coluna | Tipo | Descrição |
|---|---|---|
slug | VARCHAR(128) | Único por tenant |
custom_slug | VARCHAR(128) | FK soft para customs_registry.slug |
schedule | VARCHAR(64) | Cron 5-campos (0 7 * * *) |
timezone | VARCHAR(64) | IANA TZ (default America/Sao_Paulo) |
source_url | TEXT | URL template com placeholders {{yesterday}}, {{first_of_month}}, {{today}}, {{now}} |
html_template | TEXT | Go html/template com funções {{kg}}, {{pct}}, {{date}} |
subject_template | VARCHAR(500) | Mesmo template engine |
delivery_kind | VARCHAR(16) | email | webhook | noop |
delivery_config | JSONB | Ex.: {"to":["a@b"],"cc":["c@d"]} |
enabled | BOOLEAN | true = cron dispara |
last_run_at, last_status, last_error, next_run_at | — | Runtime bookkeeping |
customs_job_runs registra cada disparo (running, ok, error, skipped) com timestamp, tamanho renderizado e destinatários.
Parser cron — zero dependência
Suporta 5 campos (minuto hora dia mês weekday) com:
- Wildcard:
* - Listas:
1,3,5 - Ranges:
1-5 - Steps:
*/15 - Timezones IANA (usa
time.LoadLocation)
Implementação em edge/internal/customs/jobs_cron.go. 5 testes dedicados no jobs_cron_test.go.
Runner
Loop 60s em goroutine iniciada no Bootstrap (desabilitável com CUSTOMS_JOBS_RUNNER=off). Fluxo por job:
- Insere linha
runningemcustoms_job_runs fetchSource()expande placeholders + chamasource_urlautenticadorenderHTML()processa template com resposta JSON como contextodeliver()despacha — SMTP com STARTTLS / webhook POST / noop log- Computa
nextAfter()do cron + atualizalast_*enext_run_at
Env vars (SMTP)
| Variável | Default | Descrição |
|---|---|---|
SMTP_HOST | — | Se vazio, runner entra em modo dry-run (loga destinatários, não envia) |
SMTP_PORT | 587 | STARTTLS |
SMTP_USER, SMTP_PASS | — | PLAIN auth |
SMTP_FROM | simjob@localhost | Remetente |
CUSTOMS_JOBS_EDGE_URL | http://localhost:1870 | Base das URLs relativas em source_url |
CUSTOMS_JOBS_AUTH_TOKEN / CUSTOMS_JOBS_API_KEY | — | Credencial server-side que o runner usa para chamar source_url |
CUSTOMS_JOBS_RUNNER | on | off desabilita o loop em background (útil em testes) |
CLI — subsistema jobs
simjob-customs jobs init <slug> --cron="0 7 * * *" --customSlug=rel-diario
simjob-customs jobs publish <file.json>
simjob-customs jobs run <slug> # síncrono — smoke test
simjob-customs jobs enable <slug> # cron começa
simjob-customs jobs disable <slug>
simjob-customs jobs list
simjob-customs jobs rm <slug> [--yes]
🤖 Gerador de Customs com IA
Transforma material bruto do cliente (PDFs, e-mails, docs) em rascunho React + manifest via LLM. Pipeline end-to-end server-side, provider-agnóstico.
Pipeline
briefing/ ──▶ pdftotext / raw text ──▶ prompt ──▶ LLM ──▶ JSON envelope
│
▼
doctor-like validator (auto-retry 1x)
│
▼
edge/customs/<tenant>/_generated/<slug>/
├── manifest.json
├── index.js
├── README.md
└── .generated.json (metadata do run)
Providers — estratégia
O serviço não conhece DashScope nem Ollama diretamente. Fala
com o ai/llm.Router já existente. A escolha é feita por duas env vars:
| Env var | Valores | Efeito |
|---|---|---|
CUSTOMS_GEN_MODEL | qwen3-coder-plus, qwen3-coder-30b-local, claude-opus-4-7, … | ID do modelo; router escolhe o cliente correspondente |
CUSTOMS_GEN_SOVEREIGNTY | CLOUD | HYBRID | ON_PREM | ON_PREM recusa qualquer provider cloud — falha fast em vez de vazar |
CUSTOMS_GEN | off | Desabilita o endpoint completamente |
Config hoje — DashScope (1 env var)
export DASHSCOPE_API_KEY=sk-xxx
# URL + label auto-configurados:
# https://dashscope-intl.aliyuncs.com/compatible-mode/v1 → label=qwen-cloud
# Modelo default: qwen3-coder-plus
Config amanhã — local (quando o cliente tiver GPU)
# Sobe vLLM/Ollama com Qwen3-Coder-30B
export QWEN_LOCAL_URL=http://qwen-gpu.interna:8000/v1
export QWEN_LOCAL_KEY= # Ollama não precisa
export CUSTOMS_GEN_MODEL=qwen3-coder-30b-local # "local" no id ativa QwenLocal
export CUSTOMS_GEN_SOVEREIGNTY=ON_PREM # blinda cloud
# ZERO mudança em: código do generator, CLI, prompts, customs gerados.
Validações server-side (após resposta do LLM)
- JSON válido com chaves
manifest+index_js+readme_md+notes - Manifest tem
titleemenu_label; preenche defaults ausentes (entry,version,required_roles) slugehostsão forçados ao que o caller pediu (LLM não inventa nome)index.jstemexport default, senão o host não montaindex.jsnão contém fences markdown (```)index.jsnão usaprocess.envnemrequire()(quebra no browser)
Se houver qualquer erro, faz uma retry automática passando as diagnósticas como feedback. Se ainda falhar, retorna o melhor esforço + todas as diagnósticas.
CLI — simjob-customs gen
# Padrão — briefing em <customs_root>/<tenant>/_briefing, salva em _generated/
simjob-customs gen --slug=meu-relatorio --host=mes --kind=report \
--title="Meu Relatório Diário" --tenant=<tenant>
# Iterar sobre feedback (segunda passada, corrige erros específicos)
simjob-customs gen --slug=meu-relatorio --tenant=<tenant> \
--iterate="adicione tooltip nos códigos e trave a ordenação por nome"
# Dump local paralelo (desenvolvedor inspeciona no VSCode)
simjob-customs gen --slug=meu-relatorio --tenant=<tenant> --out=./draft/
# Override de modelo (útil pra A/B test cloud vs local)
simjob-customs gen --slug=meu-relatorio --model=qwen-max --tenant=<tenant>
Custo típico (DashScope qwen3-coder-plus)
Prompt ~3-6k tokens + resposta ~3-5k tokens = ~USD 0,02-0,05 por custom gerado. Para comparação, Claude Opus 4.7 no mesmo workload custaria ~USD 0,40-0,80.
Limitações atuais
- PDFs escaneados (sem OCR) viram placeholder; precisa de PDF com texto selecionável
- Imagens ainda não passam por vision — são listadas mas o conteúdo é perdido
.docxtem suporte parcial — recomendado exportar como PDF antes- 1 briefing completo por run — briefings muito grandes devem ser quebrados em subpastas
Testes e Validação
O módulo Customs tem 48 testes automatizados cobrindo backend, CLI e gerador.
Todos rodam em go test ./internal/customs/... (Go) e node --test (CLI).
Pacote edge/internal/customs/ — 24 testes
| Arquivo | Cobertura |
|---|---|
service_test.go | Validação de slug/tenant (8 casos: slug curto, uppercase, com barra, dotdot); BundlePath bloqueia path traversal; writeBundleFile confere hash SHA-256 e atomicidade (tmp+rename); rejeita entry com .. |
handlers_test.go | Role gate: vazio libera, sem lookup libera, mismatch nega, match case-insensitive libera, JSON corrompido soft-libera. Tenant resolver (header/query/default, precedência) |
bootstrap_test.go | splitSQL preserva DO $$ END$$, ignora comentários. Embedded migrations FS carrega ao menos 1 SQL |
http_smoke_test.go | Serve path curto → 404. Upload com slug mismatch → 400. Upload sem bundle → 400. Roundtrip datatypes.JSON |
jobs_cron_test.go | Parser 5 sintaxes (*, */15, 1-5, 1,3,5); nextAfter diário 07:00; weekdays; every-15-min; expandPlaceholders; formatador pt-BR |
Pacote edge/internal/customs/generator/ — 10 testes
| Teste | O que verifica |
|---|---|
TestStripFences | Remove ```json ... ``` que o LLM às vezes adiciona apesar das instruções |
TestValidateSlug | Aceita good (rel-diario, a1b2) e rejeita bad (uppercase, espaços, hífen terminal) |
TestParseAndValidate_HappyPath | JSON válido do LLM produz bundle pronto com defaults injetados |
TestParseAndValidate_CatchesMissingExportDefault | Sem export default → erro (host não montaria) |
TestParseAndValidate_OverridesSlugToMatchRequest | LLM alucina slug diferente → serviço corrige + emite diagnóstico warn |
TestParseAndValidate_BadJSON | JSON inválido gera diagnóstico error (entrada para retry automático) |
TestParseAndValidate_FlagsNodeGlobals | Uso de process.env ou require() emite warn (não funcionam no browser) |
TestBuildUserPrompt_IncludesBriefing | Prompt contém metadados do request e texto extraído dos arquivos de briefing |
TestBuildUserPrompt_IterateFeedback | Campo iterate gera seção "ITERATION FEEDBACK" no prompt |
TestFormatDiagnostics | Diagnostics são formatados de forma consumível pelo próximo round do LLM |
CLI packages/customs-cli/ — 9 testes
Arquivo src/config.test.js, executado com node --test:
- Flag explícita vence env var que vence config file
- Env var vence config file quando não há flag
- Config file é fallback final
- Falta de edge URL → erro explicativo
- Falta de credenciais → erro explicativo
requireAuth=falsepermite ausência de credenciaiswriteConfigmerge com config existenteclearConfigremove o arquivo- Trailing slash em edge URL é removido
Validador simjob-customs doctor
O mesmo validador que o server-side aplica ao output do gerador também roda offline via CLI no projeto do consultor:
manifest.jsoné JSON válidomanifest.slug,.title,.hostpresenteshost ∈ {ds, wms, mes};slugbate com regex do edgeentrysem path separator ou..required_rolesé arraysrc/index.jsxexiste e temexport default- Importa
@simjob/customs-sdk(warn se não — sinal de que auth/tenant serão plumbed manualmente) dist/index.jstem tamanho razoável (<1 MB; warn acima)- Bundle importa de
react(warn se o build não marcou como external)
Exit code 1 em qualquer error-level issue. Usado tipicamente como gate no CI antes do publish.
Rodando todos os testes
# Backend (Go)
cd edge && go test ./internal/customs/...
# CLI (Node)
cd packages/customs-cli && node --test src/config.test.js
# Build sanity — edge + hosts
go build ./... # edge
npm run build --workspace=mes-manager # MES (Next.js)
npm run build --workspace=ds # DS (Vite)
Stack Tecnológica Completa
| Camada | Tecnologia | Versão | Módulos |
|---|---|---|---|
| Edge / Núcleo | Servidor único multi-módulo (MES, WMS, APS, Customs, Segurança, IoT) | v2.x | edge |
| Banco Central | PostgreSQL + TimescaleDB (relacional + séries temporais, multi-tenant) | PG 15 | todos os módulos |
| Cache / Pub-Sub | Redis | 7.x | edge, asap |
| Object Storage | MinIO (S3-compatível) — imagens, PDFs e relatórios | — | bucket, vision, reports |
| Mensageria IoT | MQTT broker (EMQX) | 5.x | edge, vision |
| Computer Vision | Inspeção visual + IA por câmera | — | vision |
| Frontends Web | MES Manager, WMS Manager, APS Manager, Customs Admin, Edge Monitor | — | UI |
| Signage | Painéis de fábrica (TVs e monitores) | — | ds |
| Mobile | App de apontamento e picking (multi-plataforma) | — | app, appterm |
| Automação | Workflow visual de processos | — | workflow |
| Plataforma de Dados / IA | AURA MESH (produto separado, on-premises) | — | aura-mesh |
| Observabilidade | Métricas e logs estruturados | — | edge |
| Autenticação | JWT, API Keys, RBAC multi-tenant | — | todos os módulos |
Portas e Endpoints
| Serviço | Porta | Protocolo | Swagger / UI |
|---|---|---|---|
| Edge API | :1870 | HTTP · WebSocket · gRPC | /swagger/ |
| Workflow (Node-RED) | :1880 | HTTP | / |
| MES Manager | :1896 | HTTP | - |
| WMS Manager | :1872 | HTTP | - |
| APS Manager | :1873 | HTTP | - |
| Vision Sync API | :8090 | HTTP | /docs |
| Vision Server (FastAPI) | :8000 | HTTP | /docs |
| Bucket API | :9010 | HTTP | /swagger/ |
| MediaMTX RTMP | :1935 | RTMP | - |
| MediaMTX HLS | :8888 | HTTP | - |
| Redis | :6379 | TCP | - |
| PostgreSQL / TimescaleDB (Central) | :5432 | TCP | - |
| MinIO Console | :9001 | HTTP | / |
| MinIO API | :9000 | HTTP S3 | - |
Estratégia de Dados
A plataforma adota um banco de dados único e central — PostgreSQL com extensão TimescaleDB — compartilhado por todos os módulos (MES, WMS, APS, Customs, Segurança, IoT). Essa decisão arquitetural simplifica backups, recuperação, isolamento por tenant e facilita relatórios cruzados sem replicação de dados entre serviços.
| Camada | Tipo | Usado para | Retenção típica |
|---|---|---|---|
| PostgreSQL + TimescaleDB (banco central) | Relacional + séries temporais | Tudo que é estado de negócio — ordens, apontamentos, OEE, estoque, movimentações, planos, hierarquia, segurança, customs e séries de sensores IoT | Configurável por entidade · sensores compactados via Timescale |
| Redis | In-memory | Cache de leituras quentes, fila de sincronização, eventos em tempo real e sessões de usuário | Volátil |
| MinIO | Object storage | Imagens de visão computacional, PDFs gerados, anexos de relatórios e uploads de customs | Configurável por bucket |
| AURA MESH (separado) | Data Lake on-premises | Histórico longo prazo, analytics e IA — fora do banco operacional para não pesar na operação | Definida pelo cliente |
Por que um banco único?
- Consistência — relatórios cruzados (ex.: OEE × estoque × plano APS) sem ETL.
- Operação simples — um único backup, um único monitoramento, uma única política de retenção.
- Time-series no mesmo lugar — TimescaleDB cuida das séries de sensores no mesmo motor relacional.
- Isolamento por tenant — cada cliente tem seu escopo lógico no mesmo cluster, com chave de tenant em todas as tabelas.
Segurança
| Mecanismo | Implementação | Módulos |
|---|---|---|
| Autenticação JWT | golang-jwt/v5 · jsonwebtoken | Edge, MCP, Aura, ASAP |
| API Keys | Header X-API-Key, hashed com bcrypt | Edge, MCP |
| RBAC | Roles por módulo e tenant | Edge, Aura |
| Rate Limiting | Token bucket, configurável por endpoint | Edge, ASAP, LLM |
| Audit Log | Log estruturado de operações críticas | Edge |
| TLS/HTTPS | Suporte nativo em todos os serviços | Todos |
| Multi-tenant | Isolamento por tenant_id em todas as queries | Edge, Aura |
| Secrets | Variáveis de ambiente (.env), nunca em código | Todos |
Operação e Requisitos de Servidor
A plataforma é entregue como um pacote único de servidor — um servidor central hospeda todos os módulos (Edge, MES, WMS, APS, Customs, AURA MESH), isolados por contêineres e compartilhando o banco PostgreSQL central. A instalação e atualização são feitas pelo time de implantação Simjob; o cliente não precisa montar a stack.
Dimensionamento sugerido
| Ambiente | CPU | RAM | Disco | OS |
|---|---|---|---|---|
| Planta pequena (até 10 máquinas) | 4 cores | 8 GB | 200 GB SSD | Linux Ubuntu 22.04 LTS |
| Planta média (10–40 máquinas) | 8 cores | 16 GB | 500 GB NVMe | Linux Ubuntu 22.04 LTS |
| Planta grande (40+ máquinas) | 16 cores | 32 GB | 1 TB NVMe | Linux Ubuntu 22.04 LTS |
| AURA MESH (servidor dedicado) | 8 cores | 32 GB | 1 TB NVMe (Data Lake) | Linux Ubuntu 24.04 LTS |
API de Integração
O módulo de integração expõe um conjunto dedicado de endpoints REST simplificados que permite que sistemas externos (ERPs, MESs legados, sistemas SCADA, portais de clientes) troquem dados com o Edge sem precisar conhecer a estrutura interna da API.
A filosofia é uma chamada resolve tudo: ao enviar uma Ordem de Produção, por exemplo, o produto já pode vir embutido na mesma requisição — o Edge cria o produto se não existir e vincula à ordem automaticamente.
Fluxo Geral de Integração
Entrada de Dados
Todos os endpoints de entrada aceitam Content-Type: application/json e retornam o objeto criado com status 201 Created (ou 207 Multi-Status para operações em lote).
Ordens de Produção
Ao enviar uma ordem, o produto pode vir embutido no campo product. O Edge faz upsert do produto por código antes de criar a ordem — eliminando a necessidade de chamadas separadas.
{
"code": "OP-2026-001",
"machine_code": "MACH-01",
"planned_quantity": 500,
"priority": 1,
"scheduled_start": "2026-02-24T06:00:00Z",
"scheduled_end": "2026-02-24T14:00:00Z",
"notes": "Produção urgente — cliente XYZ",
"product": {
"code": "PROD-XYZ",
"name": "Peça Injetada XYZ",
"unit": "pcs",
"cycle_time": 1.2
}
}
{
"status": "in_progress",
"notes": "Iniciado no turno da manhã"
}
Produtos
{
"code": "PROD-ABC",
"name": "Componente ABC",
"description": "Componente usinado em alumínio",
"unit": "pcs",
"cycle_time": 2.5
}
Ficha Técnica (Especificação)
Envia a ficha técnica completa de um produto — características e normas podem ser passadas inline no mesmo JSON.
{
"product_code": "PROD-XYZ",
"version": "v2.1",
"technical_description": "Peça injetada em PP com 20% fibra de vidro",
"measurement_unit": "mm",
"characteristics": [
{ "name": "Comprimento", "value": "120", "unit": "mm" },
{ "name": "Largura", "value": "45", "unit": "mm" },
{ "name": "Espessura", "value": "3.5", "unit": "mm" },
{ "name": "Peso nominal", "value": "85.2", "unit": "g" }
],
"norms": [
{ "norm_code": "ABNT NBR 15600", "description": "Plásticos — tensão de tração", "norm_type": "dimensional" }
]
}
Estrutura de Materiais (BOM)
{
"parent_product_code": "PROD-MONTADO",
"child_product_code": "PROD-XYZ",
"quantity": 2,
"unit": "pcs",
"relation_type": "consumes",
"level": 1
}
Processos de Fabricação
{
"product_code": "PROD-XYZ",
"name": "Injeção",
"step_sequence": 1,
"machine_code": "INJ-01",
"description": "Ciclo de injeção em PP",
"cycle_time": 1.2
}
Documentação / Instrução de Trabalho
{
"product_code": "PROD-XYZ",
"process_code": "Injeção",
"name": "IT-001 — Instrução de Injeção PP",
"type": "procedure",
"version": "Rev. 3",
"file_url": "https://bucket.simjob.com.br/docs/IT-001-Rev3.pdf",
"description": "Parâmetros operacionais e sequência de setup da injetora"
}
Especificações de Qualidade
{
"product_code": "PROD-XYZ",
"criterion": "Dimensional — comprimento",
"test_method": "Paquímetro digital 0.01mm",
"acceptance_limit": "120 ± 0.3 mm",
"frequency": "1 a cada 50 peças"
}
Capacidade de Equipamento
{
"machine_code": "INJ-01",
"parameter": "Pressão de injeção",
"default_value": 800,
"min_range": 500,
"max_range": 1200,
"unit": "bar"
}
Rotas de Fabricação
Uma rota agrupa operações sequenciais que um produto percorre — com máquina, tempo de ciclo e setup por operação, tudo em uma única chamada.
{
"product_code": "PROD-XYZ",
"code": "ROTA-XYZ-V1",
"name": "Rota Padrão — Peça XYZ",
"version": "v1",
"operations": [
{ "sequence": 1, "code": "OP-01", "name": "Injeção", "machine_code": "INJ-01", "cycle_time": 1.2, "setup_time": 15 },
{ "sequence": 2, "code": "OP-02", "name": "Rebarbação", "machine_code": "REB-01", "cycle_time": 0.5, "setup_time": 5 },
{ "sequence": 3, "code": "OP-03", "name": "Inspeção", "machine_code": "INS-01", "cycle_time": 0.3, "setup_time": 0 }
]
}
Resumo de Endpoints de Entrada
| Endpoint | Dados enviados | Resultado |
|---|---|---|
POST /integration/orders | Ordem + produto inline | Ordem criada, produto com upsert |
POST /integration/orders/batch | Lista de ordens | 207 com criados e erros |
PUT /integration/orders/{code}/status | Novo status | Ordem atualizada + webhook disparado |
POST /integration/products | Produto | Produto criado ou retornado |
POST /integration/products/batch | Lista de produtos | 207 com criados e erros |
POST /integration/specifications | Ficha técnica + características + normas | Especificação criada |
POST /integration/bom | Pai + filho + quantidade | Entrada de BOM criada |
POST /integration/processes | Produto + sequência + máquina | Segmento de processo criado |
POST /integration/documents | Instrução + produto/processo | Work Instruction criada |
POST /integration/quality | Critério + método | Especificação de qualidade criada |
POST /integration/capacity | Máquina + parâmetro + limites | Capacidade cadastrada |
POST /integration/routes | Produto + operações inline | Rota e operações criadas |
Consulta de Dados (Outbound)
Para obter dados produzidos no sistema — especialmente apontamentos realizados — use os endpoints de consulta. Todos suportam paginação e filtros por período, máquina, ordem ou tipo.
Apontamentos Realizados
from, to, machine, order, type, page, limit{
"total": 127,
"page": 1,
"limit": 50,
"items": [
{
"id": 1042,
"type_code": "PROD",
"type_name": "Apontamento de Produção",
"node_type": "machine",
"node_id": 5,
"node_name": "Injetora 01",
"order_code": "OP-2026-001",
"occurred_at": "2026-02-15T08:32:00Z",
"registered_at": "2026-02-15T08:32:05Z",
"status": "active",
"variables": {
"quantidade_produzida": 120,
"quantidade_refugo": 3,
"tempo_ciclo_real": 1.18
},
"form_data": { "turno": "Manhã", "operador": "João Silva" }
}
]
}
Resumo de Ordem
{
"code": "OP-2026-001",
"status": "in_progress",
"product_code": "PROD-XYZ",
"product_name": "Peça Injetada XYZ",
"planned_quantity": 500,
"produced_quantity": 320,
"scrapped_quantity": 8,
"scheduled_start": "2026-02-24T06:00:00Z",
"scheduled_end": "2026-02-24T14:00:00Z",
"actual_start": "2026-02-24T06:08:00Z",
"actual_end": null,
"completion_pct": 64.0
}
Webhooks
Os webhooks permitem que o Edge notifique proativamente o sistema externo quando eventos ocorrem — eliminando a necessidade de polling periódico. O Edge realiza um POST com o payload do evento para a URL cadastrada no momento do ocorrido.
Eventos Disponíveis
Gerenciamento de Webhooks
{
"url": "https://erp.empresa.com.br/simjob/events",
"events": ["occurrence.created", "order.completed"],
"secret": "minha-chave-secreta-hmac",
"headers": {
"Authorization": "Bearer token-de-autenticacao-do-erp"
}
}
| Campo | Obrigatório | Descrição |
|---|---|---|
url | Sim | Endpoint do sistema externo que receberá o POST a cada evento |
events | Sim | Lista de eventos assinados. Use ["*"] para receber todos |
secret | Não | Chave usada para gerar a assinatura HMAC-SHA256 (header X-Simjob-Signature). Serve para o receptor validar a origem e integridade do payload — não é enviada na requisição |
headers | Não | Headers HTTP extras enviados em toda chamada (ex.: Authorization, X-API-Key). Use quando o endpoint receptor exige autenticação por token |
Payload Enviado ao Webhook
POST https://erp.empresa.com.br/simjob/events
Content-Type: application/json
User-Agent: Simjob-Edge-Webhook/1.0
X-Simjob-Signature: sha256=a3f5...d901
Authorization: Bearer token-de-autenticacao-do-erp
{
"event": "occurrence.created",
"timestamp": "2026-02-24T08:15:00Z",
"data": {
"id": 1043,
"type_code": "PROD",
"type_name": "Apontamento de Produção",
"node_type": "machine",
"node_name": "Injetora 01",
"order_code": "OP-2026-001",
"occurred_at": "2026-02-24T08:14:55Z",
"status": "active",
"variables": { "quantidade_produzida": 80, "quantidade_refugo": 1 }
}
}
Verificação de Assinatura (HMAC-SHA256)
Quando um secret é configurado no webhook, cada requisição enviada pelo Edge inclui o header X-Simjob-Signature com o formato sha256=<hex>. O receptor deve calcular o HMAC do corpo da requisição usando o mesmo secret e comparar com o header para garantir autenticidade.
import hmac, hashlib
def verify(body: bytes, secret: str, signature_header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header)
const crypto = require('crypto');
function verify(body, secret, signatureHeader) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(signatureHeader)
);
}
Autenticação no Endpoint Receptor (Headers Customizados)
O secret (HMAC) não autentica a chamada no receptor — ele apenas permite que o receptor valide que o payload veio do Edge e não foi adulterado. Se o seu endpoint exige um token de autenticação (ex.: Authorization: Bearer … ou X-API-Key), use o campo headers no cadastro do webhook. Os pares informados são enviados em toda requisição disparada pelo Edge.
| Mecanismo | Para que serve | Como ativar |
|---|---|---|
secret → X-Simjob-Signature | Validar origem e integridade do payload (o receptor recalcula o HMAC e compara) | Campo secret no cadastro |
headers → Authorization, X-API-Key, etc. | Autenticar a chamada no endpoint receptor (token estático) | Campo headers no cadastro |
Os dois mecanismos são independentes e podem ser usados juntos: cadastre secret para que o receptor valide a assinatura e headers com o token que ele espera. Recomenda-se HTTPS no endpoint, pois o token trafega nos headers da requisição.
{
"url": "https://erp.empresa.com.br/simjob/events",
"events": ["occurrence.created", "order.completed"],
"headers": {
"Authorization": "Bearer token-de-autenticacao-do-erp"
}
}
Segurança: tanto o secret quanto os headers são omitidos nas respostas de GET e POST dos webhooks — nunca retornam em texto claro após o cadastro.
Autenticação da API de Integração
A API de integração segue o mesmo mecanismo de autenticação do Edge. Por padrão, se a autenticação estiver habilitada (auth.enabled: true), as requisições precisam de um dos mecanismos abaixo:
| Mecanismo | Header | Valor |
|---|---|---|
| API Key | X-API-Key | Chave configurada em config.yaml → auth.api_keys |
| JWT Bearer | Authorization | Bearer <token> — obtido via POST /api/v1/auth/login |
Configuração Recomendada para Integração
Para sistemas de integração (ERPs, scripts automáticos), o método preferido é API Key estática configurada no config.yaml do Edge:
auth:
enabled: true
jwt_secret: "sua-chave-jwt-secreta"
api_keys:
- "api-key-do-seu-erp-123456"
curl -X POST https://edge.empresa.com.br/api/v1/integration/orders \
-H "Content-Type: application/json" \
-H "X-API-Key: api-key-do-seu-erp-123456" \
-d '{ "code": "OP-001", "machine_code": "MACH-01", ... }'
Erros Comuns
| Status | Significado | Solução |
|---|---|---|
400 Bad Request | JSON inválido ou campo obrigatório ausente | Verifique o payload — o campo error descreve o problema |
401 Unauthorized | API Key ou token ausente / inválido | Verifique o header X-API-Key ou Authorization |
404 Not Found | Recurso não encontrado (ex: máquina por código) | Verifique se o código existe no cadastro do Edge (machine_code, product_code) |
207 Multi-Status | Lote com sucesso parcial | Verifique o array errors na resposta para itens que falharam |
502 Bad Gateway | Webhook não respondeu corretamente | Verifique se a URL do webhook está acessível e retorna 2xx |