generated sotries
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user