Fix entity submission pipelines

Refactor park updates, ride updates, and timeline event submissions to use dedicated relational tables instead of JSON blobs in `submission_items.item_data`. This enforces the "NO JSON IN SQL" rule, improving queryability, data integrity, and consistency across the pipeline.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-06 15:13:36 +00:00
parent ed9d17bf10
commit bd4f75bfb2
2 changed files with 362 additions and 87 deletions

View File

@@ -1653,6 +1653,37 @@ async function createPark(supabase: any, data: any): Promise<string> {
parkId = data.park_id;
delete data.park_id; // Remove ID from update data
// ✅ FIXED: Handle location updates from temp_location_data
if (data.temp_location_data && !data.location_id) {
edgeLogger.info('Creating location from temp data for update', {
action: 'approval_create_location_update',
locationName: data.temp_location_data.name
});
const { data: newLocation, error: locationError } = await supabase
.from('locations')
.insert({
name: data.temp_location_data.name,
street_address: data.temp_location_data.street_address || null,
city: data.temp_location_data.city,
state_province: data.temp_location_data.state_province,
country: data.temp_location_data.country,
latitude: data.temp_location_data.latitude,
longitude: data.temp_location_data.longitude,
timezone: data.temp_location_data.timezone,
postal_code: data.temp_location_data.postal_code
})
.select('id')
.single();
if (locationError) {
throw new Error(`Failed to create location: ${locationError.message}`);
}
data.location_id = newLocation.id;
}
delete data.temp_location_data;
const normalizedData = normalizeParkTypeValue(normalizeStatusValue(data));
const sanitizedData = sanitizeDateFields(normalizedData);
const filteredData = filterDatabaseFields(sanitizedData, PARK_FIELDS);
@@ -1764,6 +1795,89 @@ async function createRide(supabase: any, data: any): Promise<string> {
if (error) throw new Error(`Failed to update ride: ${error.message}`);
// ✅ FIXED: Handle nested data updates (technical specs, coaster stats, name history)
// For updates, we typically replace all related data rather than merge
// Delete existing and insert new
if (technicalSpecifications.length > 0) {
// Delete existing specs
await supabase
.from('ride_technical_specifications')
.delete()
.eq('ride_id', rideId);
// Insert new specs
const techSpecsToInsert = technicalSpecifications.map((spec: any) => ({
ride_id: rideId,
spec_name: spec.spec_name,
spec_value: spec.spec_value,
spec_unit: spec.spec_unit || null,
category: spec.category || null,
display_order: spec.display_order || 0
}));
const { error: techSpecError } = await supabase
.from('ride_technical_specifications')
.insert(techSpecsToInsert);
if (techSpecError) {
edgeLogger.error('Failed to update technical specifications', { action: 'approval_update_specs', error: techSpecError.message, rideId });
}
}
if (coasterStatistics.length > 0) {
// Delete existing stats
await supabase
.from('ride_coaster_stats')
.delete()
.eq('ride_id', rideId);
// Insert new stats
const statsToInsert = coasterStatistics.map((stat: any) => ({
ride_id: rideId,
stat_name: stat.stat_name,
stat_value: stat.stat_value,
unit: stat.unit || null,
category: stat.category || null,
description: stat.description || null,
display_order: stat.display_order || 0
}));
const { error: statsError } = await supabase
.from('ride_coaster_stats')
.insert(statsToInsert);
if (statsError) {
edgeLogger.error('Failed to update coaster statistics', { action: 'approval_update_stats', error: statsError.message, rideId });
}
}
if (nameHistory.length > 0) {
// Delete existing name history
await supabase
.from('ride_name_history')
.delete()
.eq('ride_id', rideId);
// Insert new name history
const namesToInsert = nameHistory.map((name: any) => ({
ride_id: rideId,
former_name: name.former_name,
date_changed: name.date_changed || null,
reason: name.reason || null,
from_year: name.from_year || null,
to_year: name.to_year || null,
order_index: name.order_index || 0
}));
const { error: namesError } = await supabase
.from('ride_name_history')
.insert(namesToInsert);
if (namesError) {
edgeLogger.error('Failed to update name history', { action: 'approval_update_names', error: namesError.message, rideId });
}
}
// Update park ride counts after successful ride update
if (parkId) {
edgeLogger.info('Updating ride counts for park', { action: 'approval_update_counts', parkId });