mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 02:44:50 +01:00
fix: document project access member endpoints
Add the private-project access-member routes to the OpenAPI registry and model their board-only and created-response behavior. Update shared route-test fixtures for the project read checks introduced by the privacy work. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
a87df0c351
commit
7bf6cc9d85
3 files changed
+62
-4
No files matched your search
@@ -62,6 +62,12 @@ vi.mock("../services/index.js", () => ({
|
||||
workspaceOperationService: () => ({}),
|
||||
accessService: () => ({
|
||||
canUser: vi.fn(),
|
||||
decide: vi.fn(async (input: { action: string }) => ({
|
||||
allowed: input.action === "project:read",
|
||||
action: input.action,
|
||||
reason: input.action === "project:read" ? "allow_explicit_grant" : "deny_missing_grant",
|
||||
explanation: input.action === "project:read" ? "Allowed by test default." : "Missing permission.",
|
||||
})),
|
||||
hasPermission: vi.fn(),
|
||||
}),
|
||||
agentService: () => ({
|
||||
|
||||
@@ -222,7 +222,9 @@ function registerRouteMocks() {
|
||||
issueThreadInteractionService: () => mockIssueThreadInteractionService,
|
||||
taskWatchdogService: () => mockTaskWatchdogService,
|
||||
logActivity: mockLogActivity,
|
||||
projectService: () => ({}),
|
||||
projectService: () => ({
|
||||
getById: vi.fn(async (id: string) => ({ id, companyId })),
|
||||
}),
|
||||
routineService: () => ({
|
||||
syncRunStatusForIssue: vi.fn(async () => undefined),
|
||||
}),
|
||||
@@ -387,14 +389,16 @@ describe("agent issue mutation checkout ownership", () => {
|
||||
input.action === "issue:comment" ||
|
||||
input.action === "issue:read" ||
|
||||
input.action === "issue:mutate" ||
|
||||
input.action === "company_scope:read",
|
||||
input.action === "company_scope:read" ||
|
||||
input.action === "project:read",
|
||||
action: input.action,
|
||||
reason:
|
||||
input.action === "tasks:assign" ||
|
||||
input.action === "issue:comment" ||
|
||||
input.action === "issue:read" ||
|
||||
input.action === "issue:mutate" ||
|
||||
input.action === "company_scope:read"
|
||||
input.action === "company_scope:read" ||
|
||||
input.action === "project:read"
|
||||
? "allow_explicit_grant"
|
||||
: "deny_missing_grant",
|
||||
explanation:
|
||||
@@ -402,7 +406,8 @@ describe("agent issue mutation checkout ownership", () => {
|
||||
input.action === "issue:comment" ||
|
||||
input.action === "issue:read" ||
|
||||
input.action === "issue:mutate" ||
|
||||
input.action === "company_scope:read"
|
||||
input.action === "company_scope:read" ||
|
||||
input.action === "project:read"
|
||||
? "Allowed by test default."
|
||||
: "Missing permission.",
|
||||
}));
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
// Project
|
||||
createProjectSchema,
|
||||
updateProjectSchema,
|
||||
addProjectAccessMemberSchema,
|
||||
createProjectWorkspaceSchema,
|
||||
updateProjectWorkspaceSchema,
|
||||
// Company
|
||||
@@ -776,6 +777,8 @@ const BOARD_ONLY_OPERATIONS = new Set([
|
||||
"PUT /api/companies/{companyId}/resource-memberships/me/agents/{agentId}",
|
||||
"PUT /api/companies/{companyId}/resource-memberships/me/documents/{documentId}",
|
||||
"PUT /api/companies/{companyId}/resource-memberships/me/projects/{projectId}",
|
||||
"POST /api/projects/{id}/access-members",
|
||||
"DELETE /api/projects/{id}/access-members/{memberId}",
|
||||
"GET /api/companies/{companyId}/secret-provider-configs",
|
||||
"POST /api/companies/{companyId}/secret-provider-configs",
|
||||
"GET /api/companies/{companyId}/secret-providers/health",
|
||||
@@ -924,6 +927,7 @@ const CREATED_OPERATIONS = new Set([
|
||||
"POST /api/issues/{id}/comments",
|
||||
"POST /api/companies/{companyId}/issues/{issueId}/attachments",
|
||||
"POST /api/companies/{companyId}/projects",
|
||||
"POST /api/projects/{id}/access-members",
|
||||
"POST /api/projects/{id}/workspaces",
|
||||
"POST /api/companies/{companyId}/routines",
|
||||
"POST /api/companies/{companyId}/folders",
|
||||
@@ -2571,6 +2575,49 @@ registry.registerPath({
|
||||
responses: { 200: r.ok(), 401: r.unauthorized },
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/api/projects/{id}/access-members",
|
||||
tags: ["projects"],
|
||||
summary: "List project access members",
|
||||
request: { params: z.object({ id: z.string() }) },
|
||||
responses: { 200: r.ok(), 401: r.unauthorized, 403: r.forbidden, 404: r.notFound },
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "post",
|
||||
path: "/api/projects/{id}/access-members",
|
||||
tags: ["projects"],
|
||||
summary: "Add a project access member",
|
||||
request: {
|
||||
params: z.object({ id: z.string() }),
|
||||
body: jsonBody(addProjectAccessMemberSchema),
|
||||
},
|
||||
responses: {
|
||||
201: r.ok(),
|
||||
400: r.badRequest,
|
||||
401: r.unauthorized,
|
||||
403: r.forbidden,
|
||||
404: r.notFound,
|
||||
422: r.unprocessable,
|
||||
},
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "delete",
|
||||
path: "/api/projects/{id}/access-members/{memberId}",
|
||||
tags: ["projects"],
|
||||
summary: "Remove a project access member",
|
||||
request: { params: z.object({ id: z.string(), memberId: z.string() }) },
|
||||
responses: {
|
||||
200: r.ok(),
|
||||
401: r.unauthorized,
|
||||
403: r.forbidden,
|
||||
404: r.notFound,
|
||||
422: r.unprocessable,
|
||||
},
|
||||
});
|
||||
|
||||
registry.registerPath({
|
||||
method: "get",
|
||||
path: "/api/projects/{id}/workspaces",
|
||||
|
||||
Reference in new issue
Block a user