generated sotries
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
# Story 4.2: Timeline Updates Management
|
||||
|
||||
## Epic Reference
|
||||
**Epic 4:** Case Timeline System
|
||||
|
||||
## User Story
|
||||
As an **admin**,
|
||||
I want **to add and edit updates within a timeline**,
|
||||
So that **I can keep clients informed about their case progress**.
|
||||
|
||||
## Story Context
|
||||
|
||||
### Existing System Integration
|
||||
- **Integrates with:** timeline_updates table, timelines table
|
||||
- **Technology:** Livewire Volt, rich text editor
|
||||
- **Follows pattern:** Nested CRUD pattern
|
||||
- **Touch points:** Client notifications, timeline view
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Add Update
|
||||
- [ ] Add new update to timeline
|
||||
- [ ] Update text content (required)
|
||||
- [ ] Rich text formatting supported:
|
||||
- Bold, italic, underline
|
||||
- Bullet/numbered lists
|
||||
- Links
|
||||
- [ ] Timestamp automatically recorded
|
||||
- [ ] Admin name automatically recorded
|
||||
- [ ] Client notified via email on new update
|
||||
|
||||
### Edit Update
|
||||
- [ ] Edit existing update text
|
||||
- [ ] Edit history preserved (updated_at changes)
|
||||
- [ ] Cannot change timestamp or admin
|
||||
|
||||
### Display
|
||||
- [ ] Updates displayed in chronological order
|
||||
- [ ] Each update shows:
|
||||
- Date/timestamp
|
||||
- Admin name
|
||||
- Update content
|
||||
- [ ] Visual timeline representation
|
||||
|
||||
### Quality Requirements
|
||||
- [ ] HTML sanitization for security
|
||||
- [ ] Audit log for edits
|
||||
- [ ] Tests for add/edit operations
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Database Schema
|
||||
```php
|
||||
Schema::create('timeline_updates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('timeline_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('admin_id')->constrained('users');
|
||||
$table->text('update_text');
|
||||
$table->timestamps();
|
||||
});
|
||||
```
|
||||
|
||||
### Volt Component
|
||||
```php
|
||||
<?php
|
||||
|
||||
use App\Models\{Timeline, TimelineUpdate};
|
||||
use App\Notifications\TimelineUpdateNotification;
|
||||
use Livewire\Volt\Component;
|
||||
|
||||
new class extends Component {
|
||||
public Timeline $timeline;
|
||||
public string $updateText = '';
|
||||
public ?TimelineUpdate $editingUpdate = null;
|
||||
|
||||
public function addUpdate(): void
|
||||
{
|
||||
$this->validate([
|
||||
'updateText' => ['required', 'string', 'min:10'],
|
||||
]);
|
||||
|
||||
$update = $this->timeline->updates()->create([
|
||||
'admin_id' => auth()->id(),
|
||||
'update_text' => clean($this->updateText), // Sanitize HTML
|
||||
]);
|
||||
|
||||
// Notify client
|
||||
$this->timeline->user->notify(new TimelineUpdateNotification($update));
|
||||
|
||||
AdminLog::create([
|
||||
'admin_id' => auth()->id(),
|
||||
'action_type' => 'create',
|
||||
'target_type' => 'timeline_update',
|
||||
'target_id' => $update->id,
|
||||
'ip_address' => request()->ip(),
|
||||
]);
|
||||
|
||||
$this->updateText = '';
|
||||
session()->flash('success', __('messages.update_added'));
|
||||
}
|
||||
|
||||
public function editUpdate(TimelineUpdate $update): void
|
||||
{
|
||||
$this->editingUpdate = $update;
|
||||
$this->updateText = $update->update_text;
|
||||
}
|
||||
|
||||
public function saveEdit(): void
|
||||
{
|
||||
$this->validate([
|
||||
'updateText' => ['required', 'string', 'min:10'],
|
||||
]);
|
||||
|
||||
$oldText = $this->editingUpdate->update_text;
|
||||
|
||||
$this->editingUpdate->update([
|
||||
'update_text' => clean($this->updateText),
|
||||
]);
|
||||
|
||||
AdminLog::create([
|
||||
'admin_id' => auth()->id(),
|
||||
'action_type' => 'update',
|
||||
'target_type' => 'timeline_update',
|
||||
'target_id' => $this->editingUpdate->id,
|
||||
'old_values' => ['update_text' => $oldText],
|
||||
'new_values' => ['update_text' => $this->updateText],
|
||||
'ip_address' => request()->ip(),
|
||||
]);
|
||||
|
||||
$this->editingUpdate = null;
|
||||
$this->updateText = '';
|
||||
session()->flash('success', __('messages.update_edited'));
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] Can add new updates with rich text
|
||||
- [ ] Can edit existing updates
|
||||
- [ ] Updates display chronologically
|
||||
- [ ] Admin name and timestamp shown
|
||||
- [ ] Client notification sent
|
||||
- [ ] HTML properly sanitized
|
||||
- [ ] Audit log created
|
||||
- [ ] Tests pass
|
||||
- [ ] Code formatted with Pint
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Story 4.1:** Timeline creation
|
||||
- **Epic 8:** Email notifications
|
||||
|
||||
## Estimation
|
||||
|
||||
**Complexity:** Medium
|
||||
**Estimated Effort:** 3-4 hours
|
||||
Reference in New Issue
Block a user