Sobre o projeto

# IzgoN IzgoN é um servidor de sincronização delta projetado para frotas de dispositivos que relatam repetidamente estados semelhantes. Em vez de enviar payloads completos a cada ciclo, cada nó faz POST do seu estado atual; IzgoN o compara com o último estado visto e retorna `NO_CHANGE` (zero bytes de payload), um delta JSON mínimo ou o estado completo quando um delta seria maior que o estado que substitui. ## Principais recursos - **Sincronização delta**: Apenas campos alterados são enviados de volta ao dispositivo, reduzindo drasticamente os payloads de resposta. - **Sincronização condicional (v1.4.0+)**: Dispositivos que não mudaram podem enviar um token de checksum curto em vez do relatório completo, para que o relatório nunca vá para a rede. - **Medição de economia**: O painel e o endpoint `/api/metrics` mostram economia de bytes ao vivo em ambas as direções (resposta e uplink). - **Ferramenta de benchmark**: `benchmark.py` (apenas stdlib) reproduz seus próprios relatórios reais para medir a economia em seus dados, com modo sintético para testes. - **Sugestões de polling adaptativo**: O servidor pode sugerir um intervalo de relatório mais longo após vários relatórios idênticos, com compensações explícitas de obsolescência. - **Alertas de silêncio**: Notificações via webhook quando um nó para de relatar e quando ele retorna. - **Sincronização em lote**: Dispositivos que armazenaram dados em buffer enquanto offline podem liberar uma fila em uma única solicitação. - **Camada gratuita**: 10.000 sincronizações sem chave de licença, suficiente para avaliar. ## Como funciona Um nó envia seu estado dentro de `state` (ou apenas um `checksum` se inalterado). O servidor responde com um dos quatro status: - `NO_CHANGE` — nada mudou, zero bytes enviados. - `SYNC_REQUIRED` — apenas chaves alteradas são retornadas; o cliente as mescla. - `FULL_STATE` — o novo estado completo é retornado (quando um delta seria maior). - `SEND_STATE` — o servidor não tem linha de base ou o checksum é desconhecido; o cliente deve reenviar o estado completo. Objetos aninhados são comparados recursivamente; listas são comparadas como um todo (uma limitação deliberada). Um token opcional `epoch` força um estado completo após reinicialização do servidor ou espelho perdido, prevenindo dessincronização silenciosa. ## Início rápido ```bash docker run -p 8000:8000 -e DATAPULSE_API_KEY=change-me ghcr.io/izgamber/izgon:latest ``` Ou com Docker Compose (inclui Redis para linhas de base persistentes): ```bash git clone https://github.com/izGamber/IZgoN.git cd IZgoN cp .env.example .env docker compose up -d ``` Painel em `http://localhost:8000`. Envie um estado: ```bash curl -X POST http://localhost:8000/api/nodes/sensor-01/sync \ -H "Content-Type: application/json" \ -H "X-API-Key: dev-local-key" \ -d '{"state": {"temp": 21.5, "hum": 60, "batt": 98}}' ``` Repita o mesmo estado → `NO_CHANGE` com zero bytes de delta. Altere um campo → apenas esse campo é retornado. ## Benchmark com seus próprios dados ```bash python3 benchmark.py --payload-file my-reports.json ``` Aceita arrays JSON ou JSON Lines, detecta automaticamente campos de ID de dispositivo e mede a taxa de mudança dos seus dados. Modo sintético: `python3 benchmark.py --nodes 50 --rounds 100 --change-rate 0.05`. Economia medida (taxa de mudança de 5%): ~94% na resposta, ~40% no uplink (por SIM), ~65% para clientes de polling. Com taxa de mudança de 70%, a economia cai para ~35% — o limite honesto. ## Endpoints da API | Método | Caminho | Autenticação | Propósito | |---|---|---|---| | POST | `/api/nodes/{id}/sync` | Chave de API | Enviar estado ou checksum, obter delta/completo/NO_CHANGE | | POST | `/api/nodes/{id}/sync/batch` | Chave de API | Reproduzir fila armazenada em buffer em uma solicitação | | GET | `/api/nodes` | Chave de API | Listar nós e linhas de base (paginado) | | GET | `/api/metrics` | nenhuma | Totais de economia de bytes ao vivo | | GET | `/api/license` | nenhuma | Camada atual e sincronizações gratuitas restantes | | GET | `/healthz` | nenhuma | Acessibilidade do Redis, modo de armazenamento | | GET | `/` | nenhuma | Painel | ## Configuração Todas as configurações via variáveis de ambiente (veja `.env.example`). Principais: - `DATAPULSE_REDIS_URL` — conexão Redis para linhas de base - `DATAPULSE_API_KEY` — chave de autenticação (padrão `dev-local-key`, altere-a) - `DATAPULSE_FREE_TIER_LIMIT` — sincronizações gratuitas antes de 402 (padrão 10000) - `DATAPULSE_LICENSE_KEY` — chave de licença paga (assinada com Ed25519, validação offline) - `DATAPULSE_ALERT_URL` / `DATAPULSE_ALERT_AFTER` — alertas de silêncio - `DATAPULSE_ADAPTIVE` — ativar/desativar sugestões de intervalo de polling - `DATAPULSE_MAX_STATE_DEPTH` / `DATAPULSE_MAX_STATE_BYTES` — limites de payload ## Notas de segurança - A chave de API protege todas as escritas; comparação em tempo constante. - `/api/metrics` e `/healthz` não são autenticados por design. - CORS padrão é `*`; restrinja em produção. - Sem limitação de taxa integrada; coloque atrás de um proxy reverso. - O estado é limitado em profundidade (32) e tamanho (1 MB). ## Limitações - Listas não são comparadas elemento por elemento; alterar um item envia a lista inteira. - Payloads encolhendo podem acionar `FULL_STATE` (sem economia nessa sincronização). - O primeiro relatório de qualquer nó é sempre completo. - Linhas de base vivem no Redis; se apagadas, os nós ressincronizam uma vez. - Instância única, sem clustering. - Ainda não há SDK de cliente; integração é HTTP POST simples. ## Licença e preços Código-fonte disponível, não é open source. Camada gratuita: 10.000 sincronizações. Licença comercial: pagamento único, sem assinatura, validação de assinatura Ed25519 offline. Sem telefone para casa. ## Status Versão 1.4.2. Construído e mantido por uma pessoa. Demonstração ao vivo em `https://izgon-api.onrender.com` (a primeira solicitação pode levar 20–40s para ativar).