feat(company-skills): implement skill deletion with agent usage check

Added functionality to prevent deletion of skills that are still in use by agents. Updated the company skill service to throw an unprocessable error if a skill is attempted to be deleted while still referenced by agents. Enhanced the UI to include a delete button and confirmation dialog, displaying relevant messages based on agent usage. Updated tests to cover the new deletion logic and error handling.
This commit is contained in:
Daniel Sousa 2026-04-01 17:18:01 +01:00
parent 5b479652f2
commit 77f854c081
No known key found for this signature in database
4 changed files with 189 additions and 31 deletions

View file

@ -3,6 +3,7 @@ import request from "supertest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { companySkillRoutes } from "../routes/company-skills.js";
import { errorHandler } from "../middleware/index.js";
import { unprocessable } from "../errors.js";
const mockAgentService = vi.hoisted(() => ({
getById: vi.fn(),
@ -15,6 +16,7 @@ const mockAccessService = vi.hoisted(() => ({
const mockCompanySkillService = vi.hoisted(() => ({
importFromSource: vi.fn(),
deleteSkill: vi.fn(),
}));
const mockLogActivity = vi.hoisted(() => vi.fn());
@ -45,6 +47,11 @@ describe("company skill mutation permissions", () => {
imported: [],
warnings: [],
});
mockCompanySkillService.deleteSkill.mockResolvedValue({
id: "skill-1",
slug: "find-skills",
name: "Find Skills",
});
mockLogActivity.mockResolvedValue(undefined);
mockAccessService.canUser.mockResolvedValue(true);
mockAccessService.hasPermission.mockResolvedValue(false);
@ -110,4 +117,28 @@ describe("company skill mutation permissions", () => {
"https://github.com/vercel-labs/agent-browser",
);
});
it("returns a blocking error when attempting to delete a skill still used by agents", async () => {
mockCompanySkillService.deleteSkill.mockRejectedValue(
unprocessable(
'Cannot delete skill "Find Skills" while it is still used by Builder, Reviewer. Detach it from those agents first.',
),
);
const res = await request(createApp({
type: "board",
userId: "local-board",
companyIds: ["company-1"],
source: "local_implicit",
isInstanceAdmin: false,
}))
.delete("/api/companies/company-1/skills/skill-1");
expect(res.status, JSON.stringify(res.body)).toBe(422);
expect(res.body).toEqual({
error: 'Cannot delete skill "Find Skills" while it is still used by Builder, Reviewer. Detach it from those agents first.',
});
expect(mockCompanySkillService.deleteSkill).toHaveBeenCalledWith("company-1", "skill-1");
expect(mockLogActivity).not.toHaveBeenCalled();
});
});