# Integração da Galeria com o Servidor de Licenças & Updates

Este guia explica como configurar o projeto Galeria-ALPR (cliente final) para falar com o backend de licenças e distribuição de updates.

## 1. Pré-requisitos

- URL pública do servidor (ex.: `https://licencas.suaempresa.com`).
- Porta exposta: 5188 (ou a que definiu no `.env`).
- Uma licença válida criada via painel ou `POST /api/license/register`.

## 2. Configuração no Cliente (Galeria)

Defina estas variáveis no seu app (respeite maiúsculas/minúsculas e inclua os três segmentos da versão):

```env
GALERIA_API_BASE=https://licencas.suaempresa.com
GALERIA_CHANNEL=stable   # ou beta
DEVICE_ID=<fingerprint único do dispositivo>
LICENSE_KEY=<key recebida>
GALERIA_VERSION=1.0.0    # use semver completo (major.minor.patch)
GALERIA_UPDATER_PORT=3021 # porta usada pelo updater-service local
```

O `DEVICE_ID` pode ser um UUID gerado a partir de hardware ou um identificador persistido.

## 3. Fluxo de Licenciamento

### 3.1 Ativação

```http
POST /api/license/activate
Content-Type: application/json

{ "key": "GAL-XXXX-XXXX-XXXX", "deviceId": "pc-12345" }
```

Resposta:

```json
{
  "valid": true,
  "level": "standard",
  "expiresAt": "2025-01-01T00:00:00.000Z",
  "features": ["core-search"],
  "jwt": "<token>"
}
```

Guarde o `jwt` localmente para chamadas autenticadas futuras (se necessário).

### 3.2 Heartbeat / Validação

Periodicamente (ex.: a cada 6h) faça:

```
GET /api/license/heartbeat?key=GAL-...&deviceId=pc-12345
```

ou

```
GET /api/license/validate?key=...&deviceId=...
```

Isto garante que licenças revogadas/expiradas sejam detectadas.

## 4. Fluxo de Updates

### 4.1 Verificar Atualização

```
GET /api/update/check?version=1.0.0&channel=stable&key=GAL-...
```

O parâmetro `channel` é opcional e serve apenas como metadado; o servidor compara sempre com a versão ativa mais recente. Se `updateAvailable` for `true`, use os dados retornados:

```json
{
  "updateAvailable": true,
  "version": "1.2.0",
  "changelog": "Correções",
  "updateUrl": "/downloads/1.2.0.zip",
  "sha256": "abc123...",
  "signature": "..."
}
```

### 4.2 Download e Instalação

- Baixe `updateUrl` (concatene com `GALERIA_API_BASE` caso seja um caminho relativo).
- Verifique o SHA256 comparando com `sha256`.
- Extraia o ZIP para a pasta de instalação (o servidor já garante que o ZIP contém apenas os arquivos necessários).

Opcionalmente, consulte `GET /api/update/manifest` para obter as últimas versões assinadas.

### 4.3 Aplicar Update via updater-service

O cliente inclui um serviço local dedicado (`apps/updater-service`) escutando na porta `GALERIA_UPDATER_PORT` (padrão 3021). O backend proxy expõe dois endpoints:

- `POST /api/system/update/install` → encaminha para `http://127.0.0.1:3021/install`
- `GET /api/system/update/status/:jobId` → consulta o progresso do job

Exemplo de payload enviado para `/install`:

```json
{
  "downloadUrl": "/downloads/1.2.0.zip",
  "serverBaseUrl": "https://licencas.suaempresa.com",
  "licenseKey": "GAL-XXXX-XXXX-XXXX",
  "deviceId": "pc-12345",
  "channel": "beta",
  "version": "1.2.0",
  "sha256": "<hash opcional>",
  "jwt": "<token opcional>"
}
```

O serviço devolve `202 Accepted` com `{ "jobId": "<uuid>" }`. Consulte o mesmo `jobId` em `/api/system/update/status/<jobId>` para obter `status` (`pending | running | completed | failed`), `progress` (0-100) e `stage`. A UI acompanha esta resposta e recarrega quando o job conclui.

> Importante: os pacotes ZIP não devem conter `gallery/`, `uploads/`, `logs/` ou outros diretórios de dados do cliente. Apenas artefatos (backend/alpr/frontend/updater/scripts) devem ser publicados; o updater preserva automaticamente os dados locais e ignora diretórios protegidos.

Scripts úteis:

- `start-alpr.ps1/.sh`: inicia backend, alpr-service, frontend-server (quando permitido) e updater.
- `stop-galeria.ps1/.sh`: interrompe backend/alpr/frontend, mantendo o updater vivo para permitir autoupdates.
- `stop-updater.ps1/.sh`: encerra apenas o updater-service quando for necessário desligá-lo manualmente.

## 5. Tratamento de Erros

- `401/403`: credenciais inválidas (verifique `key` ou `DEVICE_ID`).
- `409` em `/update/publish`: hash duplicado (no caso do admin publicar).
- `429`: limite de rate atingido; aguarde antes de repetir.

## 6. Boas Práticas

- Cacheie o resultado de `/api/license/activate` para uso offline, mas force revalidação regular.
- Sempre verifique o hash do ZIP antes de instalar.
- Registre logs locais das interações (sucesso/erro) para suporte.
- Em ambientes com vários canais (beta/stable), permita que o cliente defina `GALERIA_CHANNEL`.

## 7. Recursos Úteis

- Painel Admin: `http://<host>:5189` (login com email/password).
- Endpoints principais: ver `server/README.md`.
- Scripts de arranque rápido: `./start-dev.sh` ou `pwsh ./start-dev.ps1`.

Com isso, a Galeria consegue autenticar licenças, validar dispositivos e manter-se atualizada com o servidor Galeria-ALPR.
