# esb — E10 ESB 中心自定义触发动作流

本模块为维护者说明。面向 Agent 的使用入口在 `skills/weaver-e10-esb/SKILL.md`，operation 合约以 `weaver-work-cli esb schema` 为准。

## 模块来源

- 源资料 Skill：`weaver-e10-customesb-execute`（ESB 中心动作流触发接口 Skill），本模块把它同步转换为 `weaver-work-cli esb` 命令面 + Agent Skill `skills/weaver-e10-esb`。
- 源接口（去域名路径，域名与认证由 `src/internal/e10` 托管，业务 `host.ts` 不拼接域名、不处理凭证）：
  - `POST /api/bs/esb/setting/customData/application/copyCustomData` — 取入参模板（只读）。
  - `POST /api/esb/server/event/triggerActionFlow` — 执行自定义触发类型动作流（写操作）。

## CLI 结构

```text
src/shortcuts/esb/
  index.ts         Commander 注册（schema / run）、输入解析、输出 envelope
  manifest.ts     operation 合约（WHAT：name/summary/risk/inputSchema/withheldOperations）
  operations.ts   run 入口：白名单校验后分发 handler
  host.ts         E10 请求适配：路径白名单、resultCode 归一化、写不确定性处理
  errors.ts       模块结构化错误
  continuation.ts prepare/apply 的 HMAC continuation 签发与校验
  operations/
    registry.ts   manifest 与 handler 强制一一对应
    types.ts      handler 类型与 envelope
    shared.ts     输入归一化、占位字段收集、resultCode 结果摘要
    input-format.ts
    trigger.ts
```

## operation 表

| operation | 风险 | 用途 |
| --- | --- | --- |
| `esb.input-format` | `read` | 按 `applicationId` 取回 `customParams` 模板、`moduleSource` 与 `esbFlowId`；无副作用 |
| `esb.trigger.prepare` | `read-before-write` | 只读回查目标动作流、组装触发请求体、签发 continuation（10 分钟）；不触发动作流 |
| `esb.trigger.apply` | `high-risk-write` | 校验 continuation 与登录身份后调用触发接口，需 `confirm: true` |

## 常见命令

Windows PowerShell：

```powershell
weaver-work-cli --json esb run esb.input-format --input-json '{"applicationId":"900000000000000001"}'
weaver-work-cli --json esb run esb.trigger.prepare --input-json '{"esbFlowId":"900000000000000001","employeeId":"10001","customParams":{"mainTable":{"dataId":"D1001"}}}'
```

macOS/Linux（bash/zsh）：

```bash
weaver-work-cli --json esb run esb.input-format --input-json '{"applicationId":"900000000000000001"}'
weaver-work-cli --json esb run esb.trigger.prepare --input-json '{"esbFlowId":"900000000000000001","employeeId":"10001","customParams":{"mainTable":{"dataId":"D1001"}}}'
```

## 安全边界

- **写操作强制确认链**：触发走 `prepare → apply`；`apply` 必须带 `confirm: true` 与有效 continuation，continuation 与签发时的 `userId`/`tenantKey` 绑定，过期或身份变化必须重新 prepare。
- **写不确定性**：触发请求已发出但未取得结果（网络中断、超时）时返回 `partial/write_uncertain`，退出码为 `Partial`，禁止自动重试——重试可能造成重复执行。
- **resultCode 归一化**：触发接口非 200 的 `resultCode` 全部在 `host.ts` 映射为结构化 subtype（如 507/508/511 → `throttled` 可重试，404 → `flow_not_found` 不可重试），`resultMsg` 原样带出。
- **输入白名单**：顶层字段严格来自 `manifest.ts` 的 `inputSchema.properties`，未知字段直接报 `unknown_field`；`esbFlowId` 与 `uniqueIndent` 二选一，都传或多缺均报错，不做静默回退。

## 已知限制（`withheldOperations`）

- `esb.actionflow.resolve`：按动作流名称解析 ID 需要 ESB 中心查询接口，源资料未给出路径与字段契约，未实现；请用户直接提供 ID。
- `esb.unique-indent.resolve`：唯一值触发所需的 `primary_key` 需直接查询 `esb_setting` 库（`SELECT primary_key FROM esb_application WHERE id = ?`），CLI 无数据库通道，只能由调用方查得后传入。
