mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 12:31:26 -05:00
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:
@@ -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 });
|
||||
|
||||
Reference in New Issue
Block a user