118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
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<string, number[]>()
|
|
|
|
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,
|
|
})))
|
|
}
|