shivao-projeto/server
PontualTech / Karlão 5a64e0897f
Some checks failed
Build Android (APK + AAB) / build-android (push) Has been cancelled
feat(iot): controle Smart Life/Tuya — Casa do Barco v1.12.0
Servidor (proxy assinado):
- server/src/tuya.js: cliente Tuya OpenAPI com HMAC-SHA256 + token cache
  (2h TTL, retry 1x em token expirado), helpers categoryLabel
- 3 endpoints novos em server/src/index.js (todos requireAuth):
  * GET  /api/iot/devices              → lista devices da conta Smart Life
  * GET  /api/iot/status/:deviceId     → DPs (data points) atuais
  * POST /api/iot/command/:deviceId    → envia comandos {code,value}
- Audit log via db.audit('iot_command', ...) pra histórico de toggles
- 503 graceful quando TUYA_ACCESS_ID/SECRET ausentes

Client (UI):
- Card 🏠 Casa do Barco em Arquivo (após Bluetooth, antes Raymarine)
- Modal "Adicionar dispositivo" lista devices da conta Smart Life,
  permite escolher quais aparecem no Shivão (multi-select via toque)
- Cards por device com ícone por categoria (cz=tomada, dj=lâmpada,
  fs=ventilador, kt=ar-cond, sd=robô, etc.) + toggle ON/OFF + status
  online/offline + tempo desde último ping
- Toggle optimistic UI: marca novo estado imediato, reverte se falhar
- Polling 10s pra sync de status, pausa em background (economiza
  Starlink + bateria)
- Backoff: 3 falhas consec → marca offline, retry 30s
- state.smartDevices[] persistido no localStorage (mesmo padrão btDevices)

Setup (admin, 1x):
- Karlão precisa criar projeto em iot.tuya.com (5 min, gratuito) e
  adicionar TUYA_ACCESS_ID + TUYA_ACCESS_SECRET no env Coolify
- Documentação completa no .env.example com passo a passo
- Sem credenciais: card mostra "⚙ Tuya não configurado"

Bumps:
- APP_VERSION 1.11.0 → 1.12.0
- sw.js VERSION shivao-v1.11.0 → shivao-v1.12.0
- mobile/package.json + build.gradle (versionCode 32→33)
- LATEST_APK_URL atualizado pro release v1.12.0

Fix gitignore:
- .env.example em pastas nested (server/.env.example) estava bloqueado
  por **/.env.* — adicionado !**/.env.example pra liberar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 18:34:02 -03:00
..
public feat(iot): controle Smart Life/Tuya — Casa do Barco v1.12.0 2026-05-10 18:34:02 -03:00
src feat(iot): controle Smart Life/Tuya — Casa do Barco v1.12.0 2026-05-10 18:34:02 -03:00
.env.example feat(iot): controle Smart Life/Tuya — Casa do Barco v1.12.0 2026-05-10 18:34:02 -03:00
.gitignore chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
docker-compose.yml chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
Dockerfile chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00
package-lock.json feat(sync): WebSocket realtime + auto-push/pull entre PC e celular v1.5.0 2026-04-28 06:51:35 -03:00
package.json feat(sync): WebSocket realtime + auto-push/pull entre PC e celular v1.5.0 2026-04-28 06:51:35 -03:00
README.md chore: initial commit + security hardening (4 runs squad shivao-melhoria) 2026-04-27 13:24:08 -03:00

Shivao Cloud

Backend para o Diário de Bordo do Shivao com:

  • ☁️ Sincronização dos dados na nuvem (multi-dispositivo)
  • 📷 Mídia (fotos, áudios, vídeos) armazenada no servidor
  • 🚨 Notificações automáticas (Telegram, e-mail, SMS, WhatsApp, ntfy, webhook) — sem precisar tocar em botão
  • 🛡️ Dead-man switch: se o celular perde sinal/bateria enquanto fundeado, o servidor mesmo dispara o alarme

Deploy no Coolify (passo a passo)

1. Subir o código para um repositório Git

Crie um repo no GitHub/GitLab e envie esta pasta. Ou use o "Public Repository" do Coolify direto.

2. No painel Coolify

  1. + New ResourceApplicationPublic/Private Repository
  2. Cole a URL do seu repositório
  3. Build Pack: Dockerfile
  4. Port: 3000
  5. Domain: configure seu domínio (ex: shivao.seu-dominio.com) — Coolify gera SSL automático

3. Variáveis de ambiente

Em Environment Variables no Coolify, adicione (mínimo):

Variável Valor
BOAT_TOKEN string aleatória longa (ex: openssl rand -hex 32)
TELEGRAM_BOT_TOKEN seu token do BotFather
TELEGRAM_CHAT_IDS seu chat ID

Veja .env.example para todas as opções (e-mail, SMS, etc.). Configure pelo menos um canal.

4. Volume persistente

Em StoragesPersistent Storage:

  • Name: shivao-data
  • Mount Path: /data

Sem isso, ao reiniciar o container você perde o banco e as mídias.

5. Deploy

Clique em Deploy. Aguarde o build. Acesse https://shivao.seu-dominio.com — vai aparecer o app.


Configurando o Telegram (5 minutos, recomendado)

  1. No Telegram, fale com @BotFather/newbot
  2. Escolha um nome e username → ele dá um token
  3. Inicie uma conversa com o bot que você criou (mande qualquer mensagem)
  4. Acesse https://api.telegram.org/bot<SEU_TOKEN>/getUpdates no navegador
  5. No JSON, procure "chat":{"id":123456789...} — esse é seu TELEGRAM_CHAT_IDS
  6. Cole no Coolify e redeploy

Para receber em grupo: adicione o bot ao grupo, mande uma mensagem, repita o passo 4 (chat ID será negativo).


Configurando ntfy.sh (sem cadastro, push grátis)

  1. Instale o app ntfy (Android / iOS)
  2. No app, Subscribe → invente um tópico único e secreto (ex: shivao-aljg29x71kqp)
  3. Coloque esse mesmo nome em NTFY_TOPIC no Coolify

⚠️ Como ntfy é público, qualquer pessoa que adivinhe o tópico vê suas notificações. Use algo aleatório e longo.


Configurando E-mail SMTP

Gmail (mais comum):

  1. Ative verificação em 2 etapas na conta Google
  2. Vá em Senhas de app
  3. Gere uma senha → use ela em SMTP_PASS
  4. Configure:
    SMTP_HOST=smtp.gmail.com
    SMTP_PORT=587
    SMTP_SECURE=false
    SMTP_USER=seu-email@gmail.com
    SMTP_PASS=senha-de-app-de-16-caracteres
    SMTP_FROM=Shivao Alertas <seu-email@gmail.com>
    SMTP_TO=destinatario@email.com,outro@email.com
    

Resend, SendGrid, Mailgun: similar, basta seguir o painel deles e usar SMTP.


Configurando Twilio (SMS / WhatsApp — pago)

Apenas se quiser SMS ou WhatsApp realmente automático.

  1. Crie conta em twilio.com
  2. Para SMS: compre um número (Brasil custa ~$1/mês + $0.05 por SMS)
  3. Para WhatsApp: ative o sandbox grátis OU peça aprovação Business
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxx
TWILIO_FROM_NUMBER=+15551234567
TWILIO_SMS_TO=+5521999998888
TWILIO_WHATSAPP_FROM=whatsapp:+14155238886
TWILIO_WHATSAPP_TO=whatsapp:+5521999998888

Como funciona o Dead-Man Switch

  1. Quando você toca em "Fundear" no app, ele avisa o servidor
  2. Enquanto a vigia está ativa, o app envia um heartbeat a cada 30 segundos: "estou vivo, GPS aqui"
  3. Se o servidor não receber heartbeat por 5 minutos (HEARTBEAT_TIMEOUT_SEC configurável), ele assume que algo deu errado (celular morreu, perdeu sinal, app fechou) e dispara o alarme remoto automaticamente para todos os contatos
  4. Quando você levanta âncora normalmente, o app avisa o servidor para parar a vigia

Isso garante que mesmo se você dormir e o celular morrer, alguém vai ser avisado.


Endpoints da API (referência)

Todas requerem header Authorization: Bearer <BOAT_TOKEN> (exceto /api/health).

Método Rota Função
GET /api/health Status público
GET /api/info Canais configurados
GET /api/data Baixar todo o estado
POST /api/data Enviar todo o estado
POST /api/media Upload de arquivo (multipart)
GET /api/media/list Lista de mídias
GET /api/media/:id Baixar mídia
DELETE /api/media/:id Apagar mídia
POST /api/anchor/start Iniciar vigia no servidor
POST /api/anchor/heartbeat Manter vivo
POST /api/anchor/alarm Disparar alarme imediato
POST /api/anchor/stop Encerrar vigia
GET /api/anchor/status Estado atual
POST /api/test Disparar mensagem de teste
GET /api/alarms Histórico de alarmes
POST /api/share/create Criar link público temporário
GET /api/share/list Listar shares ativos
DELETE /api/share/:token Revogar share
POST /api/share/position Postar posição (boat → server)
GET /share/:token Página pública do link (sem auth)
GET /api/share/:token/info Info do share (público)
GET /api/share/:token/positions Posições do share (público)

Rodando localmente (dev)

cp .env.example .env
# edite .env
npm install
npm start

Ou com Docker:

docker compose up --build

Acesse http://localhost:3000


Conectando o app

No app (Diário de Bordo), vá em Arquivo → Configurações da Nuvem, preencha:

  • Servidor: https://shivao.seu-dominio.com
  • Token: o mesmo BOAT_TOKEN que você definiu

Toque em Testar conexão → deve receber a mensagem de teste em todos os canais configurados.

A partir daí o app sincroniza automaticamente.