import type { DB, Selectable, Transaction } from "../generated/kysely-tailordb"; export const recomputeUserPermissions = async ( db: DB | Transaction, userId: string, ): Promise> => { // The User.status = ACTIVE join keeps permissions empty for PENDING/INACTIVE users. const roles = await db .selectFrom("UserRole") .innerJoin("Role", "Role.id", "UserRole.roleId") .innerJoin("User", "User.id", "UserRole.userId") .select("Role.permissions") .where("UserRole.userId", "=", userId) .where("Role.status", "=", "ACTIVE") .where("User.status", "=", "ACTIVE") .execute(); // Flatten all permissions arrays, deduplicate, sort const permissions = [...new Set(roles.flatMap((r) => r.permissions ?? []))].sort(); return db .updateTable("User") .set({ permissions }) .where("id", "=", userId) .returningAll() .executeTakeFirstOrThrow(); }; export const recomputePermissionsForUsersWithRole = async ( db: DB | Transaction, roleId: string, ): Promise[]> => { const userRoles = await db .selectFrom("UserRole") .select("userId") .where("roleId", "=", roleId) .execute(); const updatedUsers = []; for (const { userId } of userRoles) { updatedUsers.push(await recomputeUserPermissions(db, userId)); } return updatedUsers; };