feat(assistant): align tool visibility with route audiences

This commit is contained in:
2026-03-30 09:22:26 +02:00
parent 93c4374973
commit a960d43ed1
2 changed files with 83 additions and 0 deletions
@@ -375,6 +375,68 @@ describe("assistant router tool gating", () => {
expect(userNames).not.toContain("get_project_computation_graph");
});
it("keeps planning read tools behind the explicit planning permission", () => {
const userWithoutPlanning = getToolNames([], SystemRole.USER);
const userWithPlanning = getToolNames([PermissionKey.VIEW_PLANNING], SystemRole.USER);
expect(userWithoutPlanning).not.toContain("list_allocations");
expect(userWithoutPlanning).not.toContain("list_demands");
expect(userWithoutPlanning).not.toContain("check_resource_availability");
expect(userWithPlanning).toContain("list_allocations");
expect(userWithPlanning).toContain("list_demands");
expect(userWithPlanning).toContain("check_resource_availability");
});
it("keeps controller-only project and dashboard reads hidden from plain users", () => {
const controllerNames = getToolNames([
PermissionKey.VIEW_COSTS,
PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
], SystemRole.CONTROLLER);
const userNames = getToolNames([
PermissionKey.VIEW_COSTS,
PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
PermissionKey.VIEW_PLANNING,
], SystemRole.USER);
expect(controllerNames).toContain("search_projects");
expect(controllerNames).toContain("get_project");
expect(controllerNames).toContain("get_statistics");
expect(controllerNames).toContain("get_dashboard_detail");
expect(controllerNames).toContain("get_skill_gaps");
expect(controllerNames).toContain("get_project_health");
expect(controllerNames).toContain("get_budget_forecast");
expect(userNames).not.toContain("search_projects");
expect(userNames).not.toContain("get_project");
expect(userNames).not.toContain("get_statistics");
expect(userNames).not.toContain("get_dashboard_detail");
expect(userNames).not.toContain("get_skill_gaps");
expect(userNames).not.toContain("get_project_health");
expect(userNames).not.toContain("get_budget_forecast");
});
it("requires both controller role and advanced assistant access for timeline detail tools", () => {
const controllerWithAdvanced = getToolNames([
PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
], SystemRole.CONTROLLER);
const controllerWithoutAdvanced = getToolNames([], SystemRole.CONTROLLER);
const userWithAdvanced = getToolNames([
PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
], SystemRole.USER);
expect(controllerWithAdvanced).toContain("get_timeline_entries_view");
expect(controllerWithAdvanced).toContain("get_timeline_holiday_overlays");
expect(controllerWithAdvanced).toContain("get_project_timeline_context");
expect(controllerWithAdvanced).toContain("preview_project_shift");
expect(controllerWithoutAdvanced).not.toContain("get_timeline_entries_view");
expect(controllerWithoutAdvanced).not.toContain("get_timeline_holiday_overlays");
expect(controllerWithoutAdvanced).not.toContain("get_project_timeline_context");
expect(controllerWithoutAdvanced).not.toContain("preview_project_shift");
expect(userWithAdvanced).not.toContain("get_timeline_entries_view");
expect(userWithAdvanced).not.toContain("get_timeline_holiday_overlays");
expect(userWithAdvanced).not.toContain("get_project_timeline_context");
expect(userWithAdvanced).not.toContain("preview_project_shift");
});
it("keeps timeline write parity tools behind manager/admin role, manageAllocations, and advanced assistant access", () => {
const managerNames = getToolNames([
PermissionKey.MANAGE_ALLOCATIONS,