ligbox-ops-platform/specs/007-mobile-push-notifications/spec.md
Ligbox Spec Hub 3a2c64834b Initial import: ligbox-ops-platform + specs + LAPTOP + obsidian merge (CT130)
Source: VM122 /opt + obsidian-infra + LAPTOP
Hub: CT130 spec-hub 10.10.10.130
2026-06-19 17:26:41 +00:00

8.8 KiB

Feature Specification: Push Mobile & Web — Ligbox Ops (007)

Criado: 2026-06-10
Solicitado por: Roger
Status: 📋 Draft — pronta para plano
Prioridade: P1
Depende de: Spec 003 (auth), Spec 004 (contas / ntfy OTP)
API alvo: 0.9.0-desk-push (futuro)


Resumo

Sistema de notificações push para a equipe Ligbox Ops (técnicos, NOC, ops lead) a partir do Ligbox Ops Desk (desk.ligbox.com.br), complementando e-mail e UI web.

Contexto atual (Spec 004): push ntfy por tópico na ativação de conta (OTP). Usuário inscreve manualmente no app ntfy. Não há push integrado ao login nem alertas operacionais (tickets, Wazuh).

Objetivo Spec 007: evoluir para push por usuário autenticado, com eventos operacionais relevantes, começando pelo caminho mais simples e escalável.


Decisões propostas (Roger — validar no plano)

Ponto Proposta MVP Evolução
Público Usuários Desk logados (technician, noc, ops_lead, super_admin) Clientes finais — fora de escopo
MVP Fase A ntfy por usuário — tópico único por desk_users.username + opt-in em Minha conta Já temos infra parcial
MVP Fase B Web Push (PWA) — Service Worker + VAPID no Desk Android Chrome + iOS Safari 16.4+
App nativo Fora do MVP FCM/APNs via React Native / Flutter
Servidor push ntfy.sh público (Fase A) · VAPID self-hosted VM122 (Fase B) FCM unificado depois
Idioma pt-BR

Recomendação técnica (base Kimi + Ligbox)

Cenário Tecnologia Quando usar
Equipe ops, web Desk ntfy + Web Push PWA Agora — baixo custo, sem app store
App nativo futuro Firebase Cloud Messaging (FCM) Se houver app RN/Flutter
WebView embrulhando site Bridge nativo + FCM Não recomendado

Por que não só ntfy: Spec 004 usa tópico de ativação efêmero. Spec 007 amarra push ao usuário logado e dispara em eventos do Desk (ticket novo, Wazuh ≥10, pedido cadastro).

Por que Web Push depois: permite notificação mesmo sem app ntfy instalado, direto no browser (PWA instalado ou Safari iOS).


Eventos push (prioridade)

Evento Quem recebe Prioridade ntfy Fase
Novo ticket Wazuh (level ≥10) noc, ops_lead, super_admin high A
Novo pedido cadastro Desk super_admin default A
Ticket atribuído a mim usuário assignee default A
OTP ativação / senha candidato (fluxo 004) high já existe
Funil onboarding travado ops_lead low B
Audit scorecard crítico ops_lead default B

Arquitetura alvo

flowchart LR
    subgraph VM122
        API[Ligbox Ops API]
        SW[Service Worker PWA]
    end
    subgraph Clientes
        WEB[Desk browser]
        NTFY[App ntfy Android/iOS]
    end
    subgraph Push
        NTFYS[ntfy.sh]
        WEBPUSH[Web Push VAPID]
    end
    WEB --> API
    WEB --> SW
    API -->|POST tópico| NTFYS
    API -->|sendNotification| WEBPUSH
    NTFYS --> NTFY
    WEBPUSH --> WEB

Fluxo Fase A — ntfy por usuário

  1. Usuário logado abre Minha conta → ativa push ntfy
  2. API gera/recupera ntfy_topic estável: ligbox-desk-{hash(username)}
  3. UI exibe link https://ntfy.sh/{topic} + QR para app ntfy
  4. Backend grava push_ntfy_enabled = 1 em desk_users
  5. Em evento (ex.: ticket Wazuh), worker/API faz POST ntfy.sh/{topic}

Fluxo Fase B — Web Push PWA

  1. Usuário aceita permissão de notificação no browser
  2. Service Worker registra PushSubscription (endpoint + keys)
  3. Frontend envia subscription para POST /api/v1/push/subscribe
  4. Backend persiste em push_subscriptions
  5. Em evento, API envia via biblioteca pywebpush (VAPID)

Data model (novo)

desk_users (alteração)

Campo Tipo Uso
ntfy_topic TEXT Tópico estável por usuário (migrar de só registration)
push_ntfy_enabled INTEGER 1 se opt-in ntfy
push_web_enabled INTEGER 1 se tem subscription Web Push ativa

push_subscriptions (nova)

CREATE TABLE push_subscriptions (
  id INTEGER PRIMARY KEY,
  username TEXT NOT NULL,
  platform TEXT NOT NULL,       -- 'webpush' | 'fcm' (futuro)
  endpoint TEXT NOT NULL,       -- URL Web Push ou FCM token
  auth_keys TEXT,               -- JSON: p256dh, auth (webpush)
  user_agent TEXT,
  created_at TEXT NOT NULL,
  last_used_at TEXT,
  active INTEGER NOT NULL DEFAULT 1,
  UNIQUE(username, endpoint)
);

API proposta (v0.9)

Método Endpoint Auth Descrição
GET /api/v1/push/settings JWT Estado push do usuário + tópico ntfy
POST /api/v1/push/ntfy/enable JWT Gera tópico + opt-in
POST /api/v1/push/ntfy/disable JWT Opt-out
POST /api/v1/push/subscribe JWT Registra Web Push subscription
DELETE /api/v1/push/subscribe/{id} JWT Remove subscription
POST /api/v1/push/test JWT Notificação teste (só próprio user)

Interno (worker / hooks):

push_service.notify_user(username, title, body, priority="default", url="/tickets/123")
push_service.notify_role("noc", title, body, ...)

UI proposta

Minha conta (extensão Spec 004)

Nova seção Notificações push:

Bloco Conteúdo
ntfy (app) Toggle ativar · link tópico · QR · instruções Android/iOS
Browser (PWA) Botão «Ativar notificações neste dispositivo» · status permissão
Teste «Enviar notificação teste»

PWA mínimo

  • manifest.json (nome, ícone, start_url, display: standalone)
  • Service Worker sw.js — push + click abre URL do ticket
  • Registro SW em index.html boot

Comparativo de canais (referência Kimi)

Canal Android iOS Esforço Custo Ligbox
ntfy app Baixo Grátis (ntfy.sh)
Web Push PWA Chrome Safari 16.4+ Médio Grátis (VAPID)
FCM Alto (app/SDK) Grátis
OneSignal Médio Free tier 10k
SMS Alto Pago

MVP Ligbox: ntfy (Fase A) → Web Push PWA (Fase B). FCM quando existir app nativo.


User stories

US1 — Opt-in push ntfy (P1)

Como técnico, quero ativar push no app ntfy a partir de Minha conta para receber alertas sem ficar olhando o Desk.

Aceite:

  • Toggle em Minha conta gera tópico estável
  • Link + QR funcionam
  • Teste push chega no celular em <30s

US2 — Alerta ticket Wazuh (P1)

Como NOC, quero push quando ticket Wazuh crítico for criado.

Aceite:

  • Evento webhook Wazuh → push para roles noc, ops_lead, super_admin com opt-in
  • Título/body pt-BR · link abre ticket no Desk

US3 — Web Push browser (P2)

Como ops lead, quero notificação no browser (PWA) sem instalar ntfy.

Aceite:

  • Permissão browser · subscription salva
  • Push recebido com Desk aberto ou em background (SW)
  • Click na notificação abre ticket

US4 — Preferências por tipo (P3 — futuro)

Como usuário, quero escolher quais eventos geram push (tickets / cadastro / audit).


Critérios de aceite MVP (Fase A)

  • Tópico ntfy por usuário autenticado (não só ativação)
  • UI opt-in/opt-out em Minha conta
  • Push teste via API/UI
  • Push automático: novo ticket Wazuh ≥10
  • Push automático: pedido cadastro → root
  • Mensagens pt-BR
  • Documentação quickstart

Fora de escopo (007)

  • App nativo iOS/Android (Spec futura)
  • FCM / APNs direto
  • Push para clientes finais (portal onboard)
  • SMS como canal push
  • ntfy self-hosted (avaliar depois; hoje ntfy.sh)

Riscos e mitigação

Risco Mitigação
ntfy.sh indisponível Log falha; e-mail continua; Fase B Web Push
iOS sem PWA instalado Instruir instalar ntfy ou «Adicionar à tela inicial»
Spam de push Rate limit por usuário; prioridades
Tópico ntfy adivinhável Hash username + secret server-side

Referências

  • Spec 004 — ntfy OTP (api/app/ntfy_notify.py)
  • Pesquisa Kimi Code — Web Push, FCM, arquitetura push (2026-06-10)
  • Web Push API (MDN)
  • ntfy.sh docs
  • specs/007-mobile-push-notifications/tasks.md
  • specs/007-mobile-push-notifications/quickstart.md

Fases de entrega

Fase Entrega Versão API
A ntfy por usuário + eventos Wazuh/cadastro 0.9.0-push-ntfy
B Web Push PWA + manifest + SW 0.9.1-push-pwa
C Preferências + FCM (se app nativo) 0.10+