Skip to main content

Logiche tecniche

🚧 BOZZA

Questa sezione descrive come funziona il sistema di notifiche, dalla configurazione dei template all'invio effettivo.


🧠 Concetti chiave

Il sistema di notifiche si basa su un'architettura template-based che separa la configurazione dal codice.

Template di notifica

I template di notifica sono entità configurabili salvate nel database che definiscono:

  • Un codice univoco per identificare il template (es. user_registered, project_completed)
  • Il titolo e il tipo della notifica (ToDo o Info)
  • I canali abilitati (Email, Push)
  • Un URL di redirect opzionale dove l'utente viene indirizzato cliccando sulla notifica

Canali di notifica

Ogni template può avere uno o più canali configurati. Ogni canale definisce:

  • Il tipo di canale (Email o Push)
  • Il titolo specifico per quel canale
  • Il corpo del messaggio (con placeholder per variabili)
  • I destinatari (lista di indirizzi email o utenti)
  • Lo stato (abilitato/disabilitato)
  • Per le Email: subject e CTA name (nome del pulsante call-to-action)

Variabili

Le variabili sono placeholder dinamici utilizzabili nei contenuti dei canali con la sintassi {{nome_variabile}}.

Le variabili vengono gestite in modo diverso in base alla loro categoria:

  • Variabili CORE: Fornite automaticamente dal sistema (es. {{platform_name}}, {{platform_email}})
  • Variabili CONTESTUALI: Fornite dal modulo che invia la notifica in base al contesto (es. {{user_name}}, {{project_address}})

⚙️ Logiche sotto il cofano

Entità coinvolte

Le entità strettamente coinvolte nelle notifiche sono:

  • nt_notification_templates: Template di notifica riutilizzabili. Campi principali:

    • code: codice univoco per identificare il template
    • title: titolo della notifica
    • type: tipo di notifica (to_do, info)
    • channels: array JSON dei canali abilitati
    • redirect_url: URL dove reindirizzare l'utente
  • nt_notification_template_channels: Configurazione specifica per ogni canale. Campi principali:

    • nt_notification_template_id: riferimento al template
    • type: tipo di canale (email, push)
    • title: titolo specifico per il canale
    • body: corpo del messaggio con placeholder variabili
    • recipients: array JSON di destinatari
    • subject: oggetto dell'email (solo per Email)
    • cta_name: nome del pulsante CTA
    • status: abilitato/disabilitato
  • nt_variable_templates: Variabili disponibili per tutti i template. Campi principali:

    • name: nome della variabile
    • slug: slug identificativo (usato nei placeholder)
    • category: categoria della variabile (core, project, customer, ecc.)
    • type: tipo di dato (text, email, date, currency, ecc.)
  • nt_notification_variable_template: Tabella pivot che associa variabili ai template

  • notifications: Tabella standard di Laravel che salva le notifiche inviate agli utenti (per il canale Push con driver Database)

  • settings: Impostazioni per utente (es. preferenze di ricezione notifiche)


🔄 Flusso di invio notifica

1. Configurazione iniziale

Prima di poter inviare una notifica, è necessario:

  1. Creare un template di notifica nel database con un code univoco
  2. Configurare i canali desiderati (Email e/o Push) per quel template
  3. Associare le variabili necessarie al template
  4. Creare una classe Notification nel modulo che estende BaseNotification

2. Invio della notifica

Il modulo Notifiche fornisce un service centralizzato per l'invio. Ci sono diverse modalità:

Modalità 1: Con convenzione (consigliata)

use App\NtModule\Services\NtNotificationService;
use App\YourModule\Notifications\UserRegisteredNotification;

// Il template viene caricato automaticamente dal nome della classe
// UserRegisteredNotification -> cerca il template con code 'user_registered'
NtNotificationService::send(
UserRegisteredNotification::class,
['user_name' => 'Mario Rossi', 'user_email' => 'mario@example.com']
);

// I destinatari vengono risolti automaticamente dai ruoli configurati nel template

Modalità 2: Con template esplicito

// Carica esplicitamente il template
$template = NtNotificationTemplate::where('code', 'user_registered')->first();

NtNotificationService::send(
$template,
UserRegisteredNotification::class,
['user_name' => 'Mario Rossi']
);

Modalità 3: Con contesto (auto-resolve variabili)

// Passa il contesto e le variabili vengono risolte automaticamente
NtNotificationService::send(
UserRegisteredNotification::class,
[],
[],
['user' => $user, 'contract' => $contract]
);
Risoluzione automatica
  • I destinatari vengono risolti automaticamente dai ruoli configurati nei canali del template
  • Le variabili possono essere risolte automaticamente dal contesto (entità passate)
  • Il template viene caricato per convenzione dal nome della classe (es. UserRegisteredNotificationuser_registered)

3. Processing interno

Quando viene chiamato NtNotificationService::send(), il sistema:

  1. Risolve il template:

    • Se passato esplicitamente, lo usa direttamente
    • Altrimenti lo carica per convenzione dal nome classe (es. UserRegisteredNotificationuser_registered)
  2. Risolve i destinatari:

    • Legge i recipients (ruoli) dai canali abilitati del template
    • Usa Spatie Permission per trovare tutti gli utenti con quei ruoli
    • Raccoglie tutti gli utenti in una collection
  3. Risolve le variabili (se passato un contesto):

    • Usa NtVariableResolver per estrarre i valori dalle entità del contesto
    • Formatta i valori in base al tipo della variabile
    • Fa merge con eventuali variabili passate esplicitamente
  4. Crea l'istanza della notifica:

    • Istanzia la classe di notifica passando template, variabili e contesto
    • La notifica crea internamente un NtNotificationService per il processing
  5. Determina i canali:

    • Il metodo via() della notifica usa il service per mappare i canali
    • Canali NtModule (Email, Push) → Canali Laravel (mail, database, broadcast)
  6. Prepara i messaggi:

    • Per ogni canale, sostituisce i placeholder con i valori delle variabili
    • toMail(): costruisce il messaggio email usando buildMailMessage()
    • toArray(): costruisce i dati push usando buildPushData()
    • toBroadcast(): prepara l'evento per Pusher (se abilitato)
  7. Invia:

    • Usa Notification::send($recipients, $notification) di Laravel
    • Laravel invia la notifica a tutti i destinatari sui canali appropriati

📨 Sostituzione delle variabili

Il processo di sostituzione delle variabili supporta due formati di placeholder:

Formato 1: HTML Span (nei contenuti body/title)

Il formato principale usato nei contenuti HTML dei canali:

Ciao <span>@user_name</span>, benvenuto su <span>@platform_name</span>!

Il NtNotificationService cerca il pattern <span>@nome_variabile</span>:

  1. Estrae il nome della variabile (rimuovendo @)
  2. Cerca il valore nell'array $variables
  3. Sostituisce l'intero tag <span> con il valore

Esempio:

Input: "Ciao <span>@user_name</span>!"
Variables: ['user_name' => 'Mario']
Output: "Ciao Mario!"

Formato 2: Doppie graffe (nei redirect_url)

Usato principalmente negli URL di redirect:

https://example.com/contracts/{{contract_id}}

Il service cerca il pattern {{nome_variabile}} e lo sostituisce con il valore.

Esempio:

Input: "https://example.com/contracts/{{contract_id}}"
Variables: ['contract_id' => '123']
Output: "https://example.com/contracts/123"

Risoluzione automatica dal contesto

Quando si passa un contesto invece di variabili esplicite:

NtNotificationService::send(
NotificationClass::class,
[],
[],
['user' => $user, 'contract' => $contract]
);

Il NtVariableResolver estrae automaticamente i valori:

  1. Legge le variabili associate al template dal database
  2. Per ogni variabile, cerca nell'entità corrispondente del contesto
  3. Estrae il valore usando la configurazione della variabile
  4. Formatta il valore in base al tipo (date, currency, boolean, ecc.)
Logiche rilevanti
  • Le variabili CORE devono essere fornite automaticamente dal sistema
  • Le variabili CONTESTUALI vengono risolte dal contesto o passate esplicitamente
  • In strict mode (strictMode = true), se una variabile non viene trovata viene lanciata un'eccezione
  • In modalità normale, i placeholder non sostituiti vengono mantenuti nel testo
  • Per le email, il subject viene automaticamente ripulito dai tag HTML

📬 Canali di invio

Email

Per il canale Email:

  • Usa la configurazione SMTP di Laravel
  • Il mittente viene configurato automaticamente da BaseNotification
  • Il subject, body e CTA sono configurabili nel template
  • I destinatari sono specificati nel campo recipients del canale

La classe di notifica implementa buildMailMessage() per personalizzare il messaggio:

protected function buildMailMessage($notifiable, array $data)
{
$mail = $this->createMailMessage()
->subject($data['subject'] ?? $data['title'])
->line($data['body']);

if ($data['cta_name'] && $data['redirect_url']) {
$mail->action($data['cta_name'], $data['redirect_url']);
}

return $mail;
}

Push

Per il canale Push il sistema supporta tre modalità (driver):

  • Database: Salva la notifica nella tabella notifications di Laravel
  • Pusher: Invia in real-time tramite Pusher/Broadcasting
  • Both: Entrambi i metodi

La classe di notifica implementa buildPushData() per definire i dati:

protected function buildPushData($notifiable, array $data): array
{
return [
'title' => $data['title'],
'body' => $data['body'],
'type' => 'user_registered',
'url' => $data['redirect_url'],
];
}

🎨 Creazione di una nuova notifica

Per creare una nuova notifica:

Step 1: Configurare il template nel database

  1. Creare un record in nt_notification_templates con un code univoco
  2. Creare i record in nt_notification_template_channels per ogni canale desiderato
  3. Associare le variabili necessarie tramite nt_notification_variable_template

Step 2: Creare la classe Notification

namespace App\YourModule\Notifications;

use App\NtModule\Notifications\BaseNotification;

class YourCustomNotification extends BaseNotification
{
protected function getRequiredVariables(): array
{
return ['user_name', 'custom_data'];
}

protected function buildMailMessage($notifiable, array $data)
{
return $this->createMailMessage()
->subject($data['subject'] ?? $data['title'])
->line($data['body'])
->action($data['cta_name'], $data['redirect_url']);
}

protected function buildPushData($notifiable, array $data): array
{
return [
'title' => $data['title'],
'body' => $data['body'],
'type' => 'your_custom_type',
'url' => $data['redirect_url'],
];
}

protected function getBroadcastChannel()
{
return ['private-user.' . $this->notifiable->id];
}

protected function getBroadcastType(): string
{
return 'your.custom.event';
}
}

Step 3: Usare la notifica

use App\NtModule\Services\NtNotificationService;

// Modalità semplice con convenzione (consigliata)
NtNotificationService::send(
YourCustomNotification::class,
[
'user_name' => $user->name,
'custom_data' => 'Some value',
]
);

// Oppure con contesto per auto-resolve
NtNotificationService::send(
YourCustomNotification::class,
[],
[],
['user' => $user, 'project' => $project]
);

// I destinatari vengono risolti automaticamente dai ruoli nel template

🔧 Impostazioni utente

Gli utenti possono configurare le proprie preferenze di notifica tramite la tabella settings:

  • Disabilitare completamente le notifiche
  • Disabilitare specifici canali (es. solo Email, no Push)
  • Disabilitare specifici tipi di notifica

Le impostazioni sono salvate come record polimorfi associati all'utente con una key univoca che identifica il tipo di impostazione.