feat(规则): 支持同一事件多规则按条件区分并全部发送

Motivation:
止盈、止损等不同策略信号会映射到同一事件(如 trade.close),但原有唯一约束要求每个事件只能有一条规则,无法按策略区分处理。放开该约束后,同一事件可配置多条规则,通过规则条件与精确/通配优先级区分,命中条件的规则全部发送;同时将去重键从消息原文改为信号维度,避免同一信号因时间戳等无关字段差异被误判为重复。

Changes:

* 移除规则 source_id+event 的唯一约束,改为普通索引
* 事件匹配改为返回命中优先级内所有启用规则,并按 ID 逐条派发
* 通知服务遍历多条规则,按条件过滤后聚合发送渠道
* 去重键由消息 body 哈希改为策略/币种/周期/方向/价格信号维度哈希
This commit is contained in:
2026-08-17 01:20:49 +08:00
parent f5f64f7653
commit d2e8476398
13 changed files with 349 additions and 115 deletions
+3 -3
View File
@@ -95,14 +95,14 @@ make build && ./bin/server
| `smtp.*` | 邮件发送(email 渠道) | — |
| `rate_limit.default` | 每 source 每秒请求上限 | `100` |
| `rate_limit.dingtalk_per_min` | 同一钉钉机器人(access_token)每分钟发送上限;超限排队到下一分钟 | `18`(官方 20,留余量) |
| `subscription_dedup_ttl` | 多队列重复消息(body SHA-256)去重窗口 | `1h` |
| `subscription_dedup_ttl` | 多队列重复消息(策略/币种/周期/方向/价格)去重窗口 | `1h` |
| `subscriptions` | RabbitMQ 订阅列表;某条 `url` 为空则跳过 | 空 |
| `subscriptions[].source` | 对应已有 Source.name | 有 url 时必填 |
| `subscriptions[].formatter` | 目前仅 `trade_signal` | `trade_signal` |
环境变量 `RABBITMQ_URL` 未设置时不启动消费,HTTP 通知不受影响。交易信号订阅需事先创建 Source(如 `trade-signal`)、模板(可用 `{{.formatted}}`)、规则 `trade.open` / `trade.add` / `trade.close` / `trade.reduce`、以及渠道。规则条件可用 `strategyCode` / `symbol` / `period`
`crypto-strategy` 开仓(多/空,含原来的 `isSale` 空单)都映射为 `trade.open`,不再发 `trade.sell`。止盈(`isGain`)为 `trade.gain`,止损(`isClose` 且非 `isGain`)为 `trade.close`。高低分 `HLSS` 仍用 `HLSS.open` / `HLSS.sell` / `HLSS.close`。同一 Source 每个 event 只能有一条规则,所以止盈不能再和止损共用 `trade.close`。AI crypto signals 的现成模板与规则见 `docs/httpie/curls.md`
`crypto-strategy` 开仓(多/空,含原来的 `isSale` 空单)都映射为 `trade.open`,不再发 `trade.sell`。止盈(`isGain`)为 `trade.gain`,止损(`isClose` 且非 `isGain`)为 `trade.close`。高低分 `HLSS` 仍用 `HLSS.open` / `HLSS.sell` / `HLSS.close`。同一 Source 允许多条相同 event 的规则(用条件区分);精确 event 优先于通配,条件通过的规则都会发送。AI crypto signals 的现成模板与规则见 `docs/httpie/curls.md`
健康检查:`GET /health``{"status":"ok"}`
@@ -482,7 +482,7 @@ Query`page`、`page_size`。**200** `{ "data": Channel[], "total", "page"
前缀:`/api/v1/rules`
**鉴权:** Admin Key
同一 Source 下 `event` 唯一
同一 Source 下允许重复 `event`;用规则条件和精确/通配优先级区分。条件通过的规则都会发送
#### `POST /api/v1/rules` — 创建