mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 10:19:43 +00:00
- Couple streaks with milestone notifications - Scheduled pack releases with admin UI - Notification preferences screen - Refactored profile settings screens - Partner activity notifications
139 lines
4.7 KiB
PL/PgSQL
139 lines
4.7 KiB
PL/PgSQL
-- Redemption codes table
|
|
CREATE TABLE redemption_codes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
code TEXT NOT NULL UNIQUE,
|
|
description TEXT,
|
|
max_uses INTEGER DEFAULT 1,
|
|
current_uses INTEGER DEFAULT 0,
|
|
expires_at TIMESTAMPTZ,
|
|
is_active BOOLEAN DEFAULT true,
|
|
created_by UUID REFERENCES auth.users(id),
|
|
created_at TIMESTAMPTZ DEFAULT now(),
|
|
updated_at TIMESTAMPTZ DEFAULT now()
|
|
);
|
|
|
|
-- Code redemptions table
|
|
CREATE TABLE code_redemptions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
code_id UUID NOT NULL REFERENCES redemption_codes(id),
|
|
user_id UUID NOT NULL REFERENCES auth.users(id),
|
|
redeemed_at TIMESTAMPTZ DEFAULT now(),
|
|
UNIQUE(code_id, user_id)
|
|
);
|
|
|
|
ALTER TABLE redemption_codes ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE code_redemptions ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY "Admins with manage_codes permission can view redemption codes"
|
|
ON redemption_codes FOR SELECT
|
|
USING (has_permission('manage_codes'::text));
|
|
CREATE POLICY "Admins with manage_codes permission can insert redemption codes"
|
|
ON redemption_codes FOR INSERT
|
|
WITH CHECK (has_permission('manage_codes'::text));
|
|
CREATE POLICY "Admins with manage_codes permission can update redemption codes"
|
|
ON redemption_codes FOR UPDATE
|
|
USING (has_permission('manage_codes'::text));
|
|
CREATE POLICY "Admins with manage_codes permission can delete redemption codes"
|
|
ON redemption_codes FOR DELETE
|
|
USING (has_permission('manage_codes'::text));
|
|
CREATE POLICY "Super admins can manage redemption codes"
|
|
ON redemption_codes FOR ALL
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM admin_users
|
|
WHERE admin_users.user_id = auth.uid()
|
|
AND admin_users.role = 'super_admin'::admin_role
|
|
)
|
|
);
|
|
|
|
CREATE POLICY "Users can view own redemptions"
|
|
ON code_redemptions FOR SELECT
|
|
USING (auth.uid() = user_id);
|
|
CREATE POLICY "Super admins can view all redemptions"
|
|
ON code_redemptions FOR SELECT
|
|
USING (
|
|
EXISTS (
|
|
SELECT 1
|
|
FROM admin_users
|
|
WHERE admin_users.user_id = auth.uid()
|
|
AND admin_users.role = 'super_admin'::admin_role
|
|
)
|
|
);
|
|
|
|
CREATE OR REPLACE FUNCTION public.redeem_code_by_email(p_email text, p_code text)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
v_code_record record;
|
|
v_user_record record;
|
|
v_existing_redemption record;
|
|
BEGIN
|
|
-- Find the user by email
|
|
SELECT id INTO v_user_record
|
|
FROM public.profiles
|
|
WHERE LOWER(email) = LOWER(p_email);
|
|
|
|
IF v_user_record IS NULL THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'No account found with this email address');
|
|
END IF;
|
|
|
|
-- Find the code
|
|
SELECT * INTO v_code_record
|
|
FROM public.redemption_codes
|
|
WHERE UPPER(code) = UPPER(p_code);
|
|
|
|
IF v_code_record IS NULL THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'Invalid redemption code');
|
|
END IF;
|
|
|
|
-- Check if code is active
|
|
IF NOT v_code_record.is_active THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'This code is no longer active');
|
|
END IF;
|
|
|
|
-- Check if code has expired
|
|
IF v_code_record.expires_at IS NOT NULL AND v_code_record.expires_at < now() THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'This code has expired');
|
|
END IF;
|
|
|
|
-- Check if code has uses remaining
|
|
IF v_code_record.max_uses IS NOT NULL AND v_code_record.current_uses >= v_code_record.max_uses THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'This code has reached its maximum number of uses');
|
|
END IF;
|
|
|
|
-- Check if user has already redeemed this code
|
|
SELECT * INTO v_existing_redemption
|
|
FROM public.code_redemptions
|
|
WHERE code_id = v_code_record.id AND user_id = v_user_record.id;
|
|
|
|
IF v_existing_redemption IS NOT NULL THEN
|
|
RETURN jsonb_build_object('success', false, 'error', 'You have already redeemed this code');
|
|
END IF;
|
|
|
|
-- All checks passed - redeem the code
|
|
-- 1. Create redemption record
|
|
INSERT INTO public.code_redemptions (code_id, user_id)
|
|
VALUES (v_code_record.id, v_user_record.id);
|
|
|
|
-- 2. Increment current_uses
|
|
UPDATE public.redemption_codes
|
|
SET current_uses = current_uses + 1,
|
|
updated_at = now()
|
|
WHERE id = v_code_record.id;
|
|
|
|
-- 3. Set user as premium
|
|
UPDATE public.profiles
|
|
SET is_premium = true,
|
|
updated_at = now()
|
|
WHERE id = v_user_record.id;
|
|
|
|
RETURN jsonb_build_object('success', true, 'message', 'Code redeemed successfully! You now have premium access.');
|
|
END;
|
|
$function$;
|
|
|
|
GRANT EXECUTE ON FUNCTION public.redeem_code_by_email(text, text) TO PUBLIC;
|
|
GRANT EXECUTE ON FUNCTION public.redeem_code_by_email(text, text) TO anon, authenticated, service_role;
|