Skip to content

Commit ebdce71

Browse files
committed
fix(api): align v2 workspace member errors and keep the old CLI spelling
- Answer a role change for a non-member with 404 "Member not found", as the organization member route does, and drop the post-write re-read. - Answer role-change contention with 503 and Retry-After, like removal; the internal route keeps its 409. - Keep `sim workspaces members` listing members as the default subcommand of the new group. - Correct the member route prose and the workspaceId parameter wording. - Give each integration test its own fixture and cover contention.
1 parent 34a5ca6 commit ebdce71

12 files changed

Lines changed: 405 additions & 327 deletions

File tree

‎apps/docs/openapi-v2-resources.json‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@
425425
"patch": {
426426
"operationId": "updateWorkspaceMember",
427427
"summary": "Update workspace member",
428-
"description": "Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; add people with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.",
428+
"description": "Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; anyone else is Not found, and people are added with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry, except that an organization Admin is refused whatever role is requested. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.",
429429
"x-sim-operation": "workspaces.permissions.update",
430430
"x-oauth-scope": "api:write",
431431
"tags": ["Workspaces"],
@@ -442,12 +442,12 @@
442442
"name": "workspaceId",
443443
"in": "path",
444444
"required": true,
445-
"description": "Workspace to retrieve.",
445+
"description": "Workspace the member belongs to.",
446446
"schema": {
447447
"type": "string",
448448
"minLength": 1,
449449
"maxLength": 128,
450-
"description": "Workspace to retrieve."
450+
"description": "Workspace the member belongs to."
451451
}
452452
},
453453
{
@@ -555,7 +555,7 @@
555555
"delete": {
556556
"operationId": "removeWorkspaceMember",
557557
"summary": "Remove workspace member",
558-
"description": "Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.",
558+
"description": "Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end, since this endpoint is called with an API key or OAuth token rather than from a signed-in browser session. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.",
559559
"x-sim-operation": "workspaces.members.remove",
560560
"x-oauth-scope": "api:write",
561561
"tags": ["Workspaces"],
@@ -572,12 +572,12 @@
572572
"name": "workspaceId",
573573
"in": "path",
574574
"required": true,
575-
"description": "Workspace to retrieve.",
575+
"description": "Workspace the member belongs to.",
576576
"schema": {
577577
"type": "string",
578578
"minLength": 1,
579579
"maxLength": 128,
580-
"description": "Workspace to retrieve."
580+
"description": "Workspace the member belongs to."
581581
}
582582
},
583583
{

‎apps/sim/lib/api/contracts/v2/openapi/resources.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ const declaredRoutes = [
764764
applicationOperation: workspacePermissionOperations.update,
765765
operationId: 'updateWorkspaceMember',
766766
summary: 'Update workspace member',
767-
description: `Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; add people with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry. ${WORKSPACE_API_KEY_DENIED}`,
767+
description: `Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; anyone else is Not found, and people are added with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry, except that an organization Admin is refused whatever role is requested. ${WORKSPACE_API_KEY_DENIED}`,
768768
errors: RESOURCE_CONFLICT_ERRORS,
769769
success: { description: 'The member with their updated workspace role.' },
770770
}),
@@ -798,7 +798,7 @@ const declaredRoutes = [
798798
applicationOperation: removeWorkspaceMemberOperation,
799799
operationId: 'removeWorkspaceMember',
800800
summary: 'Remove workspace member',
801-
description: `Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end. ${WORKSPACE_API_KEY_DENIED}`,
801+
description: `Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end, since this endpoint is called with an API key or OAuth token rather than from a signed-in browser session. ${WORKSPACE_API_KEY_DENIED}`,
802802
errors: RESOURCE_CONFLICT_ERRORS,
803803
success: { description: 'Acknowledgement that workspace access was removed.' },
804804
}),

‎apps/sim/lib/api/contracts/v2/workspaces.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ export const v2ListWorkspaceMembersContract = defineRouteContract({
121121
response: { mode: 'json', schema: v2CursorListResponse(v2WorkspaceMemberSchema) },
122122
})
123123

124-
const v2WorkspaceMemberParamsSchema = v2WorkspaceParamsSchema
125-
.extend({
124+
const v2WorkspaceMemberParamsSchema = z
125+
.object({
126+
workspaceId: workspaceIdSchema.describe('Workspace the member belongs to.'),
126127
userId: requiredFieldSchema('User ID is required')
127128
.max(MAX_ID_LENGTH, 'User ID is too long')
128129
.describe('User identifier of the workspace member, as returned by List workspace members.'),

‎apps/sim/lib/api/mcp/generated/v2-operations.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ export const V2_MCP_OPERATIONS = {
24502450
contract: v2RemoveWorkspaceMemberContract,
24512451
summary: 'Remove workspace member',
24522452
description:
2453-
'Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.',
2453+
'Remove a member’s workspace access, or leave the workspace by naming yourself. Removing someone else requires workspace Admin access; any member may leave. The last Admin cannot leave, organization Admins hold access through their organization role and cannot be removed here, and the workspace billing account cannot be removed until billing is reassigned. Removing the workspace owner transfers ownership to the billing account. When this was the member’s last workspace in its organization, their organization membership and seat are removed too and all of their sessions end, since this endpoint is called with an API key or OAuth token rather than from a signed-in browser session. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.',
24542454
workspaceKeyUnsupported: true,
24552455
handler: () =>
24562456
import('@/app/api/v2/workspaces/[workspaceId]/members/[userId]/route').then(
@@ -3025,7 +3025,7 @@ export const V2_MCP_OPERATIONS = {
30253025
contract: v2UpdateWorkspaceMemberContract,
30263026
summary: 'Update workspace member',
30273027
description:
3028-
'Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; add people with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.',
3028+
'Change one existing member’s workspace role. Requires workspace Admin access. Only existing members can be changed; anyone else is Not found, and people are added with Create workspace invitations. You cannot lower your own role, and organization Admins, the workspace owner, and the workspace billing account always keep Admin. Members whose organization membership an identity provider manages cannot be changed here. Requesting the role a member already holds changes nothing and records no audit entry, except that an organization Admin is refused whatever role is requested. Workspace API keys return `403`; use a personal API key or scoped OAuth token.\n\nOAuth scope: `api:write`.',
30293029
workspaceKeyUnsupported: true,
30303030
handler: () =>
30313031
import('@/app/api/v2/workspaces/[workspaceId]/members/[userId]/route').then(

0 commit comments

Comments
 (0)