MeshVigil · arquitetura
O MeshVigil modela uma rede AMI RF-mesh — medidores roteando por coletores até uma central (head-end) — com telemetria sintética, injeção de caos e um parser DLMS/COSEM real no coração. O foco de engenharia é menos a simulação em si e mais torná-la determinística, testável e de hospedagem gratuita, sem timeout de serverless.
A simulação inteira roda no cliente, dentro de um Web Worker. O worker é o dono do estado autoritativo e o avança por um timer; a thread da UI renderiza uma projeção de cada snapshot. O servidor é deliberadamente fino — um health check e um armazenamento opcional de snapshots — então não há processo persistente para pagar, escalar ou ver cair.
Cada leitura que a simulação emite é serializada em um frame DLMS/COSEM DataNotificationgenuíno — framing HDLC com CRC-16/X.25 no cabeçalho e no frame, uma camada LLC, uma APDU xDLMS e dados COSEM em A-XDR carregando registradores identificados por OBIS. O inspetor então decodifica exatamente esses bytes de volta para objetos legíveis. Não há caminho de dados falso: bytes entram, objetos saem — as duas direções cobertas por testes, incluindo um round-trip completo encoder ↔ parser e um frame deliberadamente corrompido que precisa falhar na verificação de FCS.
A engine é uma função pura de (seed, tick, eventos de caos). Nenhum Math.random() é chamado em lugar nenhum; todo sorteio vem de um PRNG seedado misturado com o tick atual. A mesma seed e o mesmo log de comandos produzem uma saída byte a byte idêntica — é isso que torna a simulação testável, que permite reproduzir um snapshot compartilhado com exatidão e que deixaria um browser e um servidor concordarem sobre o estado sem uma conexão ativa.
Um desenho server-driven era uma opção. O raciocínio por trás das escolhas feitas:
| Opção | Veredito | Por quê |
|---|---|---|
| Redis + Vercel Cron + SSE | Rejeitado | O cron do Hobby roda cerca de uma vez por dia e handlers SSE batem no timeout de função — o oposto exato de um sistema que fica de pé. Ainda força uma dependência externa numa demo que deveria simplesmente funcionar. |
| Engine em Rust → WASM | Adiado | Adiciona um toolchain e um risco real de quebrar o deploy por um ganho de performance que não existe nesta escala. Um Web Worker em TypeScript já entrega execução client-side de custo zero e escala infinita. |
| Transporte por WebSocket | Rejeitado | Funções serverless não seguram sockets de longa duração. Com a engine no browser não há a que se conectar — o problema de transporte desaparece. |
| TypeScript 7 / ESLint 10 gume-vivo | Adiado | Fixei as duas ferramentas com maior chance de quebrar o type-checker embutido do build nas suas majors comprovadas. Latest onde é seguro; conservador no caminho crítico de deploy. |