import { and, eq } from "drizzle-orm" import { authProfiles, projects } from "../../db/schema" export function chatError(message: string, statusCode = 403): never { throw Object.assign(new Error(message), { statusCode }) } export function assertCustomRoomKey(key: string) { if (key === "allgemein" || /^(direct|project)_/.test(key)) { chatError("Dieser Raumschlüssel ist für Systemräume reserviert", 409) } } export function managesProjects(req: any): boolean { return Boolean(req.user?.is_admin || req.hasPermission?.("organisation.projects.write")) } export function projectChatSettingError(req: any, body: Record, previous = true) { if (!Object.prototype.hasOwnProperty.call(body, "chatEnabled")) return null if (typeof body.chatEnabled !== "boolean") return { statusCode: 400, error: "Projektchat aktiviert muss ein Wahrheitswert sein" } if (body.chatEnabled !== previous && !managesProjects(req)) { return { statusCode: 403, error: "Keine Berechtigung zum Ändern des Projektchats" } } return null } export async function projectChatAccess(db: any, req: any, projectId?: number) { const tenantId = Number(req.user?.tenant_id) const conditions = [eq(projects.tenant, tenantId), eq(projects.archived, false), eq(projects.chatEnabled, true)] if (projectId !== undefined) conditions.push(eq(projects.id, projectId)) const rows = await db.select().from(projects).where(and(...conditions)) if (managesProjects(req)) return rows const profiles = await db.select({ id: authProfiles.id }).from(authProfiles) .where(and(eq(authProfiles.tenant_id, tenantId), eq(authProfiles.user_id, req.user.user_id))) const profileIds = new Set(profiles.map((profile: any) => profile.id)) return rows.filter((project: any) => (project.profiles || []).some((id: string) => profileIds.has(id))) }