# CONTRIBUTING — Guia para devs

## Setup inicial

### Requisitos
- Node.js 20+
- npm
- (Opcional) Docker para teste do build de produção

### Rodando o backend localmente

```bash
cd server
cp .env.example .env
# Edite .env com seus valores (BOAT_TOKEN obrigatório)
npm install
npm start
```

Acesse `http://localhost:3000`

Modo dev com auto-reload:
```bash
npm run dev
```

### Rodando o frontend localmente

O HTML é standalone — pode abrir direto no navegador (`file:///...`), mas
algumas APIs do navegador (Geolocation, Wake Lock, MediaRecorder) **só
funcionam em HTTPS ou localhost**.

Recomendado: deixar o backend servindo o frontend:

```bash
cd server
npm start
# Acesse http://localhost:3000 — o backend serve public/index.html
```

Para iterar em mudanças do frontend:
- Edite `app/diario-bordo.html`
- Copie para `server/public/index.html`
- Recarregue o navegador (sem necessidade de rebuild)

Script de copy útil (para macOS/Linux):
```bash
cp app/diario-bordo.html server/public/index.html
```

### Testando com Docker

```bash
cd server
docker compose up --build
```

Para testar o pipeline completo de produção (igual Coolify faria).

---

## Estrutura do código

### `app/diario-bordo.html`

Único arquivo HTML. Para navegar pelo código, use search:

| Comentário | Função |
|------------|--------|
| `============ STORAGE ============` | Persistência local |
| `============ GPS Math ============` | Haversine, conversões |
| `============ GPS Tracking ============` | Rastreio de viagem |
| `============ ANCHOR WATCH ============` | Vigia de fundeio |
| `============ ALARM ============` | Sistema de alarme |
| `============ CONTACTS ============` | Cadastro de contatos |
| `============ CLOUD SYNC ============` | Integração com servidor |
| `============ WEBHOOKS ============` | Telegram/Discord direto |
| `============ GEOFENCING / ZONES ============` | Zonas de proibição/atenção |
| `============ CHECKLISTS ============` | Listas de verificação |
| `============ GPX EXPORT ============` | Export GPX |
| `============ BATTERY SAVER ============` | Modo economia |
| `============ WEATHER ============` | Windy + Open-Meteo |

### `server/src/`

- `index.js` — entry point Express, todos os routes
- `db.js` — wrapper SQLite com queries prepared
- `notifications.js` — fan-out para todos os canais

---

## Convenções

### Estilo de código

- **Sem build step no frontend** — escrevemos JS direto que roda no navegador.
  Cuidado com features muito recentes (target ≥ Chrome 100, Safari 16).
- **Zero dependências runtime no frontend** exceto Leaflet e Google Fonts.
- Variáveis curtas em código compacto (ex: `r` para response, `c` para content).
  Trade-off de legibilidade x tamanho do arquivo.

### CSS

- Sistema de design baseado em variáveis CSS no `:root`
- Tipografia: 3 famílias (Fraunces, Manrope, JetBrains Mono)
- Paleta marítima editorial (ver ARCHITECTURE.md)
- Mobile-first, com `@media (min-width:560px)` para desktop

### Backend

- ESM modules (`"type": "module"`)
- `async/await` em vez de promises encadeadas
- Erros logados com `console.warn` ou `console.error`
- Status HTTP semânticos: 200 ok, 400 bad input, 401 unauth, 404 not found, 500 server

### Commits e branches

- `main` — sempre deployável
- Features em branches `feat/...`, fixes em `fix/...`
- PRs com descrição clara do que muda e por quê

---

## Como adicionar uma nova funcionalidade

### Exemplo: novo canal de notificação (Slack)

1. **Backend** — em `server/src/notifications.js`:
   ```js
   async function sendSlack(text) {
     const url = process.env.SLACK_WEBHOOK_URL;
     if (!url) return null;
     try {
       const r = await fetch(url, {
         method: 'POST',
         headers: { 'Content-Type': 'application/json' },
         body: JSON.stringify({ text })
       });
       return { ok: r.ok };
     } catch (e) {
       return { ok: false, error: e.message };
     }
   }
   ```

2. Adicionar ao `dispatchAlarm()`:
   ```js
   const tasks = [
     // ...existentes
     ['slack', sendSlack(text)]
   ];
   ```

3. Adicionar a `listConfiguredChannels()`:
   ```js
   if (env.SLACK_WEBHOOK_URL) channels.push('slack');
   ```

4. **Documentar** — adicionar `SLACK_WEBHOOK_URL=` no `.env.example`

5. **Testar** localmente:
   ```bash
   curl -X POST -H "Authorization: Bearer $TOKEN" \
        http://localhost:3000/api/test
   ```

### Exemplo: novo campo na viagem

1. **Frontend** — adicionar no modal de viagem (HTML)
2. Adicionar no `saveTrip()` — incluir no objeto data
3. Adicionar na renderização (`renderTrips`)
4. **Backup compatibility**: viagens antigas não terão o campo, lembre de
   tratar `undefined` graciosamente

Não precisa mudar o backend — a API guarda JSON arbitrário em `state.data`.

---

## Debugging

### Frontend

Abrir DevTools no Chrome (F12 ou ⌥⌘I). Console mostra:
- `[zone]` ao entrar/sair de zona
- `[deadman]` no servidor (acessível via `docker logs`)
- Erros de fetch sem CORS são típicos quando se acessa `file://` em vez de `http://localhost`

Application tab:
- `Local Storage` — ver todo o estado
- `IndexedDB > diario_bordo_db > media` — ver mídias

### Backend

```bash
# Logs em produção
docker logs <container>

# Em dev, vê no terminal direto

# Testar endpoint manualmente
curl -H "Authorization: Bearer abc..." http://localhost:3000/api/info
```

SQLite — abrir o `.db` direto:
```bash
sqlite3 server/data/shivao.db
> .tables
> SELECT * FROM alarm_log ORDER BY ts DESC LIMIT 10;
```

---

## Releases

Atualmente não há versionamento formal. Sugestão para o time:

1. Adicionar `version` em `package.json`
2. Tags Git para releases (`v1.0.0`)
3. Changelog (`CHANGELOG.md`) com mudanças por versão
4. Coolify: configurar para deploy automático apenas em tags (não em todo push)

---

## Boas práticas para o app de barco

Coisas a manter em mente ao desenvolver:

1. **Conectividade incerta**: o app é usado em alto-mar. Falhas de rede são
   normais. Tudo deve degradar graciosamente.

2. **Bateria é crítica**: cada feature que ativa GPS/CPU contínuo precisa
   ser justificada. Sempre considerar o impacto em bateria.

3. **Tela ao sol**: contraste alto, fontes grandes. A paleta atual já é
   bem legível ao sol.

4. **Mãos molhadas**: tap targets grandes (mínimo 44x44 px).

5. **Sob estresse**: alarmes, MOB, etc. devem ter UX MUITO simples — botões
   óbvios, pouco texto, ações irreversíveis sempre com confirmação.

6. **Dados são preciosos**: nunca apagar sem dupla confirmação. Backup é fácil
   (aba Arquivo).

7. **Single-handed sailing**: capitão pode estar sozinho no leme. Operação
   com uma mão deve ser viável onde possível.
