Implement comprehensive update to process_approval_transaction to ensure location records are created with proper name fields during park creation and updates, and prepare migration to apply fixes in multiple phases. Includes backfill improvements and targeted fixes for Lagoon.
6.6 KiB
Location Handling Fix - Complete Summary
Problem Identified
Parks were being created without location data due to a critical bug in the approval pipeline. The locations table requires a name field (NOT NULL), but the process_approval_transaction function was attempting to INSERT locations without this field, causing silent failures and leaving parks with NULL location_id values.
Root Cause
The function was:
- ✅ Correctly JOINing
park_submission_locationstable - ✅ Fetching location fields like
country,city,latitude, etc. - ❌ NOT fetching the
nameordisplay_namefields - ❌ NOT including
namefield in the INSERT statement
This caused PostgreSQL to reject the INSERT (violating NOT NULL constraint), but since there was no explicit error handling for this specific failure, the park was still created with location_id = NULL.
What Was Fixed
Phase 1: Backfill Function (✅ COMPLETED)
File: supabase/migrations/20251112000002_fix_location_name_in_backfill.sql (auto-generated)
Updated backfill_park_locations() function to:
- Include
nameanddisplay_namefields when fetching frompark_submission_locations - Construct a location name from available data (priority: display_name → name → city/state/country)
- INSERT locations with the proper
namefield
Phase 2: Backfill Existing Data (✅ COMPLETED)
File: supabase/migrations/20251112000004_fix_location_name_in_backfill.sql (auto-generated)
Ran backfill to populate missing location data for existing parks:
- Found parks with
NULLlocation_id - Located their submission data in
park_submission_locations - Created location records with proper
namefield - Updated parks with new location_id values
Result: Lagoon park (and any others) now have proper location data and maps display correctly.
Phase 3: Approval Function Fix (⏳ PENDING)
File: docs/migrations/fix_location_handling_complete.sql
Created comprehensive SQL script to fix process_approval_transaction() for future submissions.
Key Changes:
-
Added to SELECT clause (line ~108):
psl.name as park_location_name, psl.display_name as park_location_display_name, -
Updated CREATE action location INSERT (line ~204):
v_location_name := COALESCE( v_item.park_location_display_name, v_item.park_location_name, CONCAT_WS(', ', city, state, country) ); INSERT INTO locations (name, country, ...) VALUES (v_location_name, v_item.park_location_country, ...) -
Updated UPDATE action location INSERT (line ~454):
-- Same logic as CREATE action
How to Apply the Approval Function Fix
The complete SQL script is ready in docs/migrations/fix_location_handling_complete.sql.
Option 1: Via Supabase SQL Editor (Recommended)
- Go to Supabase SQL Editor
- Copy the contents of
docs/migrations/fix_location_handling_complete.sql - Paste and execute the SQL
- Verify success by checking the function exists
Option 2: Via Migration Tool (Later)
The migration can be split into smaller chunks if needed, but the complete file is ready for manual application.
Verification Steps
1. Verify Existing Parks Have Locations
SELECT p.name, p.slug, p.location_id, l.name as location_name
FROM parks p
LEFT JOIN locations l ON p.location_id = l.id
WHERE p.slug = 'lagoon';
Expected Result: Location data should be populated ✅
2. Test New Park Submission (After Applying Fix)
- Create a new park submission with location data
- Submit for moderation
- Approve the submission
- Verify the park has a non-NULL location_id
- Check the locations table has the proper name field
- Verify the map displays on the park detail page
3. Test Park Update with Location Change
- Edit an existing park and change its location
- Submit for moderation
- Approve the update
- Verify a new location record was created with proper name
- Verify the park's location_id was updated
Database Schema Context
locations Table Structure
- id: uuid (PK)
- name: text (NOT NULL) ← This was the missing field
- country: text
- state_province: text
- city: text
- street_address: text
- postal_code: text
- latitude: numeric
- longitude: numeric
- timezone: text
- created_at: timestamp with time zone
park_submission_locations Table Structure
- id: uuid (PK)
- park_submission_id: uuid (FK)
- name: text ← We weren't fetching this
- display_name: text ← We weren't fetching this
- country: text
- state_province: text
- city: text
- street_address: text
- postal_code: text
- latitude: numeric
- longitude: numeric
- timezone: text
- created_at: timestamp with time zone
Impact Assessment
Before Fix
- ❌ Parks created without location data (location_id = NULL)
- ❌ Maps not displaying on park detail pages
- ❌ Location-based features not working
- ❌ Silent failures in approval pipeline
After Complete Fix
- ✅ All existing parks have location data (backfilled)
- ✅ Maps display correctly on park detail pages
- ✅ Future park submissions will have locations created properly
- ✅ Park updates with location changes work correctly
- ✅ No more silent failures in the pipeline
Files Created
docs/migrations/fix_location_handling_complete.sql- Complete SQL script for approval function fixdocs/LOCATION_FIX_SUMMARY.md- This document
Next Steps
- Immediate: Apply the fix from
docs/migrations/fix_location_handling_complete.sql - Testing: Run verification steps above
- Monitoring: Watch for any location-related errors in production
- Documentation: Update team on the fix and new behavior
Related Issues
This fix ensures compliance with the "Sacred Pipeline" architecture documented in docs/SUBMISSION_FLOW.md. All location data flows through:
- User form input
- Submission to
park_submission_locationstable - Moderation queue review
- Approval via
process_approval_transactionfunction - Location creation in
locationstable - Park creation/update with proper location_id reference
Additional Notes
- The
display_namefield inpark_submission_locationsis used for human-readable location labels (e.g., "375, Lagoon Drive, Farmington, Davis County, Utah, 84025, United States") - The
namefield inlocationsmust be populated for the INSERT to succeed - If neither display_name nor name is provided, we construct it from city/state/country as a fallback
- This pattern should be applied to any other entities that use location data in the future