aiai / supabase /migrations /20240414161707_basejump-setup.sql
Mohammed Foud
first commit
a51a15b
/**
____ _
| _ \ (_)
| |_) | __ _ ___ ___ _ _ _ _ __ ___ _ __
| _ < / _` / __|/ _ \ | | | | '_ ` _ \| '_ \
| |_) | (_| \__ \ __/ | |_| | | | | | | |_) |
|____/ \__,_|___/\___| |\__,_|_| |_| |_| .__/
_/ | | |
|__/ |_|
Basejump is a starter kit for building SaaS products on top of Supabase.
Learn more at https://usebasejump.com
*/
/**
* -------------------------------------------------------
* Section - Basejump schema setup and utility functions
* -------------------------------------------------------
*/
-- revoke execution by default from public
ALTER DEFAULT PRIVILEGES REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC REVOKE EXECUTE ON FUNCTIONS FROM anon, authenticated;
-- Create basejump schema
CREATE SCHEMA IF NOT EXISTS basejump;
GRANT USAGE ON SCHEMA basejump to authenticated;
GRANT USAGE ON SCHEMA basejump to service_role;
/**
* -------------------------------------------------------
* Section - Enums
* -------------------------------------------------------
*/
/**
* Invitation types are either email or link. Email invitations are sent to
* a single user and can only be claimed once. Link invitations can be used multiple times
* Both expire after 24 hours
*/
DO
$$
BEGIN
-- check it account_role already exists on basejump schema
IF NOT EXISTS(SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'invitation_type'
AND n.nspname = 'basejump') THEN
CREATE TYPE basejump.invitation_type AS ENUM ('one_time', '24_hour');
end if;
end;
$$;
/**
* -------------------------------------------------------
* Section - Basejump settings
* -------------------------------------------------------
*/
CREATE TABLE IF NOT EXISTS basejump.config
(
enable_team_accounts boolean default true,
enable_personal_account_billing boolean default true,
enable_team_account_billing boolean default true,
billing_provider text default 'stripe'
);
-- create config row
INSERT INTO basejump.config (enable_team_accounts, enable_personal_account_billing, enable_team_account_billing)
VALUES (true, true, true);
-- enable select on the config table
GRANT SELECT ON basejump.config TO authenticated, service_role;
-- enable RLS on config
ALTER TABLE basejump.config
ENABLE ROW LEVEL SECURITY;
create policy "Basejump settings can be read by authenticated users" on basejump.config
for select
to authenticated
using (
true
);
/**
* -------------------------------------------------------
* Section - Basejump utility functions
* -------------------------------------------------------
*/
/**
basejump.get_config()
Get the full config object to check basejump settings
This is not accessible from the outside, so can only be used inside postgres functions
*/
CREATE OR REPLACE FUNCTION basejump.get_config()
RETURNS json AS
$$
DECLARE
result RECORD;
BEGIN
SELECT * from basejump.config limit 1 into result;
return row_to_json(result);
END;
$$ LANGUAGE plpgsql;
grant execute on function basejump.get_config() to authenticated, service_role;
/**
basejump.is_set("field_name")
Check a specific boolean config value
*/
CREATE OR REPLACE FUNCTION basejump.is_set(field_name text)
RETURNS boolean AS
$$
DECLARE
result BOOLEAN;
BEGIN
execute format('select %I from basejump.config limit 1', field_name) into result;
return result;
END;
$$ LANGUAGE plpgsql;
grant execute on function basejump.is_set(text) to authenticated;
/**
* Automatic handling for maintaining created_at and updated_at timestamps
* on tables
*/
CREATE OR REPLACE FUNCTION basejump.trigger_set_timestamps()
RETURNS TRIGGER AS
$$
BEGIN
if TG_OP = 'INSERT' then
NEW.created_at = now();
NEW.updated_at = now();
else
NEW.updated_at = now();
NEW.created_at = OLD.created_at;
end if;
RETURN NEW;
END
$$ LANGUAGE plpgsql;
/**
* Automatic handling for maintaining created_by and updated_by timestamps
* on tables
*/
CREATE OR REPLACE FUNCTION basejump.trigger_set_user_tracking()
RETURNS TRIGGER AS
$$
BEGIN
if TG_OP = 'INSERT' then
NEW.created_by = auth.uid();
NEW.updated_by = auth.uid();
else
NEW.updated_by = auth.uid();
NEW.created_by = OLD.created_by;
end if;
RETURN NEW;
END
$$ LANGUAGE plpgsql;
/**
basejump.generate_token(length)
Generates a secure token - used internally for invitation tokens
but could be used elsewhere. Check out the invitations table for more info on
how it's used
*/
CREATE OR REPLACE FUNCTION basejump.generate_token(length int)
RETURNS text AS
$$
select regexp_replace(replace(
replace(replace(replace(encode(gen_random_bytes(length)::bytea, 'base64'), '/', ''), '+',
''), '\', ''),
'=',
''), E'[\\n\\r]+', '', 'g');
$$ LANGUAGE sql;
grant execute on function basejump.generate_token(int) to authenticated;