reviewed epic 5 & 6 stories
This commit is contained in:
@@ -11,10 +11,11 @@ So that **I can organize, publish, and maintain content efficiently**.
|
||||
## Story Context
|
||||
|
||||
### Existing System Integration
|
||||
- **Integrates with:** posts table
|
||||
- **Integrates with:** posts table, admin_logs table
|
||||
- **Technology:** Livewire Volt with pagination
|
||||
- **Follows pattern:** Admin list pattern
|
||||
- **Touch points:** Post CRUD operations
|
||||
- **Follows pattern:** Admin list pattern (see similar components in `resources/views/livewire/admin/`)
|
||||
- **Touch points:** Post CRUD operations, AdminLog audit trail
|
||||
- **Note:** HTML sanitization uses `clean()` helper (from mews/purifier package, configured in Story 5.1)
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
@@ -39,16 +40,34 @@ So that **I can organize, publish, and maintain content efficiently**.
|
||||
|
||||
### Quality Requirements
|
||||
- [ ] Bilingual labels
|
||||
- [ ] Audit log for delete actions
|
||||
- [ ] Audit log for delete and status change actions
|
||||
- [ ] Authorization check (admin only) on all actions
|
||||
- [ ] Tests for list operations
|
||||
|
||||
### Edge Cases
|
||||
- [ ] Handle post not found gracefully (race condition on delete)
|
||||
- [ ] Per-page selector visible in UI (10/25/50 options)
|
||||
- [ ] Bulk delete is **out of scope** for this story (marked optional)
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### File Location
|
||||
Create Volt component at: `resources/views/livewire/admin/posts/index.blade.php`
|
||||
|
||||
### Route
|
||||
```php
|
||||
// routes/web.php (admin group)
|
||||
Route::get('/admin/posts', function () {
|
||||
return view('livewire.admin.posts.index');
|
||||
})->middleware(['auth', 'admin'])->name('admin.posts.index');
|
||||
```
|
||||
|
||||
### Volt Component
|
||||
```php
|
||||
<?php
|
||||
|
||||
use App\Models\Post;
|
||||
use App\Models\AdminLog;
|
||||
use Livewire\Volt\Component;
|
||||
use Livewire\WithPagination;
|
||||
|
||||
@@ -154,6 +173,11 @@ new class extends Component {
|
||||
<option value="draft">{{ __('admin.draft') }}</option>
|
||||
<option value="published">{{ __('admin.published') }}</option>
|
||||
</flux:select>
|
||||
<flux:select wire:model.live="perPage">
|
||||
<option value="10">10 {{ __('admin.per_page') }}</option>
|
||||
<option value="25">25 {{ __('admin.per_page') }}</option>
|
||||
<option value="50">50 {{ __('admin.per_page') }}</option>
|
||||
</flux:select>
|
||||
</div>
|
||||
|
||||
<!-- Posts Table -->
|
||||
@@ -220,6 +244,65 @@ new class extends Component {
|
||||
</div>
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Test Scenarios
|
||||
```php
|
||||
// tests/Feature/Admin/PostManagementTest.php
|
||||
|
||||
test('admin can view posts list', function () {
|
||||
// Create admin, create posts, visit index, assert sees posts
|
||||
});
|
||||
|
||||
test('admin can filter posts by status', function () {
|
||||
// Create draft and published posts
|
||||
// Filter by 'draft' - only drafts visible
|
||||
// Filter by 'published' - only published visible
|
||||
// Filter by '' (all) - all visible
|
||||
});
|
||||
|
||||
test('admin can search posts by title in current locale', function () {
|
||||
// Create posts with known titles
|
||||
// Search by partial title - matches appear
|
||||
// Search with no matches - empty state shown
|
||||
});
|
||||
|
||||
test('admin can search posts by body content', function () {
|
||||
// Create posts with known body content
|
||||
// Search by body text - matches appear
|
||||
});
|
||||
|
||||
test('admin can sort posts by date', function () {
|
||||
// Create posts with different dates
|
||||
// Sort desc - newest first
|
||||
// Sort asc - oldest first
|
||||
});
|
||||
|
||||
test('admin can toggle post publish status', function () {
|
||||
// Create draft post
|
||||
// Toggle - becomes published, AdminLog created
|
||||
// Toggle again - becomes draft, AdminLog created
|
||||
});
|
||||
|
||||
test('admin can delete post with confirmation', function () {
|
||||
// Create post
|
||||
// Delete - post removed, AdminLog created
|
||||
});
|
||||
|
||||
test('pagination works correctly', function () {
|
||||
// Create 15 posts
|
||||
// Page 1 shows 10, page 2 shows 5
|
||||
});
|
||||
|
||||
test('audit log records status changes', function () {
|
||||
// Toggle status, verify AdminLog entry with old/new values
|
||||
});
|
||||
|
||||
test('audit log records deletions', function () {
|
||||
// Delete post, verify AdminLog entry with old values
|
||||
});
|
||||
```
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] List displays all posts
|
||||
@@ -229,13 +312,15 @@ new class extends Component {
|
||||
- [ ] Quick publish/unpublish toggle works
|
||||
- [ ] Delete with confirmation works
|
||||
- [ ] Pagination works
|
||||
- [ ] Per-page selector works (10/25/50)
|
||||
- [ ] Audit log for actions
|
||||
- [ ] Tests pass
|
||||
- [ ] All test scenarios pass
|
||||
- [ ] Code formatted with Pint
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Story 5.1:** Post creation
|
||||
- **Story 5.1:** Post creation - `docs/stories/story-5.1-post-creation-editing.md`
|
||||
- **Requires:** Post model with bilingual accessors, AdminLog model
|
||||
|
||||
## Estimation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user