import { prisma } from "@capakraken/db"; type PrismaClient = typeof prisma; /** * Resolve recipient user IDs for a broadcast target. * Deduplicates results and optionally excludes the sender. */ export async function resolveRecipients( targetType: string, targetValue: string | null | undefined, db: PrismaClient, excludeUserId?: string, ): Promise { let userIds: string[] = []; switch (targetType) { case "user": if (targetValue) userIds = [targetValue]; break; case "role": { // Find all users with the given systemRole const roleUsers = await db.user.findMany({ where: { systemRole: targetValue as "ADMIN" | "MANAGER" | "CONTROLLER" | "USER" | "VIEWER" }, select: { id: true }, }); userIds = roleUsers.map((u) => u.id); break; } case "project": { // Find all resources with assignments on this project, then their linked users if (!targetValue) break; const assignments = await db.assignment.findMany({ where: { projectId: targetValue, status: { not: "CANCELLED" } }, select: { resource: { select: { userId: true } } }, }); userIds = assignments .map((a) => a.resource.userId) .filter((id): id is string => !!id); break; } case "orgUnit": { // Find all resources in this orgUnit, then their linked users if (!targetValue) break; const resources = await db.resource.findMany({ where: { orgUnitId: targetValue, isActive: true }, select: { userId: true }, }); userIds = resources .map((r) => r.userId) .filter((id): id is string => !!id); break; } case "all": { // User model has no isActive — get all users const allUsers = await db.user.findMany({ select: { id: true }, }); userIds = allUsers.map((u) => u.id); break; } } // Deduplicate and exclude sender const unique = [...new Set(userIds)]; return excludeUserId ? unique.filter((id) => id !== excludeUserId) : unique; }