syntax = "v1" type ( // ===== Permission catalog ===== PermissionCatalogQuery { Status string `form:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 狀態篩選;可選值: open / close Type string `form:"type,optional,options=backend_user|frontend_user" validate:"omitempty,oneof=backend_user frontend_user"` // 權限類型篩選;可選值: backend_user / frontend_user Tree bool `form:"tree,optional"` // 是否回傳樹狀結構(false 則扁平 list) } PermissionNode { ID string `json:"id"` Parent string `json:"parent,omitempty"` Name string `json:"name"` HTTPMethods string `json:"http_methods,omitempty"` HTTPPath string `json:"http_path,omitempty"` Status string `json:"status"` Type string `json:"type"` Children []PermissionNode `json:"children,omitempty"` } PermissionCatalogData { Tree []PermissionNode `json:"tree,omitempty"` List []PermissionNode `json:"list,omitempty"` } // ===== Me permissions ===== MePermissionsQuery { IncludeTree bool `form:"include_tree,optional"` // 是否同時回傳 permission tree(true 會多包一份樹狀結構) } MePermissionsData { UID string `json:"uid"` TenantID string `json:"tenant_id"` Roles []string `json:"roles"` Permissions map[string]string `json:"permissions"` Tree []PermissionNode `json:"tree,omitempty"` } // ===== Roles ===== RoleData { ID string `json:"id"` TenantID string `json:"tenant_id"` Key string `json:"key"` DisplayName string `json:"display_name"` CreatorUID string `json:"creator_uid,omitempty"` Status string `json:"status"` IsSystem bool `json:"is_system"` CreateAt int64 `json:"create_at"` UpdateAt int64 `json:"update_at"` } RoleListData { Roles []RoleData `json:"roles"` } CreateRoleReq { Key string `json:"key" validate:"required,min=2,max=64"` // 角色 key(2-64 字元,不可以 system. / platform_ 開頭) DisplayName string `json:"display_name,optional"` // 角色顯示名稱(給人看的) Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close(預設 open) } UpdateRoleReq { DisplayName string `json:"display_name,optional"` // 角色顯示名稱 Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close } UpdateRoleByIDReq { ID string `path:"id"` // Role ID(path) DisplayName string `json:"display_name,optional"` // 角色顯示名稱 Status string `json:"status,optional,options=open|close" validate:"omitempty,oneof=open close"` // 角色狀態;可選值: open / close } DeleteRoleByIDReq { ID string `path:"id"` // Role ID(path) } GetRolePermissionsByIDReq { ID string `path:"id"` // Role ID(path) } ReplaceRolePermissionsByIDReq { ID string `path:"id"` // Role ID(path) PermissionIDs []string `json:"permission_ids"` // 要勾選的 Permission ID 陣列(全量取代,會自動補齊父權限) } ListUserRolesReq { UID string `path:"uid"` // 使用者 UID(path) } AssignUserRoleByUIDReq { UID string `path:"uid"` // 使用者 UID(path) RoleID string `json:"role_id" validate:"required"` // 要指派的 Role ID Source string `json:"source,optional,options=manual|zitadel|ldap|scim" validate:"omitempty,oneof=manual zitadel ldap scim"` // 指派來源;可選值: manual / zitadel / ldap / scim(預設 manual) } RevokeUserRoleByIDReq { UID string `path:"uid"` // 使用者 UID(path) RoleID string `path:"role_id"` // Role ID(path) } // ===== Role permissions ===== RolePermissionsListData { Permissions []PermissionNode `json:"permissions"` } ReplaceRolePermissionsReq { PermissionIDs []string `json:"permission_ids"` // 要勾選的 Permission ID 陣列(全量取代,會自動補齊父權限) } // ===== User roles ===== UIDPath { UID string `path:"uid"` // 使用者 UID(path) } UserRoleData { ID string `json:"id"` TenantID string `json:"tenant_id"` UID string `json:"uid"` RoleID string `json:"role_id"` RoleKey string `json:"role_key"` RoleDisplayName string `json:"role_display_name"` Source string `json:"source"` CreateAt int64 `json:"create_at"` UpdateAt int64 `json:"update_at"` } UserRoleListData { UserRoles []UserRoleData `json:"user_roles"` } AssignUserRoleReq { RoleID string `json:"role_id" validate:"required"` // 要指派的 Role ID Source string `json:"source,optional,options=manual|zitadel|ldap|scim" validate:"omitempty,oneof=manual zitadel ldap scim"` // 指派來源;可選值: manual / zitadel / ldap / scim(預設 manual) } UserRoleIDPath { UID string `path:"uid"` // 使用者 UID(path) RoleID string `path:"role_id"` // Role ID(path) } // ===== Role mappings ===== RoleMappingData { ID string `json:"id"` TenantID string `json:"tenant_id"` ExternalSource string `json:"external_source"` ExternalKey string `json:"external_key"` InternalRoleID string `json:"internal_role_id"` InternalRoleKey string `json:"internal_role_key"` CreateAt int64 `json:"create_at"` UpdateAt int64 `json:"update_at"` } RoleMappingListData { Mappings []RoleMappingData `json:"mappings"` Total int64 `json:"total"` Offset int64 `json:"offset"` Limit int64 `json:"limit"` } RoleMappingListQuery { Source string `form:"source,optional,options=zitadel|ldap|scim" validate:"omitempty,oneof=zitadel ldap scim"` // 外部來源篩選;可選值: zitadel / ldap / scim Offset int64 `form:"offset,optional"` // 分頁起點(從 0 起算) Limit int64 `form:"limit,optional"` // 每頁筆數(最大值由 server 限制) } UpsertRoleMappingReq { ExternalSource string `json:"external_source,options=zitadel|ldap|scim" validate:"required,oneof=zitadel ldap scim"` // 外部來源;可選值: zitadel / ldap / scim ExternalKey string `json:"external_key" validate:"required"` // 外部群組 / claim 的 key(例如 zitadel role 名稱) InternalRoleKey string `json:"internal_role_key" validate:"required"` // 對映的內部角色 key(必須存在於 roles 集合) } DeleteRoleMappingReq { ExternalSource string `json:"external_source,options=zitadel|ldap|scim" validate:"required,oneof=zitadel ldap scim"` // 外部來源;可選值: zitadel / ldap / scim ExternalKey string `json:"external_key" validate:"required"` // 外部群組 / claim 的 key } // ===== Policy reload ===== PolicyReloadReq { TenantID string `json:"tenant_id,optional"` // 指定要 reload 的租戶 ID;留空則 reload 所有租戶 } PolicyReloadData { Tenant string `json:"tenant"` TS int64 `json:"ts"` } // ===== OK envelopes for swagger ===== PermissionCatalogOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data PermissionCatalogData `json:"data"` } MePermissionsOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data MePermissionsData `json:"data"` } RoleListOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data RoleListData `json:"data"` } RoleOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data RoleData `json:"data"` } RolePermissionsListOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data RolePermissionsListData `json:"data"` } UserRoleListOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data UserRoleListData `json:"data"` } UserRoleOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data UserRoleData `json:"data"` } RoleMappingListOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data RoleMappingListData `json:"data"` } RoleMappingOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data RoleMappingData `json:"data"` } PolicyReloadOKStatus { Code int64 `json:"code"` Message string `json:"message"` Data PolicyReloadData `json:"data"` } ) @server( group: permission prefix: /api/v1/permissions middleware: AuthJWT tags: "Permission - 權限(讀取)" summary: "Catalog / Me(需 Bearer,不過 RBAC 檢查)" ) service gateway { @doc "取得全局 Permission Catalog(樹狀或扁平;可篩 status/type)" /* @respdoc-200 (PermissionCatalogOKStatus) // 成功(code=102000) @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 31601000: (APIErrorStatus) 系統內部錯誤 ) // 內部錯誤 @respdoc-501 ( 31605000: (APIErrorStatus) Permission 模組未配置 ) // 未實作 */ @handler getPermissionCatalog get /catalog (PermissionCatalogQuery) returns (PermissionCatalogData) @doc "取得當前使用者的 role / permission map(前端渲染選單)" /* @respdoc-200 (MePermissionsOKStatus) // 成功(code=102000) @respdoc-401 ( 31501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 31601000: (APIErrorStatus) 系統內部錯誤 ) // 內部錯誤 @respdoc-501 ( 31605000: (APIErrorStatus) Permission 模組未配置 ) // 未實作 */ @handler getMePermissions get /me (MePermissionsQuery) returns (MePermissionsData) } @server( group: permission prefix: /api/v1/permissions middleware: AuthJWT,CasbinRBAC tags: "Permission - 權限(管理)" summary: "角色 / 使用者角色 / 外部映射 / Policy(需 Bearer + RBAC)" ) service gateway { @doc "列出租戶內所有角色(含 system role)" /* @respdoc-200 (RoleListOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler listRoles get /roles returns (RoleListData) @doc "建立租戶自訂角色(key 不可改、不可使用 system./platform_ 開頭)" /* @respdoc-200 (RoleOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 31101000: (APIErrorStatus) role key 格式或保留字錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-409 ( 31303000: (APIErrorStatus) 同名 role 已存在 ) // 衝突 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler createRole post /roles (CreateRoleReq) returns (RoleData) @doc "更新角色(display_name / status;is_system 角色不可改 status)" /* @respdoc-200 (RoleOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) role 不存在 ) // 不存在 @respdoc-409 ( 31309000: (APIErrorStatus) 系統角色無法更新此欄位 ) // 衝突 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler updateRole patch /roles/:id (UpdateRoleByIDReq) returns (RoleData) @doc "刪除角色(is_system 不可刪;存在 user 指派時拒絕)" /* @respdoc-200 (EmptyOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) role 不存在 ) // 不存在 @respdoc-409 ( 31309000: (APIErrorStatus) 系統角色無法刪除 31312000: (APIErrorStatus) 角色仍有使用者指派 ) // 衝突 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler deleteRole delete /roles/:id (DeleteRoleByIDReq) @doc "讀取角色目前勾選的 permission 集合" /* @respdoc-200 (RolePermissionsListOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) role 不存在 ) // 不存在 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler getRolePermissions get /roles/:id/permissions (GetRolePermissionsByIDReq) returns (RolePermissionsListData) @doc "全量取代角色的 permission 勾選(自動補齊父權限;觸發 LoadPolicy + Pub/Sub reload)" /* @respdoc-200 (EmptyOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) role 或 permission 不存在 ) // 不存在 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 31601000: (APIErrorStatus) 系統內部錯誤 ) // 內部錯誤 */ @handler replaceRolePermissions put /roles/:id/permissions (ReplaceRolePermissionsByIDReq) @doc "查詢使用者目前指派的角色(含 RoleKey / DisplayName)" /* @respdoc-200 (UserRoleListOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler listUserRoles get /users/:uid/roles (ListUserRolesReq) returns (UserRoleListData) @doc "指派角色給使用者(預設 source=manual;source 來源由 SyncFromX 自動標)" /* @respdoc-200 (UserRoleOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) role 不存在 ) // 不存在 @respdoc-409 ( 31303000: (APIErrorStatus) 角色已指派 ) // 衝突 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler assignUserRole post /users/:uid/roles (AssignUserRoleByUIDReq) returns (UserRoleData) @doc "撤銷使用者的單一角色" /* @respdoc-200 (EmptyOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) 指派不存在 ) // 不存在 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler revokeUserRole delete /users/:uid/roles/:role_id (RevokeUserRoleByIDReq) @doc "列出外部來源 → 內部 role 的映射(zitadel / ldap / scim)" /* @respdoc-200 (RoleMappingListOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler listRoleMappings get /role-mappings (RoleMappingListQuery) returns (RoleMappingListData) @doc "Upsert 外部 IdP 群組到內部 role 的映射" /* @respdoc-200 (RoleMappingOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) 對應 internal role 不存在 ) // 不存在 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler upsertRoleMapping put /role-mappings (UpsertRoleMappingReq) returns (RoleMappingData) @doc "刪除外部 → 內部 role 映射" /* @respdoc-200 (EmptyOKStatus) // 成功 @respdoc-400 ( 10101000: (APIErrorStatus) 參數格式錯誤 ) // 參數錯誤 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-404 ( 31301000: (APIErrorStatus) 映射不存在 ) // 不存在 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 ) // 內部錯誤 */ @handler deleteRoleMapping delete /role-mappings (DeleteRoleMappingReq) @doc "強制重載 Casbin policy(單租戶或所有租戶;同步 + Pub/Sub broadcast)" /* @respdoc-200 (PolicyReloadOKStatus) // 成功 @respdoc-401 ( 31501000: (APIErrorStatus) 未授權 ) // 未授權 @respdoc-500 ( 31201000: (APIErrorStatus) 資料庫錯誤 31601000: (APIErrorStatus) 系統內部錯誤 ) // 內部錯誤 @respdoc-501 ( 31605000: (APIErrorStatus) Casbin enforcer 未配置 ) // 未實作 */ @handler reloadPolicy post /policy/reload (PolicyReloadReq) returns (PolicyReloadData) }