# Event Trigger 绑定工作流与输入映射

创建、发布并安装事件触发器，用事件数据启动独立 Workflow，说明 CEL 映射、资源身份和人工处理衔接。

Event Trigger 是独立的 Bundle 资源，描述“哪个来源的哪个事件，满足什么条件时，调用哪个动作”。
模块声明 `events`、业务发布事件、Event Trigger 消费事件是三个独立步骤。
本页说明已有的 `startInstance` 动作合同，不需要编写 Webhook 服务或保存内部地址。

```text
业务完成并发布模块事件
  → 已安装且启用的 Event Trigger 匹配来源、事件名和条件
  → actionParamMappings 把事件数据映射为动作参数
  → startInstance 启动已安装的 Workflow
  → Workflow 使用 input；前置节点结果进入 context；human 等待人工提交
```

如果报告生成后主流程就应结束，发布事件后结束主流程，由触发器启动独立的人工处理流程。
`subflow` 会等待子流程，不能用来实现这一分离。事件发布成功也不表示后续人工事项已经创建或完成。

## 1. 查询来源、动作服务和工作流身份

先按本机 `--help` 确认命令和参数，再查询目标工作区；不要根据服务显示名猜 `businessId`：

```bash
baijimu --version
baijimu runtime services list --help
baijimu runtime service get --help
baijimu bundle object create --help
baijimu runtime services list --workspace-id <WORKSPACE_ID> --json
baijimu runtime service get <SOURCE_BUSINESS_ID> --workspace-id <WORKSPACE_ID> --json
baijimu runtime service get <WORKFLOW_BUSINESS_ID> --workspace-id <WORKSPACE_ID> --method startInstance --json
baijimu bundle resources <installedBundle> --workspace-id <WORKSPACE_ID> --json
```

- 来源服务在目标 Runtime 中存在，事件名与 Module 精确版本的 `events` 声明一致，事件业务数据符合其 `paramDefinitions`。
- 动作服务确实提供 `startInstance`；读取其当前 `methodDefinition`，核对 `payload` 参数。
- 目标 Workflow 已有精确发布版本，且会随 Bundle 或其依赖安装到同一目标 Runtime。
  `installedResource.resourceLocator` 使用平台返回的完整 Workflow Locator；已有安装从资源台账回读。
  首次安装使用平台资源记录返回的完整身份，不从工作流名称、内部数据库 ID 或环境域名猜测。
- Bundle 作者文件选择 Workflow 的精确版本。触发器中的 Locator 标识工作流资源，运行时使用目标 Runtime
  已安装的版本；它不表示“从市场取最新版本”。

这里的 `businessId` 是 Event Trigger 当前动作合同要求的 Runtime 服务身份；不要把它复制到
Workflow 的 `module_method`、`emit_event` 等节点，后者使用各自的领域引用。
服务身份随目标 Runtime 确认，不把一个工作区的值当成全局常量。

## 2. 编写触发器定义

将以下结构保存为 `event-trigger.json`。尖括号内容全部替换为当前目录或资源记录返回的值。
`reportCreated`、`reportId`、`summary` 和 `reviewerUserId` 是本例业务字段，实际使用时与事件及 Workflow
输入合同保持一致。

```json
{
  "name": "报告生成后启动人工审核",
  "description": "把报告事件映射为独立审核流程的启动输入",
  "triggerBusinessId": "<SOURCE_BUSINESS_ID>",
  "triggerEvent": "reportCreated",
  "actionBusinessId": "<WORKFLOW_BUSINESS_ID>",
  "actionMethod": "startInstance",
  "actionParamMappings": {
    "payload": {
      "installedResource": {
        "resourceLocator": "<ENVIRONMENT_KEY>/<BUNDLE_ID>/WORKFLOW/<WORKFLOW_CODE>"
      },
      "input": {
        "reportId": "=event.data.reportId",
        "summary": "=event.data.summary",
        "reviewerUserId": "=event.data.reviewerUserId"
      }
    }
  },
  "status": "active"
}
```

`--definition` 只接收定义本身，不要包裹 `data` 或 `definition` 响应 envelope，也不要加入只读身份和时间戳。

| 字段                    | 配置规则                                                                  |
| --------------------- | --------------------------------------------------------------------- |
| `name`                | 为可安装运行的触发器填写非空名称。                                                     |
| `description`         | 可选说明。                                                                 |
| `triggerBusinessId`   | 事件来源 Runtime 服务身份，与下面两个来源字段三选一。                                       |
| `triggerService`      | 按当前 Runtime 的 `relayService` 元数据唯一解析来源；不是任意服务显示名称。无匹配或多匹配会失败。         |
| `triggerConnectorId`  | Connector 事件来源；使用 Connector 目录返回的身份，不用于替代普通模块服务身份。                    |
| `triggerEvent`        | 来源声明的准确事件名。                                                           |
| `triggerCondition`    | 可选 CEL 布尔表达式，例如 `event.data.needsReview == true`；不加 `=` 前缀。省略表示不额外过滤。 |
| `actionBusinessId`    | 当前 Runtime 中提供动作的服务身份。                                                |
| `actionMethod`        | 动作方法名；本页为 `startInstance`。                                            |
| `actionParamMappings` | 动作参数的 JSON 对象；本页映射到 `payload`。                                        |
| `status`              | 本例使用 `active`；`inactive` 表示不启用，也接受 `ENABLED / DISABLED`。              |

`triggerBusinessId / triggerService / triggerConnectorId` 必须且只能填写一个。
`startInstance` 的 `actionParamMappings.payload` 必须是对象，且其中的 `installedResource`
只允许 `resourceLocator`。Locator 必须是静态完整字符串并指向 `WORKFLOW`，不能用表达式动态选择。
不要在 `payload` 中加入已退役的 `runtimeKind`、`scope`、`code` 或 `applicationRuntimeId`。

## 3. 映射事件数据，保留对象和数组类型

Event Trigger 的映射字符串以 `=` 开头时按 CEL 求值；其他字符串为字面量。对象和数组会递归处理，
表达式结果保留原 JSON 类型，不要求先转成字符串。

如果整个事件业务数据就是 Workflow 输入，把上例的 `input` 改为：

```json
{
  "input": "=event.data"
}
```

如果只选择部分字段，也可以传递负责人数组：

```json
{
  "input": {
    "reportId": "=event.data.reportId",
    "userIds": "=event.data.userIds"
  }
}
```

这两段是 `payload` 内的局部替换示例，保留原有 `installedResource`。
`userIds` 应是当前工作区有效用户 ID 的字符串数组；human 使用
`"assignment": {"mode":"candidates","candidates":"{{input.userIds}}"}` 整体读取。单人自动分配，多人等待其中一人领取；
完整配置与失败规则见[动态用户列表](/development/bundle-development/issue-definition-development/#动态用户列表单人分配多人领取)。
`assignment.candidates` 仍不接受表达式字符串。

| 所在位置                                 | 引用语法      | 例子                                                            |
| ------------------------------------ | --------- | ------------------------------------------------------------- |
| Event Trigger 参数映射                   | `=CEL表达式` | `=event.data.reportId`                                        |
| Event Trigger 条件                     | CEL 布尔表达式 | `event.data.needsReview == true`                              |
| Workflow 节点输入或 human 单个 `identityId` | `{{路径}}`  | `{{input.reportId}}`、`{{context.ownerLookup.reviewerUserId}}` |

`event.data` 是事件业务载荷。只有业务载荷本身存在 `payload` 字段时才读取 `event.data.payload`；不要
凭事件名称额外套一层。Event Trigger 映射中写 `{{context.xxx}}` 不会读取 Workflow 上下文，因为工作流
此时尚未启动。当前事件映射表达式求值失败会得到 `null`，不会自动采用默认值；验收时要检查实际启动输入，
不能只看触发器保存成功。

## 4. 创建、冻结版本并纳入 Bundle

```bash
baijimu bundle object create <bundle> event-trigger --workspace-id <WORKSPACE_ID> \
  --definition @event-trigger.json --json

baijimu bundle object get <bundle> event-trigger --workspace-id <WORKSPACE_ID> \
  --object-id <TRIGGER_KEY> --json

baijimu bundle object publish <bundle> event-trigger --workspace-id <WORKSPACE_ID> \
  --object-id <TRIGGER_KEY> --version <TRIGGER_VERSION> --json

baijimu bundle manifest include <bundle> event-trigger --workspace-id <WORKSPACE_ID> \
  --file baijimu.bundle.json --object-id <TRIGGER_KEY> --version <TRIGGER_VERSION>

baijimu bundle manifest preflight <bundle> --workspace-id <WORKSPACE_ID> --file baijimu.bundle.json
```

`TRIGGER_KEY` 来自创建结果或 `bundle manifest catalog <bundle> event-trigger`，不能自己生成后冒充返回值。
已有触发器使用 `bundle object update`，传相同 `--object-id` 和新的完整 `--definition`，再冻结后继版本。
所有版本使用严格 SemVer；分别确定 Event Trigger、Workflow 和 Bundle 的版本，不覆盖已发布版本。

同时确认来源 Module、目标 Workflow，以及 human 所引用的 IssueDefinition 已纳入作者清单或显式依赖。
提交并推送 Bundle 项目的 Git 修改，从准确提交发布 Bundle Version，再安装或升级目标 Runtime。
完整流程见[Bundle 项目清单](/development/bundle-development/manifest/)和
[版本与交付](/development/bundle-development/version-and-delivery/)。仅创建触发器草稿或冻结版本不会自动启用订阅。

## 5. 验证事件到人工处理的完整链路

1. 回读 Bundle 安装资源台账，确认 Event Trigger、Workflow 和 IssueDefinition 的目标版本已安装。
2. 使用实际业务操作或工作流 `emit_event` 发布一条符合事件合同的测试事件，记录业务关联 ID。
3. 查询新 Workflow 实例及执行记录，核对 `input.reportId`、数组等字段的值与类型。未产生实例时先检查
   来源、事件名、启用状态、过滤条件、动作授权和 `startInstance` 调用结果。
4. 流程到达 human 后，确认事项输入符合 IssueDefinition；`users` 单人自动分配、多人其中一人领取，空名单失败。原有 `candidates` 单人仍需领取。
5. 提交符合 `outputType` 的结果，确认其写入 human 的 `result.path`，流程继续执行。

```bash
baijimu runtime workflow list --workspace-id <WORKSPACE_ID> --application-runtime-id <APPLICATION_RUNTIME_ID> --json
baijimu runtime workflow get --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json
baijimu runtime workflow executions --workspace-id <WORKSPACE_ID> <INSTANCE_ID> --json
```

事件发布、触发工作流、创建事项、人工完成是四个不同的成功点。排查时以各自的实际记录为准。

继续阅读：[模块事件发布](/development/bundle-development/module-development/event-development/)、
[工作流](/features/workflows/)、[人工事项定义与 human](/development/bundle-development/issue-definition-development/)。
