4.1 KiB
4.1 KiB
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
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
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