supersam/supabase/log_order_group_change.sql

123 lines
4.1 KiB
PL/PgSQL

CREATE OR REPLACE FUNCTION public.log_order_group_change()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path TO 'public'
AS $$
DECLARE
v_user_id uuid;
v_changes jsonb := '{}'::jsonb;
v_action text;
v_source text;
BEGIN
-- Determine who made the change
v_user_id := auth.uid();
v_source := CASE WHEN v_user_id IS NOT NULL THEN 'user' ELSE 'system' END;
-- Track only meaningful field changes
IF NEW.notification_status IS DISTINCT FROM OLD.notification_status THEN
v_changes := v_changes || jsonb_build_object(
'notification_status',
jsonb_build_object('old', OLD.notification_status, 'new', NEW.notification_status)
);
END IF;
IF NEW.delivery_status IS DISTINCT FROM OLD.delivery_status THEN
v_changes := v_changes || jsonb_build_object(
'delivery_status',
jsonb_build_object('old', OLD.delivery_status, 'new', NEW.delivery_status)
);
END IF;
IF NEW.status IS DISTINCT FROM OLD.status THEN
v_changes := v_changes || jsonb_build_object(
'status',
jsonb_build_object('old', OLD.status, 'new', NEW.status)
);
END IF;
IF NEW.assigned_driver_id IS DISTINCT FROM OLD.assigned_driver_id THEN
v_changes := v_changes || jsonb_build_object(
'assigned_driver_id',
jsonb_build_object('old', OLD.assigned_driver_id, 'new', NEW.assigned_driver_id)
);
END IF;
IF NEW.delivery_link IS DISTINCT FROM OLD.delivery_link THEN
v_changes := v_changes || jsonb_build_object(
'delivery_link',
jsonb_build_object('old', OLD.delivery_link, 'new', NEW.delivery_link)
);
END IF;
IF NEW.first_sms_sent_at IS DISTINCT FROM OLD.first_sms_sent_at THEN
v_changes := v_changes || jsonb_build_object(
'first_sms_sent_at',
jsonb_build_object('old', OLD.first_sms_sent_at, 'new', NEW.first_sms_sent_at)
);
END IF;
IF NEW.second_sms_sent_at IS DISTINCT FROM OLD.second_sms_sent_at THEN
v_changes := v_changes || jsonb_build_object(
'second_sms_sent_at',
jsonb_build_object('old', OLD.second_sms_sent_at, 'new', NEW.second_sms_sent_at)
);
END IF;
IF NEW.last_sms_error IS DISTINCT FROM OLD.last_sms_error THEN
v_changes := v_changes || jsonb_build_object(
'last_sms_error',
jsonb_build_object('old', OLD.last_sms_error, 'new', NEW.last_sms_error)
);
END IF;
-- Only insert if something meaningful changed
IF v_changes = '{}'::jsonb THEN
RETURN NEW;
END IF;
-- Determine action label
v_action := CASE
WHEN NEW.delivery_status IS DISTINCT FROM OLD.delivery_status THEN 'delivery_status_change'
WHEN NEW.notification_status IS DISTINCT FROM OLD.notification_status THEN 'notification_status_change'
WHEN NEW.assigned_driver_id IS DISTINCT FROM OLD.assigned_driver_id THEN 'driver_assignment_change'
WHEN NEW.delivery_link IS DISTINCT FROM OLD.delivery_link THEN 'delivery_link_change'
ELSE 'field_change'
END;
INSERT INTO order_history (order_group_id, action, old_status, new_status, user_id, metadata)
VALUES (
NEW.id,
v_action,
OLD.delivery_status,
NEW.delivery_status,
v_user_id,
jsonb_build_object('changes', v_changes, 'source', v_source, 'group_key', NEW.group_key)
);
RETURN NEW;
END;
$$;
-- Drop old trigger if exists
DROP TRIGGER IF EXISTS log_order_group_change_trigger ON public.order_groups;
-- Create trigger AFTER UPDATE (only when fields actually change)
CREATE TRIGGER log_order_group_change_trigger
AFTER UPDATE ON public.order_groups
FOR EACH ROW
WHEN (
NEW.notification_status IS DISTINCT FROM OLD.notification_status
OR NEW.delivery_status IS DISTINCT FROM OLD.delivery_status
OR NEW.status IS DISTINCT FROM OLD.status
OR NEW.assigned_driver_id IS DISTINCT FROM OLD.assigned_driver_id
OR NEW.delivery_link IS DISTINCT FROM OLD.delivery_link
OR NEW.first_sms_sent_at IS DISTINCT FROM OLD.first_sms_sent_at
OR NEW.second_sms_sent_at IS DISTINCT FROM OLD.second_sms_sent_at
OR NEW.last_sms_error IS DISTINCT FROM OLD.last_sms_error
)
EXECUTE FUNCTION public.log_order_group_change();
-- Grant access
GRANT SELECT ON order_history TO authenticated;
GRANT INSERT ON order_history TO authenticated;