import { getSessionUser } from '$lib/server/auth/session'; import { getPermissions } from '$lib/server/auth/authorization'; import { redirect } from '@sveltejs/kit'; import { getDatabase } from '$lib/server/database'; import type { LayoutServerLoad } from './$types'; import { getContributorMode } from '$lib/server/contributor-mode'; export const load: LayoutServerLoad = async ({ cookies }) => { const user = await getSessionUser(cookies); if (!user) redirect(303, '/sign-in'); const permissions = await getPermissions(user); if (!permissions.includes('*') && !permissions.includes('isac.access')) redirect(303, '/account'); const canSeeData = permissions.includes('*') || ['data.view','data.manage','data.propose','data.approve'].some((permission) => permissions.includes(permission)); const canManageData = permissions.includes('*') || permissions.includes('data.manage'); const canProposeData = permissions.includes('*') || permissions.includes('data.propose'); const canApproveData = permissions.includes('*') || permissions.includes('data.approve'); const canReviewAvatars = permissions.includes('*') || permissions.includes('avatars.review'); const canReviewCommunity = permissions.includes('*') || permissions.includes('community.comments.moderate') || permissions.includes('community.profiles.moderate'); const contributorMode = !canManageData && canProposeData ? await getContributorMode(user.id) : null; const database = canSeeData || canReviewAvatars || canReviewCommunity ? await getDatabase() : null; const pendingRows = canSeeData ? await (await database!.prepare("SELECT module,COUNT(*) AS count FROM data_change_proposals WHERE status='pending' GROUP BY module")).all() : []; const pendingProposalTotal = pendingRows.reduce((total, row) => total + Number(row.count), 0); const pendingAvatarReviews = canReviewAvatars ? Number((await (await database!.prepare("SELECT COUNT(*) AS count FROM avatar_reviews WHERE status='pending'")).get())?.count ?? 0) : 0; const canReviewComments = permissions.includes('*') || permissions.includes('community.comments.moderate'); const canReviewProfiles = permissions.includes('*') || permissions.includes('community.profiles.moderate'); const communityReviewTypes = [ ...(canReviewComments ? ['comment', 'guide'] : []), ...(canReviewProfiles ? ['profile_bio'] : []) ]; const communityTypePlaceholders = communityReviewTypes.map(() => '?').join(','); const pendingCommunityReviews = canReviewCommunity && communityReviewTypes.length ? Number((await (await database!.prepare(`SELECT (SELECT COUNT(*) FROM content_moderation_scans scan WHERE scan.content_type IN (${communityTypePlaceholders}) AND scan.status IN ('review','priority_review','error') AND NOT EXISTS(SELECT 1 FROM content_moderation_reviews review WHERE review.scan_id=scan.id)) + (SELECT COUNT(*) FROM user_content_reports WHERE content_type IN (${communityTypePlaceholders}) AND status='pending') AS count`)) .get(...communityReviewTypes, ...communityReviewTypes))?.count ?? 0) : 0; const configuredBuildNumber = process.env.SHD_BUILD_NUMBER?.trim() || '0'; const buildNumber = /^\d+$/.test(configuredBuildNumber) ? configuredBuildNumber : '0'; return { permissions, contributorMode, buildNumber, pendingProposals: Object.fromEntries(pendingRows.map((row) => [String(row.module), Number(row.count)])), oversightReviewCounts: { data: canApproveData ? pendingProposalTotal : 0, avatars: pendingAvatarReviews, community: pendingCommunityReviews } }; };