295 lines
8.4 KiB
TypeScript
295 lines
8.4 KiB
TypeScript
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<string, string> = {
|
|
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<PermissionKey>,
|
|
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<PermissionKey>,
|
|
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<PermissionKey>,
|
|
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)
|
|
));
|
|
}
|