# Phase 1 Critical Implementation - Frontend Feature Parity **Status:** Partial Complete (Tasks 1-2 Done) **Date:** 2025-11-09 **Estimated Time:** 6 hours completed of 20 hours total ## Overview Implementing critical missing features to achieve Django backend feature parity with the Supabase schema and frontend code usage. Based on comprehensive audit in `COMPREHENSIVE_FRONTEND_BACKEND_AUDIT.md`. --- ## ✅ Task 1: Fix Park Coordinate Update Bug (COMPLETED - 2 hours) ### Problem Park location coordinates couldn't be updated via API. The `latitude` and `longitude` parameters were being passed to `ParkSubmissionService.update_entity_submission()` but were never used. ### Root Cause The `ParkSubmissionService` inherited `update_entity_submission()` from base class but didn't handle the coordinate kwargs. ### Solution Implemented **File:** `django/apps/entities/services/park_submission.py` Added override of `update_entity_submission()` method: ```python @classmethod def update_entity_submission(cls, entity, user, update_data, **kwargs): """ Update a Park with special coordinate handling. Overrides base class to handle latitude/longitude updates using the Park model's set_location() method which handles both SQLite and PostGIS modes. """ # Extract coordinates for special handling latitude = kwargs.pop('latitude', None) longitude = kwargs.pop('longitude', None) # If coordinates are provided, add them to update_data for tracking if latitude is not None: update_data['latitude'] = latitude if longitude is not None: update_data['longitude'] = longitude # Create update submission through base class submission, updated_park = super().update_entity_submission( entity, user, update_data, **kwargs ) # If park was updated (moderator bypass), set location using helper method if updated_park and (latitude is not None and longitude is not None): try: updated_park.set_location(float(longitude), float(latitude)) updated_park.save() logger.info(f"Park {updated_park.id} location updated: ({latitude}, {longitude})") except Exception as e: logger.warning(f"Failed to update location for Park {updated_park.id}: {str(e)}") return submission, updated_park ``` ### Testing Required - Test coordinate updates via API endpoints - Verify both SQLite (lat/lng) and PostGIS (location_point) modes work correctly - Confirm moderator bypass updates coordinates immediately - Verify regular user submissions track coordinate changes --- ## ✅ Task 2: Implement Ride Name History Model (COMPLETED - 4 hours) ### Frontend Usage Heavily used in 34 places across 6+ files: - `RideDetail.tsx` - Shows "formerly known as" section - `FormerNamesSection.tsx` - Display component - `FormerNamesEditor.tsx` - Admin editing - `RideForm.tsx` - Form handling - `entitySubmissionHelpers.ts` - Submission logic ### Implementation #### 1. Model Created **File:** `django/apps/entities/models.py` ```python @pghistory.track() class RideNameHistory(BaseModel): """ Tracks historical names for rides. Rides can change names over their lifetime, and this model maintains a complete history of all former names with optional date ranges and reasons. """ ride = models.ForeignKey( 'Ride', on_delete=models.CASCADE, related_name='name_history', help_text="Ride this name history belongs to" ) former_name = models.CharField( max_length=255, db_index=True, help_text="Previous name of the ride" ) # Date range when this name was used from_year = models.IntegerField(null=True, blank=True) to_year = models.IntegerField(null=True, blank=True) # Precise date of name change (optional) date_changed = models.DateField(null=True, blank=True) date_changed_precision = models.CharField(max_length=20, null=True, blank=True) # Context reason = models.TextField(null=True, blank=True) # Display ordering order_index = models.IntegerField(null=True, blank=True, db_index=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = 'Ride Name History' verbose_name_plural = 'Ride Name Histories' ordering = ['ride', '-to_year', '-from_year', 'order_index'] indexes = [ models.Index(fields=['ride', 'from_year']), models.Index(fields=['ride', 'to_year']), models.Index(fields=['former_name']), ] ``` #### 2. Migration Created **File:** `django/apps/entities/migrations/0007_add_ride_name_history.py` Migration includes: - RideNameHistory model creation - RideNameHistoryEvent model for pghistory tracking - Proper indexes on ride, from_year, to_year, and former_name - pghistory triggers for automatic change tracking #### 3. Admin Interface Added **File:** `django/apps/entities/admin.py` - Added `RideNameHistory` to imports - Created `RideNameHistoryInline` for inline editing within Ride admin - Added inline to `RideAdmin.inlines` - Fields: former_name, from_year, to_year, date_changed, reason, order_index - Collapsible section in ride detail page ### Remaining Work for Task 2 - [ ] Create API endpoint: `GET /api/v1/rides/{ride_id}/name-history/` - [ ] Add name_history to ride detail serialization - [ ] Consider if CRUD operations need Sacred Pipeline integration --- ## 🔄 Task 3: Implement Entity Timeline Events (NOT STARTED - 6 hours) ### Frontend Usage 5 files actively use this: - `EntityTimelineManager.tsx` - Full timeline UI - `entitySubmissionHelpers.ts` - Sacred Pipeline integration - `systemActivityService.ts` - Activity tracking ### Required Implementation 1. Create new `django/apps/timeline/` app 2. Create `EntityTimelineEvent` model with: - Entity tracking (entity_id, entity_type) - Event details (type, date, title, description) - Location changes (from_location, to_location) - Value changes (from_value, to_value) - Moderation support (is_public, created_by, approved_by) - Submission integration 3. Integrate with Sacred Pipeline (submission flow) 4. Create API endpoints (CRUD + list by entity) 5. Add admin interface 6. Update `config/settings/base.py` INSTALLED_APPS --- ## 🔄 Task 4: Implement Reports System (NOT STARTED - 8 hours) ### Frontend Usage 7 files actively use reporting: - `ReportButton.tsx` - User reporting UI - `ReportsQueue.tsx` - Moderator review queue - `RecentActivity.tsx` - Dashboard display - `useModerationStats.ts` - Statistics hooks - `systemActivityService.ts` - System tracking ### Required Implementation 1. Create new `django/apps/reports/` app 2. Create `Report` model with: - Report type and entity tracking - Reporter information - Status workflow (pending → reviewing → resolved/dismissed) - Reviewer tracking - Proper indexes for performance 3. Create API endpoints: - POST `/api/v1/reports/` - Create report - GET `/api/v1/reports/` - List reports (moderators only) - PATCH `/api/v1/reports/{id}/` - Update status - GET `/api/v1/reports/stats/` - Statistics 4. Implement permissions (users can create, moderators can review) 5. Add admin interface 6. Update settings --- ## Key Architecture Patterns Followed ### 1. pghistory Integration - All models use `@pghistory.track()` decorator - Automatic change tracking with pghistory events - Maintains audit trail for all changes ### 2. Admin Interface - Using Unfold theme for modern UI - Inline editing for related models - Proper fieldsets and collapsible sections - Search and filter capabilities ### 3. Model Design - Proper indexes for performance - Foreign key relationships with appropriate `on_delete` - `created_at` and `updated_at` timestamps - Help text for documentation --- ## Success Criteria Progress - [x] Park coordinates can be updated via API - [x] Ride name history model exists - [x] Ride name history admin interface functional - [ ] Ride name history displayed on ride detail pages - [ ] Timeline events can be created and displayed - [ ] Users can report content - [ ] Moderators can review reports - [ ] All models have admin interfaces - [ ] All functionality follows Sacred Pipeline where appropriate - [ ] Proper permissions enforced - [ ] No regressions to existing functionality --- ## Next Steps 1. **Complete Task 2 (remaining items)**: - Add API endpoint for ride name history - Add to ride detail serialization 2. **Implement Task 3 (Timeline Events)**: - Create timeline app structure - Implement EntityTimelineEvent model - Sacred Pipeline integration - API endpoints and admin 3. **Implement Task 4 (Reports System)**: - Create reports app structure - Implement Report model - API endpoints with permissions - Admin interface and statistics 4. **Testing & Validation**: - Test all new endpoints - Verify frontend integration - Check permissions enforcement - Performance testing with indexes --- ## Files Modified ### Task 1 (Park Coordinates) - `django/apps/entities/services/park_submission.py` ### Task 2 (Ride Name History) - `django/apps/entities/models.py` - `django/apps/entities/migrations/0007_add_ride_name_history.py` - `django/apps/entities/admin.py` ### Files to Create (Tasks 3 & 4) - `django/apps/timeline/__init__.py` - `django/apps/timeline/models.py` - `django/apps/timeline/admin.py` - `django/apps/timeline/apps.py` - `django/apps/reports/__init__.py` - `django/apps/reports/models.py` - `django/apps/reports/admin.py` - `django/apps/reports/apps.py` - API endpoint files for both apps --- ## Time Tracking - Task 1: 2 hours ✅ COMPLETE - Task 2: 4 hours ✅ MOSTLY COMPLETE (API endpoints remaining) - Task 3: 6 hours 🔄 NOT STARTED - Task 4: 8 hours 🔄 NOT STARTED **Total Completed:** 6 hours **Remaining:** 14 hours **Progress:** 30% complete