import { usersTable, tasksTable, clientsTable } from "@workspace/db"; import { eq, or } from "drizzle-orm"; export type User = typeof usersTable.$inferSelect; export type Task = typeof tasksTable.$inferSelect; export type Client = typeof clientsTable.$inferSelect; export const ROLES = { ADMIN: "admin", HEAD_OF_TEAM: "head_of_team", TEAM_LEAD: "team_lead", MEMBER: "member", } as const; /** * Check if a user is an admin. */ export function isAdmin(user: User): boolean { return user.role === ROLES.ADMIN; } /** * Check if a user is Head of Team (operational supervisor). */ export function isHeadOfTeam(user: User): boolean { return user.role === ROLES.HEAD_OF_TEAM; } /** * Check if a user is a Team Lead. * Includes legacy 'dept_manager' role compatibility. */ export function isTeamLead(user: User): boolean { return user.role === ROLES.TEAM_LEAD || user.role === "dept_manager"; } /** * Check if a user is a Member. */ export function isMember(user: User): boolean { return user.role === ROLES.MEMBER; } /** * Determines if a user has access to see tasks from all teams. */ export function canAccessAllTeams(user: User): boolean { return isAdmin(user) || isHeadOfTeam(user); } /** * Determines if a user can grant admin privileges. */ export function canGrantAdmin(requestingUser: User): boolean { return isAdmin(requestingUser); } /** * Determines if a user can manage sensitive system configuration. */ export function canManageSystemConfig(user: User): boolean { return isAdmin(user); } /** * Determines if a user can view a specific task. */ export function canAccessTask(user: User, task: Task): boolean { if (canAccessAllTeams(user)) return true; if (isTeamLead(user)) { return task.fromTeam === user.team || task.assignedTeam === user.team; } // Member: Only assigned, created, or involved. // Currently schema supports assigned and created fields. return ( task.createdByUserId === user.id || task.assignedUserId === user.id ); } /** * Determines if a user can modify a specific task. */ export function canModifyTask(user: User, task: Task): boolean { if (isAdmin(user)) return true; if (isHeadOfTeam(user)) return true; // Supervise full operations if (isTeamLead(user)) { return task.fromTeam === user.team || task.assignedTeam === user.team; } // Members can update tasks they created or are assigned to return task.createdByUserId === user.id || task.assignedUserId === user.id; } /** * Determines if a user can view another user's profile/data. */ export function canAccessUser(requestingUser: User, targetUser: User): boolean { if (isAdmin(requestingUser)) return true; if (isHeadOfTeam(requestingUser)) return true; if (isTeamLead(requestingUser) && requestingUser.team === targetUser.team) return true; return requestingUser.id === targetUser.id; } /** * Returns a Drizzle filter expression for task visibility based on the new role model. */ export function getTaskVisibilityFilter(user: User) { if (canAccessAllTeams(user)) return undefined; if (isTeamLead(user)) { return or( eq(tasksTable.fromTeam, user.team), eq(tasksTable.assignedTeam, user.team) ); } // Member: ONLY assigned or created return or( eq(tasksTable.createdByUserId, user.id), eq(tasksTable.assignedUserId, user.id) ); }