Skip to main content

Overview

NutriFit uses Laravel’s notification system to send automated email notifications for authentication events, appointments, clinical records, and account management.
All notifications implement ShouldQueue interface for asynchronous processing, ensuring fast response times.

Architecture

The notification system is built on Laravel’s notification framework with queue support:
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class ExampleNotification extends Notification implements ShouldQueue
{
    use Queueable;
    
    public function via(object $notifiable): array
    {
        return ['mail'];
    }
    
    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('Subject Line')
            ->greeting('Hello!')
            ->line('Notification content...')
            ->action('Action Button', url('/'));
    }
}

Notification Types

Authentication Notifications

WelcomeNotification

Sent after email verification to welcome new users

VerifyEmailNotification

Email verification link for new accounts

ResetPasswordNotification

Password reset link when requested

PasswordChangedNotification

Confirmation after password change

Welcome Email Example

app/Notifications/WelcomeNotification.php
class WelcomeNotification extends Notification implements ShouldQueue
{
    use Queueable;

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('🎉 ¡Bienvenido a NutriFit!')
            ->greeting('¡Hola ' . $notifiable->name . '!')
            ->line('¡Gracias por registrarte en NutriFit! Nos alegra que formes parte de nuestra comunidad.')
            ->line('Tu cuenta ha sido creada exitosamente y ya puedes empezar a usar todas nuestras funcionalidades:')
            ->line('✅ Agendar citas con nutricionistas profesionales')
            ->line('✅ Mantener tu historial clínico organizado')
            ->line('✅ Recibir seguimiento continuo de tu progreso')
            ->action('Explorar NutriFit', url('/paciente/dashboard'))
            ->salutation('¡Bienvenido al equipo! ' . config('app.name'));
    }
}

Account Management Notifications

Sent when administrator enables a disabled account
Sent when administrator disables an account
Sent when nutritionist creates patient’s personal data

Appointment Notifications

The system sends comprehensive appointment-related notifications:
AppointmentCreatedNotification (to Nutritionist)
app/Notifications/AppointmentCreatedNotification.php
public function toMail(object $notifiable): MailMessage
{
    $appointmentDate = $this->appointment->start_time->format('d/m/Y');
    $appointmentTime = $this->appointment->start_time->format('H:i');
    $patientName = $this->appointment->paciente->name;

    return (new MailMessage)
        ->subject('🗓️ Nueva Cita Agendada - NutriFit')
        ->greeting('¡Hola Dr(a). ' . $notifiable->name . '!')
        ->line('Se ha agendado una nueva cita en tu calendario.')
        ->line('**Paciente:** ' . $patientName)
        ->line('**Fecha:** ' . $appointmentDate)
        ->line('**Hora:** ' . $appointmentTime)
        ->action('Ver Detalles', url('/nutricionista/dashboard'));
}
AppointmentCreatedForPatientNotification (to Patient)Confirms booking to the patient

Clinical Record Notifications

AttentionCompletedNotification Sent to patient when nutritionist completes clinical attention:
app/Notifications/AttentionCompletedNotification.php
class AttentionCompletedNotification extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public Attention $attention
    ) {}

    public function toMail(object $notifiable): MailMessage
    {
        $appointmentDate = $this->attention->appointment->start_time->format('d/m/Y');
        $appointmentTime = $this->attention->appointment->start_time->format('H:i');
        $nutricionistaName = $this->attention->nutricionista->name;

        $weight = $this->attention->attentionData->weight ?? 'N/A';
        $bmi = $this->attention->attentionData->bmi ?? 'N/A';

        return (new MailMessage)
            ->subject('✅ Atención Nutricional Completada - NutriFit')
            ->greeting('¡Hola ' . $notifiable->name . '!')
            ->line('Tu atención nutricional ha sido completada exitosamente.')
            ->line('**Nutricionista:** Dr(a). ' . $nutricionistaName)
            ->line('**Fecha de atención:** ' . $appointmentDate . ' a las ' . $appointmentTime)
            ->line('**Peso registrado:** ' . $weight . ' kg')
            ->line('**IMC:** ' . number_format($bmi, 2))
            ->line('Se ha generado un plan nutricional personalizado con diagnóstico y recomendaciones específicas para ti.')
            ->action('Ver Reporte Completo', 
                url('/paciente/citas/' . $this->attention->appointment_id))
            ->line('Recuerda seguir las recomendaciones de tu nutricionista para alcanzar tus objetivos de salud.');
    }
}

Contact Form Notification

ContactFormNotification Sent to administrators when users submit the contact form.

Sending Notifications

Direct Sending

Notifications are sent using Laravel’s notification facade:
use App\Notifications\AppointmentCreatedNotification;

// Send to single user
$user->notify(new AppointmentCreatedNotification($appointment));

// Send to multiple users
Notification::send($users, new WelcomeNotification());

Queued Processing

All notifications implement ShouldQueue for background processing:
class AppointmentReminderNotification extends Notification implements ShouldQueue
{
    use Queueable;
    
    // Notification will be processed in background
}
Queued notifications prevent blocking the request-response cycle, providing better user experience.

Queue Workers

Configuration

Configure queue connection in .env:
.env
QUEUE_CONNECTION=database
# or
QUEUE_CONNECTION=redis
# or
QUEUE_CONNECTION=sync  # For development

Running Queue Workers

php artisan queue:work
Processes queued jobs. Use Ctrl+C to stop.

Queue Monitoring

# List failed jobs
php artisan queue:failed

# Retry failed job
php artisan queue:retry <job-id>

# Retry all failed jobs
php artisan queue:retry all

# Flush failed jobs
php artisan queue:flush

Scheduled Notifications

Appointment Reminders

Reminders are sent via scheduled command:
app/Console/Commands/SendAppointmentReminders.php
class SendAppointmentReminders extends Command
{
    protected $signature = 'appointments:send-reminders';

    public function handle()
    {
        $tomorrow = Carbon::tomorrow()->toDateString();
        
        $appointments = Appointment::whereDate('start_time', $tomorrow)
            ->whereHas('appointmentState', function($query) {
                $query->whereIn('name', ['confirmada', 'pendiente']);
            })
            ->with(['paciente', 'nutricionista'])
            ->get();

        foreach ($appointments as $appointment) {
            $appointment->paciente->notify(
                new AppointmentReminderNotification($appointment)
            );
            $appointment->nutricionista->notify(
                new AppointmentReminderNotification($appointment)
            );
        }
    }
}

Schedule Configuration

Add to app/Console/Kernel.php:
protected function schedule(Schedule $schedule)
{
    // Send appointment reminders daily at 9 AM
    $schedule->command('appointments:send-reminders')
        ->dailyAt('09:00');
}

Running Scheduler

Add to crontab:
* * * * * cd /path-to-nutrifit && php artisan schedule:run >> /dev/null 2>&1

Email Configuration

SMTP Setup

Configure email in .env:
.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME="${APP_NAME}"

Testing Emails

Use Mailtrap or similar for development:
# Send test notification
php artisan tinker
>>> $user = User::first();
>>> $user->notify(new \App\Notifications\WelcomeNotification());

Notification Customization

Custom Styling

Publish notification templates:
php artisan vendor:publish --tag=laravel-notifications
Customize in resources/views/vendor/notifications/.

Multi-Channel Notifications

Add additional channels:
public function via(object $notifiable): array
{
    return ['mail', 'database', 'broadcast'];
}

public function toDatabase(object $notifiable): array
{
    return [
        'appointment_id' => $this->appointment->id,
        'message' => 'New appointment scheduled',
    ];
}

Best Practices

Implement ShouldQueue on all notifications to prevent blocking requests
Use recipient’s name and include specific details
Use descriptive subjects with emojis for visual recognition
Regularly check and retry failed notification jobs
Test all notification types in development environment

Troubleshooting

If notifications aren’t being sent, check these common issues:

Queue Not Processing

# Check if queue worker is running
ps aux | grep "queue:work"

# Start queue worker
php artisan queue:work

Failed Jobs

# View failed jobs
php artisan queue:failed

# Check error details
php artisan queue:failed-table
php artisan migrate

Email Not Sending

# Test email configuration
php artisan config:clear
php artisan cache:clear

# Check logs
tail -f storage/logs/laravel.log

Appointments

Learn about appointment scheduling

Authentication

Explore authentication system

Clinical Records

Understand clinical attention workflow

Build docs developers (and LLMs) love