Update e2e config, package.json, and database schema

The e2e test configuration has been modified to take screenshots only on failure and the dev server code has been adjusted for better project directory handling. The "supabase:reset" command in package.json no longer starts the server after reset. Default roles 'owner' and 'member' are also now seeded into the roles table, and constraints in the roles table and its associated functions have been updated to manage hierarchy levels and role naming more effectively.
This commit is contained in:
giancarlo
2024-04-13 17:10:42 +08:00
parent 8e04365bd0
commit 4b9c023700
4 changed files with 49 additions and 31 deletions

View File

@@ -26,7 +26,7 @@ export default defineConfig({
baseURL: 'http://localhost:3000', baseURL: 'http://localhost:3000',
// take a screenshot when a test fails // take a screenshot when a test fails
screenshot: 'on', screenshot: 'only-on-failure',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry' trace: 'on-first-retry'
@@ -68,10 +68,11 @@ export default defineConfig({
/* Run your local dev server before starting the tests */ /* Run your local dev server before starting the tests */
webServer: { webServer: {
command: 'cd ../../ && pnpm run dev', cwd: '../../',
command: 'pnpm run dev',
url: 'http://localhost:3000', url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI, reuseExistingServer: !process.env.CI,
stdout: 'pipe', stdout: 'pipe',
stderr: 'pipe' stderr: 'pipe',
} }
}); });

View File

@@ -19,14 +19,15 @@
"with-env:test": "dotenv -e ./.env.test --", "with-env:test": "dotenv -e ./.env.test --",
"supabase:start": "supabase status || supabase start", "supabase:start": "supabase status || supabase start",
"supabase:stop": "supabase stop", "supabase:stop": "supabase stop",
"supabase:reset": "supabase db reset || supabase start", "supabase:reset": "supabase db reset",
"supabase:status": "supabase status", "supabase:status": "supabase status",
"supabase:test": "supabase db test", "supabase:test": "supabase db test",
"supabase:db:lint": "supabase db lint", "supabase:db:lint": "supabase db lint",
"supabase:deploy": "supabase link --project-ref $SUPABASE_PROJECT_REF && supabase db push", "supabase:deploy": "supabase link --project-ref $SUPABASE_PROJECT_REF && supabase db push",
"supabase:typegen": "pnpm run supabase:typegen:packages && pnpm run supabase:typegen:app", "supabase:typegen": "pnpm run supabase:typegen:packages && pnpm run supabase:typegen:app",
"supabase:typegen:packages": "supabase gen types typescript --local > ../../packages/supabase/src/database.types.ts", "supabase:typegen:packages": "supabase gen types typescript --local > ../../packages/supabase/src/database.types.ts",
"supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts" "supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts",
"supabase:db:dump:local": "supabase db dump --local --data-only"
}, },
"dependencies": { "dependencies": {
"@hookform/resolvers": "^3.3.4", "@hookform/resolvers": "^3.3.4",

View File

@@ -359,12 +359,7 @@ begin
public.accounts_memberships public.accounts_memberships
set set
account_role =( account_role =(
select kit.get_upper_system_role())
name
from
public.roles
where
hierarchy_level = 1)
where where
target_account_id = account_id target_account_id = account_id
and user_id = new_owner_id; and user_id = new_owner_id;
@@ -421,6 +416,21 @@ create trigger protect_account_fields
before update on public.accounts for each row before update on public.accounts for each row
execute function kit.protect_account_fields(); execute function kit.protect_account_fields();
create or replace function kit.get_upper_system_role()
returns varchar
as $$
declare
role varchar(50);
begin
select name from public.roles
where account_id is null and
hierarchy_level = 1 into role;
return role;
end;
$$
language plpgsql;
create or replace function kit.add_current_user_to_new_account() create or replace function kit.add_current_user_to_new_account()
returns trigger returns trigger
language plpgsql language plpgsql
@@ -436,7 +446,7 @@ begin
values( values(
new.id, new.id,
auth.uid(), auth.uid(),
'owner'); kit.get_upper_system_role());
end if; end if;
@@ -490,7 +500,7 @@ create trigger "on_auth_user_updated"
-- Account Memberships table -- Account Memberships table
create table if not exists public.roles( create table if not exists public.roles(
name varchar(50) not null, name varchar(50) not null,
hierarchy_level int not null, hierarchy_level int not null check (hierarchy_level > 0),
account_id uuid references public.accounts(id) on delete cascade, account_id uuid references public.accounts(id) on delete cascade,
unique(name, account_id), unique(name, account_id),
primary key (name) primary key (name)
@@ -509,9 +519,13 @@ end; $$ language plpgsql immutable;
grant execute on function kit.get_system_role_uuid() to authenticated, service_role; grant execute on function kit.get_system_role_uuid() to authenticated, service_role;
-- we create a unique index on the roles table to ensure that the
-- can there be a unique hierarchy_level per account (or system role)
create unique index idx_unique_hierarchy_per_account create unique index idx_unique_hierarchy_per_account
on public.roles (hierarchy_level, coalesce(account_id, kit.get_system_role_uuid())); on public.roles (hierarchy_level, coalesce(account_id, kit.get_system_role_uuid()));
-- we create a unique index on the roles table to ensure that the
-- can there be a unique name per account (or system role)
create unique index idx_unique_name_per_account create unique index idx_unique_name_per_account
on public.roles (name, coalesce(account_id, kit.get_system_role_uuid())); on public.roles (name, coalesce(account_id, kit.get_system_role_uuid()));
@@ -537,22 +551,6 @@ create constraint trigger tr_check_non_personal_account_roles
for each row for each row
execute procedure kit.check_non_personal_account_roles(); execute procedure kit.check_non_personal_account_roles();
-- Seed the roles table with default roles 'owner' and
-- 'member'
insert into public.roles(
name,
hierarchy_level)
values (
'owner',
1);
insert into public.roles(
name,
hierarchy_level)
values (
'member',
2);
-- RLS -- RLS
alter table public.roles enable row level security; alter table public.roles enable row level security;
@@ -672,7 +670,7 @@ create policy roles_read on public.roles
or public.has_role_on_account(account_id) or public.has_role_on_account(account_id)
); );
-- Function to check if a user can remove a member from an account -- Function to check if a user can remove a member from an account
create or replace function create or replace function
kit.can_remove_account_member(target_team_account_id uuid, kit.can_remove_account_member(target_team_account_id uuid,
user_id uuid) user_id uuid)
@@ -882,6 +880,7 @@ begin
where where
id = target_account_id id = target_account_id
and primary_owner_user_id = target_user_id) into is_primary_owner; and primary_owner_user_id = target_user_id) into is_primary_owner;
-- If the user is the primary owner, they have the highest role and can -- If the user is the primary owner, they have the highest role and can
-- perform any action -- perform any action
if is_primary_owner then if is_primary_owner then
@@ -908,9 +907,11 @@ begin
from from
public.roles public.roles
where where
name = role_name; name = role_name
and account_id = target_account_id or account_id is null;
-- If the user's role is higher than the target role, they can perform -- If the user's role is higher than the target role, they can perform
-- the action -- the action
return user_role_hierarchy_level < target_role_hierarchy_level; return user_role_hierarchy_level < target_role_hierarchy_level;
end; end;

View File

@@ -1,3 +1,18 @@
-- Seed the roles table with default roles 'owner' and 'member'
insert into public.roles(
name,
hierarchy_level)
values (
'owner',
1);
insert into public.roles(
name,
hierarchy_level)
values (
'member',
2);
-- We seed the role_permissions table with the default roles and permissions -- We seed the role_permissions table with the default roles and permissions
insert into public.role_permissions( insert into public.role_permissions(
role, role,