B2B-30: adds personal code to account, company admins invites members

This commit is contained in:
devmc-ee
2025-06-22 15:22:07 +03:00
parent 39c02c6d34
commit 251f2a4ef1
50 changed files with 3546 additions and 2611 deletions

View File

@@ -0,0 +1,5 @@
alter table public.accounts
add column if not exists personal_code char(11) unique;
alter table public.invitations
add column if not exists personal_code char(11) unique;

View File

@@ -0,0 +1,146 @@
drop function if exists public.add_invitations_to_account(text, public.invitation[]);
drop type if exists public.invitation;
create type public.invitation as (
email text,
role text,
personal_code char(11)
);
create or replace function public.add_invitations_to_account (
account_slug text,
invitations public.invitation[]
) returns public.invitations[]
set search_path = ''
as $$
declare
new_invitation public.invitations;
all_invitations public.invitations[] := array[]::public.invitations[];
invite_token text;
invite public.invitation;
begin
foreach invite in array invitations loop
invite_token := extensions.uuid_generate_v4();
insert into public.invitations (
email,
account_id,
invited_by,
role,
invite_token,
personal_code
)
values (
invite.email,
(select id from public.accounts where slug = account_slug),
auth.uid(),
invite.role,
invite_token,
invite.personal_code
)
returning * into new_invitation;
all_invitations := array_append(all_invitations, new_invitation);
end loop;
return all_invitations;
end;
$$ language plpgsql;
grant execute on function public.add_invitations_to_account(text, public.invitation[]) to authenticated;
drop function if exists public.get_account_invitations(text);
create function public.get_account_invitations (account_slug text)
returns table (
id integer,
email varchar(255),
account_id uuid,
invited_by uuid,
role varchar(50),
created_at timestamptz,
updated_at timestamptz,
expires_at timestamptz,
personal_code char(11),
inviter_name varchar,
inviter_email varchar
)
set search_path = ''
as $$
begin
return query
select
invitation.id,
invitation.email,
invitation.account_id,
invitation.invited_by,
invitation.role,
invitation.created_at,
invitation.updated_at,
invitation.expires_at,
invitation.personal_code,
account.name,
account.email
from
public.invitations as invitation
join public.accounts as account on invitation.account_id = account.id
where
account.slug = account_slug;
end;
$$ language plpgsql;
grant execute on function public.get_account_invitations(text) to authenticated, service_role;
drop function if exists public.get_account_members(text);
-- Functions "public.get_account_members"
-- Function to get the members of an account by the account slug
create
or replace function public.get_account_members (account_slug text) returns table (
id uuid,
user_id uuid,
account_id uuid,
role varchar(50),
role_hierarchy_level int,
primary_owner_user_id uuid,
name varchar,
email varchar,
personal_code char(11),
picture_url varchar,
created_at timestamptz,
updated_at timestamptz
) language plpgsql
set
search_path = '' as $$
begin
return QUERY
select
acc.id,
am.user_id,
am.account_id,
am.account_role,
r.hierarchy_level,
a.primary_owner_user_id,
acc.name,
acc.email,
acc.personal_code,
acc.picture_url,
am.created_at,
am.updated_at
from
public.accounts_memberships am
join public.accounts a on a.id = am.account_id
join public.accounts acc on acc.id = am.user_id
join public.roles r on r.name = am.account_role
where
a.slug = account_slug;
end;
$$;
grant
execute on function public.get_account_members (text) to authenticated,
service_role;

View File

@@ -0,0 +1,22 @@
create or replace function public.is_company_admin(account_slug text)
returns boolean
set search_path = ''
language plpgsql
as $$
declare
is_owner boolean;
begin
select exists (
select 1
from public.accounts_memberships am
join public.accounts a on a.id = am.account_id
where am.user_id = auth.uid()
and am.account_role = 'owner'
and a.slug = account_slug
) into is_owner;
return is_owner;
end;
$$;
grant execute on function public.is_company_admin(text) to authenticated, service_role;

View File

@@ -0,0 +1,53 @@
create or replace function kit.setup_new_user()
returns trigger
language plpgsql
security definer
set search_path = ''
as $$
declare
user_name text;
picture_url text;
personal_code text;
begin
if new.raw_user_meta_data ->> 'name' is not null then
user_name := new.raw_user_meta_data ->> 'name';
end if;
if user_name is null and new.email is not null then
user_name := split_part(new.email, '@', 1);
end if;
if user_name is null then
user_name := '';
end if;
if new.raw_user_meta_data ->> 'avatar_url' is not null then
picture_url := new.raw_user_meta_data ->> 'avatar_url';
else
picture_url := null;
end if;
personal_code := new.raw_user_meta_data ->> 'personalCode';
insert into public.accounts (
id,
primary_owner_user_id,
name,
is_personal_account,
picture_url,
email,
personal_code
)
values (
new.id,
new.id,
user_name,
true,
picture_url,
new.email,
personal_code
);
return new;
end;
$$;

View File

@@ -0,0 +1,20 @@
create or replace function public.get_invitations_with_account_ids(
company_id uuid,
personal_codes text[]
)
returns table (
invite_token text,
personal_code text,
account_id uuid
)
language sql
as $$
select
i.invite_token,
i.personal_code,
a.id as account_id
from public.invitations i
join public.accounts a on a.personal_code = i.personal_code
where i.account_id = company_id
and i.personal_code = any(personal_codes);
$$;