JamesProduto · Funcionalidades · Desenvolvimento
Repositório

feature · observed

Notificações

Alertas persistidos no banco, filtráveis no painel e distribuídos opcionalmente por Telegram e e-mail.

O que o módulo entrega

Notificações é a camada de comunicação do James. Ela transforma eventos de finanças, automações, importações e rotinas em mensagens com título, nível, detalhes e uma ação que leva de volta ao sistema.

Os fluxos automáticos persistem suas notificações no banco de dados. GeneralNotification faz isso quando database está presente em channels; Telegram e e-mail são canais complementares e podem estar desabilitados sem impedir o registro interno quando ele foi solicitado.

Diagram Design · Mermaid · arraste para mover · Ctrl/⌘ + scroll para zoom

100%Abrir inteiro ↗

Renderizando diagrama declarativo…

Legenda
  • Etapa
  • Decisão
  • Resultado
  • Conexão
Leitura semântica

Eventos do sistema passam por GeneralNotification e pelo pipeline de canais. O banco é o canal interno; Telegram e e-mail são opcionais conforme a configuração.

Fonte declarativa: diagrams/sources/notifications-flow.mmd

Contrato de uma notificação

GeneralNotification recebe um payload estável:

PHP
new GeneralNotification(
    title: 'Título curto',
    message: 'Explicação do que aconteceu.',
    actionUrl: route('financial.dashboard'),
    level: NotificationLevel::Warning,
    details: ['Valor' => 'R$ 150,00'],
    channels: ['database', 'telegram', 'mail'],
    actionLabel: 'Abrir painel',
    items: [],
)
CampoUso
titleTítulo exibido no painel, e-mail e Telegram.
messageTexto principal da ocorrência.
action_urlLink opcional para a tela relacionada.
action_labelTexto do botão da ação.
levelinfo, success, warning ou danger.
detailsMapa chave/valor para metadados legíveis.
itemsLista de itens com descrição, quantidade, preço unitário e total.
channelsCanais desejados para GeneralNotification.

As notificações específicas de vencimentos e resumo financeiro usam payloads adicionais (due_alert e financial_summary) para renderizar blocos estruturados na interface e nas mensagens externas.

Níveis

CaseValorUso visual
NotificationLevel::InfoinfoInformação ou conclusão sem alerta.
NotificationLevel::SuccesssuccessOperação concluída com êxito.
NotificationLevel::WarningwarningPrazo, pendência ou atenção necessária.
NotificationLevel::DangerdangerErro, falha ou risco financeiro.

Cada nível fornece rótulo, cor e ícone Heroicon. No e-mail, o nível Danger usa o estilo de erro do Laravel Mail; no Telegram, o nível aparece em caixa alta no cabeçalho.

De onde as notificações vêm

Alertas de vencimentos

O comando finance:due-today-alerts procura itens para hoje e amanhã em três fontes:

  • transações pendentes ou efetivadas que se enquadram no período;
  • faturas de cartão não pagas com vencimento no período;
  • recorrências ativas ainda não materializadas, sem duplicar as recorrências já representadas pela fatura do cartão.

O alerta consolida quantidade, receitas, despesas, impacto líquido e a lista de dias/itens. Ele não é enviado quando não há itens. Um cache por usuário impede reenvio do mesmo dia; --force permite reenviar manualmente.

Resumo financeiro mensal

O comando finance:monthly-digest calcula o mês anterior e compara receitas, despesas e resultado com o mês anterior a ele. O resumo inclui:

  • receitas, despesas e resultado do período;
  • variações em relação ao período comparado;
  • saldo atual das contas;
  • compromissos pendentes;
  • saldo líquido;
  • distribuição por categorias de receita e despesa.

O envio mensal também usa uma chave de cache por usuário e período. --force permite repetir o resumo quando necessário.

Rotinas e importação de NFC-e

O processamento de recorrências, a rolagem de faturas e outras automações usam GeneralNotification para informar sucesso ou falha. A importação assíncrona de NFC-e envia uma notificação com ação para abrir o rascunho ou tentar novamente. Consulte Rotinas automáticas e Importação de NFC-e.

Canais de entrega

Banco de dados

É o canal interno e alimenta /notifications. O JSON persistido contém o payload da notificação e permite renderizar detalhes, itens, nível e ação sem depender do canal externo.

Telegram

O canal é usado somente quando TELEGRAM_BOT_TOKEN e TELEGRAM_CHAT_ID estão preenchidos. A mensagem inclui título, texto, detalhes, itens e botão de ação quando a URL é externa.

Se a URL aponta para localhost ou 127.0.0.1, o James não cria um botão inline inválido para a API do Telegram; ele coloca o endereço como texto seguro na mensagem.

E-mail

O e-mail exige destinatário com endereço preenchido e NOTIFICATIONS_MAIL_ENABLED=true. A mensagem usa os templates transacionais do Laravel, inclui detalhes e itens e adiciona um botão quando existe actionUrl.

Filas

GeneralNotification, DueTodayNotification e FinancialSummaryNotification implementam ShouldQueue. Em produção, o worker precisa estar ativo para que as notificações queued sejam processadas. O registro no banco, o envio externo e a disponibilidade da fila devem ser tratados como partes distintas do fluxo.

Central /notifications

O painel autenticado permite:

  • pesquisar no payload JSON da notificação;
  • filtrar por unread ou read;
  • filtrar por data inicial e final;
  • ordenar do mais novo para o mais antigo ou vice-versa;
  • navegar por páginas de 20 registros;
  • abrir uma notificação, marcando-a como lida;
  • marcar todas as notificações como lidas;
  • excluir uma notificação individual.

O contador da sidebar e o cartão do Dashboard usam somente notificações não lidas. A tela de detalhes verifica se a notificação pertence ao usuário autenticado antes de exibi-la ou alterá-la.

Exemplos para desenvolvimento

Notificação somente interna

PHP
use App\Notifications\GeneralNotification;

$user->notify(new GeneralNotification(
    title: 'Rascunho pronto',
    message: 'A NFC-e foi importada e aguarda revisão.',
    actionUrl: route('financial.transactions.edit', $transaction),
    channels: ['database'],
));

Notificação com itens

PHP
$user->notify(new GeneralNotification(
    title: 'Importação concluída',
    message: 'Revise os itens antes de efetivar a transação.',
    details: ['Emitente' => 'Comércio exemplo', 'Total' => 'R$ 120,00'],
    items: [
        ['description' => 'Produto', 'quantity' => '2', 'unit_price' => 'R$ 60,00', 'total' => 'R$ 120,00'],
    ],
));

Nos testes, use Notification::fake() e faça asserções por destinatário, classe, nível, título e payload. O projeto mantém testes de unidade para os três formatos de notificação e testes de feature para a central web.

Referências