# 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> // POST /moderation/queue/claim/ async claimNextSubmission(): Promise // POST /moderation/submissions/{id}/start-review/ async startReview(submissionId: string): Promise // POST /moderation/submissions/{id}/extend-lock/ async extendLock(submissionId: string): Promise // POST /moderation/submissions/{id}/release-lock/ async releaseLock(submissionId: string): Promise // POST /moderation/submissions/{id}/approve/ async approveSubmission(submissionId: string, notes?: string): Promise // POST /moderation/submissions/{id}/reject/ async rejectSubmission(submissionId: string, reason: string): Promise // POST /moderation/submissions/{id}/approve-selective/ async approveSelective(submissionId: string, itemIds: string[]): Promise // GET /moderation/stats/ async getModerationStats(): Promise // GET /moderation/submissions/{id}/ async getSubmission(submissionId: string): Promise // GET /moderation/submissions/{id}/items/ async getSubmissionItems(submissionId: string): Promise } ``` #### 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.