libra/docs/stories/story-4.6-timeline-update-n...

5.2 KiB

Story 4.6: Timeline Update Notifications

Epic Reference

Epic 4: Case Timeline System

User Story

As a client, I want to receive email notifications when my timeline is updated, So that I stay informed about my case progress without checking the portal.

Story Context

Existing System Integration

  • Integrates with: timeline_updates creation, email system
  • Technology: Laravel Notifications, queued emails
  • Follows pattern: Event-driven notification pattern
  • Touch points: Timeline update creation

Acceptance Criteria

Notification Trigger

  • Email sent when new update added to timeline
  • Triggered automatically on TimelineUpdate creation
  • Queued for performance

Email Content

  • Case name and reference
  • Update summary or full text
  • Date of update
  • Link to view timeline
  • Libra branding

Language Support

  • Email in client's preferred language
  • Arabic template
  • English template

Exclusions

  • No email for archived timeline reactivation
  • No email if client deactivated

Quality Requirements

  • Professional email template
  • Tests for notification sending
  • Error handling for failed sends

Technical Notes

Notification Class

<?php

namespace App\Notifications;

use App\Models\TimelineUpdate;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class TimelineUpdateNotification extends Notification
{
    use Queueable;

    public function __construct(
        public TimelineUpdate $update
    ) {}

    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        $locale = $notifiable->preferred_language ?? 'ar';
        $timeline = $this->update->timeline;

        return (new MailMessage)
            ->subject($this->getSubject($locale, $timeline->case_name))
            ->markdown('emails.timeline.update.' . $locale, [
                'update' => $this->update,
                'timeline' => $timeline,
                'user' => $notifiable,
            ]);
    }

    private function getSubject(string $locale, string $caseName): string
    {
        return $locale === 'ar'
            ? "تحديث جديد على قضيتك: {$caseName}"
            : "New update on your case: {$caseName}";
    }
}

Email Templates

Arabic

<x-mail::message>
# تحديث جديد على قضيتك

عزيزي {{ $user->name }}،

تم إضافة تحديث جديد على قضيتك:

**القضية:** {{ $timeline->case_name }}
@if($timeline->case_reference)
**الرقم المرجعي:** {{ $timeline->case_reference }}
@endif

**تاريخ التحديث:** {{ $update->created_at->translatedFormat('d M Y - g:i A') }}

---

{!! $update->update_text !!}

---

<x-mail::button :url="route('client.timelines.show', $timeline)">
عرض التفاصيل الكاملة
</x-mail::button>

مع أطيب التحيات،
مكتب ليبرا للمحاماة
</x-mail::message>

English

<x-mail::message>
# New Update on Your Case

Dear {{ $user->name }},

A new update has been added to your case:

**Case:** {{ $timeline->case_name }}
@if($timeline->case_reference)
**Reference:** {{ $timeline->case_reference }}
@endif

**Update Date:** {{ $update->created_at->format('M d, Y - g:i A') }}

---

{!! $update->update_text !!}

---

<x-mail::button :url="route('client.timelines.show', $timeline)">
View Full Details
</x-mail::button>

Best regards,
Libra Law Firm
</x-mail::message>

Trigger in Update Creation

// In Story 4.2 addUpdate method
$update = $this->timeline->updates()->create([...]);

// Check if user is active before notifying
if ($this->timeline->user->isActive()) {
    $this->timeline->user->notify(new TimelineUpdateNotification($update));
}

Testing

use App\Notifications\TimelineUpdateNotification;
use Illuminate\Support\Facades\Notification;

it('sends notification when timeline update created', function () {
    Notification::fake();

    $timeline = Timeline::factory()->create();
    $update = TimelineUpdate::factory()->create(['timeline_id' => $timeline->id]);

    $timeline->user->notify(new TimelineUpdateNotification($update));

    Notification::assertSentTo($timeline->user, TimelineUpdateNotification::class);
});

it('does not send notification to deactivated user', function () {
    Notification::fake();

    $user = User::factory()->create(['status' => 'deactivated']);
    $timeline = Timeline::factory()->for($user)->create();

    // Add update (should check user status)
    // ...

    Notification::assertNotSentTo($user, TimelineUpdateNotification::class);
});

Definition of Done

  • Email sent on new update
  • Arabic template works
  • English template works
  • Uses client's preferred language
  • Link to timeline works
  • Queued for performance
  • No email to deactivated users
  • Tests pass
  • Code formatted with Pint

Dependencies

  • Story 4.2: Timeline updates management
  • Epic 8: Email infrastructure

Estimation

Complexity: Low-Medium Estimated Effort: 2-3 hours