Skip to content

Notification System

Volare uses Laravel’s notification system to send alerts via email and database channels. Notifications are queued for asynchronous processing.

  • Notify admins when offers are created
  • Alert supplier users about offers linked to their suppliers
  • Send system alerts requiring both email and in-app visibility
  • Trigger user notifications from observer events

Required env vars:

  • MAIL_MAILER=smtp
  • MAIL_HOST=mailpit (local) or SMTP server
  • MAIL_PORT=1025 (local) or SMTP port
  • MAIL_FROM_ADDRESS="noreply@volare.test"
  • MAIL_FROM_NAME="Volare"

Queue worker: Must be running for async notifications

Terminal window
./vendor/bin/sail artisan queue:work

Database: Notifications stored in notifications table

All notifications use dual channels:

  • mail - Email delivery via configured SMTP
  • database - Stored in database, visible in Filament admin notification bell

Notifications implement ShouldQueue interface for async processing:

  • Prevents blocking request lifecycle
  • Handles email delivery failures gracefully
  • Uses Laravel queue system (Redis-backed)

Recipients are determined by business logic:

  • Admin users - Via Role::Admin enum
  • Supplier users - Via supplier_id relationship chain
  • Duplicates removed before sending

Sent when new offers are created in the system.

OfferObserver::created() - After SKU generation completes

Source: backend/app/Observers/OfferObserver.php:67-92

  • All users with Role::Admin
  • Users linked to offer’s supplier via: Offer → SupplierTourRate → SupplierTour → Supplier → Users
  • Merged and deduplicated before sending
  • Subject: “New Offer Created: {SKU}”
  • Body includes:
    • Product name from ProductByMarket → ProductTemplate
    • SKU (auto-generated)
    • Departure airport IATA code
    • Departure date (formatted: dd MMM yyyy)
    • Final price (formatted with €)
    • Link to offer in Filament admin
[
'title' => 'New Offer Created',
'message' => 'Offer {SKU} has been created.',
'offer_id' => $offer->id,
'sku' => $offer->sku,
'final_price' => $offer->final_price,
]

Source: backend/app/Notifications/OfferCreatedNotification.php

Terminal window
# Send test notification to first user
./vendor/bin/sail artisan notification:test
# Send to specific email
./vendor/bin/sail artisan notification:test user@example.com

Source: backend/app/Console/Commands/SendTestNotification.php

use Illuminate\Support\Facades\Notification;
Notification::fake();
// Trigger notification...
Notification::assertSentTo($user, OfferCreatedNotification::class);
Notification::assertSentTo($user, OfferCreatedNotification::class, function ($notification, $channels) {
return in_array('mail', $channels) && in_array('database', $channels);
});

Test suite: backend/tests/Feature/Notifications/OfferCreatedNotificationTest.php

  • Notifications are queued - queue worker must be running
  • Both channels always used (email + database)
  • Admin users receive all offer notifications
  • Supplier users receive notifications for their supplier’s offers only
  • SKU must be generated before notification (handled by observer)
  • Duplicates removed if user matches both admin and supplier criteria

Database notifications appear in Filament admin panel:

  • Notification bell icon in header
  • Unread count badge
  • Click to view details
  • Mark as read functionality

Use Mailpit for email testing:

  • Web UI: http://localhost:8025
  • SMTP: localhost:1025
  • View all sent emails without actual delivery
  • Test email templates and content

See: Mailpit Setup

See: Creating Notifications Guide