Update database types and relationships

The commit removes semicolons at the ends of lines and makes updates to the Database object in the `database.types.ts` file. This better aligns the syntax with TypeScript norms. It also affects many database relationships, including but not limited to `Accounts`, `Roles`, and `Subscriptions`.
This commit is contained in:
giancarlo
2024-04-16 22:17:28 +08:00
parent 1cb0470ce0
commit 8dd4b594d2
10 changed files with 2200 additions and 1904 deletions

View File

@@ -20,7 +20,7 @@ import pathsConfig from '~/config/paths.config';
export const loadTeamWorkspace = cache(async (accountSlug: string) => { export const loadTeamWorkspace = cache(async (accountSlug: string) => {
const client = getSupabaseServerComponentClient(); const client = getSupabaseServerComponentClient();
const accountPromise = client.rpc('organization_account_workspace', { const accountPromise = client.rpc('team_account_workspace', {
account_slug: accountSlug, account_slug: accountSlug,
}); });

View File

@@ -16,7 +16,7 @@ import { loadUserWorkspace } from '../_lib/load-user-workspace';
export function HomeSidebar() { export function HomeSidebar() {
const collapsed = getSidebarCollapsed(); const collapsed = getSidebarCollapsed();
const { accounts, user } = use(loadUserWorkspace()); const { accounts, user, workspace } = use(loadUserWorkspace());
return ( return (
<Sidebar collapsed={collapsed}> <Sidebar collapsed={collapsed}>
@@ -38,7 +38,11 @@ export function HomeSidebar() {
<div className={'absolute bottom-4 left-0 w-full'}> <div className={'absolute bottom-4 left-0 w-full'}>
<SidebarContent> <SidebarContent>
<ProfileAccountDropdownContainer collapsed={collapsed} user={user} /> <ProfileAccountDropdownContainer
collapsed={collapsed}
user={user}
account={workspace}
/>
</SidebarContent> </SidebarContent>
</div> </div>
</Sidebar> </Sidebar>

View File

@@ -9,27 +9,37 @@ import { useUser } from '@kit/supabase/hooks/use-user';
import featuresFlagConfig from '~/config/feature-flags.config'; import featuresFlagConfig from '~/config/feature-flags.config';
import pathsConfig from '~/config/paths.config'; import pathsConfig from '~/config/paths.config';
const paths = {
home: pathsConfig.app.home,
};
const features = {
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
};
export function ProfileAccountDropdownContainer(props: { export function ProfileAccountDropdownContainer(props: {
collapsed: boolean; collapsed: boolean;
user: User | null; user: User | null;
account?: {
id: string | null;
name: string | null;
picture_url: string | null;
};
}) { }) {
const signOut = useSignOut(); const signOut = useSignOut();
const user = useUser(props.user); const user = useUser(props.user);
const userData = user.data ?? props.user ?? null; const userData = user.data ?? props.user ?? null;
return ( return (
<div className={props.collapsed ? '' : 'w-full animate-in fade-in-90'}> <div className={props.collapsed ? '' : 'w-full'}>
<PersonalAccountDropdown <PersonalAccountDropdown
paths={{
home: pathsConfig.app.home,
}}
features={{
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
}}
className={'w-full'} className={'w-full'}
paths={paths}
features={features}
showProfileName={!props.collapsed} showProfileName={!props.collapsed}
user={userData} user={userData}
account={props.account}
signOutRequested={() => signOut.mutateAsync()} signOutRequested={() => signOut.mutateAsync()}
/> />
</div> </div>

View File

@@ -1,26 +1,62 @@
import { cache } from 'react'; import { cache } from 'react';
import { SupabaseClient } from '@supabase/supabase-js';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import featureFlagsConfig from '~/config/feature-flags.config'; import featureFlagsConfig from '~/config/feature-flags.config';
import { Database } from '~/lib/database.types'; import { Database } from '~/lib/database.types';
/**
* @name loadUserWorkspace
* @description
* Load the user workspace data. It's a cached per-request function that fetches the user workspace data.
* It can be used across the server components to load the user workspace data.
*/
export const loadUserWorkspace = cache(async () => { export const loadUserWorkspace = cache(async () => {
const client = getSupabaseServerComponentClient(); const client = getSupabaseServerComponentClient();
const loadAccounts = featureFlagsConfig.enableTeamAccounts; const loadAccounts = featureFlagsConfig.enableTeamAccounts;
const accounts = loadAccounts ? await loadUserAccounts(client) : []; const accountsPromise = loadAccounts
const { data } = await client.auth.getUser(); ? loadUserAccounts(client)
: Promise.resolve([]);
const workspacePromise = loadUserAccountWorkspace(client);
const userPromise = client.auth.getUser();
const [accounts, workspace, userResult] = await Promise.all([
accountsPromise,
workspacePromise,
userPromise,
]);
const user = userResult.data.user;
if (!user) {
throw new Error('User is not logged in');
}
return { return {
accounts, accounts,
user: data.user, workspace,
user,
}; };
}); });
async function loadUserAccounts( async function loadUserAccountWorkspace(client: SupabaseClient<Database>) {
client: ReturnType<typeof getSupabaseServerComponentClient<Database>>, const { data, error } = await client
) { .from('user_account_workspace')
.select(`*`)
.single();
if (error) {
throw error;
}
return data;
}
async function loadUserAccounts(client: SupabaseClient<Database>) {
const { data: accounts, error } = await client const { data: accounts, error } = await client
.from('user_accounts') .from('user_accounts')
.select(`name, slug, picture_url`); .select(`name, slug, picture_url`);

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -1781,19 +1781,21 @@ language plpgsql;
-- --
-- VIEW "user_account_workspace": -- VIEW "user_account_workspace":
-- we create a view to load the general app data for the authenticated -- we create a view to load the general app data for the authenticated
-- user which includes the user's accounts, memberships, and roles, and relative subscription status -- user which includes the user accounts and memberships
create or replace view public.user_account_workspace as create or replace view public.user_account_workspace as
select select
accounts.id as id, accounts.id as id,
accounts.name as name, accounts.name as name,
accounts.picture_url as picture_url, accounts.picture_url as picture_url,
accounts.public_data as public_data,
subscriptions.status as subscription_status subscriptions.status as subscription_status
from from
public.accounts public.accounts
left join public.subscriptions on accounts.id = subscriptions.account_id left join public.subscriptions on accounts.id = subscriptions.account_id
where where
primary_owner_user_id = auth.uid() primary_owner_user_id = auth.uid()
and accounts.is_personal_account = true; and accounts.is_personal_account = true
limit 1;
grant select on public.user_account_workspace to authenticated, service_role; grant select on public.user_account_workspace to authenticated, service_role;
@@ -1822,7 +1824,7 @@ grant select on public.user_accounts to authenticated, service_role;
-- Function: get the account workspace for an organization account -- Function: get the account workspace for an organization account
-- to load all the required data for the authenticated user within the account scope -- to load all the required data for the authenticated user within the account scope
create or replace function create or replace function
public.organization_account_workspace(account_slug text) public.team_account_workspace(account_slug text)
returns table( returns table(
id uuid, id uuid,
name varchar(255), name varchar(255),
@@ -1869,7 +1871,7 @@ end;
$$ $$
language plpgsql; language plpgsql;
grant execute on function public.organization_account_workspace(text) grant execute on function public.team_account_workspace(text)
to authenticated, service_role; to authenticated, service_role;
-- Functions: get account members -- Functions: get account members

View File

@@ -36,19 +36,29 @@ export function PersonalAccountDropdown({
showProfileName, showProfileName,
paths, paths,
features, features,
account,
}: { }: {
className?: string; className?: string;
user: User | null; user: User | null;
account?: {
id: string | null;
name: string | null;
picture_url: string | null;
};
signOutRequested: () => unknown; signOutRequested: () => unknown;
showProfileName?: boolean; showProfileName?: boolean;
paths: { paths: {
home: string; home: string;
}; };
features: { features: {
enableThemeToggle: boolean; enableThemeToggle: boolean;
}; };
}) { }) {
const { data: personalAccountData } = usePersonalAccountData(); const { data: personalAccountData } = usePersonalAccountData(account);
const signedInAsLabel = useMemo(() => { const signedInAsLabel = useMemo(() => {
const email = user?.email ?? undefined; const email = user?.email ?? undefined;
@@ -57,7 +67,8 @@ export function PersonalAccountDropdown({
return email ?? phone; return email ?? phone;
}, [user?.email, user?.phone]); }, [user?.email, user?.phone]);
const displayName = personalAccountData?.name ?? user?.email ?? ''; const displayName =
account?.name ?? personalAccountData?.name ?? user?.email ?? '';
const isSuperAdmin = useMemo(() => { const isSuperAdmin = useMemo(() => {
return user?.app_metadata.role === 'super-admin'; return user?.app_metadata.role === 'super-admin';

View File

@@ -5,7 +5,15 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useSupabase } from '@kit/supabase/hooks/use-supabase'; import { useSupabase } from '@kit/supabase/hooks/use-supabase';
import { useUser } from '@kit/supabase/hooks/use-user'; import { useUser } from '@kit/supabase/hooks/use-user';
export function usePersonalAccountData() { export function usePersonalAccountData(
partialAccount?:
| {
id: string | null;
name: string | null;
picture_url: string | null;
}
| undefined,
) {
const client = useSupabase(); const client = useSupabase();
const user = useUser(); const user = useUser();
const userId = user.data?.id; const userId = user.data?.id;
@@ -43,6 +51,7 @@ export function usePersonalAccountData() {
enabled: !!userId, enabled: !!userId,
refetchOnWindowFocus: false, refetchOnWindowFocus: false,
refetchOnMount: false, refetchOnMount: false,
initialData: partialAccount,
}); });
} }

File diff suppressed because it is too large Load Diff