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

@@ -16,6 +16,8 @@ import { RenewInvitationSchema } from '../../schema/renew-invitation.schema';
import { UpdateInvitationSchema } from '../../schema/update-invitation.schema';
import { createAccountInvitationsService } from '../services/account-invitations.service';
import { createAccountPerSeatBillingService } from '../services/account-per-seat-billing.service';
import { createNotificationsApi } from '@kit/notifications/api';
import { getLogger } from '@kit/shared/logger';
/**
* @name createInvitationsAction
@@ -23,14 +25,55 @@ import { createAccountPerSeatBillingService } from '../services/account-per-seat
*/
export const createInvitationsAction = enhanceAction(
async (params) => {
const logger = await getLogger();
const client = getSupabaseServerClient();
const serviceClient = getSupabaseServerAdminClient();
// Create the service
const service = createAccountInvitationsService(client);
const api = createNotificationsApi(serviceClient);
// send invitations
await service.sendInvitations(params);
const { invitations: invitationParams, accountSlug } = params;
const personalCodes = invitationParams.map(({ personal_code }) => personal_code);
const { data: company, error: companyError } = await client
.from('accounts')
.select('id')
.eq('slug', accountSlug);
logger.debug({ company, companyError, personalCodes })
if (companyError || !company?.length || !company[0]) {
throw new Error(`Failed to fetch company id: ${companyError?.message || 'not found'}`);
}
const { data: invitations, error: invitationError } = await serviceClient.rpc(
'get_invitations_with_account_ids',
{
company_id: company[0].id,
personal_codes: personalCodes,
}
);
logger.debug({ invitations, invitationError })
if (invitationError) {
throw new Error(`Failed to fetch invitations with accounts: ${invitationError.message}`);
}
const notificationPromises = invitations
.map(({ invite_token, account_id }) =>
api.createNotification({
account_id: account_id!,
body: `You are invited to join the company: ${accountSlug}`,
link: `/join?invite_token=${invite_token}`,
})
);
await Promise.all(notificationPromises);
logger.info('All invitation notifications are sent')
revalidateMemberPage();
return {

View File

@@ -0,0 +1,24 @@
import { SupabaseClient } from '@supabase/supabase-js';
import { Database } from '@kit/supabase/database';
/**
* @name isCompanyAdmin
* @description Check if the current user is a super admin.
* @param client
*/
export async function isCompanyAdmin(client: SupabaseClient<Database>, accountSlug: string) {
try {
const { data, error } = await client.rpc('is_company_admin', {
account_slug: accountSlug,
});
if (error) {
throw error;
}
return data;
} catch {
return false;
}
}