# TH Hotel 前端开发规范

## 1. 文档定位

本文整理 TH Hotel 当前前端开发约定，供本项目 UI 开发和其他 agent 协作参考。

本文是当前项目专属补充，不应整份复制到其他项目。可复用的通用前端规则应沉淀到 `docs/import/reusable/frontend-development-guidelines.md`。

前端只负责展示、交互、人工确认、调试入口和调用本项目后端。前端不得直接调用 OHIP、
SuperAgent、AgentBus 或任何持有 Secret 的外部系统。

## 2. 技术栈

以 `client/package.json` 为准，当前前端技术栈如下：

| 类别 | 当前选择 |
| --- | --- |
| 运行时 | Node.js 22.13+ LTS |
| 框架 | Vue 3.5.x |
| 语言 | TypeScript ~6.0.x，Strict 模式 |
| 构建 | Vite 8.x |
| 组件写法 | Composition API，`<script setup lang="ts">` |
| 路由 | Vue Router 5.x |
| 客户端状态 | Pinia 3.x |
| 服务端状态 | TanStack Vue Query 5.x |
| UI 组件库 | PrimeVue 4.x |
| 图标 | PrimeIcons |
| 国际化 | vue-i18n 11.x |
| Vue SFC 类型检查 | vue-tsc |
| 测试 | Vitest 4.x、Vue Test Utils 2.x、jsdom |
| Lint | ESLint 10.x、typescript-eslint 8.x、eslint-plugin-vue |

不引入通用 Admin Template。新增 UI 应延续现有设计语言和样式 token。

兼容性要求：

- Vite、ESLint 和 Vitest 的 Node.js 要求必须同时满足，当前统一使用 Node.js 22.13+ LTS。
- TypeScript 版本必须与 `typescript-eslint` 支持范围一致；在确认 `typescript-eslint` 支持更高版本前，TypeScript 锁定为 `~6.0.x`，不得使用宽泛的 `^6.0.0`。
- Vue SFC 项目必须配置 `vue-tsc` 做类型检查，不能只依赖 `tsc`。
- 升级 Vue、Vite、TypeScript、ESLint、Vitest、PrimeVue、Pinia、Vue Router 或 Vue Query 前，必须先检查版本兼容性并更新本文。

## 3. 目录约定

当前前端目录：

```text
client/src
├── components
│   ├── common
│   └── reservation
├── composables
├── i18n
│   └── locales
├── layouts
├── router
├── services
├── stores
├── styles
├── tests
├── types
└── views
    └── reservation
```

目录规则：

- API 请求封装放入 `src/services`。
- 手写类型定义放入 `src/types`。
- 可复用组合逻辑放入 `src/composables`。
- 路由定义放入 `src/router`。
- Pinia Store 放入 `src/stores`。
- i18n 入口和语言包放入 `src/i18n`。
- 页面级组件放入 `src/views`。
- 可复用业务组件放入 `src/components/<domain>`。
- 通用布局放入 `src/layouts`。
- 全局样式和设计 token 放入 `src/styles`。
- 未来 OpenAPI 生成代码放入 `src/generated`，禁止手工修改。

## 4. 组件规范

- 页面和组件统一使用 Vue 3 Composition API。
- `.vue` 文件使用 `<script setup lang="ts">`。
- Props、Emits、响应式状态和服务返回值必须有明确类型。
- 避免在模板中写复杂业务逻辑，复杂逻辑放入 computed、composable 或服务层。
- 不在组件里直接拼接后端 URL，统一通过 services。
- 不在组件里直接访问浏览器全局存储保存业务事实。
- 不把中文或英文显示文案作为业务判断依据。
- 不为未知的财务部、前台流程硬编码页面、状态或菜单。

## 5. 状态管理规则

Pinia 只保存客户端状态，例如：

- 当前用户上下文
- 当前酒店
- 当前部门
- 语言和页面偏好
- 轻量 UI 状态

服务端数据使用 TanStack Vue Query：

- 列表、详情、Timeline、Task、Preflight、SourceMessage 等后端数据通过 Query 获取。
- Mutation 完成后按 query key 精准失效或更新缓存。
- 不把服务端数据长期复制进 Pinia。
- 不用 Pinia 绕过后端权限、状态机或校验。

## 6. API 请求规范

- 浏览器只能调用本项目后端。
- 所有请求封装到 `src/services`。
- 服务函数返回明确 TypeScript 类型。
- 统一使用 `httpClient` 处理 JSON、错误和 Problem Detail。
- 前端不直接调用 OHIP、SuperAgent、AgentBus、数据库或对象存储。
- 前端不发送后端 Secret、replay access key、Provider API Key 或 Oracle 凭证。
- 调试页面如果需要触发受控后端能力，应由后端提供 debug-only 包装接口，Secret 保留在后端。

## 7. 国际化规范

首期交付：

```text
zh-CN
en-US
```

架构预留：

```text
th-TH
```

规则：

- 新增页面和组件不得硬编码中英文业务文案。
- 系统固定文案必须使用稳定 i18n key。
- 后端返回稳定业务代码和必要 `labelKey`，前端按 key 显示。
- 前端不得把中文或英文文本作为业务判断依据。
- 酒店配置名称、客人消息、姓名、备注、邮件正文和附件内容保持原文。
- 日期、时间、数字和货币按当前语言、酒店时区和币种配置格式化。
- API 仍传递结构化原始值，不传本地化展示字符串作为业务参数。

## 8. 类型与业务代码

- TypeScript 类型应贴近后端 API 契约。
- 稳定业务代码使用 string union 或枚举型常量，避免散落 magic string。
- 动态操作参数使用稳定 `fieldKey`。
- 表单字段展示使用 `labelKey` 或 i18n key。
- 不用 `label`、中文标题或英文标题做字段标识。
- 接口字段变更时，同步更新 `src/types`、services、页面和测试。

## 9. UI 与交互规范

- UI 组件库使用 PrimeVue。
- 避免引入大型 Admin Template。
- 页面应优先表达业务主线，而不是堆叠技术字段。
- Debug 页面可以显示技术 ID，但业务页面应优先展示可理解的业务状态和来源摘要。
- 预检、人工复核、任务确认要清楚区分：
  - 外部 Provider 建议
  - 人工确认值
  - 最终执行结果
- 邮件原文、附件详情和外部响应详情应通过受控详情接口读取，不默认塞进所有 Task 页面。
- 涉及客户信息、付款信息和附件时，应默认最小展示。

## 10. 前端安全规范

- `VITE_*` 变量会暴露到浏览器构建产物，不能保存 Secret。
- 前端不得保存数据库密码、OHIP 凭证、SuperAgent API Key、AgentBus Token、replay key。
- 不在 LocalStorage、SessionStorage 或 URL 中保存敏感业务数据。
- 错误提示不展示 Authorization、Cookie、Token、原始邮件全文或附件 URL。
- 测试夹具不得使用真实客人、真实酒店或真实支付信息。

## 11. 配置规范

常用公开配置：

```text
VITE_API_BASE_URL=http://localhost:8080
VITE_APP_ENV=local
VITE_DEFAULT_LOCALE=zh-CN
VITE_ENABLE_MOCKS=false
```

本地开发如需代理后端：

```text
VITE_API_PROXY_TARGET=http://127.0.0.1:8081
```

规则：

- 公开配置可以放 `VITE_*`。
- Secret 一律不进入 `VITE_*`。
- Reservation 查询默认不再依赖 `VITE_RESERVATION_HOTEL_ID`。单酒店阶段可不传 `hotel_id`，由后端按平台酒店表唯一 `ACTIVE` 酒店或当前登录用户上下文解析；如前端有酒店选择器，只传当前选中的酒店，后端负责校验访问权限。
- `VITE_RESERVATION_HOTEL_ID` 仅允许作为本地夹具或临时调试覆盖，不作为 test / prod 业务事实来源。
- 生产需要运行时配置时，应由部署系统生成公开配置文件，例如 `/app-config.json`。
- 需要秘密的外部调用一律经后端代理或适配器。

## 12. 路由规范

- Vue Router 管理部门级路由。
- 新增业务路由前确认对应后端 API 和权限边界。
- 平台 Shell 只保留已确认部门入口，不硬编码未知流程。
- 详情页路由参数使用稳定 ID。
- 页面刷新后必须能通过后端详情接口恢复必要状态，不依赖内存临时状态。

## 13. 表单与人工确认规范

- 人工确认表单优先使用后端返回的字段契约。
- 保存草稿时使用稳定 `fieldKey`。
- 不把显示文案作为提交字段名。
- 表单应展示字段来源：Provider 建议、来源消息、人工修正、最终值。
- 提交前前端可做基础格式校验，但最终业务校验在后端。
- 发生版本冲突时，应提示用户刷新或重新确认，不静默覆盖。

## 14. Agent 前端开发 Skill 使用

当前项目后续如果由 Codex 或其他 agent 开发前端，涉及 UI、交互、视觉或浏览器验证时，应优先使用当前环境可用的前端相关 skill。Skill 只作为辅助，不能覆盖本项目 Vue、TypeScript、Vite、PrimeVue、Pinia、Vue Query、i18n、接口契约和安全边界。

当前项目建议：

- 新页面、复杂交互或业务页面信息架构：优先使用 `design-taste-frontend` 和 `ui-ux-pro-max`。
- 设计 token、组件规范和样式体系：优先使用 `design-system`。
- 已有页面视觉重构：优先使用 `redesign-existing-projects`。
- 根据截图、设计稿或视觉参考还原页面：优先使用 `image-to-code`。
- 浏览器验证、截图检查、点击路径和响应式检查：优先使用 `browser:control-in-app-browser`。
- 需要生成插图、图片或占位视觉资产：可使用 `imagegen`。
- `ui-styling` 可参考其可访问性、组件状态和样式组织原则，但本项目未确认使用 shadcn 或 Tailwind 前，不得因此引入 shadcn、Tailwind 或替换 PrimeVue。
- `superpowers:brainstorming`、`superpowers:writing-plans`、`superpowers:test-driven-development`、`superpowers:verification-before-completion` 用于需求澄清、计划、测试和验收，不属于 UI 框架选择依据。

交付要求：

- 涉及 UI 或交互变更时，应说明使用了哪些 skill，或说明为什么未使用。
- 涉及可视化结果时，应尽量提供浏览器截图、响应式检查或交互验证结果。
- 如果 skill 建议与本项目规范冲突，以本项目规范、接口契约和用户明确要求为准。

## 15. 测试与检查命令

前端最低检查：

```bash
cd client
pnpm lint
pnpm typecheck
pnpm test
pnpm build
```

`pnpm typecheck` 应执行 `vue-tsc --noEmit` 或等价命令，确保 `.vue` 单文件组件也被类型检查覆盖。

聚焦开发时可运行：

```bash
cd client
pnpm test -- SomeSpecName.spec.ts
```

如果命令尚未配置或因环境问题无法运行，必须明确说明，不能假装通过。

## 16. Git 与协作流程

- 改动前说明目标、范围和将修改的文件。
- 每次只处理一个模块、一个页面或一个纵向切片。
- 不修改与当前任务无关的用户变更。
- 前后端接口变化前，先确认 API 契约和字段映射。
- 修改后运行项目已配置的检查命令。
- Git commit message 使用中文，清楚说明本次提交的业务或技术变更。

## 17. 前端提交前检查清单

- [ ] 是否只调用本项目后端？
- [ ] 是否没有把 Secret 放入 `VITE_*`、源码、测试或 URL？
- [ ] 新文案是否已进入 i18n？
- [ ] 是否避免用中文或英文显示文本做业务判断？
- [ ] API 请求是否放在 `src/services`？
- [ ] 手写类型是否放在 `src/types`？
- [ ] 可复用逻辑是否放在 `src/composables`？
- [ ] 服务端数据是否使用 Vue Query，而不是长期塞进 Pinia？
- [ ] 是否没有手工修改 `src/generated`？
- [ ] 涉及 UI、交互或视觉变更时，是否使用或说明未使用合适的前端 / 设计 skill？
- [ ] 涉及可视化结果时，是否做过浏览器、截图或响应式验证？
- [ ] 是否运行了 `pnpm lint` 或说明了无法运行原因？
- [ ] 是否运行了 `pnpm typecheck` 或说明了无法运行原因？
- [ ] 是否运行了 `pnpm test` 或说明了无法运行原因？
- [ ] 是否运行了 `pnpm build` 或说明了无法运行原因？

## 18. Reservation 前端低保真结构图与流程图

本节只记录当前 Reservation 前端第一版信息架构草图，用于对齐页面结构和业务主线。具体 checkpoint 设计、接口契约和实施计划应放入单独需求或设计文档，不在本规范中展开。

### 18.1 订单工作台低保真结构图

```text
┌────────────────────────────────────────────────────────────────────────────┐
│ Hotel OMS                           中文 / EN / ไทย        主题 / 用户      │
├───────────────┬────────────────────────────────────────────────────────────┤
│               │ 订单工作台                                                 │
│  订单管理      │                                                            │
│  任务队列      │ ┌──────────────────────────────────────────────────────┐   │
│  消息来源      │ │ 筛选区                                                 │   │
│  系统状态      │ │ 日期范围 | 业务号 | 订单状态 | 任务状态 | 任务卡类型      │   │
│               │ └──────────────────────────────────────────────────────┘   │
│               │                                                            │
│               │ ┌──────────────────────────────────────────────────────┐   │
│               │ │ 订单 / 任务列表                                       │   │
│               │ │ 业务号      订单状态   当前任务      任务状态   操作     │   │
│               │ │ GRP-001    ACTIVE    New Booking  待确认    查看     │   │
│               │ │ TMP-002    TEMP      Fallback     人工复核  查看     │   │
│               │ │ CNF-003    ACTIVE    Cancel       READY     执行     │   │
│               │ └──────────────────────────────────────────────────────┘   │
└───────────────┴────────────────────────────────────────────────────────────┘
```

中文说明：

- 左侧导航只保留已确认的 Reservation 相关入口，不提前暴露未确认部门流程。
- 工作台首屏服务于“找到需要处理的订单或任务”，不是普通订单 CRUD 首页。
- 列表行应同时表达订单状态、当前任务、任务状态和下一步动作。

### 18.2 任务列表低保真结构图

```text
┌────────────────────────────────────────────────────────────────────────────┐
│ Hotel OMS                           中文 / EN / ไทย        主题 / 用户      │
├───────────────┬────────────────────────────────────────────────────────────┤
│               │ 任务列表                                                   │
│  订单列表      │                                                            │
│  任务列表      │ ┌──────────────────────────────────────────────────────┐   │
│  消息来源      │ │ 筛选区                                                 │   │
│  系统状态      │ │ 日期范围 | 订单号/业务号 | 任务类型 | 任务状态 | 可处理 │   │
│               │ │ 来源邮件关键词 | 是否参与队列                         │   │
│               │ └──────────────────────────────────────────────────────┘   │
│               │                                                            │
│               │ ┌──────────────────────────────────────────────────────┐   │
│               │ │ 任务数据                                               │   │
│               │ │ 任务号   订单号     任务卡        状态      来源邮件     │   │
│               │ │ #10001  GRP-001   New Booking  待确认   Booking Req   │   │
│               │ │ #10002  GRP-001   Update       阻塞中   Booking Upd   │   │
│               │ │ #10003  TMP-002   Fallback     人工复核 Unknown Msg   │   │
│               │ │                                                        │   │
│               │ │ 队列 | 可处理 | 邮件会话 | 查看任务 | 查看订单           │   │
│               │ └──────────────────────────────────────────────────────┘   │
└───────────────┴────────────────────────────────────────────────────────────┘
```

中文说明：

- 任务列表是独立菜单，服务于“按任务处理”的工作方式，不是订单列表的复制。
- 列表数据来自 `GET /api/reservation/tasks`；该接口已存在第一版，前端应直接接真实接口，不展示 fixture 假数据。
- 每行任务至少展示 `task_id`、关联订单、任务卡名称、任务类型 / 子类型、任务状态、队列顺序、是否可处理、只读原因和来源邮件摘要。
- 每行操作保留“查看任务”“查看订单”“查看邮件会话”三个入口；邮件会话入口按该任务的 `source_message_id` 或 `external_conversation_id` 打开。
- 如果来源邮件会话字段暂未接入，邮件会话入口置灰或展示“接口待补”，不使用假会话数据。

### 18.3 订单详情与任务卡低保真结构图

```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 订单详情  GRP-001 / TMP-20260707-0001        ACTIVE / TEMPORARY             │
│ 主来源消息 #190...  业务号来源 AI_CANDIDATE    最近更新 2026-07-08          │
├────────────────────────────────────────────────────────────────────────────┤
│ 订单摘要                                                                     │
│ Group Code / Confirmation No. / 临时单号 / 订单状态 / 主来源消息 / 创建时间   │
├───────────────────────────────┬────────────────────────────────────────────┤
│ 同订单任务队列                  │ 当前任务卡                                   │
│                               │                                            │
│ ① New Booking   待确认  邮件会话│ New Booking 卡                              │
│ ② Update        阻塞中  邮件会话│ ┌ 证据区 ───────────────────────────────┐   │
│ ③ Trace Notes   未开始  邮件会话│ │ 生成原因 / 来源消息摘要 / 附件 / 邮件会话│   │
│                               │ └──────────────────────────────────────┘   │
│                               │ ┌ 基础信息 ─────────────────────────────┐   │
│                               │ │ Group Code / Confirmation No. / 类型   │   │
│                               │ └──────────────────────────────────────┘   │
│                               │ ┌ 入住与房型 ───────────────────────────┐   │
│                               │ │ 入住日期 / 离店日期 / 房量 / 房型 / Rate│   │
│                               │ └──────────────────────────────────────┘   │
│                               │                                            │
│                               │ [保存草稿] [确认任务]                       │
├───────────────────────────────┴────────────────────────────────────────────┤
│ OPERA 模拟操作                                                               │
│ ① 预检查 PENDING / SUCCEEDED / FAILED     ② 写入 PENDING / SUCCEEDED / FAILED │
│                                                                            │
│ 审计时间线：AI 创建 → 保存草稿 → 人工确认 → OPERA 预检查 → OPERA 写入          │
└────────────────────────────────────────────────────────────────────────────┘
```

中文说明：

- 订单详情页必须沿用“订单归档容器 + 同订单任务队列 + 当前任务卡 + OPERA 模拟操作 + 审计时间线”的既有结构，不另起一套订单详情布局。
- 后续任务如果被前置任务阻塞，应在任务队列和任务卡操作区同时体现只读状态。
- 任务卡字段必须按后端字段矩阵分组渲染，不直接把 AI 原始 JSON 展示成自由表单。
- 邮件入口按任务粒度展示：每个任务可能来自不同 `source_message_id`，也可能落在不同 `external_conversation_id`。点击“邮件会话”只打开该任务来源消息所在的完整邮件会话，不代表订单下所有来源消息的合集。
- 当前任务卡证据区展示来源消息摘要、附件摘要和“查看邮件会话”入口；完整邮件正文、HTML 和附件详情进入单独邮件会话详情页查看，避免订单详情页被长邮件撑开。
- OPERA 模拟和审计是任务确认后的执行轨迹，不应和 AI 原始建议混在同一区域。

### 18.4 任务详情低保真结构图

```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 任务详情 #10002   Update Booking / RATE_CHANGE      PENDING_CONFIRM         │
│ 关联订单 GRP-001 [查看订单]   来源邮件 Booking Update [查看邮件会话]          │
├────────────────────────────────────────────────────────────────────────────┤
│ 处理状态                                                                     │
│ 可处理 / 阻塞原因 / 队列顺序 / 前置任务状态 / 只读说明                         │
├────────────────────────────────────────────────────────────────────────────┤
│ 证据区                                                                       │
│ 生成原因 / 来源消息摘要 / 附件摘要 / 完整邮件会话入口                         │
├────────────────────────────────────────────────────────────────────────────┤
│ 任务卡字段                                                                    │
│ 基础信息：Group Code / Confirmation No. / 业务动作                           │
│ 变更内容：before_after / rate_code / fix_charge_items                        │
│ 人工复核：visible_reason / required fields / validation                      │
├────────────────────────────────────────────────────────────────────────────┤
│ 操作区                                                                       │
│ [保存草稿] [确认任务]                                                         │
├────────────────────────────────────────────────────────────────────────────┤
│ OPERA 模拟操作                                                               │
│ 预检查 / 写入 / 重试状态 / 最近错误                                           │
├────────────────────────────────────────────────────────────────────────────┤
│ 审计流水                                                                     │
│ AI 创建 → 草稿保存 → 人工确认 → OPERA 预检查 → OPERA 写入                     │
└────────────────────────────────────────────────────────────────────────────┘
```

中文说明：

- 任务详情页聚焦单个任务卡的查看、编辑、确认和执行轨迹，不承载同订单全局队列；同订单全局队列仍回到订单详情页查看。
- 任务详情读取来自 `GET /api/reservation/tasks/{taskId}`，草稿保存、确认任务、OPERA 模拟和审计流水使用后端已存在的任务工作流接口。
- 证据区只展示来源消息摘要和附件摘要；完整邮件正文、HTML、历史邮件和回复进入邮件会话详情页。
- 字段区按后端 `fields[]` 的 `display_area` 和字段规则分组渲染，不把 AI 原始 JSON 直接展示为自由表单。
- 如果任务不可处理，操作区应保持只读，并展示 `availability` 或 `readonly_reason_code` 给出的原因。

### 18.5 邮件会话详情低保真结构图

```text
┌────────────────────────────────────────────────────────────────────────────┐
│ 邮件会话详情  Re: Booking Update                         返回订单 / 返回任务 │
│ Conversation thread-20260708-001  共 6 封  最近收到 2026-07-08 11:28        │
├────────────────────────────────────────────────────────────────────────────┤
│ 会话摘要                                                                     │
│ 酒店 / 渠道 EMAIL / 发件人汇总 / 主题 / 关联订单 GRP-001 / 关联任务 3 个       │
├────────────────────────────────────────────────────────────────────────────┤
│ 邮件时间线                                                                   │
│                                                                            │
│ ┌ 2026-07-06 09:10  guest@example.com  Booking Request ────────────────┐   │
│ │ 邮件全文正文或已清洗 HTML                                               │   │
│ │ 附件：rooming-list.xlsx / voucher.pdf                                  │   │
│ │ 关联：New Booking #10001                                               │   │
│ └──────────────────────────────────────────────────────────────────────┘   │
│ ┌ 2026-07-07 14:22  hotel@example.com  Re: Booking Request ────────────┐   │
│ │ 邮件全文正文或已清洗 HTML                                               │   │
│ │ 附件：无                                                               │   │
│ │ 关联：无                                                               │   │
│ └──────────────────────────────────────────────────────────────────────┘   │
│ ┌ 2026-07-08 11:28  guest@example.com  Re: Booking Update ─────────────┐   │
│ │ 邮件全文正文或已清洗 HTML                                               │   │
│ │ 附件：change-request.pdf                                               │   │
│ │ 关联：Update Booking #10002                                            │   │
│ └──────────────────────────────────────────────────────────────────────┘   │
└────────────────────────────────────────────────────────────────────────────┘
```

中文说明：

- 邮件会话详情页展示同一个 `external_conversation_id` 下的全部邮件，包括历史邮件、当前邮件和后续回复。
- 页面入口可以来自订单详情任务队列、当前任务卡证据区或任务详情页，但落地页统一为“邮件会话详情”，不是单封邮件详情。
- 每封邮件应展示完整正文或清洗后的 HTML、附件列表、内联图片信息、发送 / 接收时间、发件人展示值、主题和关联订单 / 任务。
- 前端不在本页展示假数据；后端接口未接入时显示“接口待接入 / 暂无邮件会话数据”。
- 邮件全文属于用户在邮箱中本来可见的信息，前端页面不做业务层面的截断隐藏；但仍必须通过本项目后端接口读取，不在前端保存外部系统 Secret 或访问 key。

### 18.6 Reservation 任务主流程图

```mermaid
flowchart LR
  A["SourceMessage Inbox<br/>来源消息"] --> B["AI 过渡层<br/>保存 AI 原始 JSON"]
  B --> C["订单<br/>业务号或临时单号"]
  B --> D["任务队列<br/>按 execution_order 排序"]
  D --> E["任务卡详情<br/>字段矩阵驱动渲染"]
  E --> F["保存草稿<br/>draft_payload"]
  E --> G["最终确认<br/>confirmed_payload"]
  G --> H["OPERA 模拟操作<br/>预检查 / 写入"]
  H --> I["审计时间线<br/>确认、执行、重试记录"]
```

中文说明：

- `SourceMessage Inbox` 是来源事实层，不表达订单、任务或业务结论。
- AI 输出只作为原始建议和证据保存，不能直接改变最终业务状态。
- 用户确认后的 `confirmed_payload` 才能作为 OPERA 模拟操作输入。
- 审计时间线用于串联人工确认、OPERA 执行和重试记录，便于后续追溯。
