重构权限模型:基于角色职责的四层分级

根据角色职责重新设计权限分级:
- owner.superuser: 系统级管理(机构/角色/权限)
- *.admin: 机构级管理(人员/角色分配)
- reseller.operator: 运营(产品/合同/定价)
- reseller.sale: 销售(客户/折扣)
- reseller.accountant: 财务(充值/对账)
- reseller.maintainer: 运维
- customer.customer: 终端客户

权限模型:
1. Public (any): CSS静态资源
2. Logined (所有登录用户10角色): 控制台、数据查看、用户自己的CRUD、推理、执行
3. Admin (superuser+5种admin): 系统级LLM配置管理
4. Superuser (仅owner.superuser): 技能部署等高危操作
This commit is contained in:
yumoqing 2026-05-13 14:27:53 +08:00
parent 6c62313bb9
commit 6951ee7ebf

View File

@ -2,10 +2,22 @@
# setup_harnessed_perms.sh
# 为 harnessed_agent执行层和 harnessed_reasoning推理层模块配置 RBAC 角色权限
#
# 角色职责定义:
# owner.superuser — 系统级管理员:系统机构类型管理、角色管理、权限管理、添加业主机构管理员
# 系统初始化时由代码自动创建,拥有全部权限
# *.admin — 机构管理员owner/reseller/provider/customer.admin
# 添加本机构人员、分配人员角色、管理系统级配置
# reseller.operator — 运营:产品管理、供应商合同、产品定价、统一客户折扣、营销活动
# reseller.sale — 销售:客户管理、客户特殊折扣设定
# reseller.accountant — 财务:线下客户充值、分销商/供应商对账结算
# reseller.maintainer — 维护:系统运维
# logined — 所有已登录用户(含上述所有角色)
#
# 权限分级策略(基于业务功能分析):
# 1. public — 静态资源CSSany 角色可用
# 2. read — 控制台主页、数据查看页面、只读APIlogined + 管理员可用
# 3. admin — 配置管理、数据创建/更新/删除、执行操作,仅管理员可用
# 2. logined — 控制台主页、数据查看、核心使用功能,所有登录用户可用
# 3. admin — 系统配置管理、Agent/推理配置,仅 superuser 和机构管理员
# 4. superuser — 技能部署等高危操作,仅系统超级管理员
#
# 运行位置: sage 项目根目录 (包含 set_role_perm.py 的目录)
# 用法: bash setup_harnessed_perms.sh
@ -15,21 +27,6 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR"
# 角色定义
ADMIN_ROLES=(
# 通用登录角色 — read 级别使用
"logined"
# 各机构类型管理员 — admin 级别使用
"owner.admin"
"reseller.admin"
"provider.admin"
"customer.admin"
# Reseller 业务角色
"reseller.operator"
"reseller.accountant"
"reseller.maintainer"
)
COUNT=0
set_perm() {
local role="$1"
@ -38,16 +35,20 @@ set_perm() {
COUNT=$((COUNT + 1))
}
# 角色分组
ALL_LOGINED=("logined" "owner.superuser" "owner.admin" "reseller.admin" "provider.admin" "customer.admin" "reseller.operator" "reseller.sale" "reseller.accountant" "reseller.maintainer" "customer.customer")
ADMIN_ROLES=("owner.superuser" "owner.admin" "reseller.admin" "provider.admin" "customer.admin")
SUPERUSER_ONLY=("owner.superuser")
echo "============================================"
echo " harnessed 模块权限初始化"
echo "============================================"
# =============================================
# 层级 1: PUBLIC — 静态资源CSS文件
# 任何用户(含未登录)均可访问
# 层级 1: PUBLIC — 静态资源
# =============================================
echo ""
echo ">>> [1/3] Public: 静态资源 (any)"
echo ">>> [1/4] Public: 静态资源 (any)"
PUBLIC_FILES=(
"/harnessed_agent/ios_design.css"
"/harnessed_reasoning/ios_design.css"
@ -57,19 +58,19 @@ for f in "${PUBLIC_FILES[@]}"; do
done
# =============================================
# 层级 2: READ — 控制台主页 + 数据查看
# 所有登录用户 + 管理员可用
# 层级 2: LOGINED — 所有登录用户可用
# =============================================
echo ""
echo ">>> [2/3] Read: 控制台主页 + 数据查看 (logined + 管理员)"
echo ">>> [2/4] Logined: 控制台 + 数据查看 + 核心使用 (所有登录用户)"
READ_PATHS=(
# ---------- harnessed_agent ----------
LOGINED_PATHS=(
# ========== harnessed_agent ==========
# 控制台/主页(用户使用入口)
"/harnessed_agent/hermes_agent.ui"
"/harnessed_agent/agent_console.ui"
"/harnessed_agent/menu.ui"
# 数据查看页面(只读浏览)
# 数据查看(所有登录用户可查看自己的数据)
"/harnessed_agent/sessions.ui"
"/harnessed_agent/skills.ui"
"/harnessed_agent/tasks.ui"
@ -77,12 +78,8 @@ READ_PATHS=(
"/harnessed_agent/memory.ui"
"/harnessed_agent/tools.ui"
"/harnessed_agent/remote_skills.ui"
# API 配置查看(只读)
"/harnessed_agent/api/agent_config_get.dspy"
# ---------- CRUD index.ui (列表页面,只读浏览) ----------
# 注意: ahserver indexes 配置会自动匹配 index.ui访问 /harnessed_agent/hermes_memory
# 时 path 为 /harnessed_agent/hermes_memory不含/index.ui两种路径都需要注册
# CRUD 列表页 — 目录路径ahserver indexes 匹配)+ /index.ui
"/harnessed_agent/hermes_memory"
"/harnessed_agent/hermes_memory/index.ui"
"/harnessed_agent/hermes_sessions"
@ -108,7 +105,7 @@ READ_PATHS=(
"/harnessed_agent/task_dependencies"
"/harnessed_agent/task_dependencies/index.ui"
# ---------- CRUD get_*.dspy (单条记录读取) ----------
# CRUD 数据读取get_*.dspy
"/harnessed_agent/hermes_memory/get_hermes_memory.dspy"
"/harnessed_agent/hermes_sessions/get_hermes_sessions.dspy"
"/harnessed_agent/hermes_skills/get_hermes_skills.dspy"
@ -122,23 +119,104 @@ READ_PATHS=(
"/harnessed_agent/executions_by_workflow/get_executions_by_workflow.dspy"
"/harnessed_agent/task_dependencies/get_task_dependencies.dspy"
# ---------- harnessed_reasoning ----------
# 控制台/主页(用户使用入口)
# CRUD 数据写入(用户管理自己的数据)
# 记忆管理(用户可增删改自己的记忆)
"/harnessed_agent/hermes_memory/add_hermes_memory.dspy"
"/harnessed_agent/hermes_memory/update_hermes_memory.dspy"
"/harnessed_agent/hermes_memory/delete_hermes_memory.dspy"
"/harnessed_agent/api/hermes_memory_create.dspy"
"/harnessed_agent/api/hermes_memory_update.dspy"
"/harnessed_agent/api/hermes_memory_delete.dspy"
# 任务管理(用户可创建/管理自己的任务)
"/harnessed_agent/hermes_tasks/add_hermes_tasks.dspy"
"/harnessed_agent/hermes_tasks/update_hermes_tasks.dspy"
"/harnessed_agent/hermes_tasks/delete_hermes_tasks.dspy"
"/harnessed_agent/api/hermes_tasks_create.dspy"
"/harnessed_agent/api/hermes_tasks_update.dspy"
"/harnessed_agent/api/hermes_tasks_delete.dspy"
# 技能管理(用户可管理自己的技能)
"/harnessed_agent/hermes_skills/add_hermes_skills.dspy"
"/harnessed_agent/hermes_skills/update_hermes_skills.dspy"
"/harnessed_agent/hermes_skills/delete_hermes_skills.dspy"
"/harnessed_agent/api/hermes_skills_create.dspy"
"/harnessed_agent/api/hermes_skills_update.dspy"
"/harnessed_agent/api/hermes_skills_delete.dspy"
# 会话管理(用户可管理自己的会话)
"/harnessed_agent/hermes_sessions/add_hermes_sessions.dspy"
"/harnessed_agent/hermes_sessions/update_hermes_sessions.dspy"
"/harnessed_agent/hermes_sessions/delete_hermes_sessions.dspy"
"/harnessed_agent/api/hermes_sessions_create.dspy"
"/harnessed_agent/api/hermes_sessions_update.dspy"
"/harnessed_agent/api/hermes_sessions_delete.dspy"
# 工作流管理(用户可管理自己的工作流)
"/harnessed_agent/hermes_workflows/add_hermes_workflows.dspy"
"/harnessed_agent/hermes_workflows/update_hermes_workflows.dspy"
"/harnessed_agent/hermes_workflows/delete_hermes_workflows.dspy"
"/harnessed_agent/api/hermes_workflows_create.dspy"
"/harnessed_agent/api/hermes_workflows_update.dspy"
"/harnessed_agent/api/hermes_workflows_delete.dspy"
# 执行记录(用户可创建/更新执行记录)
"/harnessed_agent/hermes_executions/add_hermes_executions.dspy"
"/harnessed_agent/hermes_executions/update_hermes_executions.dspy"
"/harnessed_agent/hermes_executions/delete_hermes_executions.dspy"
"/harnessed_agent/api/hermes_executions_create.dspy"
"/harnessed_agent/api/hermes_executions_update.dspy"
"/harnessed_agent/api/hermes_executions_delete.dspy"
# 执行任务
"/harnessed_agent/hermes_executions_task/add_hermes_executions_task.dspy"
"/harnessed_agent/hermes_executions_task/update_hermes_executions_task.dspy"
"/harnessed_agent/hermes_executions_task/delete_hermes_executions_task.dspy"
"/harnessed_agent/api/hermes_executions_task_create.dspy"
"/harnessed_agent/api/hermes_executions_task_update.dspy"
"/harnessed_agent/api/hermes_executions_task_delete.dspy"
# 任务-工作流关联
"/harnessed_agent/hermes_tasks_workflow/add_hermes_tasks_workflow.dspy"
"/harnessed_agent/hermes_tasks_workflow/update_hermes_tasks_workflow.dspy"
"/harnessed_agent/hermes_tasks_workflow/delete_hermes_tasks_workflow.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_create.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_update.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_delete.dspy"
# 远程技能
"/harnessed_agent/harnessed_remote_skills/add_harnessed_remote_skills.dspy"
"/harnessed_agent/harnessed_remote_skills/update_harnessed_remote_skills.dspy"
"/harnessed_agent/harnessed_remote_skills/delete_harnessed_remote_skills.dspy"
"/harnessed_agent/api/harnessed_remote_skills_create.dspy"
"/harnessed_agent/api/harnessed_remote_skills_update.dspy"
"/harnessed_agent/api/harnessed_remote_skills_delete.dspy"
# 执行-工作流关联
"/harnessed_agent/executions_by_workflow/add_executions_by_workflow.dspy"
"/harnessed_agent/executions_by_workflow/update_executions_by_workflow.dspy"
"/harnessed_agent/executions_by_workflow/delete_executions_by_workflow.dspy"
"/harnessed_agent/api/executions_by_workflow_create.dspy"
"/harnessed_agent/api/executions_by_workflow_update.dspy"
"/harnessed_agent/api/executions_by_workflow_delete.dspy"
# 任务依赖
"/harnessed_agent/task_dependencies/add_task_dependencies.dspy"
"/harnessed_agent/task_dependencies/update_task_dependencies.dspy"
"/harnessed_agent/task_dependencies/delete_task_dependencies.dspy"
"/harnessed_agent/api/task_dependencies_create.dspy"
"/harnessed_agent/api/task_dependencies_update.dspy"
"/harnessed_agent/api/task_dependencies_delete.dspy"
# Agent 核心执行(用户使用功能)
"/harnessed_agent/api/agent_execute.dspy"
"/harnessed_agent/api/agent_config_get.dspy"
"/harnessed_agent/hermes.dspy"
# ========== harnessed_reasoning ==========
# 控制台/主页
"/harnessed_reasoning/hermes_reasoning.ui"
"/harnessed_reasoning/reasoning_console.ui"
"/harnessed_reasoning/menu.ui"
# WSS WebSocket 端点nginx会去掉/wss前缀应用收到的path不含/wss
# WSS WebSocket 端点nginx去掉/wss前缀后应用收到的path
"/harnessed_reasoning/reasoning_console.wss"
# 数据查看页面
# 数据查看
"/harnessed_reasoning/harnessed_reasoning_sessions_crud.ui"
"/harnessed_reasoning/harnessed_reasoning_config_view.ui"
# API 会话列表(只读)
"/harnessed_reasoning/api/sessions_list.dspy"
"/harnessed_reasoning/api/config_get.dspy"
# 推理提交(核心使用功能,所有登录用户可用)
"/harnessed_reasoning/api/reasoning_submit.dspy"
# ---------- CRUD index.ui (列表页面,只读浏览) ----------
# CRUD 列表页 — 目录路径 + /index.ui
"/harnessed_reasoning/harnessed_reasoning_sessions_crud"
"/harnessed_reasoning/harnessed_reasoning_sessions_crud/index.ui"
"/harnessed_reasoning/harnessed_reasoning_session_detail"
@ -146,137 +224,76 @@ READ_PATHS=(
"/harnessed_reasoning/harnessed_reasoning_config_view"
"/harnessed_reasoning/harnessed_reasoning_config_view/index.ui"
# ---------- CRUD get_*.dspy (单条记录读取) ----------
# CRUD 数据读取
"/harnessed_reasoning/harnessed_reasoning_sessions_crud/get_harnessed_reasoning_sessions_crud.dspy"
"/harnessed_reasoning/harnessed_reasoning_session_detail/get_harnessed_reasoning_session_detail.dspy"
"/harnessed_reasoning/harnessed_reasoning_config_view/get_harnessed_reasoning_config_view.dspy"
)
READ_ROLES=("logined" "owner.admin" "reseller.admin" "provider.admin" "customer.admin" "reseller.operator" "reseller.accountant" "reseller.maintainer")
for p in "${READ_PATHS[@]}"; do
for role in "${READ_ROLES[@]}"; do
set_perm "${role}" "${p}"
done
done
# =============================================
# 层级 3: ADMIN — 配置管理 + 数据操作 + 执行
# 仅管理员角色可用
# =============================================
echo ""
echo ">>> [3/3] Admin: 配置管理 + 数据操作 + 执行 (仅管理员)"
ADMIN_PATHS=(
# ---------- harnessed_agent ----------
# 配置管理页面(管理员专用)
"/harnessed_agent/agent_config.ui"
"/harnessed_agent/agent_config_form.ui"
# 技能部署(管理员操作)
"/harnessed_agent/deploy_skill.ui"
"/harnessed_agent/execute_remote_skill.ui"
# harnessed_agent CRUD 写操作add/update/delete
"/harnessed_agent/hermes_memory/add_hermes_memory.dspy"
"/harnessed_agent/hermes_memory/update_hermes_memory.dspy"
"/harnessed_agent/hermes_memory/delete_hermes_memory.dspy"
"/harnessed_agent/hermes_sessions/add_hermes_sessions.dspy"
"/harnessed_agent/hermes_sessions/update_hermes_sessions.dspy"
"/harnessed_agent/hermes_sessions/delete_hermes_sessions.dspy"
"/harnessed_agent/hermes_skills/add_hermes_skills.dspy"
"/harnessed_agent/hermes_skills/update_hermes_skills.dspy"
"/harnessed_agent/hermes_skills/delete_hermes_skills.dspy"
"/harnessed_agent/hermes_tasks/add_hermes_tasks.dspy"
"/harnessed_agent/hermes_tasks/update_hermes_tasks.dspy"
"/harnessed_agent/hermes_tasks/delete_hermes_tasks.dspy"
"/harnessed_agent/hermes_workflows/add_hermes_workflows.dspy"
"/harnessed_agent/hermes_workflows/update_hermes_workflows.dspy"
"/harnessed_agent/hermes_workflows/delete_hermes_workflows.dspy"
"/harnessed_agent/hermes_executions/add_hermes_executions.dspy"
"/harnessed_agent/hermes_executions/update_hermes_executions.dspy"
"/harnessed_agent/hermes_executions/delete_hermes_executions.dspy"
"/harnessed_agent/hermes_executions_task/add_hermes_executions_task.dspy"
"/harnessed_agent/hermes_executions_task/update_hermes_executions_task.dspy"
"/harnessed_agent/hermes_executions_task/delete_hermes_executions_task.dspy"
"/harnessed_agent/hermes_tasks_workflow/add_hermes_tasks_workflow.dspy"
"/harnessed_agent/hermes_tasks_workflow/update_hermes_tasks_workflow.dspy"
"/harnessed_agent/hermes_tasks_workflow/delete_hermes_tasks_workflow.dspy"
"/harnessed_agent/harnessed_remote_skills/add_harnessed_remote_skills.dspy"
"/harnessed_agent/harnessed_remote_skills/update_harnessed_remote_skills.dspy"
"/harnessed_agent/harnessed_remote_skills/delete_harnessed_remote_skills.dspy"
"/harnessed_agent/harnessed_agent_config_view/add_harnessed_agent_config_view.dspy"
"/harnessed_agent/harnessed_agent_config_view/update_harnessed_agent_config_view.dspy"
"/harnessed_agent/harnessed_agent_config_view/delete_harnessed_agent_config_view.dspy"
"/harnessed_agent/executions_by_workflow/add_executions_by_workflow.dspy"
"/harnessed_agent/executions_by_workflow/update_executions_by_workflow.dspy"
"/harnessed_agent/executions_by_workflow/delete_executions_by_workflow.dspy"
"/harnessed_agent/task_dependencies/add_task_dependencies.dspy"
"/harnessed_agent/task_dependencies/update_task_dependencies.dspy"
"/harnessed_agent/task_dependencies/delete_task_dependencies.dspy"
# harnessed_agent api/ CRUD 写操作API接口层
"/harnessed_agent/api/harnessed_agent_config_create.dspy"
"/harnessed_agent/api/harnessed_agent_config_update.dspy"
"/harnessed_agent/api/harnessed_agent_config_delete.dspy"
"/harnessed_agent/api/hermes_sessions_create.dspy"
"/harnessed_agent/api/hermes_sessions_update.dspy"
"/harnessed_agent/api/hermes_sessions_delete.dspy"
"/harnessed_agent/api/hermes_skills_create.dspy"
"/harnessed_agent/api/hermes_skills_update.dspy"
"/harnessed_agent/api/hermes_skills_delete.dspy"
"/harnessed_agent/api/hermes_tasks_create.dspy"
"/harnessed_agent/api/hermes_tasks_update.dspy"
"/harnessed_agent/api/hermes_tasks_delete.dspy"
"/harnessed_agent/api/hermes_workflows_create.dspy"
"/harnessed_agent/api/hermes_workflows_update.dspy"
"/harnessed_agent/api/hermes_workflows_delete.dspy"
"/harnessed_agent/api/hermes_executions_create.dspy"
"/harnessed_agent/api/hermes_executions_update.dspy"
"/harnessed_agent/api/hermes_executions_delete.dspy"
"/harnessed_agent/api/hermes_executions_task_create.dspy"
"/harnessed_agent/api/hermes_executions_task_update.dspy"
"/harnessed_agent/api/hermes_executions_task_delete.dspy"
"/harnessed_agent/api/hermes_memory_create.dspy"
"/harnessed_agent/api/hermes_memory_update.dspy"
"/harnessed_agent/api/hermes_memory_delete.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_create.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_update.dspy"
"/harnessed_agent/api/hermes_tasks_workflow_delete.dspy"
"/harnessed_agent/api/harnessed_remote_skills_create.dspy"
"/harnessed_agent/api/harnessed_remote_skills_update.dspy"
"/harnessed_agent/api/harnessed_remote_skills_delete.dspy"
"/harnessed_agent/api/executions_by_workflow_create.dspy"
"/harnessed_agent/api/executions_by_workflow_update.dspy"
"/harnessed_agent/api/executions_by_workflow_delete.dspy"
"/harnessed_agent/api/task_dependencies_create.dspy"
"/harnessed_agent/api/task_dependencies_update.dspy"
"/harnessed_agent/api/task_dependencies_delete.dspy"
# Agent 执行操作
"/harnessed_agent/api/agent_execute.dspy"
"/harnessed_agent/api/agent_config_save.dspy"
"/harnessed_agent/hermes.dspy"
# ---------- harnessed_reasoning ----------
# 配置管理(管理员专用)
"/harnessed_reasoning/api/config_save.dspy"
# harnessed_reasoning CRUD 写操作add/update/delete
# CRUD 数据写入(用户管理自己的推理会话数据)
"/harnessed_reasoning/harnessed_reasoning_sessions_crud/add_harnessed_reasoning_sessions_crud.dspy"
"/harnessed_reasoning/harnessed_reasoning_sessions_crud/update_harnessed_reasoning_sessions_crud.dspy"
"/harnessed_reasoning/harnessed_reasoning_sessions_crud/delete_harnessed_reasoning_sessions_crud.dspy"
"/harnessed_reasoning/harnessed_reasoning_session_detail/add_harnessed_reasoning_session_detail.dspy"
"/harnessed_reasoning/harnessed_reasoning_session_detail/update_harnessed_reasoning_session_detail.dspy"
"/harnessed_reasoning/harnessed_reasoning_session_detail/delete_harnessed_reasoning_session_detail.dspy"
# 推理核心功能(所有登录用户可用)
"/harnessed_reasoning/api/reasoning_submit.dspy"
"/harnessed_reasoning/api/sessions_list.dspy"
"/harnessed_reasoning/api/config_get.dspy"
)
for p in "${LOGINED_PATHS[@]}"; do
for role in "${ALL_LOGINED[@]}"; do
set_perm "${role}" "${p}"
done
done
# =============================================
# 层级 3: ADMIN — 系统配置管理
# =============================================
echo ""
echo ">>> [3/4] Admin: 系统配置管理 (superuser + 机构管理员)"
ADMIN_PATHS=(
# harnessed_agent — Agent 系统配置影响整个系统的LLM设置
"/harnessed_agent/agent_config.ui"
"/harnessed_agent/agent_config_form.ui"
"/harnessed_agent/api/agent_config_save.dspy"
"/harnessed_agent/api/harnessed_agent_config_create.dspy"
"/harnessed_agent/api/harnessed_agent_config_update.dspy"
"/harnessed_agent/api/harnessed_agent_config_delete.dspy"
"/harnessed_agent/harnessed_agent_config_view/add_harnessed_agent_config_view.dspy"
"/harnessed_agent/harnessed_agent_config_view/update_harnessed_agent_config_view.dspy"
"/harnessed_agent/harnessed_agent_config_view/delete_harnessed_agent_config_view.dspy"
# harnessed_reasoning — 推理系统配置
"/harnessed_reasoning/api/config_save.dspy"
"/harnessed_reasoning/harnessed_reasoning_config_view/add_harnessed_reasoning_config_view.dspy"
"/harnessed_reasoning/harnessed_reasoning_config_view/update_harnessed_reasoning_config_view.dspy"
"/harnessed_reasoning/harnessed_reasoning_config_view/delete_harnessed_reasoning_config_view.dspy"
)
ADMIN_ROLES_ONLY=("owner.admin" "reseller.admin" "provider.admin" "customer.admin" "reseller.operator" "reseller.accountant" "reseller.maintainer")
for p in "${ADMIN_PATHS[@]}"; do
for role in "${ADMIN_ROLES_ONLY[@]}"; do
for role in "${ADMIN_ROLES[@]}"; do
set_perm "${role}" "${p}"
done
done
# =============================================
# 层级 4: SUPERUSER — 系统级高危操作
# =============================================
echo ""
echo ">>> [4/4] Superuser: 技能部署等高危操作 (仅 owner.superuser)"
SUPERUSER_PATHS=(
# 技能部署(可能影响全局)
"/harnessed_agent/deploy_skill.ui"
"/harnessed_agent/execute_remote_skill.ui"
)
for p in "${SUPERUSER_PATHS[@]}"; do
for role in "${SUPERUSER_ONLY[@]}"; do
set_perm "${role}" "${p}"
done
done
@ -290,8 +307,16 @@ echo " 权限配置完成,共设置 ${COUNT} 条权限"
echo "============================================"
echo ""
echo "权限摘要:"
echo " Public (any): ${#PUBLIC_FILES[@]} 个文件"
echo " Read (logined+admin): ${#READ_PATHS[@]} 个路径 x ${#READ_ROLES[@]} 角色 = $((${#READ_PATHS[@]} * ${#READ_ROLES[@]}))"
echo " Admin (admin-only): ${#ADMIN_PATHS[@]} 个路径 x ${#ADMIN_ROLES_ONLY[@]} 角色 = $((${#ADMIN_PATHS[@]} * ${#ADMIN_ROLES_ONLY[@]}))"
echo " Public (any): ${#PUBLIC_FILES[@]} 个路径"
echo " Logined (所有登录用户): ${#LOGINED_PATHS[@]} 个路径 x ${#ALL_LOGINED[@]} 角色 = $((${#LOGINED_PATHS[@]} * ${#ALL_LOGINED[@]}))"
echo " Admin (superuser+机构管理员): ${#ADMIN_PATHS[@]} 个路径 x ${#ADMIN_ROLES[@]} 角色 = $((${#ADMIN_PATHS[@]} * ${#ADMIN_ROLES[@]}))"
echo " Superuser (系统级): ${#SUPERUSER_PATHS[@]} 个路径 x ${#SUPERUSER_ONLY[@]} 角色 = $((${#SUPERUSER_PATHS[@]} * ${#SUPERUSER_ONLY[@]}))"
echo ""
echo "角色说明:"
echo " owner.superuser — 系统级: 机构类型/角色/权限管理"
echo " *.admin — 机构级: 添加本机构人员、分配角色"
echo " reseller.operator — 运营: 产品/合同/定价/折扣/营销"
echo " reseller.sale — 销售: 客户管理/特殊折扣"
echo " reseller.accountant — 财务: 充值/对账/结算"
echo ""
echo "注意: 修改权限后需重启应用以刷新 RBAC 缓存。"