import { PermissionKey, SystemRole } from "@capakraken/shared"; import { ADVANCED_ASSISTANT_TOOLS, TOOL_DEFINITIONS } from "./assistant-tools.js"; import type { ToolDef } from "./assistant-tools/shared.js"; const TOOL_PERMISSION_MAP: Record = { update_resource: "manageResources", create_resource: "manageResources", deactivate_resource: "manageResources", create_role: PermissionKey.MANAGE_ROLES, update_role: PermissionKey.MANAGE_ROLES, delete_role: PermissionKey.MANAGE_ROLES, update_project: "manageProjects", create_project: "manageProjects", delete_project: "manageProjects", create_estimate: "manageProjects", clone_estimate: "manageProjects", update_estimate_draft: "manageProjects", submit_estimate_version: "manageProjects", approve_estimate_version: "manageProjects", create_estimate_revision: "manageProjects", create_estimate_export: "manageProjects", generate_estimate_weekly_phasing: "manageProjects", update_estimate_commercial_terms: "manageProjects", generate_project_cover: "manageProjects", remove_project_cover: "manageProjects", import_csv_data: PermissionKey.IMPORT_DATA, create_allocation: "manageAllocations", cancel_allocation: "manageAllocations", update_allocation_status: "manageAllocations", update_timeline_allocation_inline: "manageAllocations", apply_timeline_project_shift: "manageAllocations", quick_assign_timeline_resource: "manageAllocations", batch_quick_assign_timeline_resources: "manageAllocations", batch_shift_timeline_allocations: "manageAllocations", create_demand: "manageAllocations", fill_demand: "manageAllocations", create_estimate_planning_handoff: "manageAllocations", execute_task_action: "manageAllocations", }; const COST_TOOLS = new Set([ "get_budget_status", "get_chargeability", "get_chargeability_report", "get_resource_computation_graph", "get_project_computation_graph", "resolve_rate", "list_rate_cards", "get_estimate_detail", "get_estimate_version_snapshot", "find_best_project_resource", "get_staffing_suggestions", ]); const PLANNING_READ_TOOLS = new Set([ "list_allocations", "list_demands", "list_blueprints", "get_blueprint", "list_clients", "list_roles", "list_management_levels", "list_utilization_categories", "check_resource_availability", "get_staffing_suggestions", "find_capacity", "find_best_project_resource", ]); const RESOURCE_OVERVIEW_TOOLS = new Set([ "search_resources", "get_country", "list_org_units", ]); const CONTROLLER_ONLY_TOOLS = new Set([ "search_by_skill", "search_projects", "get_project", "search_estimates", "get_timeline_entries_view", "get_timeline_holiday_overlays", "get_project_timeline_context", "preview_project_shift", "get_statistics", "get_dashboard_detail", "get_skill_gaps", "get_project_health", "get_budget_forecast", "query_change_history", "get_entity_timeline", "export_resources_csv", "export_projects_csv", "list_audit_log_entries", "get_audit_log_entry", "get_audit_log_timeline", "get_audit_activity_summary", "get_chargeability_report", "get_resource_computation_graph", "get_project_computation_graph", "get_estimate_detail", "list_estimate_versions", "get_estimate_version_snapshot", "get_estimate_weekly_phasing", "get_estimate_commercial_terms", ]); const MANAGER_ONLY_TOOLS = new Set([ "import_csv_data", "list_assignable_users", "create_notification", "update_timeline_allocation_inline", "apply_timeline_project_shift", "quick_assign_timeline_resource", "batch_quick_assign_timeline_resources", "batch_shift_timeline_allocations", "create_estimate", "clone_estimate", "update_estimate_draft", "submit_estimate_version", "approve_estimate_version", "create_estimate_revision", "create_estimate_export", "create_estimate_planning_handoff", "generate_estimate_weekly_phasing", "update_estimate_commercial_terms", "create_task_for_user", "assign_task", "send_broadcast", "list_broadcasts", "get_broadcast_detail", "approve_vacation", "reject_vacation", "get_pending_vacation_approvals", "get_entitlement_summary", "set_entitlement", "create_role", "update_role", "delete_role", "create_client", "update_client", ]); const ADMIN_ONLY_TOOLS = new Set([ "list_users", "get_active_user_count", "create_user", "set_user_password", "update_user_role", "update_user_name", "link_user_resource", "auto_link_users_by_email", "set_user_permissions", "reset_user_permissions", "get_effective_user_permissions", "disable_user_totp", "list_dispo_import_batches", "get_dispo_import_batch", "stage_dispo_import_batch", "validate_dispo_import_batch", "cancel_dispo_import_batch", "list_dispo_staged_resources", "list_dispo_staged_projects", "list_dispo_staged_assignments", "list_dispo_staged_vacations", "list_dispo_staged_unresolved_records", "resolve_dispo_staged_record", "commit_dispo_import_batch", "get_system_settings", "update_system_settings", "clear_stored_runtime_secrets", "get_ai_configured", "test_ai_connection", "test_smtp_connection", "test_gemini_connection", "list_system_role_configs", "update_system_role_config", "list_webhooks", "get_webhook", "create_webhook", "update_webhook", "delete_webhook", "test_webhook", "create_org_unit", "update_org_unit", "create_country", "update_country", "create_metro_city", "update_metro_city", "delete_metro_city", "list_holiday_calendars", "get_holiday_calendar", "create_holiday_calendar", "update_holiday_calendar", "delete_holiday_calendar", "create_holiday_calendar_entry", "update_holiday_calendar_entry", "delete_holiday_calendar_entry", ]); function hasLegacyToolAccess( toolName: string, permissions: Set, userRole: string, hasResourceOverviewAccess: boolean, hasControllerAccess: boolean, hasManagerAccess: boolean, ) { const requiredPerm = TOOL_PERMISSION_MAP[toolName]; if (requiredPerm && !permissions.has(requiredPerm as PermissionKey)) { return false; } if (ADMIN_ONLY_TOOLS.has(toolName) && userRole !== SystemRole.ADMIN) { return false; } if (MANAGER_ONLY_TOOLS.has(toolName) && !hasManagerAccess) { return false; } if (RESOURCE_OVERVIEW_TOOLS.has(toolName) && !hasResourceOverviewAccess) { return false; } if (CONTROLLER_ONLY_TOOLS.has(toolName) && !hasControllerAccess) { return false; } if (PLANNING_READ_TOOLS.has(toolName) && !permissions.has(PermissionKey.VIEW_PLANNING)) { return false; } if (COST_TOOLS.has(toolName) && !permissions.has(PermissionKey.VIEW_COSTS)) { return false; } if (ADVANCED_ASSISTANT_TOOLS.has(toolName) && !permissions.has(PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS)) { return false; } return true; } function hasToolAccess( tool: ToolDef, permissions: Set, userRole: string, hasResourceOverviewAccess: boolean, ): boolean { if (!tool.access) { const hasControllerAccess = userRole === SystemRole.ADMIN || userRole === SystemRole.MANAGER || userRole === SystemRole.CONTROLLER; const hasManagerAccess = userRole === SystemRole.ADMIN || userRole === SystemRole.MANAGER; return hasLegacyToolAccess( tool.function.name, permissions, userRole, hasResourceOverviewAccess, hasControllerAccess, hasManagerAccess, ); } if (tool.access.requiredPermissions?.some((permission) => !permissions.has(permission))) { return false; } if (tool.access.allowedSystemRoles && !tool.access.allowedSystemRoles.includes(userRole as SystemRole)) { return false; } if (tool.access.requiresResourceOverview && !hasResourceOverviewAccess) { return false; } if (tool.access.requiresPlanningRead && !permissions.has(PermissionKey.VIEW_PLANNING)) { return false; } if (tool.access.requiresCostView && !permissions.has(PermissionKey.VIEW_COSTS)) { return false; } if (tool.access.requiresAdvancedAssistant && !permissions.has(PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS)) { return false; } return true; } export function getAvailableAssistantTools( permissions: Set, userRole: string, ): ToolDef[] { const hasResourceOverviewAccess = permissions.has(PermissionKey.VIEW_ALL_RESOURCES) || permissions.has(PermissionKey.MANAGE_RESOURCES); return TOOL_DEFINITIONS.filter((tool) => ( hasToolAccess(tool, permissions, userRole, hasResourceOverviewAccess) )); }