# 角色模板开发

在 Bundle 中发布角色模板，让工作流人工节点和 Runtime 权限使用稳定 roleKey。

`ROLE_TEMPLATE_SET` 是 Bundle 内的不可变版本资源。它声明业务角色的稳定 `roleKey`、展示信息和
Runtime 权限，不保存成员。用户、部门和用户组到角色的分配属于目标工作区。

## 定义格式

```json
{
  "templates": [
    {
      "templateKey": "sales",
      "roleKey": "crm.sales",
      "roleName": "销售",
      "description": "处理 CRM 线索和客户",
      "adoptExisting": false,
      "grants": [
        {
          "serviceId": "crm-core",
          "permissionCode": "crm.customer.read"
        }
      ]
    }
  ]
}
```

- `templateKey` 在一个模板集内唯一，用于追踪模板来源；它不是工作区角色身份。
- `roleKey` 是跨版本稳定的角色身份，也是工作流人工节点 `identityType: "role"` 时的 `identityId`。
- `roleName` 和 `description` 是 Bundle 提供的展示元数据。
- `grants` 不能为空；`serviceId + permissionCode` 必须指向当前 Runtime 已登记的权限点。
- `adoptExisting` 默认为 `false`。目标工作区已有同 `roleKey` 的人工角色时，安装会失败，避免 Bundle
  静默接管。只有所有贡献该 `roleKey` 的 Bundle 模板都设置为 `true`，人工角色才能覆盖展示信息和启停状态；
  Bundle 权限仍按当前安装资源取并集。

多个已安装 Bundle 可以贡献同一个 `roleKey`，但 `roleName` 和 `description` 必须一致，否则角色目录和
安装校验会失败关闭。

## 创建、发布和引用

把上面的 JSON 保存为 `role-templates.json`，然后通过统一资源命令创建和发布：

```bash
baijimu bundle resource create <workspace> <bundle> ROLE_TEMPLATE_SET crm-roles \
  --definition @role-templates.json --json

baijimu bundle resource publish <workspace> <bundle> ROLE_TEMPLATE_SET crm-roles 1.0.0 --json

baijimu bundle manifest resource add manifest.json \
  --resource-type ROLE_TEMPLATE_SET --resource-key crm-roles --semantic-version 1.0.0
baijimu bundle manifest validate manifest.json
```

修改模板时先完整更新草稿，再发布新的严格 Semantic Version；已发布版本不可修改。

## 安装与卸载语义

安装不会向目标工作区复制 `workspace_role`、角色权限或 Bundle 安装快照。平台按
`workspaceId + applicationRuntimeId` 读取当前有效 Bundle 安装资源，解析每个精确
`ROLE_TEMPLATE_SET` 版本，并与工作区人工角色合并成实时目录：

- Bundle-only 角色在角色管理页只读，但可以分配给用户、部门或用户组，也可以作为人工节点候选。
- 同时存在人工角色且允许 `adoptExisting` 时，管理员只编辑人工部分。
- 卸载后，派生角色及其权限立即从当前 Runtime 目录和鉴权中消失，不需要资源所有者执行删除。
- 主体到 `roleKey` 的绑定保留为 dormant；以后再次安装提供同一 `roleKey` 的 Bundle 时自动恢复。
- 已创建 Issue 的角色候选仍按稳定 `roleKey` 与工作区主体绑定匹配，不保存角色成员快照。

因此，Bundle 作者应把 `roleKey` 当作长期兼容的公开身份。改变 `roleKey` 等同于定义一个新角色，旧绑定和
历史人工事项不会自动迁移到新身份。
