reviewed epic 8 stories
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
## 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**,
|
||||
@@ -12,7 +15,8 @@ So that **I can access the platform**.
|
||||
|
||||
### Trigger
|
||||
- [ ] Sent automatically on user creation by admin
|
||||
- [ ] Queued for performance
|
||||
- [ ] Queued for performance (implements `ShouldQueue`)
|
||||
- [ ] Triggered via model observer on User created event
|
||||
|
||||
### Content
|
||||
- [ ] Personalized greeting (name/company)
|
||||
@@ -23,18 +27,45 @@ So that **I can access the platform**.
|
||||
- [ ] Contact info for questions
|
||||
|
||||
### Language
|
||||
- [ ] Email in user's preferred_language
|
||||
- [ ] Email in user's `preferred_language` field
|
||||
- [ ] Default to Arabic ('ar') if `preferred_language` is null
|
||||
- [ ] Arabic template
|
||||
- [ ] English template
|
||||
|
||||
### Design
|
||||
- [ ] Professional branding
|
||||
- [ ] Call-to-action button: "Login Now"
|
||||
- [ ] 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
|
||||
|
||||
```php
|
||||
class WelcomeEmail extends Mailable
|
||||
// app/Mail/WelcomeEmail.php
|
||||
class WelcomeEmail extends Mailable implements ShouldQueue
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
@@ -46,9 +77,9 @@ class WelcomeEmail extends Mailable
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
subject: $this->user->preferred_language === 'ar'
|
||||
? 'مرحباً بك في مكتب ليبرا للمحاماة'
|
||||
: 'Welcome to Libra Law Firm',
|
||||
subject: $this->user->preferred_language === 'en'
|
||||
? 'Welcome to Libra Law Firm'
|
||||
: 'مرحباً بك في مكتب ليبرا للمحاماة',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -56,18 +87,90 @@ class WelcomeEmail extends Mailable
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'emails.welcome.' . ($this->user->preferred_language ?? 'ar'),
|
||||
with: [
|
||||
'loginUrl' => route('login'),
|
||||
'password' => $this->password,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
// 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
|
||||
```php
|
||||
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
|
||||
- [ ] Email sent on user creation
|
||||
- [ ] Credentials included
|
||||
- [ ] Arabic template works
|
||||
- [ ] English template works
|
||||
- [ ] Login button works
|
||||
- [ ] Tests pass
|
||||
- [ ] `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
|
||||
|
||||
Reference in New Issue
Block a user