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

221 lines
5.2 KiB
Markdown

# 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
<?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
```blade
<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
```blade
<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
```php
// 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
```php
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