3.5 KiB
3.5 KiB
Story 4.3: Timeline Archiving
Epic Reference
Epic 4: Case Timeline System
User Story
As an admin, I want to archive completed cases and unarchive if needed, So that I can organize active and completed case timelines.
Story Context
Existing System Integration
- Integrates with: timelines table
- Technology: Livewire Volt
- Follows pattern: Soft state change pattern
- Touch points: Timeline list views
Acceptance Criteria
Archive Timeline
- Archive button on timeline detail
- Status changes to 'archived'
- Timeline remains visible to client
- No further updates can be added (until unarchived)
- Visual indicator shows archived status
Unarchive Timeline
- Unarchive button on archived timelines
- Status returns to 'active'
- Updates can be added again
List Filtering
- Filter timelines by status (active/archived/all)
- Archived timelines sorted separately in client view
- Bulk archive option for multiple timelines
Quality Requirements
- Audit log for status changes
- Bilingual labels
- Tests for archive/unarchive
Technical Notes
Timeline Model Methods
class Timeline extends Model
{
public function archive(): void
{
$this->update(['status' => 'archived']);
}
public function unarchive(): void
{
$this->update(['status' => 'active']);
}
public function isArchived(): bool
{
return $this->status === 'archived';
}
public function scopeActive($query)
{
return $query->where('status', 'active');
}
public function scopeArchived($query)
{
return $query->where('status', 'archived');
}
}
Volt Component Actions
public function archive(): void
{
if ($this->timeline->isArchived()) {
return;
}
$this->timeline->archive();
AdminLog::create([
'admin_id' => auth()->id(),
'action_type' => 'archive',
'target_type' => 'timeline',
'target_id' => $this->timeline->id,
'ip_address' => request()->ip(),
]);
session()->flash('success', __('messages.timeline_archived'));
}
public function unarchive(): void
{
if (!$this->timeline->isArchived()) {
return;
}
$this->timeline->unarchive();
AdminLog::create([
'admin_id' => auth()->id(),
'action_type' => 'unarchive',
'target_type' => 'timeline',
'target_id' => $this->timeline->id,
'ip_address' => request()->ip(),
]);
session()->flash('success', __('messages.timeline_unarchived'));
}
public function bulkArchive(array $ids): void
{
Timeline::whereIn('id', $ids)->update(['status' => 'archived']);
foreach ($ids as $id) {
AdminLog::create([
'admin_id' => auth()->id(),
'action_type' => 'archive',
'target_type' => 'timeline',
'target_id' => $id,
'ip_address' => request()->ip(),
]);
}
session()->flash('success', __('messages.timelines_archived', ['count' => count($ids)]));
}
Definition of Done
- Can archive active timeline
- Can unarchive archived timeline
- Cannot add updates to archived timeline
- Filter by status works
- Bulk archive works
- Visual indicators correct
- Audit log created
- Tests pass
- Code formatted with Pint
Dependencies
- Story 4.1: Timeline creation
- Story 4.2: Timeline updates
Estimation
Complexity: Low Estimated Effort: 2 hours