import { and, eq, inArray } from "drizzle-orm" import { FastifyInstance } from "fastify" import { authProfileTeams, branches, teams } from "../../db/schema" function normalizeTeamIds(values: any[]): number[] { return [...new Set( values .map((value) => { if (typeof value === "number") return value if (typeof value === "string" && value.trim()) return Number(value) if (value && typeof value === "object" && "id" in value) return Number(value.id) return NaN }) .filter((value) => Number.isFinite(value)) )] } export async function enrichProfilesWithTeams(server: FastifyInstance, profiles: any[]) { if (!profiles.length) return profiles const profileIds = profiles.map((profile) => profile.id).filter(Boolean) if (!profileIds.length) return profiles const profileTeamRows = await server.db .select() .from(authProfileTeams) .where(inArray(authProfileTeams.profile_id, profileIds)) const teamIds = [...new Set(profileTeamRows.map((row) => row.team_id).filter(Boolean))] const teamRows = teamIds.length ? await server.db.select().from(teams).where(inArray(teams.id, teamIds)) : [] const branchIds = [...new Set(teamRows.map((team) => team.branch).filter(Boolean))] const branchRows = branchIds.length ? await server.db.select().from(branches).where(inArray(branches.id, branchIds)) : [] const branchMap = new Map(branchRows.map((branch) => [branch.id, branch])) const teamMap = new Map(teamRows.map((team) => [ team.id, { ...team, branch: team.branch ? branchMap.get(team.branch) || null : null, }, ])) const teamIdsByProfile = new Map() for (const row of profileTeamRows) { const current = teamIdsByProfile.get(row.profile_id) || [] current.push(row.team_id) teamIdsByProfile.set(row.profile_id, current) } return profiles.map((profile) => { const assignedTeamIds = [...new Set(teamIdsByProfile.get(profile.id) || [])] return { ...profile, teams: assignedTeamIds .map((teamId) => teamMap.get(teamId)) .filter(Boolean), team_ids: assignedTeamIds, } }) } export async function resolveTenantTeamIds( server: FastifyInstance, tenantId: number, values: any[], ) { const requestedTeamIds = normalizeTeamIds(values) if (!requestedTeamIds.length) { return [] } const validTeams = await server.db .select({ id: teams.id }) .from(teams) .where( and( eq(teams.tenant, tenantId), inArray(teams.id, requestedTeamIds) ) ) const validTeamIds = validTeams.map((team) => team.id) if (validTeamIds.length !== requestedTeamIds.length) { throw new Error("INVALID_TEAM_SELECTION") } return validTeamIds } export async function syncProfileTeams( server: FastifyInstance, profileId: string, teamIds: number[], userId?: string | null ) { await server.db .delete(authProfileTeams) .where(eq(authProfileTeams.profile_id, profileId)) if (!teamIds.length) return await server.db .insert(authProfileTeams) .values(teamIds.map((teamId) => ({ profile_id: profileId, team_id: teamId, created_by: userId || null, }))) }