Files
root-org/src/routes/[orgSlug]/settings/+page.server.ts
2026-02-07 01:31:55 +02:00

86 lines
2.5 KiB
TypeScript

import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import type { OrgLayoutData } from '$lib/types/layout';
import { createLogger } from '$lib/utils/logger';
import { getServiceAccountEmail } from '$lib/api/google-calendar-push';
import { env } from '$env/dynamic/private';
const log = createLogger('page.settings');
export const load: PageServerLoad = async ({ parent, locals }) => {
const { org, userRole } = await parent() as OrgLayoutData;
// Only admins and owners can access settings
if (userRole !== 'owner' && userRole !== 'admin') {
redirect(303, `/${org.slug}`);
}
const orgId = org.id;
// Fetch all settings data in parallel
const [membersResult, rolesResult, invitesResult, calendarResult] = await Promise.all([
// Get org members (without embedded profile join — FK points to auth.users, not profiles)
locals.supabase
.from('org_members')
.select('id, user_id, role, role_id, invited_at')
.eq('org_id', orgId),
// Get org roles
locals.supabase
.from('org_roles')
.select('*')
.eq('org_id', orgId)
.order('position'),
// Get pending invites
locals.supabase
.from('org_invites')
.select('*')
.eq('org_id', orgId)
.is('accepted_at', null)
.gt('expires_at', new Date().toISOString()),
// Get org Google Calendar connection
locals.supabase
.from('org_google_calendars')
.select('*')
.eq('org_id', orgId)
.single()
]);
if (membersResult.error) {
log.error('Failed to fetch members', { error: membersResult.error, data: { orgId } });
}
// Fetch profiles separately since org_members.user_id FK points to auth.users, not profiles
const rawMembers = membersResult.data ?? [];
const userIds = rawMembers.map(m => m.user_id).filter((id): id is string => id !== null);
let profilesMap: Record<string, { id: string; email: string; full_name: string | null; avatar_url: string | null }> = {};
if (userIds.length > 0) {
const { data: profiles } = await locals.supabase
.from('profiles')
.select('id, email, full_name, avatar_url')
.in('id', userIds);
if (profiles) {
profilesMap = Object.fromEntries(profiles.map(p => [p.id, p]));
}
}
const members = rawMembers.map(m => ({
...m,
profiles: (m.user_id ? profilesMap[m.user_id] : null) ?? null
}));
const serviceAccountEmail = env.GOOGLE_SERVICE_ACCOUNT_KEY
? getServiceAccountEmail(env.GOOGLE_SERVICE_ACCOUNT_KEY)
: null;
return {
members,
roles: rolesResult.data ?? [],
invites: invitesResult.data ?? [],
orgCalendar: calendarResult.data,
serviceAccountEmail,
userRole
};
};