libra/docs/stories/story-8.2-welcome-email.md

5.2 KiB

Story 8.2: Welcome Email (Account Created)

Epic Reference

Epic 8: Email Notification System

Dependencies

Requires: Story 8.1 (Email Infrastructure Setup) - base template, queue configuration, SMTP setup

User Story

As a new client, I want to receive a welcome email with my login credentials, So that I can access the platform.

Acceptance Criteria

Trigger

  • Sent automatically on user creation by admin
  • Queued for performance (implements ShouldQueue)
  • Triggered via model observer on User created event

Content

  • Personalized greeting (name/company)
  • "Your account has been created" message
  • Login credentials (email, password)
  • Login URL link with button
  • Brief platform introduction
  • Contact info for questions

Language

  • Email in user's preferred_language field
  • Default to Arabic ('ar') if preferred_language is null
  • Arabic template
  • English template

Design

  • Professional branding (inherits from base template in Story 8.1)
  • Call-to-action button: "Login Now" / "تسجيل الدخول"

Technical Notes

Prerequisites from Story 8.1

  • Base email template with Libra branding (navy #0A1F44, gold #D4AF37)
  • Queue configuration for async email delivery
  • SMTP configuration via .env

User Model Requirement

The User model requires a preferred_language field. If not already present, add:

  • Migration: $table->string('preferred_language', 2)->default('ar');
  • Fillable: Add 'preferred_language' to $fillable array

Files to Create

Mailable Class:

  • app/Mail/WelcomeEmail.php

View Templates:

  • resources/views/emails/welcome/ar.blade.php (Arabic)
  • resources/views/emails/welcome/en.blade.php (English)

Observer:

  • app/Observers/UserObserver.php (if not exists)
  • Register in AppServiceProvider boot method

Implementation

// app/Mail/WelcomeEmail.php
class WelcomeEmail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public function __construct(
        public User $user,
        public string $password
    ) {}

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: $this->user->preferred_language === 'en'
                ? 'Welcome to Libra Law Firm'
                : 'مرحباً بك في مكتب ليبرا للمحاماة',
        );
    }

    public function content(): Content
    {
        return new Content(
            markdown: 'emails.welcome.' . ($this->user->preferred_language ?? 'ar'),
            with: [
                'loginUrl' => route('login'),
                'password' => $this->password,
            ],
        );
    }
}
// app/Observers/UserObserver.php
class UserObserver
{
    public function created(User $user): void
    {
        // Only send if password was set (admin creation scenario)
        // The plain password must be passed from the creation context
    }
}

Trigger Mechanism

The welcome email requires the plain-text password, which is only available at creation time. Options:

  1. Recommended: Dispatch from the admin user creation action/controller after creating user
  2. Alternative: Use a custom event UserCreatedWithPassword that carries both user and password

Edge Cases

  • Missing preferred_language: Default to Arabic ('ar')
  • Email delivery failure: Handled by queue retry mechanism (Story 8.1)
  • Password in email: This is intentional for admin-created accounts; password is shown once

Testing Requirements

Unit Tests

  • WelcomeEmail mailable contains correct subject for Arabic user
  • WelcomeEmail mailable contains correct subject for English user
  • WelcomeEmail uses correct template based on language
  • Default language is Arabic when preferred_language is null

Feature Tests

  • Email is queued when user is created
  • Arabic template renders without errors
  • English template renders without errors
  • Email contains login URL
  • Email contains user's password
  • Email contains user's name

Test Example

use App\Mail\WelcomeEmail;
use App\Models\User;
use Illuminate\Support\Facades\Mail;

test('welcome email is sent when user is created', function () {
    Mail::fake();

    $user = User::factory()->create(['preferred_language' => 'ar']);

    Mail::to($user)->send(new WelcomeEmail($user, 'test-password'));

    Mail::assertQueued(WelcomeEmail::class, function ($mail) use ($user) {
        return $mail->user->id === $user->id;
    });
});

test('welcome email uses arabic template by default', function () {
    $user = User::factory()->create(['preferred_language' => null]);
    $mailable = new WelcomeEmail($user, 'password123');

    $mailable->assertSeeInHtml('تسجيل الدخول');
});

Definition of Done

  • WelcomeEmail mailable class created
  • Arabic template (emails/welcome/ar.blade.php) created
  • English template (emails/welcome/en.blade.php) created
  • Email triggered on user creation by admin
  • Email is queued (not sent synchronously)
  • Credentials included in email
  • Login button links to correct URL
  • All tests pass
  • Code formatted with Pint

Estimation

Complexity: Low | Effort: 2-3 hours