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

12 KiB

Phase 1 Frontend Feature Parity - Implementation Status

Date: November 9, 2025
Status: PARTIALLY COMPLETE (30% - 6 of 20 hours completed)

Overview

Phase 1 addresses critical missing features identified in the comprehensive frontend-backend audit to achieve 100% feature parity between the Django backend and the Supabase schema that the frontend expects.


COMPLETED WORK (6 hours)

Task 1: Fixed Park Coordinate Update Bug (2 hours) COMPLETE

Problem: Park location coordinates couldn't be updated via API because the latitude and longitude parameters were passed to ParkSubmissionService.update_entity_submission() but never used.

Solution Implemented:

  • File: django/apps/entities/services/park_submission.py
  • Added override method that extracts and handles coordinates
  • Coordinates now properly update when moderators bypass the Sacred Pipeline
  • Full tracking through ContentSubmission for audit trail

Files Modified:

  • django/apps/entities/services/park_submission.py

Task 2: Implemented Ride Name History Model & API (4 hours) COMPLETE

Frontend Usage: Used in 34+ places across 6 files (RideDetail.tsx, FormerNamesSection.tsx, FormerNamesEditor.tsx, etc.)

Completed:

  1. Created RideNameHistory model in django/apps/entities/models.py
  2. Generated migration django/apps/entities/migrations/0007_add_ride_name_history.py
  3. Added admin interface with RideNameHistoryInline in django/apps/entities/admin.py
  4. Created RideNameHistoryOut schema in django/api/v1/schemas.py
  5. Added API endpoint GET /api/v1/rides/{ride_id}/name-history/ in django/api/v1/endpoints/rides.py

Model Features:

@pghistory.track()
class RideNameHistory(BaseModel):
    ride = models.ForeignKey('Ride', on_delete=models.CASCADE, related_name='name_history')
    former_name = models.CharField(max_length=255, db_index=True)
    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, db_index=True)

API Endpoint:

  • URL: GET /api/v1/rides/{ride_id}/name-history/
  • Response: List of historical names with date ranges
  • Authentication: Not required for read access

Files Modified:

  • django/apps/entities/models.py
  • django/apps/entities/migrations/0007_add_ride_name_history.py
  • django/apps/entities/admin.py
  • django/api/v1/schemas.py
  • django/api/v1/endpoints/rides.py

🔄 IN PROGRESS WORK

Task 3: Implement Entity Timeline Events (Started - 0 of 6 hours)

Frontend Usage: 5 files actively use this: EntityTimelineManager.tsx, entitySubmissionHelpers.ts, systemActivityService.ts

Progress:

  • Created timeline app structure (django/apps/timeline/)
  • Created __init__.py and apps.py
  • NEXT: Create EntityTimelineEvent model
  • Generate and run migration
  • Add admin interface
  • Create timeline API endpoints
  • Update settings.py

Required Model Structure:

@pghistory.track()
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('entities.Location', null=True, on_delete=models.SET_NULL, related_name='+')
    to_location = models.ForeignKey('entities.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('users.User', null=True, on_delete=models.SET_NULL)
    approved_by = models.ForeignKey('users.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)
    
    class Meta:
        ordering = ['-event_date', '-created_at']
        indexes = [
            models.Index(fields=['entity_type', 'entity_id', '-event_date']),
            models.Index(fields=['event_type', '-event_date']),
        ]

Required API Endpoints:

  • GET /api/v1/timeline/entity/{entity_type}/{entity_id}/ - Get timeline for entity
  • GET /api/v1/timeline/recent/ - Get recent timeline events
  • POST /api/v1/timeline/ - Create timeline event (moderators)
  • PATCH /api/v1/timeline/{id}/ - Update timeline event (moderators)
  • DELETE /api/v1/timeline/{id}/ - Delete timeline event (moderators)

PENDING WORK (14 hours remaining)

Task 4: Implement Reports System (8 hours) - NOT STARTED

Frontend Usage: 7 files actively use reporting: ReportButton.tsx, ReportsQueue.tsx, RecentActivity.tsx, useModerationStats.ts, systemActivityService.ts

Required Implementation:

  1. Create reports app (django/apps/reports/)

    • __init__.py, apps.py, models.py, admin.py, services.py
  2. Create Report model:

@pghistory.track()
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('users.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('users.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)
  1. Create API endpoints:

    • POST /api/v1/reports/ - Create report
    • GET /api/v1/reports/ - List reports (moderators only)
    • GET /api/v1/reports/{id}/ - Get report detail
    • PATCH /api/v1/reports/{id}/ - Update status (moderators)
    • GET /api/v1/reports/stats/ - Statistics (moderators)
  2. Implement permissions:

    • Users can create reports
    • Only moderators can view/review reports
    • Moderators can update status and add review notes
  3. Add admin interface with Unfold theme

  4. Update settings.py to include 'apps.reports'


📋 IMPLEMENTATION CHECKLIST

Immediate Next Steps (Task 3 Completion)

  • Create django/apps/timeline/models.py with EntityTimelineEvent model
  • Generate migration: python manage.py makemigrations timeline
  • Run migration: python manage.py migrate timeline
  • Create django/apps/timeline/admin.py with EntityTimelineEventAdmin
  • Add 'apps.timeline' to config/settings/base.py INSTALLED_APPS
  • Create timeline API schemas in django/api/v1/schemas.py
  • Create django/api/v1/endpoints/timeline.py with endpoints
  • Add timeline router to django/api/v1/api.py
  • Test timeline functionality

Task 4 Steps (Reports System)

  • Create django/apps/reports/ directory
  • Create reports app files: init.py, apps.py, models.py, admin.py
  • Create Report model with pghistory tracking
  • Generate and run migration
  • Add 'apps.reports' to settings INSTALLED_APPS
  • Create report API schemas
  • Create django/api/v1/endpoints/reports.py
  • Implement permissions (users create, moderators review)
  • Add reports router to API
  • Create admin interface
  • Test reporting functionality
  • Document usage

Final Steps

  • Run all pending migrations
  • Test all new endpoints with curl/Postman
  • Update API documentation
  • Create completion document
  • Mark Phase 1 as complete

🔧 Key Technical Patterns to Follow

1. All Models Must Use @pghistory.track()

import pghistory

@pghistory.track()
class MyModel(models.Model):
    # fields here

2. Use Django Ninja for API Endpoints

from ninja import Router

router = Router(tags=["Timeline"])

@router.get("/{entity_type}/{entity_id}/", response={200: List[TimelineEventOut]})
def get_entity_timeline(request, entity_type: str, entity_id: UUID):
    # implementation

3. Register in Admin with Unfold Theme

from unfold.admin import ModelAdmin

@admin.register(EntityTimelineEvent)
class EntityTimelineEventAdmin(ModelAdmin):
    list_display = ['event_type', 'entity_type', 'entity_id', 'event_date']

4. Add Proper Database Indexes

class Meta:
    indexes = [
        models.Index(fields=['entity_type', 'entity_id', '-event_date']),
        models.Index(fields=['status', 'created_at']),
    ]

5. Use BaseModel or VersionedModel for Timestamps

from apps.core.models import BaseModel

class MyModel(BaseModel):
    # Automatically includes created_at, updated_at

📊 Progress Summary

Total Estimated: 20 hours
Completed: 6 hours (30%)
Remaining: 14 hours (70%)

  • Task 1: Complete (2 hours)
  • Task 2: Complete (4 hours)
  • Task 3: 🔄 Started (0 of 6 hours completed)
  • Task 4: Not started (8 hours)

🚀 Recommendations

Option A: Complete Phase 1 Incrementally

Continue with Task 3 and Task 4 implementation. This is the original plan and provides full feature parity.

Pros:

  • Complete feature parity with frontend
  • All frontend code can function as expected
  • No technical debt

Cons:

  • Requires 14 more hours of development
  • More complex to test all at once

Option B: Deploy What's Complete, Continue Later

Deploy Tasks 1 & 2 now, continue with Tasks 3 & 4 in Phase 2.

Pros:

  • Immediate value from completed work
  • Ride name history (heavily used feature) available now
  • Can gather feedback before continuing

Cons:

  • Frontend timeline features won't work until Task 3 complete
  • Frontend reporting features won't work until Task 4 complete
  • Requires two deployment cycles

Option C: Focus on High-Impact Features

Prioritize Task 3 (Timeline Events) which is used in 5 files, defer Task 4 (Reports) which could be implemented as an enhancement.

Pros:

  • Balances completion time vs. impact
  • Timeline is more core to entity tracking
  • Reports could be a nice-to-have

Cons:

  • Still leaves reporting incomplete
  • Frontend reporting UI won't function

📝 Notes

  • All implementations follow the "Sacred Pipeline" pattern for user-submitted data
  • Timeline and Reports apps are independent and can be implemented in any order
  • Migration 0007_add_ride_name_history is ready to run
  • Timeline app structure is in place, ready for model implementation

📚 Reference Documentation

  • django/COMPREHENSIVE_FRONTEND_BACKEND_AUDIT.md - Original audit identifying these gaps
  • django/PHASE_1_FRONTEND_PARITY_PARTIAL_COMPLETE.md - Previous progress documentation
  • django/SACRED_PIPELINE_AUDIT_AND_IMPLEMENTATION_PLAN.md - Sacred Pipeline patterns
  • django/API_GUIDE.md - API implementation patterns
  • django/ADMIN_GUIDE.md - Admin interface patterns