Skip to Content
TecnicaFunzionalitaSistema di Notifiche

Sistema di Notifiche

Panoramica

Il sistema di notifiche permette di informare gli utenti di eventi importanti, operazioni automatiche e azioni che richiedono attenzione. Le notifiche sono categorizzate per tipo, priorità e categoria, e possono includere azioni da intraprendere.

Modello Dati

Notification Schema

{ tenant_id: ObjectId (required) - Tenant di appartenenza user_id: ObjectId (optional) - Utente specifico (null = tutti gli utenti) title: string - Titolo della notifica message: string - Messaggio dettagliato type: "info" | "success" | "warning" | "error" - Tipo di notifica priority: "low" | "medium" | "high" | "urgent" - Priorità category: "system" | "inventory" | "sales" | "costs" | "invoices" | "general" actionUrl: string (optional) - URL dell'azione associata actionLabel: string (optional) - Label del pulsante azione metadata: Object (optional) - Dati aggiuntivi isRead: boolean - Stato di lettura readAt: Date (optional) - Data di lettura source: string (optional) - Origine della notifica expiresAt: Date (optional) - Data di scadenza createdAt: Date - Data di creazione updatedAt: Date - Data di aggiornamento }

API Endpoints

GET /api/notifications

Recupera le notifiche dell’utente corrente.

Query Parameters:

  • unreadOnly (boolean) - Solo notifiche non lette
  • limit (number) - Limite risultati (default: 50)
  • category (string) - Filtra per categoria

Response:

{ "success": true, "notifications": [...], "unreadCount": 5 }

POST /api/notifications

Crea una nuova notifica.

Body:

{ "user_id": "optional_user_id", "title": "Titolo notifica", "message": "Messaggio dettagliato", "type": "warning", "priority": "high", "category": "inventory", "actionUrl": "/inventario", "actionLabel": "Gestisci Inventario", "metadata": { "productId": "123" }, "source": "job:inventory-check" }

PUT /api/notifications

Aggiorna lo stato delle notifiche.

Body (marca come letta):

{ "notificationIds": ["id1", "id2"], "markAsRead": true }

Body (marca tutte come lette):

{ "markAllAsRead": true }

DELETE /api/notifications

Elimina notifiche.

Query Parameters:

  • id (string) - ID notifica da eliminare
  • deleteAll (boolean) - Elimina tutte le notifiche lette

Utility Functions

Il file src/lib/notifications.ts fornisce funzioni helper per creare notifiche comuni:

createNotification(params)

Funzione generica per creare qualsiasi tipo di notifica.

await createNotification({ tenant_id: "tenant123", title: "Titolo", message: "Messaggio", type: "info", priority: "medium", category: "general", });

notifyLowStock(tenant_id, productName, currentStock, productId)

Notifica per stock basso.

await notifyLowStock(tenant_id, "Farina 00", 5, "product_id");

notifyInvoiceImported(tenant_id, invoiceNumber, supplierName, amount, invoiceId)

Notifica per fattura importata.

await notifyInvoiceImported( tenant_id, "FT-2024-001", "Fornitore Rossi", 1500.0, "invoice_id", );

notifySyncError(tenant_id, service, errorMessage)

Notifica per errore di sincronizzazione.

await notifySyncError(tenant_id, "Cassa in Cloud", "API Key non valida");

notifyHighFoodCost(tenant_id, productName, foodCostPercentage, productId)

Notifica per food cost elevato.

await notifyHighFoodCost(tenant_id, "Pizza Margherita", 45.5, "product_id");

notifyUnusualSales(tenant_id, message, changePercentage)

Notifica per andamento vendite anomalo.

await notifyUnusualSales( tenant_id, "Le vendite sono aumentate del 25% questa settimana", 25, );

notifySystemMessage(tenant_id, title, message, priority)

Notifica generica di sistema.

await notifySystemMessage( tenant_id, "Manutenzione Programmata", "Il sistema sarà in manutenzione domenica dalle 2:00 alle 4:00", "medium", );

Componenti UI

NotificationBell

Componente campana per l’header che mostra il badge con il conteggio notifiche non lette.

Caratteristiche:

  • Badge con conteggio notifiche non lette
  • Dropdown con ultime 20 notifiche
  • Polling automatico ogni 30 secondi
  • Click per marcare come letta
  • Azioni rapide (elimina, segna tutte lette)

Uso:

import { NotificationBell } from "@/components/NotificationBell"; <NotificationBell />;

Pagina Notifiche (/notifiche)

Pagina completa per gestire tutte le notifiche.

Caratteristiche:

  • Visualizzazione completa di tutte le notifiche
  • Filtri (tutte/non lette)
  • Badge priorità e categoria
  • Azioni (segna letta, elimina singola, elimina tutte lette)
  • Indicatori visivi per tipo e priorità
  • Link alle azioni associate

Integrazione nel Codice

Esempio: Generazione notifica dopo importazione fattura

import { notifyInvoiceImported } from "@/lib/notifications"; // Dopo il salvataggio della fattura const invoice = await Invoice.create(invoiceData); await notifyInvoiceImported( tenant_id, invoice.invoice_number, invoice.supplier.name, invoice.total, invoice._id.toString(), );

Esempio: Notifica da Job/Cron

import { notifyLowStock, notifyHighFoodCost } from "@/lib/notifications"; // In un job che controlla l'inventario async function checkInventory() { const products = await SellingProduct.find({ isSemifinished: true, stockEstimate: { $lt: 10 }, }); for (const product of products) { await notifyLowStock( product.tenant_id, product.name, product.stockEstimate, product._id.toString(), ); } }

Esempio: Notifica da API

// In una route API import { createNotification } from "@/lib/notifications"; export async function POST(request: Request) { const { tenant_id } = requireAuth(request); // ... logica applicativa ... await createNotification({ tenant_id, title: "Operazione Completata", message: "L'operazione è stata completata con successo", type: "success", priority: "low", category: "general", source: "api:custom-operation", }); }

Best Practices

  1. Priorità: Usa urgent solo per situazioni critiche che richiedono attenzione immediata
  2. Categorie: Mantieni le categorie coerenti per permettere filtri efficaci
  3. Azioni: Quando possibile, fornisci sempre actionUrl e actionLabel per notifiche che richiedono follow-up
  4. Metadata: Usa il campo metadata per memorizzare informazioni contestuali utili
  5. Source: Specifica sempre la source per tracciare l’origine delle notifiche
  6. Scadenza: Usa expiresAt per notifiche temporanee (es. promozioni, eventi)
  7. Target: Usa user_id: null per notifiche broadcast a tutto il tenant

Notifiche Automatiche Implementate

✅ Fatture

  • Fattura importata con successo

🔄 Da Implementare

  • Stock basso (job automatico)
  • Food cost elevato (analisi periodica)
  • Errori sincronizzazione servizi esterni
  • Andamento vendite anomalo
  • Scadenze pagamenti fornitori
  • Prodotti in scadenza
  • Obiettivi food cost raggiunti/mancati
  • Backup completati
  • Aggiornamenti sistema

Performance

Indici MongoDB

  • { tenant_id: 1, isRead: 1, createdAt: -1 } - Query principali
  • { tenant_id: 1, user_id: 1, isRead: 1 } - Filtri utente
  • { expiresAt: 1 } - TTL index per pulizia automatica

Polling

Il componente NotificationBell effettua polling ogni 30 secondi per aggiornare il conteggio.

Cleanup

Le notifiche con expiresAt vengono eliminate automaticamente da MongoDB tramite TTL index.

Estensibilità

Il sistema è progettato per essere facilmente estendibile:

  1. Nuovi tipi: Aggiungi nuovi tipi al enum type nel modello
  2. Nuove categorie: Aggiungi nuove categorie al enum category
  3. Nuove helper functions: Crea funzioni in lib/notifications.ts per casi d’uso specifici
  4. Integrazione WebSocket: Possibile implementare notifiche real-time con WebSocket
  5. Email notifications: Possibile aggiungere invio email per notifiche prioritarie
  6. Push notifications: Possibile implementare push notifications per mobile
Last updated on