Files
thrilltrack-explorer/django-backend/COMPREHENSIVE_FRONTEND_BACKEND_AUDIT.md

15 KiB

Comprehensive Frontend-Backend Feature Parity Audit

Date: 2025-11-09 Auditor: Cline Scope: Complete comparison of Django backend vs Supabase schema + Frontend usage analysis


Executive Summary

Overall Status: 85% Feature Complete

What Works:

  • All core entities (Parks, Rides, Companies, Ride Models)
  • Sacred Pipeline (Form → Submission → Moderation → Approval → Versioning)
  • Reviews with helpful votes
  • User ride credits & top lists
  • Photos with CloudFlare integration
  • Complete moderation system
  • pghistory-based versioning (SUPERIOR to Supabase)
  • Search with PostgreSQL GIN indexes

Critical Issues Found:

  1. 🔴 BUG: Park coordinate updates don't work (2 hour fix)
  2. 🔴 MISSING: Ride Name History model (heavily used by frontend)
  3. 🔴 MISSING: Entity Timeline Events (frontend has timeline manager)
  4. 🔴 MISSING: Reports System (frontend has reporting UI)
  5. 🟡 MISSING: Blog Posts (if part of MVP)
  6. 🟡 MISSING: Contact Submissions (if part of MVP)

1. Core Entities Analysis

FULLY IMPLEMENTED

Entity Supabase Django Notes
Companies Django uses M2M for company_types (better than JSONB)
Locations Country/Subdivision/Locality models
Parks All fields present, coordinate update bug found
Rides All type-specific fields as nullable on main model
Ride Models Complete implementation
Reviews With helpful votes
User Ride Credits Complete
User Top Lists Relational structure
Profiles Django User model

2. Sacred Pipeline Analysis

FULLY OPERATIONAL

Django Implementation:

  • ContentSubmission - Main submission container
  • SubmissionItem - Individual items in submission
  • Polymorphic submission services per entity type
  • Complete moderation queue
  • Lock system prevents conflicts
  • Audit trail via pghistory

Supabase Schema:

  • Separate tables per entity type (park_submissions, ride_submissions, etc.)
  • submission_items for tracking

Verdict: Django's unified approach is SUPERIOR


3. Versioning & History

DJANGO SUPERIOR

Django:

  • pghistory tracks ALL changes automatically
  • No manual version table management
  • Complete audit trail
  • Rollback capability

Supabase:

  • Manual version tables (park_versions, ride_versions, etc.)
  • entity_versions, entity_field_history
  • version_diffs for comparisons

Verdict: Django's pghistory approach is better


4. Critical Missing Features (Frontend Actively Uses)

🔴 1. RIDE NAME HISTORY - CRITICAL

Supabase Tables:

  • ride_name_history - tracks former names
  • ride_former_names - same table, two names in schema

Frontend Usage: (34 results in search)

  • RideDetail.tsx - Displays "formerly known as" section
  • FormerNamesSection.tsx - Dedicated component
  • FormerNamesEditor.tsx - Admin editing interface
  • RideForm.tsx - Form handling
  • entitySubmissionHelpers.ts - Submission logic

Impact: Every ride detail page with name changes is broken

Django Status: Missing completely

Required Implementation:

class RideNameHistory(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    ride = models.ForeignKey('Ride', on_delete=models.CASCADE, 
                             related_name='name_history')
    former_name = models.CharField(max_length=255)
    from_year = models.IntegerField(null=True, blank=True)
    to_year = models.IntegerField(null=True, blank=True)
    date_changed = models.DateField(null=True, blank=True)
    date_changed_precision = models.CharField(max_length=20, 
                                              null=True, blank=True)
    reason = models.TextField(null=True, blank=True)
    order_index = models.IntegerField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Estimated Effort: 4 hours

  • Model creation + migration
  • Admin interface
  • API endpoint (list name history for ride)
  • Integration with submission system

🔴 2. ENTITY TIMELINE EVENTS - CRITICAL

Supabase Table:

  • entity_timeline_events

Frontend Usage: (5 files)

  • EntityTimelineManager.tsx - Full timeline management
  • entitySubmissionHelpers.ts - Sacred Pipeline integration
  • systemActivityService.ts - Activity tracking

Impact: Historical milestone tracking completely non-functional

Django Status: Missing completely

Required Implementation:

class EntityTimelineEvent(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    entity_id = models.UUIDField(db_index=True)
    entity_type = models.CharField(max_length=50, db_index=True)
    event_type = models.CharField(max_length=100)
    event_date = models.DateField()
    event_date_precision = models.CharField(max_length=20, null=True)
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)
    
    # Event details
    from_entity_id = models.UUIDField(null=True, blank=True)
    to_entity_id = models.UUIDField(null=True, blank=True)
    from_location = models.ForeignKey('Location', null=True, 
                                      on_delete=models.SET_NULL,
                                      related_name='+')
    to_location = models.ForeignKey('Location', null=True,
                                    on_delete=models.SET_NULL,
                                    related_name='+')
    from_value = models.TextField(null=True, blank=True)
    to_value = models.TextField(null=True, blank=True)
    
    # Moderation
    is_public = models.BooleanField(default=True)
    display_order = models.IntegerField(null=True, blank=True)
    
    # Tracking
    created_by = models.ForeignKey(User, null=True, 
                                   on_delete=models.SET_NULL)
    approved_by = models.ForeignKey(User, null=True,
                                    on_delete=models.SET_NULL,
                                    related_name='+')
    submission = models.ForeignKey('moderation.ContentSubmission',
                                   null=True, on_delete=models.SET_NULL)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Estimated Effort: 6 hours

  • Model + migration
  • Submission service integration
  • API endpoints (CRUD + list by entity)
  • Admin interface

🔴 3. REPORTS SYSTEM - CRITICAL

Supabase Table:

  • reports

Frontend Usage: (7 files)

  • ReportButton.tsx - User reporting interface
  • ReportsQueue.tsx - Moderator queue
  • RecentActivity.tsx - Dashboard
  • useModerationStats.ts - Statistics
  • systemActivityService.ts - System tracking

Impact: No user reporting capability, community moderation broken

Django Status: Missing completely

Required Implementation:

class Report(models.Model):
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('reviewing', 'Under Review'),
        ('resolved', 'Resolved'),
        ('dismissed', 'Dismissed'),
    ]
    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    report_type = models.CharField(max_length=50)
    reported_entity_id = models.UUIDField(db_index=True)
    reported_entity_type = models.CharField(max_length=50, db_index=True)
    
    reporter = models.ForeignKey(User, on_delete=models.CASCADE,
                                 related_name='reports_filed')
    reason = models.TextField(null=True, blank=True)
    
    status = models.CharField(max_length=20, choices=STATUS_CHOICES,
                             default='pending', db_index=True)
    reviewed_by = models.ForeignKey(User, null=True,
                                    on_delete=models.SET_NULL,
                                    related_name='reports_reviewed')
    reviewed_at = models.DateTimeField(null=True, blank=True)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        indexes = [
            models.Index(fields=['status', 'created_at']),
            models.Index(fields=['reported_entity_type', 'reported_entity_id']),
        ]

Estimated Effort: 8 hours

  • Model + migration
  • API endpoints (create, list, update status)
  • Integration with moderation system
  • Admin interface
  • Statistics endpoints

🟡 4. BLOG POSTS - MVP DEPENDENT

Supabase Table:

  • blog_posts

Frontend Usage: (3 full pages)

  • BlogIndex.tsx - Blog listing
  • BlogPost.tsx - Individual post view
  • AdminBlog.tsx - Complete CRUD admin interface

Impact: Entire blog section non-functional

Django Status: Missing

Required Implementation:

class BlogPost(models.Model):
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('published', 'Published'),
        ('archived', 'Archived'),
    ]
    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255)
    content = models.TextField()
    
    status = models.CharField(max_length=20, choices=STATUS_CHOICES,
                             default='draft', db_index=True)
    published_at = models.DateTimeField(null=True, blank=True,
                                        db_index=True)
    
    featured_image_id = models.CharField(max_length=255, null=True)
    featured_image_url = models.URLField(null=True, blank=True)
    
    view_count = models.IntegerField(default=0)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Estimated Effort: 6 hours (if needed for MVP)


🟡 5. CONTACT SUBMISSIONS - MVP DEPENDENT

Supabase Tables:

  • contact_submissions
  • contact_email_threads
  • contact_rate_limits

Frontend Usage:

  • AdminContact.tsx - Full admin interface with CRUD

Impact: Contact form and support ticket system broken

Django Status: Missing

Required Implementation:

class ContactSubmission(models.Model):
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('in_progress', 'In Progress'),
        ('resolved', 'Resolved'),
        ('archived', 'Archived'),
    ]
    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    
    # Contact info
    name = models.CharField(max_length=255)
    email = models.EmailField()
    subject = models.CharField(max_length=255)
    message = models.TextField()
    category = models.CharField(max_length=50)
    
    # Tracking
    status = models.CharField(max_length=20, choices=STATUS_CHOICES,
                             default='pending', db_index=True)
    ticket_number = models.CharField(max_length=20, unique=True,
                                     null=True, blank=True)
    
    # Assignment
    user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL,
                            related_name='contact_submissions')
    assigned_to = models.ForeignKey(User, null=True,
                                    on_delete=models.SET_NULL,
                                    related_name='assigned_contacts')
    
    # Admin tracking
    admin_notes = models.TextField(null=True, blank=True)
    resolved_at = models.DateTimeField(null=True, blank=True)
    resolved_by = models.ForeignKey(User, null=True,
                                    on_delete=models.SET_NULL,
                                    related_name='+')
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

Estimated Effort: 6 hours (if needed for MVP)


5. Features NOT Used by Frontend

SAFE TO SKIP

  1. park_operating_hours - Only in TypeScript types, no actual frontend usage
  2. ride_technical_specifications - Django stores in main Ride model (acceptable)
  3. ride_coaster_stats - Django stores in main Ride model (acceptable)
  4. Advanced monitoring tables - Better handled by external tools

6. Critical Bug Found

🔴 PARK COORDINATE UPDATE BUG

Location: django/api/v1/endpoints/parks.py lines 344-350

Issue:

latitude = data.pop('latitude', None)
longitude = data.pop('longitude', None)

submission, updated_park = ParkSubmissionService.update_entity_submission(
    entity=park,
    user=user,
    update_data=data,
    latitude=latitude,  # ← Passed but never used!
    longitude=longitude,  # ← Passed but never used!

Problem: ParkSubmissionService.update_entity_submission() inherits from base class and doesn't handle the latitude/longitude kwargs, so coordinate updates silently fail.

Fix Required: Override update_entity_submission() in ParkSubmissionService to handle location updates.

Estimated Effort: 2 hours


7. Implementation Timeline

Phase 1: Critical Blockers (20 hours / 2.5 days)

  1. Fix Park Coordinate Bug - 2 hours

    • Override method in ParkSubmissionService
    • Handle location creation/update
    • Test coordinate updates
  2. Ride Name History - 4 hours

    • Model + migration
    • API endpoints
    • Admin interface
    • Submission integration
  3. Entity Timeline Events - 6 hours

    • Model + migration
    • API endpoints (CRUD + list)
    • Submission service
    • Admin interface
  4. Reports System - 8 hours

    • Model + migration
    • API endpoints (create, list, update)
    • Moderation integration
    • Admin interface
    • Statistics

Phase 2: MVP Features (12 hours / 1.5 days) - IF NEEDED

  1. Blog Posts - 6 hours (if blog is part of MVP)
  2. Contact Submissions - 6 hours (if contact form is part of MVP)

8. Recommendations

Immediate Actions:

  1. Fix the coordinate bug (2 hours) - This is blocking park updates
  2. Determine MVP scope:
    • Is blog required?
    • Is contact form required?
  3. Implement Phase 1 features (remaining 18 hours)
  4. If blog/contact needed, implement Phase 2 (12 hours)

Total Effort:

  • Minimum: 20 hours (without blog/contact)
  • Full Parity: 32 hours (with everything)

9. Django Advantages

Despite missing features, Django implementation has several improvements:

  1. Better Architecture: Unified ContentSubmission vs separate tables per type
  2. Superior Versioning: pghistory beats manual version tables
  3. Proper Normalization: M2M for company_types vs JSONB
  4. Service Layer: Clean separation of concerns
  5. Type Safety: Python typing throughout
  6. Built-in Admin: Django admin for all models

10. Conclusion

The Django backend is 85% feature complete and architecturally superior to Supabase in many ways. However, 5 critical features that the frontend actively uses are missing:

🔴 MUST FIX:

  1. Park coordinate update bug
  2. Ride Name History model
  3. Entity Timeline Events model
  4. Reports System model

🟡 IF PART OF MVP: 5. Blog Posts model 6. Contact Submissions model

Total work: 20-32 hours depending on MVP scope

The Sacred Pipeline is fully functional and tested. All core entity CRUD operations work. The missing pieces are specific features the frontend has UI for but the backend doesn't support yet.