# 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 Resource** → **Application** → **Public/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 **Storages** → **Persistent 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](https://t.me/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](https://play.google.com/store/apps/details?id=io.heckel.ntfy) / [iOS](https://apps.apple.com/us/app/ntfy/id1625396347))
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](https://myaccount.google.com/apppasswords)
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](https://www.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)

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

Ou com Docker:

```bash
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.
