Files
thrilltrack-explorer/migration/PHASE_06_MODERATION_ADMIN.md

257 lines
7.6 KiB
Markdown

# PHASE 6: Moderation & Admin
**Status:** ⬜ Not Started
**Estimated Time:** 10-12 hours
**Priority:** CRITICAL
**Depends On:** Phase 1 (Foundation), Phase 3 (Sacred Pipeline)
**Blocks:** Phase 12 (Pages Migration)
---
## 🎯 Goal
Complete migration of moderation system from Supabase to Django, including moderation queue, approval/rejection flows, and admin dashboard.
---
## 📋 Tasks
### Task 6.1: Moderation Service (4 hours)
**File:** `src/services/moderation/moderationService.ts`
#### Create Core Service
```typescript
class ModerationService extends BaseService {
// GET /moderation/queue/
async getModerationQueue(filters?: QueueFilters): Promise<PaginatedResponse<ContentSubmission>>
// POST /moderation/queue/claim/
async claimNextSubmission(): Promise<ContentSubmission | null>
// POST /moderation/submissions/{id}/start-review/
async startReview(submissionId: string): Promise<ModerationLock>
// POST /moderation/submissions/{id}/extend-lock/
async extendLock(submissionId: string): Promise<ModerationLock>
// POST /moderation/submissions/{id}/release-lock/
async releaseLock(submissionId: string): Promise<void>
// POST /moderation/submissions/{id}/approve/
async approveSubmission(submissionId: string, notes?: string): Promise<void>
// POST /moderation/submissions/{id}/reject/
async rejectSubmission(submissionId: string, reason: string): Promise<void>
// POST /moderation/submissions/{id}/approve-selective/
async approveSelective(submissionId: string, itemIds: string[]): Promise<void>
// GET /moderation/stats/
async getModerationStats(): Promise<ModerationStats>
// GET /moderation/submissions/{id}/
async getSubmission(submissionId: string): Promise<ContentSubmission>
// GET /moderation/submissions/{id}/items/
async getSubmissionItems(submissionId: string): Promise<SubmissionItem[]>
}
```
#### Checklist
- [ ] Create `moderationService.ts` with all methods
- [ ] Create types for moderation operations
- [ ] Create mappers for API transformations
- [ ] Handle lock management properly
- [ ] Handle selective approval logic
- [ ] Export from `src/services/moderation/index.ts`
---
### Task 6.2: Update ModerationQueue Component (3 hours)
**File:** `src/components/moderation/ModerationQueue.tsx`
#### Replace ALL Supabase Calls
```typescript
// OLD - Supabase
const { data } = await supabase.from('content_submissions')
.select('*')
.eq('status', 'pending_review');
// NEW - Django Service
const submissions = await moderationService.getModerationQueue({
status: 'pending_review'
});
```
#### Checklist
- [ ] Replace queue fetching with `moderationService.getModerationQueue()`
- [ ] Replace claim logic with `moderationService.claimNextSubmission()`
- [ ] Update lock extension with `moderationService.extendLock()`
- [ ] Update lock release with `moderationService.releaseLock()`
- [ ] Remove all realtime subscriptions (Django uses polling or WebSockets)
- [ ] Test queue display
- [ ] Test claiming submissions
- [ ] Verify lock management works
---
### Task 6.3: Update Approval/Rejection Components (2 hours)
**Files:**
- `src/components/moderation/ApprovalDialog.tsx`
- `src/components/moderation/RejectionDialog.tsx`
- `src/components/moderation/SelectiveApprovalDialog.tsx`
#### Checklist
- [ ] Replace approval with `moderationService.approveSubmission()`
- [ ] Replace rejection with `moderationService.rejectSubmission()`
- [ ] Replace selective approval with `moderationService.approveSelective()`
- [ ] Update success/error handling
- [ ] Test all three approval flows
- [ ] Verify Sacred Pipeline integrity
---
### Task 6.4: Update Admin Dashboard (3 hours)
**Files:**
- `src/pages/AdminDashboard.tsx`
- `src/components/admin/ModerationStats.tsx`
- `src/components/admin/PipelineHealthAlerts.tsx`
#### Replace Admin Queries
```typescript
// OLD - Supabase
const { data } = await supabase.rpc('get_moderation_stats');
// NEW - Django Service
const stats = await moderationService.getModerationStats();
```
#### Checklist
- [ ] Replace `supabase.rpc('get_moderation_stats')` with service
- [ ] Update pipeline health monitoring
- [ ] Remove Supabase admin audit log calls
- [ ] Update admin user management (if any)
- [ ] Test admin dashboard loads
- [ ] Test stats display correctly
---
## 🎯 Success Criteria
### Service Layer
- [ ] ModerationService created and fully functional
- [ ] All moderation operations use service
- [ ] Lock management works correctly
- [ ] Selective approval works
- [ ] Stats fetching works
### Components
- [ ] Zero `supabase.from('content_submissions')` calls
- [ ] Zero `supabase.from('moderation_locks')` calls
- [ ] Zero `supabase.rpc()` calls for moderation
- [ ] ModerationQueue works with Django
- [ ] All approval flows work
- [ ] Admin dashboard works
### Testing
- [ ] Can view moderation queue
- [ ] Can claim a submission
- [ ] Lock extends automatically
- [ ] Can approve submission
- [ ] Can reject submission
- [ ] Can selective approve (approve some items, reject others)
- [ ] Lock releases on page navigation
- [ ] Stats update correctly
- [ ] Pipeline health monitoring works
### Sacred Pipeline
- [ ] All approvals go through Django
- [ ] No bypass of moderation system
- [ ] Versioning happens on approval
- [ ] Rejection reasons are saved
- [ ] Admin notes are saved
---
## 📝 Implementation Notes
### Lock Management
- Locks prevent multiple moderators from reviewing same submission
- Locks auto-extend every 30 seconds (client-side timer)
- Locks auto-release after 5 minutes of inactivity (server-side)
- Must release lock on component unmount
- Must release lock on page navigation
### Selective Approval
- Allows approving some submission items while rejecting others
- Common for batch submissions (e.g., adding 10 rides at once)
- Each item can be individually approved/rejected
- Must maintain data integrity
### Realtime Updates
- Supabase used realtime subscriptions for queue updates
- Django migration: either polling (every 10s) or WebSockets
- For MVP, polling is acceptable
- Queue should refresh when lock is released
### Admin Permissions
- Only users with `role='moderator'` or `role='admin'` can access
- Backend enforces permissions on all endpoints
- Frontend should hide moderation UI for non-moderators
---
## 🔗 Related Files
### Services
- `src/services/moderation/moderationService.ts`
- `src/services/moderation/types.ts`
- `src/services/moderation/mappers.ts`
### Components
- `src/components/moderation/ModerationQueue.tsx`
- `src/components/moderation/QueueFilters.tsx`
- `src/components/moderation/SubmissionCard.tsx`
- `src/components/moderation/ApprovalDialog.tsx`
- `src/components/moderation/RejectionDialog.tsx`
- `src/components/moderation/SelectiveApprovalDialog.tsx`
- `src/components/admin/ModerationStats.tsx`
- `src/components/admin/PipelineHealthAlerts.tsx`
### Pages
- `src/pages/AdminDashboard.tsx`
- `src/pages/ModerationQueue.tsx`
### Hooks
- `src/hooks/useModerationQueue.ts`
- `src/hooks/useModerationStats.ts`
- `src/hooks/useModerationLock.ts`
---
## 🚨 Critical Warnings
### DO NOT
- ❌ Create any bypass mechanism for moderation
- ❌ Allow direct database writes without submissions
- ❌ Skip versioning on approval
- ❌ Allow approvals without proper permissions
- ❌ Leave locks hanging (always cleanup)
### MUST DO
- ✅ ALL entity changes go through ContentSubmission
- ✅ Locks are properly managed and released
- ✅ Selective approval maintains data integrity
- ✅ Admin permissions are enforced
- ✅ Rejection reasons are mandatory
---
## ⏭️ Next Phase
**Phase 7:** Media & Photos - Migrate photo upload and management to Django + CloudFlare Images.