Files
thrilltrack-explorer/migration/PHASE_06_MODERATION_ADMIN.md

7.6 KiB

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

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

// 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

// 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

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.