shivao-projeto/PROJECT_CONTEXT.md
PontualTech / Karlão 5b02feae50 chore: initial commit + security hardening (4 runs squad shivao-melhoria)
Importação inicial do projeto Shivão (Diário de Bordo do veleiro) em estado
pronto pra produção, já incluindo as 5 mudanças de hardening implementadas
pela squad shivao-melhoria em 2026-04-27.

Mudanças de hardening (HANDOFF.md seção " Pronto"):

1. **Rate limiting nos 3 endpoints públicos de share**
   - express-rate-limit ^8.4.1, 60 req/min/IP
   - server/src/index.js linhas 38, 262, 271, 279

2. **Tamanho de upload reduzido pra 50MB** (era 200MB)
   - multer linha 84

3. **Validação Zod nos endpoints autenticados** (POST /api/data e /zones)
   - novo arquivo server/src/schemas/index.js
   - middleware validate() retorna 400 com top 5 issues

4. **Audit log de ações sensíveis**
   - nova tabela audit_log + funções db.audit() e db.recentAudit()
   - 6 endpoints instrumentados (state_set, media_insert/delete, share_create/revoke/zones_update)
   - novo endpoint GET /api/audit (autenticado)

5. **Catch silencioso de webhook em zona PROIBIDA tratado**
   - app/diario-bordo.html + server/public/index.html linha 3280
   - agora loga erro + exibe toast ao usuário

Status final do HANDOFF:
- 🔴 Críticos restantes: 1 (CORS — decisão consciente single-tenant, não-acionável)
- 🟡 Importantes: 4 itens (testes, vigia reconnect, refator frontend, demais catches)
- 🟢 Bom-ter: 5 itens

Stack: Node 20 ESM + Express + better-sqlite3 + Docker (Coolify)
Single-tenant pessoal · single-file frontend HTML · offline-first

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:24:08 -03:00

4.8 KiB

PROJECT_CONTEXT — Histórico e contexto

Documento informal sobre como o projeto chegou ao estado atual. Útil para a equipe entender as decisões e a evolução.

Origem

O projeto começou simples: o dono do veleiro Shivao queria um diário de bordo digital para registrar viagens, manutenções, horímetro do motor e passageiros, com possibilidade de exportar e compartilhar.

A primeira versão foi um HTML standalone com localStorage — funcional, mas limitado. A partir daí, foi crescendo iterativamente:

Linha do tempo

  1. v1: HTML básico — viagens, manutenções, exportar JSON/CSV
  2. v2: Adicionado uso no Android, fotos da câmera, áudio (MediaRecorder), vídeo, lembretes de manutenção futura, lista de manutenções a fazer com custos. Migrado armazenamento de mídia para IndexedDB.
  3. v3: GPS — detecção de posição inicial, rastreio em tempo real, cálculo de milhas náuticas e velocidade em nós, mapa Leaflet com OSM.
  4. v4 (design): Refatoração visual completa — adoção da estética "marítimo editorial" com Fraunces (serif itálico), Manrope, JetBrains Mono, paleta pergaminho/marinha/latão.
  5. v5: Vigia de fundeio com alarme sonoro forte, vibração, botões para disparar mensagens de WhatsApp/SMS/e-mail (limitação: browser não envia automaticamente, requer 1 toque por contato).
  6. v6: Servidor próprio (Node.js + SQLite + Docker para Coolify VPS) com sincronização na nuvem, dead-man switch, e fan-out automático de notificações para múltiplos canais (Telegram, ntfy, e-mail SMTP, Twilio, webhook).
  7. v7: Webhooks diretos do app (Telegram, Discord, genérico) sem precisar do servidor; histórico de fundeios com mapa de cada sessão; compensação de maré/corrente via "swing circle" (centro de giro independente da posição da âncora) com auto-recentro.
  8. v8: Geofencing com zonas de proibição/atenção; compartilhamento público de posição em tempo real (link temporário com mapa Leaflet); importação de tracks GPX.
  9. v9: Exportação GPX por viagem; modo economia de energia (Battery API); previsão meteorológica (Open-Meteo); checklists de bordo customizáveis.
  10. v10 (atual): Migração da meteorologia para Windy Point Forecast API (premium key do dono) com cálculo de vento a partir de componentes wind_u/wind_v e ondas em modelo gfsWave paralelo. Open-Meteo mantido como fallback.

Princípios mantidos durante a evolução

  • Single-tenant: o app é pessoal, do dono. Sem necessidade de gestão de usuários, login complexo, etc.
  • Offline-first: o app funciona 100% sem o servidor. O servidor é uma camada de robustez, não dependência.
  • Single-file frontend: facilita distribuição, instalação no celular e uso offline.
  • Single binary backend: 1 container Docker, 1 banco SQLite, 1 volume. Deploy trivial no Coolify.
  • Estética cuidada: o app não é um "app de app store qualquer" — tem identidade visual própria, faz sentido para um barco de verdade.
  • Sem dark patterns: zero analytics, zero tracking, zero ads. Tudo do dono fica no servidor do dono.

O que NÃO foi feito por opção

  • Login/registro de usuários: por ser single-tenant pessoal.
  • App nativo iOS/Android: maior complexidade, sem ganho proporcional para uso pessoal. PWA atende.
  • Service Worker: ficou como TODO. App funciona offline-first mas não é PWA full ainda.
  • Push notifications via FCM: para o uso anchor watch, polling com heartbeat é melhor. Para outros casos, ntfy resolve.
  • TypeScript: por simplicidade. Equipe pode migrar se quiser.
  • Build step: para manter o "1 arquivo HTML" como deliverável principal.

Limitações conhecidas e aceitas

(coisas que conscientemente deixamos como estão)

  • Frontend monolítico em um único arquivo HTML
  • API do servidor sobrescreve estado (não merge — vence o último write)
  • Mensagens automáticas SMS/WhatsApp dependem do servidor (Twilio pago) ou do tap manual do usuário no celular
  • iOS tem limitações em algumas APIs (Battery, alguns modos de áudio com silencioso ativado)

Para o time de devs

O dono está confortável em deixar vocês continuarem a evolução. Pontos importantes:

  1. Não compliquem prematuramente. O app funciona. Adicione complexidade só quando ela se justifica.
  2. Mantenham a estética. A identidade visual é parte da experiência.
  3. Test em condições reais. Bateria fraca, sinal fraco, sol forte, mãos molhadas — esses são os cenários reais.
  4. Coordenem com o dono antes de mudanças grandes (refatorações, mudanças de stack, novos custos recorrentes).
  5. Backups são sagrados. Antes de qualquer mudança no schema, garantir que os dados existentes do dono não se perdem.

Boa sorte! 🌊