@dotcms/ai 26.8.14-1-next.2533 → 26.8.19-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/spec.cjs.js +527 -0
  3. package/spec.esm.js +527 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/ai",
3
- "version": "26.8.14-1-next.2533",
3
+ "version": "26.08.19-01",
4
4
  "description": "The dotCMS agentic runtime — run model-written or human-written code safely against a dotCMS instance, with auth and policy owned in one place.",
5
5
  "repository": {
6
6
  "type": "git",
package/spec.cjs.js CHANGED
@@ -4758,6 +4758,65 @@ var paths = {
4758
4758
  }
4759
4759
  },
4760
4760
  "/api/v1/roles/{roleid}": {
4761
+ "delete": {
4762
+ description: "Deletes a role. The deletion CASCADES and is not reversible: the role is removed from all users that have it, all permissions granted to the role are deleted, and its layout (tool-group) assignments are detached. The response reports how many users were affected. Deletion is rejected when the role has child roles or is referenced by a workflow action's Assign To (409), and for system or locked roles (403).",
4763
+ operationId: "deleteRole",
4764
+ parameters: [
4765
+ {
4766
+ description: "Id of the role to delete",
4767
+ "in": "path",
4768
+ name: "roleid",
4769
+ required: true,
4770
+ schema: {
4771
+ type: "string"
4772
+ }
4773
+ }
4774
+ ],
4775
+ responses: {
4776
+ "200": {
4777
+ content: {
4778
+ "application/json": {
4779
+ schema: {
4780
+ $ref: "#/components/schemas/ResponseEntityRoleDeletionView"
4781
+ }
4782
+ }
4783
+ },
4784
+ description: "Role deleted successfully; usersAffected reports the cascade blast radius"
4785
+ },
4786
+ "401": {
4787
+ content: {
4788
+ "application/json": {
4789
+ }
4790
+ },
4791
+ description: "Unauthorized - authentication required"
4792
+ },
4793
+ "403": {
4794
+ content: {
4795
+ "application/json": {
4796
+ }
4797
+ },
4798
+ description: "Forbidden - admin permissions required, or the role is a system or locked role"
4799
+ },
4800
+ "404": {
4801
+ content: {
4802
+ "application/json": {
4803
+ }
4804
+ },
4805
+ description: "Role not found"
4806
+ },
4807
+ "409": {
4808
+ content: {
4809
+ "application/json": {
4810
+ }
4811
+ },
4812
+ description: "Conflict - the role has child roles, or a workflow action references it"
4813
+ }
4814
+ },
4815
+ summary: "Delete a role",
4816
+ tags: [
4817
+ "Roles"
4818
+ ]
4819
+ },
4761
4820
  get: {
4762
4821
  description: "Load role based on the role id with optional children roles",
4763
4822
  operationId: "loadRoleByRoleId",
@@ -4825,6 +4884,218 @@ var paths = {
4825
4884
  tags: [
4826
4885
  "Roles"
4827
4886
  ]
4887
+ },
4888
+ put: {
4889
+ description: "Updates an existing role's name, key, description, can-grant flags and parent. PUT is a full replace: every field of the role is overwritten from the request body, so clients must send the complete role representation — omitted fields are reset (booleans default to false, omitted roleKey/description are cleared, omitted parentRoleId reparents to root). A null parentRoleId turns the role into a root role. Reparenting under the role's own descendant is rejected. System and locked roles cannot be updated. Note: the role is updated in place — grants and permissions attached to the role are preserved.",
4890
+ operationId: "updateRole",
4891
+ parameters: [
4892
+ {
4893
+ description: "Id of the role to update",
4894
+ "in": "path",
4895
+ name: "roleid",
4896
+ required: true,
4897
+ schema: {
4898
+ type: "string"
4899
+ }
4900
+ }
4901
+ ],
4902
+ requestBody: {
4903
+ content: {
4904
+ "application/json": {
4905
+ schema: {
4906
+ $ref: "#/components/schemas/RoleForm"
4907
+ }
4908
+ }
4909
+ },
4910
+ description: "Role information — same shape as POST /v1/roles",
4911
+ required: true
4912
+ },
4913
+ responses: {
4914
+ "200": {
4915
+ content: {
4916
+ "application/json": {
4917
+ schema: {
4918
+ $ref: "#/components/schemas/ResponseEntityRoleDetailView"
4919
+ }
4920
+ }
4921
+ },
4922
+ description: "Role updated successfully"
4923
+ },
4924
+ "400": {
4925
+ content: {
4926
+ "application/json": {
4927
+ }
4928
+ },
4929
+ description: "Bad request - invalid role name, or the reparent would create a hierarchy cycle"
4930
+ },
4931
+ "401": {
4932
+ content: {
4933
+ "application/json": {
4934
+ }
4935
+ },
4936
+ description: "Unauthorized - authentication required"
4937
+ },
4938
+ "403": {
4939
+ content: {
4940
+ "application/json": {
4941
+ }
4942
+ },
4943
+ description: "Forbidden - admin permissions required, or the role is a system or locked role"
4944
+ },
4945
+ "404": {
4946
+ content: {
4947
+ "application/json": {
4948
+ }
4949
+ },
4950
+ description: "Role or parent role not found"
4951
+ },
4952
+ "409": {
4953
+ content: {
4954
+ "application/json": {
4955
+ }
4956
+ },
4957
+ description: "Conflict - duplicate role key, or duplicate role name under the same parent"
4958
+ }
4959
+ },
4960
+ summary: "Update a role",
4961
+ tags: [
4962
+ "Roles"
4963
+ ]
4964
+ }
4965
+ },
4966
+ "/api/v1/roles/{roleid}/users": {
4967
+ "delete": {
4968
+ description: "Bulk-removes the DIRECT membership of the given users from the role. The batch has PARTIAL-SUCCESS semantics: it never fails as a whole once the role resolves — every removable membership is removed and every other entry is reported in the skipped list with a reason: not_found (no user matches the id), inherited (the user is not a direct member — the membership is inherited through the role hierarchy, or the user is not a member at all; inherited membership can only be revoked by removing the user from the ancestor role that grants it), or error (unexpected per-user failure, logged server-side). Removals are committed per user, so entries already processed stay removed regardless of later entries.",
4969
+ operationId: "removeUsersFromRole",
4970
+ parameters: [
4971
+ {
4972
+ description: "Id of the role to remove users from",
4973
+ "in": "path",
4974
+ name: "roleid",
4975
+ required: true,
4976
+ schema: {
4977
+ type: "string"
4978
+ }
4979
+ }
4980
+ ],
4981
+ requestBody: {
4982
+ content: {
4983
+ "application/json": {
4984
+ schema: {
4985
+ $ref: "#/components/schemas/RoleUsersForm"
4986
+ }
4987
+ }
4988
+ },
4989
+ description: "Ids of the users to remove from the role",
4990
+ required: true
4991
+ },
4992
+ responses: {
4993
+ "200": {
4994
+ content: {
4995
+ "application/json": {
4996
+ schema: {
4997
+ $ref: "#/components/schemas/ResponseEntityRoleUsersRemovalView"
4998
+ }
4999
+ }
5000
+ },
5001
+ description: "Batch processed; removedUserIds and skipped report the per-user outcomes"
5002
+ },
5003
+ "400": {
5004
+ content: {
5005
+ "application/json": {
5006
+ }
5007
+ },
5008
+ description: "Bad request - missing body, empty userIds, or null/blank entries"
5009
+ },
5010
+ "401": {
5011
+ content: {
5012
+ "application/json": {
5013
+ }
5014
+ },
5015
+ description: "Unauthorized - authentication required"
5016
+ },
5017
+ "403": {
5018
+ content: {
5019
+ "application/json": {
5020
+ }
5021
+ },
5022
+ description: "Forbidden - admin permissions required"
5023
+ },
5024
+ "404": {
5025
+ content: {
5026
+ "application/json": {
5027
+ }
5028
+ },
5029
+ description: "Role not found"
5030
+ }
5031
+ },
5032
+ summary: "Remove users from a role",
5033
+ tags: [
5034
+ "Roles"
5035
+ ]
5036
+ }
5037
+ },
5038
+ "/api/v1/roles/{roleid}/users/{userId}": {
5039
+ post: {
5040
+ description: "Grants the role to the user as a DIRECT membership. The operation is IDEMPOTENT: granting a role the user already holds returns 200 and changes nothing — no duplicate membership is created and retries are safe, even when the role's editUsers flag has since been turned off. Note the inherited-membership behavior (legacy parity): role membership is inherited DOWN the role tree, so a user holding a parent role implicitly holds every child role. Granting a role the user already INHERITS this way also returns 200 but does NOT create a direct membership — the user will not appear in the role's direct-users list afterwards. Roles whose editUsers flag is false cannot be granted (403); workflow and system roles are non-grantable because that flag is false on them.",
5041
+ operationId: "addUserToRole",
5042
+ parameters: [
5043
+ {
5044
+ description: "Id of the role to grant",
5045
+ "in": "path",
5046
+ name: "roleid",
5047
+ required: true,
5048
+ schema: {
5049
+ type: "string"
5050
+ }
5051
+ },
5052
+ {
5053
+ description: "Id of the user to grant the role to",
5054
+ "in": "path",
5055
+ name: "userId",
5056
+ required: true,
5057
+ schema: {
5058
+ type: "string"
5059
+ }
5060
+ }
5061
+ ],
5062
+ responses: {
5063
+ "200": {
5064
+ content: {
5065
+ "application/json": {
5066
+ schema: {
5067
+ $ref: "#/components/schemas/ResponseEntityRoleUserGrantView"
5068
+ }
5069
+ }
5070
+ },
5071
+ description: "User holds the role after the call; the response carries the granted roleId and a minimal user payload"
5072
+ },
5073
+ "401": {
5074
+ content: {
5075
+ "application/json": {
5076
+ }
5077
+ },
5078
+ description: "Unauthorized - authentication required"
5079
+ },
5080
+ "403": {
5081
+ content: {
5082
+ "application/json": {
5083
+ }
5084
+ },
5085
+ description: "Forbidden - admin permissions required, or the role's editUsers flag is false"
5086
+ },
5087
+ "404": {
5088
+ content: {
5089
+ "application/json": {
5090
+ }
5091
+ },
5092
+ description: "Role or user not found"
5093
+ }
5094
+ },
5095
+ summary: "Grant a role to a user",
5096
+ tags: [
5097
+ "Roles"
5098
+ ]
4828
5099
  }
4829
5100
  },
4830
5101
  "/api/v1/site": {
@@ -18543,6 +18814,41 @@ var components = {
18543
18814
  }
18544
18815
  }
18545
18816
  },
18817
+ ResponseEntityRoleDeletionView: {
18818
+ type: "object",
18819
+ properties: {
18820
+ entity: {
18821
+ $ref: "#/components/schemas/RoleDeletionView"
18822
+ },
18823
+ errors: {
18824
+ type: "array",
18825
+ items: {
18826
+ $ref: "#/components/schemas/ErrorEntity"
18827
+ }
18828
+ },
18829
+ i18nMessagesMap: {
18830
+ type: "object",
18831
+ additionalProperties: {
18832
+ type: "string"
18833
+ }
18834
+ },
18835
+ messages: {
18836
+ type: "array",
18837
+ items: {
18838
+ $ref: "#/components/schemas/MessageEntity"
18839
+ }
18840
+ },
18841
+ pagination: {
18842
+ $ref: "#/components/schemas/Pagination"
18843
+ },
18844
+ permissions: {
18845
+ type: "array",
18846
+ items: {
18847
+ type: "string"
18848
+ }
18849
+ }
18850
+ }
18851
+ },
18546
18852
  ResponseEntityRoleDetailView: {
18547
18853
  type: "object",
18548
18854
  properties: {
@@ -18616,6 +18922,76 @@ var components = {
18616
18922
  }
18617
18923
  }
18618
18924
  },
18925
+ ResponseEntityRoleUserGrantView: {
18926
+ type: "object",
18927
+ properties: {
18928
+ entity: {
18929
+ $ref: "#/components/schemas/RoleUserGrantView"
18930
+ },
18931
+ errors: {
18932
+ type: "array",
18933
+ items: {
18934
+ $ref: "#/components/schemas/ErrorEntity"
18935
+ }
18936
+ },
18937
+ i18nMessagesMap: {
18938
+ type: "object",
18939
+ additionalProperties: {
18940
+ type: "string"
18941
+ }
18942
+ },
18943
+ messages: {
18944
+ type: "array",
18945
+ items: {
18946
+ $ref: "#/components/schemas/MessageEntity"
18947
+ }
18948
+ },
18949
+ pagination: {
18950
+ $ref: "#/components/schemas/Pagination"
18951
+ },
18952
+ permissions: {
18953
+ type: "array",
18954
+ items: {
18955
+ type: "string"
18956
+ }
18957
+ }
18958
+ }
18959
+ },
18960
+ ResponseEntityRoleUsersRemovalView: {
18961
+ type: "object",
18962
+ properties: {
18963
+ entity: {
18964
+ $ref: "#/components/schemas/RoleUsersRemovalView"
18965
+ },
18966
+ errors: {
18967
+ type: "array",
18968
+ items: {
18969
+ $ref: "#/components/schemas/ErrorEntity"
18970
+ }
18971
+ },
18972
+ i18nMessagesMap: {
18973
+ type: "object",
18974
+ additionalProperties: {
18975
+ type: "string"
18976
+ }
18977
+ },
18978
+ messages: {
18979
+ type: "array",
18980
+ items: {
18981
+ $ref: "#/components/schemas/MessageEntity"
18982
+ }
18983
+ },
18984
+ pagination: {
18985
+ $ref: "#/components/schemas/Pagination"
18986
+ },
18987
+ permissions: {
18988
+ type: "array",
18989
+ items: {
18990
+ type: "string"
18991
+ }
18992
+ }
18993
+ }
18994
+ },
18619
18995
  ResponseEntityRoleViewListView: {
18620
18996
  type: "object",
18621
18997
  properties: {
@@ -19938,6 +20314,32 @@ var components = {
19938
20314
  }
19939
20315
  }
19940
20316
  },
20317
+ RoleDeletionView: {
20318
+ type: "object",
20319
+ properties: {
20320
+ deleted: {
20321
+ type: "boolean",
20322
+ description: "Whether the role was deleted",
20323
+ example: true
20324
+ },
20325
+ roleId: {
20326
+ type: "string",
20327
+ description: "Id of the deleted role",
20328
+ example: "48190c8c-42c4-46af-8d1a-0cd5db894797"
20329
+ },
20330
+ usersAffected: {
20331
+ type: "integer",
20332
+ format: "int32",
20333
+ description: "Number of users the role was removed from by the cascading deletion. Counts direct assignments only; users inheriting the role through the role hierarchy are not included",
20334
+ example: 3
20335
+ }
20336
+ },
20337
+ required: [
20338
+ "deleted",
20339
+ "roleId",
20340
+ "usersAffected"
20341
+ ]
20342
+ },
19941
20343
  RoleForm: {
19942
20344
  type: "object",
19943
20345
  properties: {
@@ -19967,6 +20369,32 @@ var components = {
19967
20369
  "roleName"
19968
20370
  ]
19969
20371
  },
20372
+ RoleMemberUserView: {
20373
+ type: "object",
20374
+ description: "The user the role was granted to",
20375
+ properties: {
20376
+ email: {
20377
+ type: "string",
20378
+ description: "Email address of the user",
20379
+ example: "user@example.com"
20380
+ },
20381
+ fullName: {
20382
+ type: "string",
20383
+ description: "Full name of the user",
20384
+ example: "Jane Doe"
20385
+ },
20386
+ userId: {
20387
+ type: "string",
20388
+ description: "Id of the user",
20389
+ example: "dotcms.org.2807"
20390
+ }
20391
+ },
20392
+ required: [
20393
+ "email",
20394
+ "fullName",
20395
+ "userId"
20396
+ ]
20397
+ },
19970
20398
  RoleResponseEntityView: {
19971
20399
  type: "object",
19972
20400
  properties: {
@@ -20005,6 +20433,74 @@ var components = {
20005
20433
  }
20006
20434
  }
20007
20435
  },
20436
+ RoleUserGrantView: {
20437
+ type: "object",
20438
+ properties: {
20439
+ granted: {
20440
+ type: "boolean",
20441
+ description: "Whether the user holds the role after the call. The grant is idempotent, so this is also true when the user already held the role and nothing changed",
20442
+ example: true
20443
+ },
20444
+ roleId: {
20445
+ type: "string",
20446
+ description: "Id of the granted role",
20447
+ example: "48190c8c-42c4-46af-8d1a-0cd5db894797"
20448
+ },
20449
+ user: {
20450
+ $ref: "#/components/schemas/RoleMemberUserView"
20451
+ }
20452
+ },
20453
+ required: [
20454
+ "granted",
20455
+ "roleId",
20456
+ "user"
20457
+ ]
20458
+ },
20459
+ RoleUsersForm: {
20460
+ type: "object",
20461
+ properties: {
20462
+ userIds: {
20463
+ type: "array",
20464
+ description: "Ids of the users to remove from the role",
20465
+ example: [
20466
+ "dotcms.org.2807"
20467
+ ],
20468
+ items: {
20469
+ type: "string",
20470
+ description: "Ids of the users to remove from the role",
20471
+ example: "[\"dotcms.org.2807\"]"
20472
+ },
20473
+ uniqueItems: true
20474
+ }
20475
+ },
20476
+ required: [
20477
+ "userIds"
20478
+ ]
20479
+ },
20480
+ RoleUsersRemovalView: {
20481
+ type: "object",
20482
+ properties: {
20483
+ removedUserIds: {
20484
+ type: "array",
20485
+ description: "Ids of the users whose direct membership in the role was removed",
20486
+ items: {
20487
+ type: "string",
20488
+ description: "Ids of the users whose direct membership in the role was removed"
20489
+ }
20490
+ },
20491
+ skipped: {
20492
+ type: "array",
20493
+ description: "Users that could not be removed, each with a reason",
20494
+ items: {
20495
+ $ref: "#/components/schemas/SkippedUserView"
20496
+ }
20497
+ }
20498
+ },
20499
+ required: [
20500
+ "removedUserIds",
20501
+ "skipped"
20502
+ ]
20503
+ },
20008
20504
  RoleView: {
20009
20505
  type: "object",
20010
20506
  properties: {
@@ -20038,6 +20534,12 @@ var components = {
20038
20534
  parent: {
20039
20535
  type: "string"
20040
20536
  },
20537
+ roleChildren: {
20538
+ type: "array",
20539
+ items: {
20540
+ $ref: "#/components/schemas/RoleView"
20541
+ }
20542
+ },
20041
20543
  roleKey: {
20042
20544
  type: "string"
20043
20545
  },
@@ -20393,6 +20895,31 @@ var components = {
20393
20895
  }
20394
20896
  }
20395
20897
  },
20898
+ SkippedUserView: {
20899
+ type: "object",
20900
+ description: "Users that could not be removed, each with a reason",
20901
+ properties: {
20902
+ reason: {
20903
+ type: "string",
20904
+ description: "Why the user was skipped",
20905
+ "enum": [
20906
+ "not_found",
20907
+ "inherited",
20908
+ "error"
20909
+ ],
20910
+ example: "inherited"
20911
+ },
20912
+ userId: {
20913
+ type: "string",
20914
+ description: "Id of the skipped user, as submitted in the request",
20915
+ example: "dotcms.org.2807"
20916
+ }
20917
+ },
20918
+ required: [
20919
+ "reason",
20920
+ "userId"
20921
+ ]
20922
+ },
20396
20923
  SmallRoleView: {
20397
20924
  type: "object",
20398
20925
  properties: {
package/spec.esm.js CHANGED
@@ -4756,6 +4756,65 @@ var paths = {
4756
4756
  }
4757
4757
  },
4758
4758
  "/api/v1/roles/{roleid}": {
4759
+ "delete": {
4760
+ description: "Deletes a role. The deletion CASCADES and is not reversible: the role is removed from all users that have it, all permissions granted to the role are deleted, and its layout (tool-group) assignments are detached. The response reports how many users were affected. Deletion is rejected when the role has child roles or is referenced by a workflow action's Assign To (409), and for system or locked roles (403).",
4761
+ operationId: "deleteRole",
4762
+ parameters: [
4763
+ {
4764
+ description: "Id of the role to delete",
4765
+ "in": "path",
4766
+ name: "roleid",
4767
+ required: true,
4768
+ schema: {
4769
+ type: "string"
4770
+ }
4771
+ }
4772
+ ],
4773
+ responses: {
4774
+ "200": {
4775
+ content: {
4776
+ "application/json": {
4777
+ schema: {
4778
+ $ref: "#/components/schemas/ResponseEntityRoleDeletionView"
4779
+ }
4780
+ }
4781
+ },
4782
+ description: "Role deleted successfully; usersAffected reports the cascade blast radius"
4783
+ },
4784
+ "401": {
4785
+ content: {
4786
+ "application/json": {
4787
+ }
4788
+ },
4789
+ description: "Unauthorized - authentication required"
4790
+ },
4791
+ "403": {
4792
+ content: {
4793
+ "application/json": {
4794
+ }
4795
+ },
4796
+ description: "Forbidden - admin permissions required, or the role is a system or locked role"
4797
+ },
4798
+ "404": {
4799
+ content: {
4800
+ "application/json": {
4801
+ }
4802
+ },
4803
+ description: "Role not found"
4804
+ },
4805
+ "409": {
4806
+ content: {
4807
+ "application/json": {
4808
+ }
4809
+ },
4810
+ description: "Conflict - the role has child roles, or a workflow action references it"
4811
+ }
4812
+ },
4813
+ summary: "Delete a role",
4814
+ tags: [
4815
+ "Roles"
4816
+ ]
4817
+ },
4759
4818
  get: {
4760
4819
  description: "Load role based on the role id with optional children roles",
4761
4820
  operationId: "loadRoleByRoleId",
@@ -4823,6 +4882,218 @@ var paths = {
4823
4882
  tags: [
4824
4883
  "Roles"
4825
4884
  ]
4885
+ },
4886
+ put: {
4887
+ description: "Updates an existing role's name, key, description, can-grant flags and parent. PUT is a full replace: every field of the role is overwritten from the request body, so clients must send the complete role representation — omitted fields are reset (booleans default to false, omitted roleKey/description are cleared, omitted parentRoleId reparents to root). A null parentRoleId turns the role into a root role. Reparenting under the role's own descendant is rejected. System and locked roles cannot be updated. Note: the role is updated in place — grants and permissions attached to the role are preserved.",
4888
+ operationId: "updateRole",
4889
+ parameters: [
4890
+ {
4891
+ description: "Id of the role to update",
4892
+ "in": "path",
4893
+ name: "roleid",
4894
+ required: true,
4895
+ schema: {
4896
+ type: "string"
4897
+ }
4898
+ }
4899
+ ],
4900
+ requestBody: {
4901
+ content: {
4902
+ "application/json": {
4903
+ schema: {
4904
+ $ref: "#/components/schemas/RoleForm"
4905
+ }
4906
+ }
4907
+ },
4908
+ description: "Role information — same shape as POST /v1/roles",
4909
+ required: true
4910
+ },
4911
+ responses: {
4912
+ "200": {
4913
+ content: {
4914
+ "application/json": {
4915
+ schema: {
4916
+ $ref: "#/components/schemas/ResponseEntityRoleDetailView"
4917
+ }
4918
+ }
4919
+ },
4920
+ description: "Role updated successfully"
4921
+ },
4922
+ "400": {
4923
+ content: {
4924
+ "application/json": {
4925
+ }
4926
+ },
4927
+ description: "Bad request - invalid role name, or the reparent would create a hierarchy cycle"
4928
+ },
4929
+ "401": {
4930
+ content: {
4931
+ "application/json": {
4932
+ }
4933
+ },
4934
+ description: "Unauthorized - authentication required"
4935
+ },
4936
+ "403": {
4937
+ content: {
4938
+ "application/json": {
4939
+ }
4940
+ },
4941
+ description: "Forbidden - admin permissions required, or the role is a system or locked role"
4942
+ },
4943
+ "404": {
4944
+ content: {
4945
+ "application/json": {
4946
+ }
4947
+ },
4948
+ description: "Role or parent role not found"
4949
+ },
4950
+ "409": {
4951
+ content: {
4952
+ "application/json": {
4953
+ }
4954
+ },
4955
+ description: "Conflict - duplicate role key, or duplicate role name under the same parent"
4956
+ }
4957
+ },
4958
+ summary: "Update a role",
4959
+ tags: [
4960
+ "Roles"
4961
+ ]
4962
+ }
4963
+ },
4964
+ "/api/v1/roles/{roleid}/users": {
4965
+ "delete": {
4966
+ description: "Bulk-removes the DIRECT membership of the given users from the role. The batch has PARTIAL-SUCCESS semantics: it never fails as a whole once the role resolves — every removable membership is removed and every other entry is reported in the skipped list with a reason: not_found (no user matches the id), inherited (the user is not a direct member — the membership is inherited through the role hierarchy, or the user is not a member at all; inherited membership can only be revoked by removing the user from the ancestor role that grants it), or error (unexpected per-user failure, logged server-side). Removals are committed per user, so entries already processed stay removed regardless of later entries.",
4967
+ operationId: "removeUsersFromRole",
4968
+ parameters: [
4969
+ {
4970
+ description: "Id of the role to remove users from",
4971
+ "in": "path",
4972
+ name: "roleid",
4973
+ required: true,
4974
+ schema: {
4975
+ type: "string"
4976
+ }
4977
+ }
4978
+ ],
4979
+ requestBody: {
4980
+ content: {
4981
+ "application/json": {
4982
+ schema: {
4983
+ $ref: "#/components/schemas/RoleUsersForm"
4984
+ }
4985
+ }
4986
+ },
4987
+ description: "Ids of the users to remove from the role",
4988
+ required: true
4989
+ },
4990
+ responses: {
4991
+ "200": {
4992
+ content: {
4993
+ "application/json": {
4994
+ schema: {
4995
+ $ref: "#/components/schemas/ResponseEntityRoleUsersRemovalView"
4996
+ }
4997
+ }
4998
+ },
4999
+ description: "Batch processed; removedUserIds and skipped report the per-user outcomes"
5000
+ },
5001
+ "400": {
5002
+ content: {
5003
+ "application/json": {
5004
+ }
5005
+ },
5006
+ description: "Bad request - missing body, empty userIds, or null/blank entries"
5007
+ },
5008
+ "401": {
5009
+ content: {
5010
+ "application/json": {
5011
+ }
5012
+ },
5013
+ description: "Unauthorized - authentication required"
5014
+ },
5015
+ "403": {
5016
+ content: {
5017
+ "application/json": {
5018
+ }
5019
+ },
5020
+ description: "Forbidden - admin permissions required"
5021
+ },
5022
+ "404": {
5023
+ content: {
5024
+ "application/json": {
5025
+ }
5026
+ },
5027
+ description: "Role not found"
5028
+ }
5029
+ },
5030
+ summary: "Remove users from a role",
5031
+ tags: [
5032
+ "Roles"
5033
+ ]
5034
+ }
5035
+ },
5036
+ "/api/v1/roles/{roleid}/users/{userId}": {
5037
+ post: {
5038
+ description: "Grants the role to the user as a DIRECT membership. The operation is IDEMPOTENT: granting a role the user already holds returns 200 and changes nothing — no duplicate membership is created and retries are safe, even when the role's editUsers flag has since been turned off. Note the inherited-membership behavior (legacy parity): role membership is inherited DOWN the role tree, so a user holding a parent role implicitly holds every child role. Granting a role the user already INHERITS this way also returns 200 but does NOT create a direct membership — the user will not appear in the role's direct-users list afterwards. Roles whose editUsers flag is false cannot be granted (403); workflow and system roles are non-grantable because that flag is false on them.",
5039
+ operationId: "addUserToRole",
5040
+ parameters: [
5041
+ {
5042
+ description: "Id of the role to grant",
5043
+ "in": "path",
5044
+ name: "roleid",
5045
+ required: true,
5046
+ schema: {
5047
+ type: "string"
5048
+ }
5049
+ },
5050
+ {
5051
+ description: "Id of the user to grant the role to",
5052
+ "in": "path",
5053
+ name: "userId",
5054
+ required: true,
5055
+ schema: {
5056
+ type: "string"
5057
+ }
5058
+ }
5059
+ ],
5060
+ responses: {
5061
+ "200": {
5062
+ content: {
5063
+ "application/json": {
5064
+ schema: {
5065
+ $ref: "#/components/schemas/ResponseEntityRoleUserGrantView"
5066
+ }
5067
+ }
5068
+ },
5069
+ description: "User holds the role after the call; the response carries the granted roleId and a minimal user payload"
5070
+ },
5071
+ "401": {
5072
+ content: {
5073
+ "application/json": {
5074
+ }
5075
+ },
5076
+ description: "Unauthorized - authentication required"
5077
+ },
5078
+ "403": {
5079
+ content: {
5080
+ "application/json": {
5081
+ }
5082
+ },
5083
+ description: "Forbidden - admin permissions required, or the role's editUsers flag is false"
5084
+ },
5085
+ "404": {
5086
+ content: {
5087
+ "application/json": {
5088
+ }
5089
+ },
5090
+ description: "Role or user not found"
5091
+ }
5092
+ },
5093
+ summary: "Grant a role to a user",
5094
+ tags: [
5095
+ "Roles"
5096
+ ]
4826
5097
  }
4827
5098
  },
4828
5099
  "/api/v1/site": {
@@ -18541,6 +18812,41 @@ var components = {
18541
18812
  }
18542
18813
  }
18543
18814
  },
18815
+ ResponseEntityRoleDeletionView: {
18816
+ type: "object",
18817
+ properties: {
18818
+ entity: {
18819
+ $ref: "#/components/schemas/RoleDeletionView"
18820
+ },
18821
+ errors: {
18822
+ type: "array",
18823
+ items: {
18824
+ $ref: "#/components/schemas/ErrorEntity"
18825
+ }
18826
+ },
18827
+ i18nMessagesMap: {
18828
+ type: "object",
18829
+ additionalProperties: {
18830
+ type: "string"
18831
+ }
18832
+ },
18833
+ messages: {
18834
+ type: "array",
18835
+ items: {
18836
+ $ref: "#/components/schemas/MessageEntity"
18837
+ }
18838
+ },
18839
+ pagination: {
18840
+ $ref: "#/components/schemas/Pagination"
18841
+ },
18842
+ permissions: {
18843
+ type: "array",
18844
+ items: {
18845
+ type: "string"
18846
+ }
18847
+ }
18848
+ }
18849
+ },
18544
18850
  ResponseEntityRoleDetailView: {
18545
18851
  type: "object",
18546
18852
  properties: {
@@ -18614,6 +18920,76 @@ var components = {
18614
18920
  }
18615
18921
  }
18616
18922
  },
18923
+ ResponseEntityRoleUserGrantView: {
18924
+ type: "object",
18925
+ properties: {
18926
+ entity: {
18927
+ $ref: "#/components/schemas/RoleUserGrantView"
18928
+ },
18929
+ errors: {
18930
+ type: "array",
18931
+ items: {
18932
+ $ref: "#/components/schemas/ErrorEntity"
18933
+ }
18934
+ },
18935
+ i18nMessagesMap: {
18936
+ type: "object",
18937
+ additionalProperties: {
18938
+ type: "string"
18939
+ }
18940
+ },
18941
+ messages: {
18942
+ type: "array",
18943
+ items: {
18944
+ $ref: "#/components/schemas/MessageEntity"
18945
+ }
18946
+ },
18947
+ pagination: {
18948
+ $ref: "#/components/schemas/Pagination"
18949
+ },
18950
+ permissions: {
18951
+ type: "array",
18952
+ items: {
18953
+ type: "string"
18954
+ }
18955
+ }
18956
+ }
18957
+ },
18958
+ ResponseEntityRoleUsersRemovalView: {
18959
+ type: "object",
18960
+ properties: {
18961
+ entity: {
18962
+ $ref: "#/components/schemas/RoleUsersRemovalView"
18963
+ },
18964
+ errors: {
18965
+ type: "array",
18966
+ items: {
18967
+ $ref: "#/components/schemas/ErrorEntity"
18968
+ }
18969
+ },
18970
+ i18nMessagesMap: {
18971
+ type: "object",
18972
+ additionalProperties: {
18973
+ type: "string"
18974
+ }
18975
+ },
18976
+ messages: {
18977
+ type: "array",
18978
+ items: {
18979
+ $ref: "#/components/schemas/MessageEntity"
18980
+ }
18981
+ },
18982
+ pagination: {
18983
+ $ref: "#/components/schemas/Pagination"
18984
+ },
18985
+ permissions: {
18986
+ type: "array",
18987
+ items: {
18988
+ type: "string"
18989
+ }
18990
+ }
18991
+ }
18992
+ },
18617
18993
  ResponseEntityRoleViewListView: {
18618
18994
  type: "object",
18619
18995
  properties: {
@@ -19936,6 +20312,32 @@ var components = {
19936
20312
  }
19937
20313
  }
19938
20314
  },
20315
+ RoleDeletionView: {
20316
+ type: "object",
20317
+ properties: {
20318
+ deleted: {
20319
+ type: "boolean",
20320
+ description: "Whether the role was deleted",
20321
+ example: true
20322
+ },
20323
+ roleId: {
20324
+ type: "string",
20325
+ description: "Id of the deleted role",
20326
+ example: "48190c8c-42c4-46af-8d1a-0cd5db894797"
20327
+ },
20328
+ usersAffected: {
20329
+ type: "integer",
20330
+ format: "int32",
20331
+ description: "Number of users the role was removed from by the cascading deletion. Counts direct assignments only; users inheriting the role through the role hierarchy are not included",
20332
+ example: 3
20333
+ }
20334
+ },
20335
+ required: [
20336
+ "deleted",
20337
+ "roleId",
20338
+ "usersAffected"
20339
+ ]
20340
+ },
19939
20341
  RoleForm: {
19940
20342
  type: "object",
19941
20343
  properties: {
@@ -19965,6 +20367,32 @@ var components = {
19965
20367
  "roleName"
19966
20368
  ]
19967
20369
  },
20370
+ RoleMemberUserView: {
20371
+ type: "object",
20372
+ description: "The user the role was granted to",
20373
+ properties: {
20374
+ email: {
20375
+ type: "string",
20376
+ description: "Email address of the user",
20377
+ example: "user@example.com"
20378
+ },
20379
+ fullName: {
20380
+ type: "string",
20381
+ description: "Full name of the user",
20382
+ example: "Jane Doe"
20383
+ },
20384
+ userId: {
20385
+ type: "string",
20386
+ description: "Id of the user",
20387
+ example: "dotcms.org.2807"
20388
+ }
20389
+ },
20390
+ required: [
20391
+ "email",
20392
+ "fullName",
20393
+ "userId"
20394
+ ]
20395
+ },
19968
20396
  RoleResponseEntityView: {
19969
20397
  type: "object",
19970
20398
  properties: {
@@ -20003,6 +20431,74 @@ var components = {
20003
20431
  }
20004
20432
  }
20005
20433
  },
20434
+ RoleUserGrantView: {
20435
+ type: "object",
20436
+ properties: {
20437
+ granted: {
20438
+ type: "boolean",
20439
+ description: "Whether the user holds the role after the call. The grant is idempotent, so this is also true when the user already held the role and nothing changed",
20440
+ example: true
20441
+ },
20442
+ roleId: {
20443
+ type: "string",
20444
+ description: "Id of the granted role",
20445
+ example: "48190c8c-42c4-46af-8d1a-0cd5db894797"
20446
+ },
20447
+ user: {
20448
+ $ref: "#/components/schemas/RoleMemberUserView"
20449
+ }
20450
+ },
20451
+ required: [
20452
+ "granted",
20453
+ "roleId",
20454
+ "user"
20455
+ ]
20456
+ },
20457
+ RoleUsersForm: {
20458
+ type: "object",
20459
+ properties: {
20460
+ userIds: {
20461
+ type: "array",
20462
+ description: "Ids of the users to remove from the role",
20463
+ example: [
20464
+ "dotcms.org.2807"
20465
+ ],
20466
+ items: {
20467
+ type: "string",
20468
+ description: "Ids of the users to remove from the role",
20469
+ example: "[\"dotcms.org.2807\"]"
20470
+ },
20471
+ uniqueItems: true
20472
+ }
20473
+ },
20474
+ required: [
20475
+ "userIds"
20476
+ ]
20477
+ },
20478
+ RoleUsersRemovalView: {
20479
+ type: "object",
20480
+ properties: {
20481
+ removedUserIds: {
20482
+ type: "array",
20483
+ description: "Ids of the users whose direct membership in the role was removed",
20484
+ items: {
20485
+ type: "string",
20486
+ description: "Ids of the users whose direct membership in the role was removed"
20487
+ }
20488
+ },
20489
+ skipped: {
20490
+ type: "array",
20491
+ description: "Users that could not be removed, each with a reason",
20492
+ items: {
20493
+ $ref: "#/components/schemas/SkippedUserView"
20494
+ }
20495
+ }
20496
+ },
20497
+ required: [
20498
+ "removedUserIds",
20499
+ "skipped"
20500
+ ]
20501
+ },
20006
20502
  RoleView: {
20007
20503
  type: "object",
20008
20504
  properties: {
@@ -20036,6 +20532,12 @@ var components = {
20036
20532
  parent: {
20037
20533
  type: "string"
20038
20534
  },
20535
+ roleChildren: {
20536
+ type: "array",
20537
+ items: {
20538
+ $ref: "#/components/schemas/RoleView"
20539
+ }
20540
+ },
20039
20541
  roleKey: {
20040
20542
  type: "string"
20041
20543
  },
@@ -20391,6 +20893,31 @@ var components = {
20391
20893
  }
20392
20894
  }
20393
20895
  },
20896
+ SkippedUserView: {
20897
+ type: "object",
20898
+ description: "Users that could not be removed, each with a reason",
20899
+ properties: {
20900
+ reason: {
20901
+ type: "string",
20902
+ description: "Why the user was skipped",
20903
+ "enum": [
20904
+ "not_found",
20905
+ "inherited",
20906
+ "error"
20907
+ ],
20908
+ example: "inherited"
20909
+ },
20910
+ userId: {
20911
+ type: "string",
20912
+ description: "Id of the skipped user, as submitted in the request",
20913
+ example: "dotcms.org.2807"
20914
+ }
20915
+ },
20916
+ required: [
20917
+ "reason",
20918
+ "userId"
20919
+ ]
20920
+ },
20394
20921
  SmallRoleView: {
20395
20922
  type: "object",
20396
20923
  properties: {