import { db } from "../db"; import { roles, roleMembers } from "@shared/schema"; import { and, eq } from "drizzle-orm"; /** * Доступ к модулям (GPS / Финансы) по флагам users. и roles.. * * Effective-доступ = users. OR любая организационная роль пользователя * с флагом OR appRole = 'admin'. Оба флага NOT NULL DEFAULT true — при выкатке * никто не блокируется; админ снимает галки в матрице на странице /users. * * Для Финансов флаг работает как ДОПОЛНИТЕЛЬНЫЙ ограничитель поверх * существующего app-role права finance.manage (см. requirePermission) — * только отбирает доступ, не добавляет. */ export type ModuleAccessKey = "gps" | "finance"; export interface ModuleAccessUser { id: number; organizationId: number; appRole?: string; gpsAccess?: boolean; financeAccess?: boolean; } export async function hasModuleAccess(user: ModuleAccessUser, module: ModuleAccessKey): Promise { if (user.appRole === "admin") return true; const userFlag = module === "gps" ? user.gpsAccess : user.financeAccess; if (userFlag) return true; // Флаг любой организационной роли пользователя const rows = await db .select({ gpsAccess: roles.gpsAccess, financeAccess: roles.financeAccess }) .from(roleMembers) .innerJoin(roles, eq(roleMembers.roleId, roles.id)) .where(and(eq(roleMembers.userId, user.id), eq(roles.organizationId, user.organizationId))); return rows.some((r) => (module === "gps" ? r.gpsAccess : r.financeAccess)); }