mirror of
https://github.com/mito-systems/ranger-app.git
synced 2025-12-25 14:44:07 +00:00
232 lines
5.5 KiB
PL/PgSQL
232 lines
5.5 KiB
PL/PgSQL
-- Additional SQL functions for the points system
|
|
-- This file is meant to be run after supabase-schema.sql
|
|
|
|
-- Function to get transaction count for a user
|
|
CREATE OR REPLACE FUNCTION get_user_transaction_count(
|
|
user_id_param TEXT
|
|
)
|
|
RETURNS INTEGER AS $$
|
|
DECLARE
|
|
count_result INTEGER;
|
|
user_uuid UUID;
|
|
BEGIN
|
|
-- Convert to UUID
|
|
user_uuid := user_id_param::UUID;
|
|
|
|
SELECT COUNT(*) INTO count_result
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
RETURN count_result;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Function to get a user's first transaction date
|
|
CREATE OR REPLACE FUNCTION get_user_first_transaction_date(
|
|
user_id_param TEXT
|
|
)
|
|
RETURNS TIMESTAMP WITH TIME ZONE AS $$
|
|
DECLARE
|
|
first_date TIMESTAMP WITH TIME ZONE;
|
|
user_uuid UUID;
|
|
BEGIN
|
|
-- Convert to UUID
|
|
user_uuid := user_id_param::UUID;
|
|
|
|
SELECT MIN(created_at) INTO first_date
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
RETURN first_date;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Function to get a user's latest transaction date
|
|
CREATE OR REPLACE FUNCTION get_user_latest_transaction_date(
|
|
user_id_param TEXT
|
|
)
|
|
RETURNS TIMESTAMP WITH TIME ZONE AS $$
|
|
DECLARE
|
|
latest_date TIMESTAMP WITH TIME ZONE;
|
|
user_uuid UUID;
|
|
BEGIN
|
|
-- Convert to UUID
|
|
user_uuid := user_id_param::UUID;
|
|
|
|
SELECT MAX(created_at) INTO latest_date
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
RETURN latest_date;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Function to get user info by ID
|
|
CREATE OR REPLACE FUNCTION get_user_info(
|
|
user_id_param TEXT
|
|
)
|
|
RETURNS json AS $$
|
|
DECLARE
|
|
user_record users;
|
|
user_uuid UUID;
|
|
BEGIN
|
|
-- Convert to UUID
|
|
user_uuid := user_id_param::UUID;
|
|
|
|
SELECT * INTO user_record
|
|
FROM users
|
|
WHERE id = user_uuid;
|
|
|
|
IF FOUND THEN
|
|
RETURN row_to_json(user_record);
|
|
ELSE
|
|
RETURN NULL;
|
|
END IF;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Function to get user stats (combines user info and point total)
|
|
CREATE OR REPLACE FUNCTION get_user_stats(
|
|
user_id_param TEXT
|
|
)
|
|
RETURNS json AS $$
|
|
DECLARE
|
|
user_info json;
|
|
points_total INTEGER;
|
|
transaction_count INTEGER;
|
|
first_date TIMESTAMP WITH TIME ZONE;
|
|
latest_date TIMESTAMP WITH TIME ZONE;
|
|
user_uuid UUID;
|
|
result json;
|
|
BEGIN
|
|
-- Convert to UUID
|
|
user_uuid := user_id_param::UUID;
|
|
|
|
-- Get user info
|
|
SELECT row_to_json(u) INTO user_info
|
|
FROM users u
|
|
WHERE id = user_uuid;
|
|
|
|
-- Get points total
|
|
SELECT COALESCE(SUM(points), 0) INTO points_total
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
-- Get transaction count
|
|
SELECT COUNT(*) INTO transaction_count
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
-- Get first and latest transaction dates
|
|
SELECT MIN(created_at), MAX(created_at)
|
|
INTO first_date, latest_date
|
|
FROM point_transactions
|
|
WHERE user_id = user_uuid;
|
|
|
|
-- Build result object
|
|
SELECT json_build_object(
|
|
'user', user_info,
|
|
'points', points_total,
|
|
'transaction_count', transaction_count,
|
|
'first_transaction', first_date,
|
|
'latest_transaction', latest_date
|
|
) INTO result;
|
|
|
|
RETURN result;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Migration helper function to transfer data from old schema to new schema
|
|
-- This is only needed if you're migrating from the old schema
|
|
CREATE OR REPLACE FUNCTION migrate_user_data(
|
|
old_user_id_param TEXT,
|
|
new_user_id_param TEXT,
|
|
email_param TEXT,
|
|
name_param TEXT DEFAULT NULL
|
|
)
|
|
RETURNS BOOLEAN AS $$
|
|
DECLARE
|
|
old_user_uuid UUID;
|
|
new_user_uuid UUID;
|
|
BEGIN
|
|
-- Convert to UUIDs
|
|
old_user_uuid := old_user_id_param::UUID;
|
|
new_user_uuid := new_user_id_param::UUID;
|
|
|
|
-- Ensure new user exists
|
|
INSERT INTO users (id, email, name, first_login, last_login)
|
|
VALUES (new_user_uuid, email_param, name_param, now(), now())
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- Update transactions to use new user ID
|
|
UPDATE point_transactions
|
|
SET user_id = new_user_uuid
|
|
WHERE user_id = old_user_uuid;
|
|
|
|
RETURN TRUE;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Function to merge duplicate users by email
|
|
-- This will find all users with the same email, keep the oldest one,
|
|
-- and migrate all transactions to that user
|
|
CREATE OR REPLACE FUNCTION merge_duplicate_users_by_email(
|
|
email_param TEXT
|
|
)
|
|
RETURNS json AS $$
|
|
DECLARE
|
|
primary_user_id UUID;
|
|
duplicate_user record;
|
|
result json;
|
|
merge_count INT := 0;
|
|
transaction_count INT := 0;
|
|
BEGIN
|
|
-- Find the oldest user with this email to use as the primary
|
|
SELECT id INTO primary_user_id
|
|
FROM users
|
|
WHERE email = email_param
|
|
ORDER BY first_login ASC
|
|
LIMIT 1;
|
|
|
|
-- If no user found, return error
|
|
IF primary_user_id IS NULL THEN
|
|
RETURN json_build_object(
|
|
'success', FALSE,
|
|
'message', 'No user found with this email'
|
|
);
|
|
END IF;
|
|
|
|
-- Find all other users with the same email
|
|
FOR duplicate_user IN
|
|
SELECT id
|
|
FROM users
|
|
WHERE email = email_param
|
|
AND id != primary_user_id
|
|
LOOP
|
|
-- Migrate this user's transactions to the primary user
|
|
UPDATE point_transactions
|
|
SET user_id = primary_user_id
|
|
WHERE user_id = duplicate_user.id;
|
|
|
|
-- Count migrated transactions
|
|
GET DIAGNOSTICS transaction_count = ROW_COUNT;
|
|
|
|
-- Delete the duplicate user
|
|
DELETE FROM users
|
|
WHERE id = duplicate_user.id;
|
|
|
|
merge_count := merge_count + 1;
|
|
END LOOP;
|
|
|
|
-- Build the result object
|
|
result := json_build_object(
|
|
'success', TRUE,
|
|
'primary_user_id', primary_user_id,
|
|
'merged_users_count', merge_count,
|
|
'migrated_transactions', transaction_count,
|
|
'email', email_param
|
|
);
|
|
|
|
RETURN result;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER; |