# 任务 (Task)

Task 是**定时任务（定时器）**的定义——**action 闭包的第二成员**（action = controller | task | third callback，无第四种）。

```
action = trigger =
  ① controller       —— 前端/外部调用的 RPC 入口
  ② task             —— 定时器（cron 驱动）：到期退款、结算、提现、报表、关单
  ③ third callback   —— 外部系统主动回调
```

- **Task 只表示定时器**（cron 驱动）。异步/事件驱动的操作归 event 体系（EventObserver / EventNotifier，待设计），不属于 task。
- Task 是**契约**（名字 + cron + 做什么），不声明状态变化——状态变化由 journey 步骤表达。
- Task 实现（扫描逻辑、幂等）在实现层（如 pylon-flow step）。

## 定义

```ts
// task_schema/auto-refund.task.ts
export const AutoRefundTask = defineTask({
  name: 'AutoRefundTask',
  label: '到期自动退款',
  cron: '0 3 * * *',
  description: '扫描已锁定券码 + auto_refund + valid_to<now → 按订单发起全额退款',
});
```

## 字段

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `name` | string | ✅ | `XxTask`（PascalCase + `Task` 后缀） |
| `label` | string | ✅ | 中文名 |
| `cron` | string | ✅ | 定时表达式（系统怎么触发的契约，一处看全） |
| `description` | string | 可选 | 做什么（叙述） |

## 命名与存储规则

| 约定 | 规则 | 例子 |
|---|---|---|
| `name` | PascalCase + `Task` 后缀 | `AutoRefundTask` |
| 导出符号 | = name | `export const AutoRefundTask` |
| 文件位置 | `task_schema/`（项目根，与 schema/ 并列） | `task_schema/auto-refund.task.ts` |
| 文件名 | name 去 `Task` 后缀转 kebab + `.task.ts` | `auto-refund.task.ts` |
| 一文件一 task | loader 机器校验（仿 loadDaos/loadEntities） | 多导出/零导出报错 |

## 校验

- 运行时（`defineTask`）：
  - `name` 必须以 `Task` 结尾，否则抛错
  - `cron` 必填（task 是定时器），否则抛错
- 存储（`loadTasks`）：
  - 唯一合法目录是 `task_schema/` 根（一级）
  - **导出符号 == schema name**，否则抛错
  - 文件名 = name 去 `Task` 后缀转 kebab + `.task.ts`，否则抛错
  - 一文件一 task（多导出/零导出报错）

## 作为 action 引用

Task 与 controller、third callback 并列，是 action 闭包成员，被状态迁移与 journey 步骤引用：

```ts
// journey 步骤
{ action: AutoRefundTask, host: api, text: '到期自动退款' }
```

lint 校验：`action` 引用必须是三类之一（controller | task | third callback）且引用存在。

## 与 pylon-flow 的关系

pylon-flow 的 step 函数是 task 的实现形态之一：

```ts
// flow/flows/settlement.flow.ts（api driver）
export async function autoRefund(flow, deps) { ... }   // 实现 AutoRefundTask
export default { autoRefund };
```

- **task schema = 契约**（名字/cron/做什么）
- **pylon-flow step = 实现**（怎么跑）
- 对账：task schema 的 name ↔ pylon-flow 的 step names——"定时任务已声明但没实现"可 lint
