import type { User } from "../drizzle/schema"; import * as db from "./db"; import { userHasLogisticsAccess } from "./logisticsGroup"; import { getDelegatedSignerIdsForDirectrice, getDirectriceIdsDelegatingToUser, } from "./salleSignatureDelegation"; export type AuthenticatedPortalUser = User & { canManageLogistics: boolean; canSignSalle: boolean; salleSignatureDelegatedByUserIds: number[]; }; type MinimalUser = Pick; export async function userHasSalleSignatureAccess(user: Pick) { if (user.role === "super_admin" || user.role === "directrice") { return true; } const [internalUsers, delegatedBySetting] = await Promise.all([ db.getAdminUsers(), getDirectriceIdsDelegatingToUser(user.id), ]); return internalUsers.some((entry) => { if (entry.role !== "directrice" || !entry.isActive) return false; return entry.delegatedSalleSignerUserId === user.id || delegatedBySetting.includes(entry.id); }); } export async function getSalleSignatureDelegatedByUserIds(userId: number) { const [internalUsers, delegatedBySetting] = await Promise.all([ db.getAdminUsers(), getDirectriceIdsDelegatingToUser(userId), ]); return Array.from( new Set( internalUsers .filter( (entry) => entry.role === "directrice" && entry.isActive && entry.delegatedSalleSignerUserId === userId ) .map((entry) => entry.id) .concat(delegatedBySetting) ) ); } export async function withEffectiveInternalAccess( user: TUser ): Promise<(AuthenticatedPortalUser & NonNullable) | null> { if (!user) return null; const [effectiveLogisticsAccess, effectiveSalleSignatureAccess, delegatedByUserIds] = await Promise.all([ userHasLogisticsAccess(user as MinimalUser), userHasSalleSignatureAccess(user), getSalleSignatureDelegatedByUserIds(user.id), ]); return { ...user, canManageLogistics: effectiveLogisticsAccess, canSignSalle: effectiveSalleSignatureAccess, salleSignatureDelegatedByUserIds: delegatedByUserIds, } as AuthenticatedPortalUser & NonNullable; } export async function getSalleSignatureDelegateCandidates(currentUserId: number) { const internalUsers = await db.getAdminUsers(); return internalUsers .filter( (entry) => entry.isActive && entry.id !== currentUserId && ( entry.role === "accueil" || entry.role === "admin" || entry.role === "directrice" || entry.role === "super_admin" ) ) .map((entry) => ({ id: entry.id, name: entry.name || "Sans nom", email: entry.email || "", role: entry.role, })); } export async function getSalleSignatureDelegates(directriceUserId: number) { const delegateIds = await getDelegatedSignerIdsForDirectrice(directriceUserId); const delegates = await Promise.all(delegateIds.map((id) => db.getUserById(id))); return delegates .filter((entry): entry is NonNullable => Boolean(entry?.isActive)) .map((entry) => ({ id: entry.id, name: entry.name || "Sans nom", email: entry.email || "", role: entry.role, })); }