Skip to content

Stack

Stack atual (implementado)

CamadaTecnologiaVersão
RuntimeNode.js24 LTS
LinguagemTypeScript (strict)5.x
HTTPFastify5.x
Armazenamento SQLbetter-sqlite311.x
Validaçãozod3.x
Cripto (Ed25519)hypercore-crypto (libsodium)3.x
Seeds BIP-39@scure/bip391.x
Loggerpino9.x
Monorepopnpm workspaces9.x
Testesvitest3.x
DocsVitePress1.x
FirmwarePlatformIO + framework Arduino (ESP32)

Planejado / em avaliação

CamadaTecnologiaStatus
Serialização canônicaProtobuf (@bufbuild/protobuf no Node, nanopb no ESP32)Schemas existem, codegen inativo — veja ADR-001
Geolocalizaçãoh3-jsPlanejado com os recursos de mapa
Operações de conjunto em filtrosRoaring BitmapsPlanejado com os filtros
App desktopTauri 2.xFase futura
Replicação de nósLog de eventos assinado + sync entre peersEm design — veja Roadmap

Estrutura do repositório

raiznet/
├── apps/
│   ├── server/          # Nó Fastify (endpoints público + local)
│   ├── cli/             # Ferramenta de operação e depuração
│   ├── website/         # Landing page raiznet.com
│   ├── dashboard/       # Dashboard web
│   └── prototype/       # Canvas de design da UI (React + Vite)
├── packages/
│   ├── protocol/        # Schemas .proto (formato canônico, planejado)
│   ├── crypto/          # Derivação de chaves, assinatura, AES-256-GCM
│   └── core/            # Abstrações compartilhadas
├── firmware/
│   ├── safraSense/      # Firmware ESP32 de referência (sensor completo)
│   └── esp32-sensor/    # Exemplo mínimo
└── docs/                # Este site

O firmware de produção do hardware SafraSense da Arateki vive em um repositório separado; o firmware neste repositório é a implementação de referência aberta do protocolo.

Decisões de design

Não introduzir sem discussão:

  • NestJS — pesado demais
  • Express — obsoleto frente ao Fastify
  • ORMs — better-sqlite3 direto
  • Redis — não se justifica neste estágio
  • Docker em dev — roda local
  • Kafka — desnecessário

O papel do SQLite

Hoje, o SQLite é o armazenamento local primário do nó: a ingestão valida um bloco e o escreve diretamente em raiznet_public.db / raiznet_private.db.

O objetivo de design é que a fonte da verdade passe a ser um log de eventos assinado e somente-anexação, com o SQLite como índice derivado que pode ser apagado e reconstruído reproduzindo o log (veja ADR-002). O schema de tabela larga já está moldado para isso:

  • Consultas agregadas rápidas (colunas REAL fixas por sensor)
  • Sem ORM — SQL direto com resultados tipados
  • Novos tipos de sensor exigem adicionar três colunas (_plain, _cipher, _nonce) por campo