Skip to content

Comunicação e Notificações

Visão Geral

O módulo de Comunicação (Domain/Communication) oferece notificações in-app, mural de pedidos de oração em tempo real, alertas de aniversariantes e envio de e-mail em massa com templates.

Broadcasting: Laravel Reverb + Echo para atualizações em tempo real.

Notificações In-App

Infraestrutura

  • Tabela notifications — tabela nativa do Laravel (UUID) no banco do tenant
  • NotificationPreference — preferências por membro, canal (database/mail) e categoria (prayer/birthday/general/event)
  • HasDynamicChannels trait — permite que notificações respeitem as preferências do membro

Sino de Notificação (Header)

O componente NotificationBell fica no header e:

  • Mostra badge com contagem de não lidas
  • Dropdown com últimas 5 notificações ao clicar
  • Atualiza em tempo real via Echo (canal privado por user)
  • JSON endpoints: GET /notifications/unread-count, GET /notifications/latest

Página de Notificações

Rota: /notificationsPermissão: notification.view (todos os roles)

Lista paginada de notificações com marcar como lida individual ou todas.

Preferências

Rota: /notification-preferencesPermissão: notification.manage (todos os roles)

Grid de toggles: categorias (linhas) × canais (colunas). Rota de update via composite key: PATCH /notification-preferences/{channel}/{category}.

Feature Flag

notifications — habilitado para todos os planos.

Mural de Pedidos de Oração

Models

PrayerRequest (prayer_requests)

CampoTipoDescrição
ulidstring(26)Identificador público
member_idFK → membersQuem postou
contenttextConteúdo do pedido
is_anonymousbooleanPostou anonimamente
statusenumpending, approved, rejected
approved_byFK → usersModerador que aprovou
approved_attimestampData de aprovação

PrayerSupport (prayer_supports) — pivot "Estou orando"

CampoTipoDescrição
prayer_request_idFKPedido
member_idFKQuem está orando

Unique constraint: [prayer_request_id, member_id]

Fluxo

  1. Membro posta pedido (opcionalmente anônimo) → status pending
  2. Moderador aprova/rejeita
  3. Aprovação dispara broadcast PrayerRequestApproved → aparece no mural em tempo real
  4. Membros clicam "Estou orando" → toggle via TogglePrayerSupportAction → broadcast PrayerSupportUpdated

Throttle

Máximo 5 pedidos por dia por membro (PrayerRequestThrottledException).

Rotas

MétodoRotaAção
GET/prayer-wallLista aprovados + pendentes (moderador)
POST/prayer-wallCriar pedido
PATCH/prayer-wall/{ulid}/approveAprovar
PATCH/prayer-wall/{ulid}/rejectRejeitar
DELETE/prayer-wall/{ulid}Excluir (próprio ou moderador)
POST/prayer-wall/{ulid}/supportToggle "Estou orando"

Permissões

PermissãoRoles
prayer.viewmembro
prayer.createmembro
prayer.moderateadmin-igreja, admin-congregacao, lider-grupo

Feature Flag

prayer_wall — habilitado para todos os planos.

Aniversariantes

Lógica

Usa data_nascimento do Member. Query cross-DB compatível (SQLite para testes, MySQL para produção) via strftime/MONTH()+DAY().

Actions

  • GetBirthdayMembersAction — períodos: today, week, month
  • SendBirthdayNotificationsAction — notifica roles de liderança

Widget no Dashboard

Card "Aniversariantes da Semana" com avatar/iniciais, nome, data e idade.

Job Agendado

SendDailyBirthdayNotifications — diário às 07:00, itera todos os tenants com feature birthday_alerts.

Feature Flag

birthday_alerts — planos Crescimento e Expansão.

E-mail em Massa

Models

EmailTemplate (email_templates)

CampoTipoDescrição
ulidstring(26)Identificador público
namestringNome do template
slugstringSlug único
subject_templatestringAssunto com
body_templatetextBody com (NÃO Blade)
variablesjsonLista de variáveis disponíveis

5 templates pré-definidos (seed): Comunicado Geral, Convite para Evento, Aviso Importante, Boletim Semanal, Boas-vindas a Novo Membro.

MassEmail (mass_emails)

CampoTipoDescrição
ulidstring(26)Identificador público
email_template_idFKTemplate usado
subjectstringAssunto renderizado
bodytextConteúdo renderizado
filtersjsonCritérios de audiência
statusenumdraft, sending, sent, failed
total_recipientsintTotal destinatários
sent_count / failed_countintContadores

MassEmailRecipient (mass_email_recipients) — rastreio por destinatário.

Fluxo (Wizard 4 Steps)

  1. Selecionar template
  2. Preencher variáveis + assunto
  3. Selecionar audiência (grupos + filtros: sexo, idade, congregação, status)
  4. Preview + contagem → enviar

Audiência

ResolveAudienceAction aceita filtros com ULIDs (nunca IDs):

  • group_ulids — grupos
  • sexo — M/F
  • idade_min / idade_max — faixa etária
  • status_membro — situação na igreja

Queue

Bus::batch() com chunks de 50 recipients. Callbacks atualizam status do MassEmail.

Permissões

PermissãoRoles
mass_email.viewadmin-igreja, admin-congregacao, secretario
mass_email.createadmin-igreja, admin-congregacao, secretario
mass_email.manageadmin-igreja

Feature Flag

mass_email — planos Crescimento e Expansão.

Feature Trial (Painel Central)

Mudança no extra_features

O campo extra_features do Tenant evoluiu de array de strings para array de objetos com expiração opcional:

php
// Formato: [{'feature': 'mass_email', 'expires_at': '2026-04-15'}, ...]

Tenant::hasFeature() suporta ambos os formatos (backward compat).

Actions (Domain/Shared)

  • GrantFeatureTrialAction — ativa feature com ou sem data de expiração
  • RevokeFeatureAction — remove feature
  • CleanExpiredFeaturesAction — job diário às 00:30, remove trials vencidos

Painel Admin Central

RotaAção
GET /admin/tenants/{tenant}/featuresLista features do tenant
POST /admin/tenants/{tenant}/featuresAtivar feature/trial
DELETE /admin/tenants/{tenant}/features/{feature}Desativar
GET /admin/plans/{plan}/featuresEditar features do plano
PUT /admin/plans/{plan}/featuresSalvar features do plano

Broadcasting (Reverb + Echo)

Setup

  • Backend: Laravel Reverb (server), config em config/broadcasting.php
  • Frontend: Laravel Echo + pusher-js em resources/js/echo.ts
  • Auth: rota manual POST /broadcasting/auth (não Broadcast::routes() que sobrescreve middleware)
  • Authorizer customizado com axios (envia CSRF + cookies)

Canais

CanalTipoUso
App.Domain.User.Models.User.{ulid}PrivadoNotificações do user
prayer-wall.{tenantId}PrivadoAtualizações do mural

Variáveis de Ambiente

env
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=...
REVERB_APP_KEY=...
REVERB_APP_SECRET=...
REVERB_HOST=reverb           # hostname Docker interno
REVERB_PORT=8080

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="localhost"  # "localhost" para o browser
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
ItemÍconeRotaPermissão
NotificaçõesBellnotifications.indexnotification.view
Mural de OraçãoBookHeartprayer-wall.indexprayer.view
E-mail em MassaMailmass-emails.indexmass_email.view
PreferênciasSettingsnotification-preferences.indexnotification.manage