From c67581ba0a0836848e4c97f0fa5ccdea6cd17e0b Mon Sep 17 00:00:00 2001 From: Ernesto Resende Date: Tue, 25 Nov 2025 20:49:53 -0300 Subject: [PATCH 1/2] chore(permissions-client): update client with new spec --- clients/permissions-client/package.json | 2 +- clients/permissions-client/src/openapi.d.ts | 56 +++++- clients/permissions-client/src/openapi.json | 210 +++++++++++++++++++- 3 files changed, 261 insertions(+), 7 deletions(-) diff --git a/clients/permissions-client/package.json b/clients/permissions-client/package.json index f8480cbe..6d0e190e 100644 --- a/clients/permissions-client/package.json +++ b/clients/permissions-client/package.json @@ -1,6 +1,6 @@ { "name": "@epilot/permissions-client", - "version": "0.16.2", + "version": "0.17.0-alpha.1", "description": "Client library for epilot Permissions API", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/clients/permissions-client/src/openapi.d.ts b/clients/permissions-client/src/openapi.d.ts index a39df0b6..f8a2a53a 100644 --- a/clients/permissions-client/src/openapi.d.ts +++ b/clients/permissions-client/src/openapi.d.ts @@ -121,6 +121,12 @@ declare namespace Components { * Type of the role */ type: "user_role"; + /** + * Optional parent role that this role inherits from. Must be an `org_role` or `share_role`. + * example: + * 123:owner + */ + parent_role?: string; /** * List of grants (permissions) applied to the role */ @@ -336,6 +342,17 @@ declare namespace Components { operation: "equals"; values: any[]; } + /** + * Error response + */ + export interface Error { + /** + * Error message + * example: + * Parent role 123:nonexistent does not exist + */ + message: string; + } export interface Grant { /** * example: @@ -389,6 +406,18 @@ declare namespace Components { */ RoleId[]; } + /** + * All roles attached to an users of an organization + */ + export interface OrgAssignments { + organizationId?: /** + * Id of an organization + * example: + * 123 + */ + OrganizationId; + assignments?: /* A role attached to an user */ InternalAssignment[]; + } /** * A role automatically applied to all users in an organization. */ @@ -438,6 +467,18 @@ declare namespace Components { */ pricing_tier?: string; } + /** + * All roles attached to an users of an organization + */ + export interface OrgRoles { + organizationId?: /** + * Id of an organization + * example: + * 123 + */ + OrganizationId; + roles?: Role[]; + } /** * Id of an organization * example: @@ -705,6 +746,12 @@ declare namespace Components { * List of grants (permissions) applied to the role */ grants: Grant[]; + /** + * Optional parent role that this role inherits from. Must be an `org_role` or `share_role`. + * example: + * 123:owner + */ + parent_role?: string; } } } @@ -753,6 +800,8 @@ declare namespace Paths { export type RequestBody = Components.Schemas.CreateRolePayload; namespace Responses { export type $200 = Components.Schemas.Role; + export type $400 = /* Error response */ Components.Schemas.Error; + export type $404 = /* Error response */ Components.Schemas.Error; } } namespace DeleteRole { @@ -839,6 +888,8 @@ declare namespace Paths { export type RequestBody = Components.Schemas.RolePayload; namespace Responses { export type $200 = Components.Schemas.Role; + export type $400 = /* Error response */ Components.Schemas.Error; + export type $404 = /* Error response */ Components.Schemas.Error; } } namespace RefreshPermissions { @@ -881,7 +932,6 @@ declare namespace Paths { } } - export interface OperationMethods { /** * listCurrentRoles - listCurrentRoles @@ -1172,18 +1222,20 @@ export interface PathsDictionary { export type Client = OpenAPIClient - export type Assignment = Components.Schemas.Assignment; export type Assignments = Components.Schemas.Assignments; export type BaseRole = Components.Schemas.BaseRole; export type BaseRoleForCreate = Components.Schemas.BaseRoleForCreate; export type CreateRolePayload = Components.Schemas.CreateRolePayload; export type EqualsCondition = Components.Schemas.EqualsCondition; +export type Error = Components.Schemas.Error; export type Grant = Components.Schemas.Grant; export type GrantCondition = Components.Schemas.GrantCondition; export type GrantWithDependencies = Components.Schemas.GrantWithDependencies; export type InternalAssignment = Components.Schemas.InternalAssignment; +export type OrgAssignments = Components.Schemas.OrgAssignments; export type OrgRole = Components.Schemas.OrgRole; +export type OrgRoles = Components.Schemas.OrgRoles; export type OrganizationId = Components.Schemas.OrganizationId; export type PartnerRole = Components.Schemas.PartnerRole; export type PortalRole = Components.Schemas.PortalRole; diff --git a/clients/permissions-client/src/openapi.json b/clients/permissions-client/src/openapi.json index fbaf9b74..2fc5ded6 100644 --- a/clients/permissions-client/src/openapi.json +++ b/clients/permissions-client/src/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.0.3", "info": { "title": "Permissions API", - "version": "1.0.0", + "version": "1.1.0", "description": "Flexible Role-based Access Control for epilot" }, "tags": [ @@ -109,6 +109,66 @@ } } } + }, + "400": { + "description": "Invalid role configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "parent_role_invalid_type": { + "summary": "Parent role must be org_role or share_role", + "value": { + "message": "Parent role must be org_role or share_role, got user_role" + } + }, + "parent_role_different_org": { + "summary": "Parent org_role must be in the same organization", + "value": { + "message": "Parent org_role must be in the same organization" + } + }, + "parent_role_max_hierarchy": { + "summary": "Parent role cannot itself have a parent", + "value": { + "message": "Parent role cannot itself have a parent (max 2 levels of hierarchy)" + } + }, + "circular_dependency_self": { + "summary": "Role cannot be its own parent", + "value": { + "message": "Role cannot be its own parent" + } + }, + "circular_dependency_detected": { + "summary": "Circular dependency detected", + "value": { + "message": "Circular dependency detected: role 123:child would create a cycle" + } + } + } + } + } + }, + "404": { + "description": "Parent role does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "parent_role_not_found": { + "summary": "Parent role does not exist", + "value": { + "message": "Parent role 123:nonexistent does not exist" + } + } + } + } + } } } } @@ -464,6 +524,27 @@ } ] } + }, + "User role with parent": { + "description": "Example user role that inherits from a parent role", + "value": { + "id": "123:limited_manager", + "name": "Limited Manager", + "slug": "limited_manager", + "type": "user_role", + "organization_id": "123", + "parent_role": "123:manager", + "grants": [ + { + "action": "entity:view", + "resource": "contact:*" + }, + { + "action": "entity:edit", + "resource": "contact:*" + } + ] + } } } } @@ -479,6 +560,66 @@ } } } + }, + "400": { + "description": "Bad Request - Invalid role configuration", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "parent_role_invalid_type": { + "summary": "Parent role must be org_role or share_role", + "value": { + "message": "Parent role must be org_role or share_role, got user_role" + } + }, + "parent_role_different_org": { + "summary": "Parent org_role must be in the same organization", + "value": { + "message": "Parent org_role must be in the same organization" + } + }, + "parent_role_max_hierarchy": { + "summary": "Parent role cannot itself have a parent", + "value": { + "message": "Parent role cannot itself have a parent (max 2 levels of hierarchy)" + } + }, + "circular_dependency_self": { + "summary": "Role cannot be its own parent", + "value": { + "message": "Role cannot be its own parent" + } + }, + "circular_dependency_detected": { + "summary": "Circular dependency detected", + "value": { + "message": "Circular dependency detected: role 123:child would create a cycle" + } + } + } + } + } + }, + "404": { + "description": "Not Found - Parent role does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + }, + "examples": { + "parent_role_not_found": { + "summary": "Parent role does not exist", + "value": { + "message": "Parent role 123:nonexistent does not exist" + } + } + } + } + } } } }, @@ -925,6 +1066,16 @@ "enum": [ "user_role" ] + }, + "parent_role": { + "allOf": [ + { + "$ref": "#/components/schemas/RoleId" + }, + { + "description": "Optional parent role that this role inherits from. Must be an `org_role` or `share_role`." + } + ] } } } @@ -1095,6 +1246,36 @@ } } }, + "OrgAssignments": { + "type": "object", + "description": "All roles attached to an users of an organization", + "properties": { + "organizationId": { + "$ref": "#/components/schemas/OrganizationId" + }, + "assignments": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InternalAssignment" + } + } + } + }, + "OrgRoles": { + "type": "object", + "description": "All roles attached to an users of an organization", + "properties": { + "organizationId": { + "$ref": "#/components/schemas/OrganizationId" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Role" + } + } + } + }, "Assignments": { "type": "array", "description": "List of role ids attached to an user", @@ -1198,6 +1379,16 @@ "enum": [ "user_role" ] + }, + "parent_role": { + "allOf": [ + { + "$ref": "#/components/schemas/RoleId" + }, + { + "description": "Optional parent role that this role inherits from. Must be an `org_role` or `share_role`." + } + ] } } }, @@ -1259,13 +1450,24 @@ ] } ] + }, + "Error": { + "type": "object", + "description": "Error response", + "properties": { + "message": { + "type": "string", + "description": "Error message", + "example": "Parent role 123:nonexistent does not exist" + } + }, + "required": [ + "message" + ] } } }, "servers": [ - { - "url": "https://permissions.sls.epilot.io" - }, { "url": "https://permissions.sls.epilot.io" } From 9f1df9c787c6fe2d3e927c9ea9811ccc2fb47af3 Mon Sep 17 00:00:00 2001 From: Ernesto Resende Date: Wed, 26 Nov 2025 02:30:25 -0300 Subject: [PATCH 2/2] chore(permissions-client): update client with new spec --- clients/permissions-client/package.json | 2 +- clients/permissions-client/src/openapi.d.ts | 2 +- clients/permissions-client/src/openapi.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/permissions-client/package.json b/clients/permissions-client/package.json index 6d0e190e..4aa04bdb 100644 --- a/clients/permissions-client/package.json +++ b/clients/permissions-client/package.json @@ -1,6 +1,6 @@ { "name": "@epilot/permissions-client", - "version": "0.17.0-alpha.1", + "version": "0.17.0-alpha.2", "description": "Client library for epilot Permissions API", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/clients/permissions-client/src/openapi.d.ts b/clients/permissions-client/src/openapi.d.ts index f8a2a53a..22995edb 100644 --- a/clients/permissions-client/src/openapi.d.ts +++ b/clients/permissions-client/src/openapi.d.ts @@ -122,7 +122,7 @@ declare namespace Components { */ type: "user_role"; /** - * Optional parent role that this role inherits from. Must be an `org_role` or `share_role`. + * Optional parent role that this role inherits from. Must be an `org_role` or a sharing role of type `share_role` or `partner_role`. * example: * 123:owner */ diff --git a/clients/permissions-client/src/openapi.json b/clients/permissions-client/src/openapi.json index 2fc5ded6..cb82c318 100644 --- a/clients/permissions-client/src/openapi.json +++ b/clients/permissions-client/src/openapi.json @@ -1386,7 +1386,7 @@ "$ref": "#/components/schemas/RoleId" }, { - "description": "Optional parent role that this role inherits from. Must be an `org_role` or `share_role`." + "description": "Optional parent role that this role inherits from. Must be an `org_role` or a sharing role of type `share_role` or `partner_role`." } ] }