mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 20:51:17 -05:00
257 lines
7.6 KiB
Markdown
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.
|