# ALGORITMO COMPLETO: NOTIFICAÇÕES FIREBASE FCM - PONTA A PONTA

## FASE 1: SETUP INICIAL (uma vez só)

### 1.1 Frontend Setup
```
QUANDO usuário acessa qualquer página do sistema:
  SE navegador suporta notificações:
    SOLICITAR permissão para notificações
    SE permissão = 'granted':
      REGISTRAR service worker (/firebase-messaging-sw.js)
      OBTER token FCM usando VAPID key
      ENVIAR token para backend via POST /api/register-token
      SALVAR token no localStorage (opcional)
    SENÃO:
      LOGAR "Permissão negada"
```

### 1.2 Backend Setup
```
CRIAR tabela user_tokens:
  - id (int, primary key)
  - user_id (int, foreign key)
  - fcm_token (varchar 255)
  - device_type (enum: 'web', 'android')
  - created_at (timestamp)
  - is_active (boolean, default true)

INSTALAR Firebase Admin SDK
CONFIGURAR service account JSON (chave privada Firebase)
```

## FASE 2: REGISTRO DE TOKENS

### 2.1 Endpoint: POST /api/register-token
```
RECEBER requisição:
  - user_id (do session/JWT)
  - fcm_token (do frontend)
  - device_type = 'web'

VALIDAR:
  SE user_id é válido E fcm_token não é vazio:
    VERIFICAR se token já existe para este usuário
    SE existe:
      ATUALIZAR timestamp (updated_at = NOW())
    SENÃO:
      INSERIR novo registro na tabela user_tokens
    RETORNAR success: true
  SENÃO:
    RETORNAR error: "Dados inválidos"
```

## FASE 3: DETECÇÃO DE EVENTOS (dispositivos GPS)

### 3.1 Monitor de Eventos
```
LOOP infinito nos dispositivos GPS:
  PARA cada veículo monitorado:
    LER posição atual (lat, lng, timestamp)
    CALCULAR velocidade
    VERIFICAR regras de negócio:

      SE velocidade = 0 POR MAIS DE 30 minutos:
        DISPARAR evento "VEICULO_PARADO"
        CHAMAR backend: POST /api/notify-event

      SE velocidade > limite_permitido:
        DISPARAR evento "EXCESSO_VELOCIDADE"
        CHAMAR backend: POST /api/notify-event

      SE saiu da área permitida (geofence):
        DISPARAR evento "FORA_AREA"
        CHAMAR backend: POST /api/notify-event

      SE não comunica POR MAIS DE 60 minutos:
        DISPARAR evento "SEM_COMUNICACAO"
        CHAMAR backend: POST /api/notify-event

  AGUARDAR 30 segundos
  REPETIR
```

## FASE 4: PROCESSAMENTO DE EVENTOS

### 4.1 Endpoint: POST /api/notify-event
```
RECEBER dados do dispositivo:
  - veiculo_id
  - evento_tipo ("VEICULO_PARADO", "EXCESSO_VELOCIDADE", etc.)
  - timestamp
  - dados_extras (velocidade, posição, etc.)

PROCESSAR evento:
  BUSCAR veículo na tabela veiculos WHERE id = veiculo_id
  BUSCAR usuários que monitoram este veículo:
    SELECT user_id FROM veiculo_usuarios WHERE veiculo_id = veiculo_id

  PARA cada user_id encontrado:
    BUSCAR tokens ativos:
      SELECT fcm_token FROM user_tokens
      WHERE user_id = user_id AND is_active = true

    PARA cada token:
      CHAMAR função enviar_notificacao(token, evento)
```

### 4.2 Função: enviar_notificacao(token, evento)
```
MONTAR mensagem baseada no tipo de evento:

  SE evento_tipo = "VEICULO_PARADO":
    titulo = "Veículo Parado"
    corpo = "Placa {placa} está parado há {tempo}"
    click_action = "/crivo/localiza-mobile/pages/mapa.html?veiculo={id}"

  SE evento_tipo = "EXCESSO_VELOCIDADE":
    titulo = "Excesso de Velocidade"
    corpo = "Placa {placa} a {velocidade}km/h (limite: {limite}km/h)"

  SE evento_tipo = "FORA_AREA":
    titulo = "Fora da Área"
    corpo = "Placa {placa} saiu da área permitida"

  SE evento_tipo = "SEM_COMUNICACAO":
    titulo = "Sem Comunicação"
    corpo = "Placa {placa} sem sinal há {tempo}"

ENVIAR via Firebase Admin SDK:
  firebase_admin.messaging.send({
    token: token,
    notification: {
      title: titulo,
      body: corpo,
      icon: "/crivo/localiza-mobile/img/localiza-logo.png"
    },
    data: {
      veiculo_id: veiculo_id,
      evento_tipo: evento_tipo,
      click_action: click_action
    }
  })

LOGAR resultado (sucesso/erro)
SE erro de token inválido:
  MARCAR token como inativo (is_active = false)
```

## FASE 5: RECEBIMENTO NO FRONTEND

### 5.1 Notificação em Foreground (usuário na página)
```
QUANDO onMessage dispara:
  RECEBER payload da notificação
  EXIBIR notificação nativa do browser:
    new Notification(payload.notification.title, {
      body: payload.notification.body,
      icon: payload.notification.icon,
      data: payload.data
    })

  SE payload.data.click_action existe:
    PREPARAR redirecionamento para clique
```

### 5.2 Notificação em Background (service worker)
```
QUANDO onBackgroundMessage dispara:
  RECEBER payload
  EXIBIR notificação via service worker:
    self.registration.showNotification(titulo, opcoes)

QUANDO usuário clica na notificação:
  FECHAR notificação
  SE click_action especificado:
    ABRIR ou FOCAR aba com a URL
  SENÃO:
    ABRIR página padrão (/pages/mapa.html)
```

## FASE 6: MANUTENÇÃO E LIMPEZA

### 6.1 Limpeza de Tokens Inativos
```
EXECUTAR diariamente (cron job):
  DELETE FROM user_tokens
  WHERE is_active = false
  AND updated_at < (NOW() - INTERVAL 30 DAY)
```

### 6.2 Teste de Tokens Ativos
```
EXECUTAR semanalmente:
  PARA cada token em user_tokens WHERE is_active = true:
    TENTAR enviar notificação de teste
    SE falha (token inválido):
      MARCAR is_active = false
```

## ENDPOINTS NECESSÁRIOS

### Frontend → Backend
- POST /api/register-token - registra token FCM do usuário
- GET /api/user/notifications - histórico de notificações (opcional)

### Dispositivo GPS → Backend
- POST /api/notify-event - evento detectado pelo dispositivo
- POST /api/heartbeat - dispositivo informa que está ativo (opcional)

### Admin/Teste
- POST /api/send-test-notification - enviar notificação de teste
- GET /api/tokens/active - listar tokens ativos

## TECNOLOGIAS NECESSÁRIAS

### Frontend (já implementado)
- Firebase JS SDK v12.3.0
- Service Worker (/firebase-messaging-sw.js)
- VAPID public key

### Backend
- Firebase Admin SDK (Node.js/Python/Java)
- Service Account JSON (chave privada)
- Banco de dados (MySQL/PostgreSQL)
- HTTP server (Express.js/FastAPI/Spring)

### Dispositivos GPS
- HTTP client para chamar APIs
- Timer/scheduler para monitoramento contínuo
- Lógica de regras de negócio (geofence, velocidade, etc.)

## EXEMPLO DE TESTE COMPLETO

```
1. ABRIR http://localhost/crivo/localiza-mobile/pages/mapa.html
2. ACEITAR permissão de notificação
3. VERIFICAR token no console do DevTools
4. SIMULAR evento do dispositivo:
   POST /api/notify-event {
     "veiculo_id": 123,
     "evento_tipo": "VEICULO_PARADO",
     "timestamp": "2025-09-30T10:00:00Z"
   }
5. VERIFICAR notificação aparece no browser
6. CLICAR na notificação → redireciona para página correta
```