feat(assistant): align resource tool visibility with read audiences

This commit is contained in:
2026-03-30 10:11:55 +02:00
parent bd654251f7
commit 65fe7ce04f
4 changed files with 54 additions and 1 deletions
@@ -697,6 +697,52 @@ describe("resource router", () => {
});
});
it("blocks controller-only resource analytics for plain users", async () => {
const db = {
resource: {
findMany: vi.fn(),
},
assignment: {
findMany: vi.fn(),
},
demandRequirement: {
findMany: vi.fn(),
},
};
const caller = createProtectedCaller(db);
await expect(caller.getSkillsAnalytics()).rejects.toMatchObject({
code: "FORBIDDEN",
message: "Controller access required",
});
await expect(caller.searchBySkills({
rules: [{ skill: "Houdini", minProficiency: 4 }],
})).rejects.toMatchObject({
code: "FORBIDDEN",
message: "Controller access required",
});
await expect(caller.listWithUtilization({})).rejects.toMatchObject({
code: "FORBIDDEN",
message: "Controller access required",
});
await expect(caller.getChargeabilityStats({})).rejects.toMatchObject({
code: "FORBIDDEN",
message: "Controller access required",
});
await expect(caller.getSkillMarketplace({
searchSkill: "Houdini",
availableOnly: true,
})).rejects.toMatchObject({
code: "FORBIDDEN",
message: "Controller access required",
});
expect(db.resource.findMany).not.toHaveBeenCalled();
expect(db.assignment.findMany).not.toHaveBeenCalled();
expect(db.demandRequirement.findMany).not.toHaveBeenCalled();
});
it("rejects chargeability summary access for foreign resources", async () => {
const db = {
resource: {