mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:51:14 -05:00
Fix RPC function syntax error
Correct syntax error in RPC function migration due to comments.
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
-- Fix composite submission user attribution
|
||||
-- Ensures create_submission_with_items sets session variables so the versioning trigger
|
||||
-- can properly attribute entity changes to the original submitter
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.create_submission_with_items(
|
||||
p_user_id uuid,
|
||||
p_submission_type text,
|
||||
p_content jsonb,
|
||||
p_items jsonb[]
|
||||
)
|
||||
RETURNS uuid
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path TO 'public'
|
||||
AS $$
|
||||
DECLARE
|
||||
v_submission_id UUID;
|
||||
v_item JSONB;
|
||||
v_item_data JSONB;
|
||||
v_item_type TEXT;
|
||||
v_action_type TEXT;
|
||||
v_park_submission_id UUID;
|
||||
v_company_submission_id UUID;
|
||||
v_ride_submission_id UUID;
|
||||
v_ride_model_submission_id UUID;
|
||||
v_photo_submission_id UUID;
|
||||
v_timeline_event_submission_id UUID;
|
||||
v_submission_item_id UUID;
|
||||
v_temp_ref_key TEXT;
|
||||
v_temp_ref_value TEXT;
|
||||
v_ref_type TEXT;
|
||||
v_ref_order_index INTEGER;
|
||||
BEGIN
|
||||
-- CRITICAL: Set session variables for versioning attribution
|
||||
-- This ensures create_relational_version() trigger can properly attribute changes
|
||||
PERFORM set_config('app.current_user_id', p_user_id::text, false);
|
||||
PERFORM set_config('app.submission_id', '', false);
|
||||
|
||||
-- Create main submission
|
||||
INSERT INTO content_submissions (user_id, submission_type, status, approval_mode)
|
||||
VALUES (p_user_id, p_submission_type, 'pending', 'full')
|
||||
RETURNING id INTO v_submission_id;
|
||||
|
||||
-- Update submission_id in session after creating the submission
|
||||
PERFORM set_config('app.submission_id', v_submission_id::text, false);
|
||||
|
||||
-- Validate items array
|
||||
IF array_length(p_items, 1) IS NULL OR array_length(p_items, 1) = 0 THEN
|
||||
RAISE EXCEPTION 'Cannot create submission without items';
|
||||
END IF;
|
||||
|
||||
-- Process each item
|
||||
FOREACH v_item IN ARRAY p_items
|
||||
LOOP
|
||||
v_item_type := (v_item->>'item_type')::TEXT;
|
||||
v_action_type := (v_item->>'action_type')::TEXT;
|
||||
v_item_data := v_item->'item_data';
|
||||
|
||||
-- Reset IDs for this iteration
|
||||
v_park_submission_id := NULL;
|
||||
v_company_submission_id := NULL;
|
||||
v_ride_submission_id := NULL;
|
||||
v_ride_model_submission_id := NULL;
|
||||
v_photo_submission_id := NULL;
|
||||
v_timeline_event_submission_id := NULL;
|
||||
|
||||
-- Create specialized submission records based on item_type
|
||||
IF v_item_type = 'park' THEN
|
||||
INSERT INTO park_submissions (
|
||||
submission_id, name, slug, description, park_type, status,
|
||||
opening_date, opening_date_precision, closing_date, closing_date_precision,
|
||||
location_id, temp_location_data, operator_id, property_owner_id,
|
||||
website_url, phone, email,
|
||||
banner_image_url, banner_image_id, card_image_url, card_image_id
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'name',
|
||||
v_item_data->>'slug',
|
||||
v_item_data->>'description',
|
||||
v_item_data->>'park_type',
|
||||
v_item_data->>'status',
|
||||
(v_item_data->>'opening_date')::DATE,
|
||||
v_item_data->>'opening_date_precision',
|
||||
(v_item_data->>'closing_date')::DATE,
|
||||
v_item_data->>'closing_date_precision',
|
||||
(v_item_data->>'location_id')::UUID,
|
||||
(v_item_data->'temp_location_data')::JSONB,
|
||||
(v_item_data->>'operator_id')::UUID,
|
||||
(v_item_data->>'property_owner_id')::UUID,
|
||||
v_item_data->>'website_url',
|
||||
v_item_data->>'phone',
|
||||
v_item_data->>'email',
|
||||
v_item_data->>'banner_image_url',
|
||||
v_item_data->>'banner_image_id',
|
||||
v_item_data->>'card_image_url',
|
||||
v_item_data->>'card_image_id'
|
||||
) RETURNING id INTO v_park_submission_id;
|
||||
|
||||
ELSIF v_item_type IN ('manufacturer', 'operator', 'property_owner', 'designer') THEN
|
||||
INSERT INTO company_submissions (
|
||||
submission_id, name, slug, description, company_type, person_type,
|
||||
founded_year, founded_date, founded_date_precision,
|
||||
headquarters_location, website_url, logo_url,
|
||||
banner_image_url, banner_image_id, card_image_url, card_image_id
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'name',
|
||||
v_item_data->>'slug',
|
||||
v_item_data->>'description',
|
||||
v_item_type,
|
||||
COALESCE(v_item_data->>'person_type', 'company'),
|
||||
(v_item_data->>'founded_year')::INTEGER,
|
||||
(v_item_data->>'founded_date')::DATE,
|
||||
v_item_data->>'founded_date_precision',
|
||||
v_item_data->>'headquarters_location',
|
||||
v_item_data->>'website_url',
|
||||
v_item_data->>'logo_url',
|
||||
v_item_data->>'banner_image_url',
|
||||
v_item_data->>'banner_image_id',
|
||||
v_item_data->>'card_image_url',
|
||||
v_item_data->>'card_image_id'
|
||||
) RETURNING id INTO v_company_submission_id;
|
||||
|
||||
ELSIF v_item_type = 'ride' THEN
|
||||
INSERT INTO ride_submissions (
|
||||
submission_id, name, slug, description, category, status,
|
||||
park_id, manufacturer_id, designer_id, ride_model_id,
|
||||
opening_date, opening_date_precision, closing_date, closing_date_precision,
|
||||
height_requirement_cm, age_requirement, max_speed_kmh, duration_seconds,
|
||||
capacity_per_hour, gforce_max, inversions_count, length_meters,
|
||||
height_meters, drop_meters,
|
||||
banner_image_url, banner_image_id, card_image_url, card_image_id, image_url,
|
||||
ride_sub_type, coaster_type, seating_type, intensity_level
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'name',
|
||||
v_item_data->>'slug',
|
||||
v_item_data->>'description',
|
||||
v_item_data->>'category',
|
||||
v_item_data->>'status',
|
||||
(v_item_data->>'park_id')::UUID,
|
||||
(v_item_data->>'manufacturer_id')::UUID,
|
||||
(v_item_data->>'designer_id')::UUID,
|
||||
(v_item_data->>'ride_model_id')::UUID,
|
||||
(v_item_data->>'opening_date')::DATE,
|
||||
v_item_data->>'opening_date_precision',
|
||||
(v_item_data->>'closing_date')::DATE,
|
||||
v_item_data->>'closing_date_precision',
|
||||
(v_item_data->>'height_requirement_cm')::NUMERIC,
|
||||
(v_item_data->>'age_requirement')::INTEGER,
|
||||
(v_item_data->>'max_speed_kmh')::NUMERIC,
|
||||
(v_item_data->>'duration_seconds')::INTEGER,
|
||||
(v_item_data->>'capacity_per_hour')::INTEGER,
|
||||
(v_item_data->>'gforce_max')::NUMERIC,
|
||||
(v_item_data->>'inversions_count')::INTEGER,
|
||||
(v_item_data->>'length_meters')::NUMERIC,
|
||||
(v_item_data->>'height_meters')::NUMERIC,
|
||||
(v_item_data->>'drop_meters')::NUMERIC,
|
||||
v_item_data->>'banner_image_url',
|
||||
v_item_data->>'banner_image_id',
|
||||
v_item_data->>'card_image_url',
|
||||
v_item_data->>'card_image_id',
|
||||
v_item_data->>'image_url',
|
||||
v_item_data->>'ride_sub_type',
|
||||
v_item_data->>'coaster_type',
|
||||
v_item_data->>'seating_type',
|
||||
v_item_data->>'intensity_level'
|
||||
) RETURNING id INTO v_ride_submission_id;
|
||||
|
||||
ELSIF v_item_type = 'ride_model' THEN
|
||||
INSERT INTO ride_model_submissions (
|
||||
submission_id, name, slug, manufacturer_id, category, ride_type, description,
|
||||
banner_image_url, banner_image_id, card_image_url, card_image_id
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'name',
|
||||
v_item_data->>'slug',
|
||||
(v_item_data->>'manufacturer_id')::UUID,
|
||||
v_item_data->>'category',
|
||||
v_item_data->>'ride_type',
|
||||
v_item_data->>'description',
|
||||
v_item_data->>'banner_image_url',
|
||||
v_item_data->>'banner_image_id',
|
||||
v_item_data->>'card_image_url',
|
||||
v_item_data->>'card_image_id'
|
||||
) RETURNING id INTO v_ride_model_submission_id;
|
||||
|
||||
ELSIF v_item_type = 'photo' THEN
|
||||
INSERT INTO photo_submissions (
|
||||
submission_id, entity_type, entity_id, title
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'entity_type',
|
||||
(v_item_data->>'entity_id')::UUID,
|
||||
v_item_data->>'title'
|
||||
) RETURNING id INTO v_photo_submission_id;
|
||||
|
||||
ELSIF v_item_type IN ('timeline_event', 'milestone') THEN
|
||||
INSERT INTO timeline_event_submissions (
|
||||
submission_id, entity_type, entity_id, event_type, event_date,
|
||||
event_date_precision, title, description
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_data->>'entity_type',
|
||||
(v_item_data->>'entity_id')::UUID,
|
||||
v_item_data->>'event_type',
|
||||
(v_item_data->>'event_date')::DATE,
|
||||
v_item_data->>'event_date_precision',
|
||||
v_item_data->>'title',
|
||||
v_item_data->>'description'
|
||||
) RETURNING id INTO v_timeline_event_submission_id;
|
||||
END IF;
|
||||
|
||||
-- Insert submission_item with proper foreign key linkage
|
||||
INSERT INTO submission_items (
|
||||
submission_id,
|
||||
item_type,
|
||||
action_type,
|
||||
park_submission_id,
|
||||
company_submission_id,
|
||||
ride_submission_id,
|
||||
ride_model_submission_id,
|
||||
photo_submission_id,
|
||||
timeline_event_submission_id,
|
||||
status,
|
||||
order_index,
|
||||
depends_on
|
||||
) VALUES (
|
||||
v_submission_id,
|
||||
v_item_type,
|
||||
v_action_type,
|
||||
v_park_submission_id,
|
||||
v_company_submission_id,
|
||||
v_ride_submission_id,
|
||||
v_ride_model_submission_id,
|
||||
v_photo_submission_id,
|
||||
v_timeline_event_submission_id,
|
||||
'pending',
|
||||
COALESCE((v_item->>'order_index')::INTEGER, 0),
|
||||
(v_item->>'depends_on')::UUID
|
||||
) RETURNING id INTO v_submission_item_id;
|
||||
|
||||
-- Extract and store temp refs from item_data
|
||||
IF v_item_data IS NOT NULL AND jsonb_typeof(v_item_data) = 'object' THEN
|
||||
FOR v_temp_ref_key, v_temp_ref_value IN
|
||||
SELECT key, value::text
|
||||
FROM jsonb_each_text(v_item_data)
|
||||
WHERE key LIKE '_temp_%_ref'
|
||||
AND value ~ '^\d+$'
|
||||
LOOP
|
||||
BEGIN
|
||||
-- Extract ref_type from key (e.g., "_temp_operator_ref" -> "operator")
|
||||
v_ref_type := substring(v_temp_ref_key from '_temp_(.+)_ref');
|
||||
v_ref_order_index := v_temp_ref_value::INTEGER;
|
||||
|
||||
-- Insert temp ref record
|
||||
INSERT INTO submission_item_temp_refs (
|
||||
submission_item_id,
|
||||
ref_type,
|
||||
ref_order_index
|
||||
) VALUES (
|
||||
v_submission_item_id,
|
||||
v_ref_type,
|
||||
v_ref_order_index
|
||||
);
|
||||
|
||||
RAISE NOTICE 'Stored temp ref: item_id=%, ref_type=%, order_index=%',
|
||||
v_submission_item_id, v_ref_type, v_ref_order_index;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
RAISE WARNING 'Failed to store temp ref % for item %: %',
|
||||
v_temp_ref_key, v_submission_item_id, SQLERRM;
|
||||
END;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
END LOOP;
|
||||
|
||||
RETURN v_submission_id;
|
||||
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- Clear session variables to prevent pollution
|
||||
PERFORM set_config('app.current_user_id', '', false);
|
||||
PERFORM set_config('app.submission_id', '', false);
|
||||
|
||||
RAISE NOTICE 'Submission creation failed for user % (type=%): %', p_user_id, p_submission_type, SQLERRM;
|
||||
RAISE;
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user