## Summary 本 issue 只解决图片中的「实时告警中心」规划,不实现「通知渠道网关」和「大盘复盘 2.0」。但告警通知投递会复用现有 `NotificationService`,后续也可以接入 [#1200](https://github.com/ZhuLinsen/daily_stock_analysis/issues/1200) 的通知路由、测试与降噪能力;大盘红绿灯联动则依赖 [#1177](https://github.com/ZhuLinsen/daily_stock_analysis/pull/1177) 已合入的 Market Light 基础能力,并在后续 Phase 中要求补齐可复用结构化快照。 目标不是重写现有 `EventMonitor`,而是在当前 `src/agent/events.py`、schedule 后台轮询、系统配置、通知发送和 Web 设置页基础上,补齐产品化告警闭环:可管理规则、可测试、可追踪触发历史、可记录通知结果、可冷却降噪,并逐步覆盖技术指标、持仓风险和大盘红绿灯联动。 当前基线: - `EventMonitor` 运行时已存在,当前支持三类规则:`price_cross`、`price_change_percent`、`volume_spike`。 - `AGENT_EVENT_MONITOR_ENABLED`、`AGENT_EVENT_MONITOR_INTERVAL_MINUTES`、`AGENT_EVENT_ALERT_RULES_JSON` 已进入配置加载、config registry 和系统配置校验。 - schedule 模式已能加载 `EventMonitor` 并通过后台任务定时执行,触发后复用 `NotificationService.send()`。 - Web 设置页可以展示 Agent/Event Monitor 配置项,但没有独立的告警中心页面、规则 CRUD、测试按钮、触发历史或通知结果详情。 - 现有 `risk_alerts` 是分析报告/Agent 情报里的风险文案,不等同于用户可管理的告警规则。 - 持仓风险服务已有集中度、回撤、止损接近等风险摘要能力,但尚未接入告警规则和轮询触发。 - 大盘复盘已输出“大盘红绿灯 / Market Light”文本块,但还缺少稳定的 `MarketLightSnapshot` payload 供 API、Web、Agent 和告警规则复用。 默认兼容规则: - 未创建 Web 告警规则时,保持当前 `AGENT_EVENT_ALERT_RULES_JSON` 配置行为不变。 - 新增持久化规则默认不静默迁移、删除或覆盖用户已有 `.env` / Web 配置。 - 新增配置默认关闭或为空,不改变当前每日分析、问股、通知和大盘复盘主流程。 - 单条告警规则失败不得影响其他规则,也不得中断主分析流程。 - 单一通知渠道失败不得影响其他渠道;告警中心只记录失败原因,不把通知失败误判为规则失败。 - 高成本或不稳定数据源缺失时应记录 degraded / skipped 状态,不伪造触发结论。 ## Key Changes ### P0:告警中心基线、模型契约与兼容边界 先建立真实基线和数据契约,不做 Web 大改,也不重写通知框架。 - 创建 `docs/alerts.md` 骨架,包含目录、现有 EventMonitor 基线、规则类型表、Phase 规划和兼容说明。 - 明确实体模型:`alert_rule`、`alert_trigger`、`alert_notification`、`alert_cooldown`。 - 明确规则 payload 最小字段:目标范围、规则类型、参数、严重级别、启停状态、冷却策略、通知策略、创建来源。 - 明确触发记录最小字段:规则 ID、目标标的、观察值、阈值、触发原因、数据源、数据时间、触发时间、状态。 - 明确通知记录最小字段:trigger ID、渠道、attempt、成功/失败、错误分类、耗时、脱敏后的诊断信息。 - 保留 `AGENT_EVENT_ALERT_RULES_JSON` legacy 配置路径,先作为运行时兼容来源,不在 P0 做自动迁移。 - 评估存储落点,优先复用仓库现有 storage/repository/service 模式;若需要 schema 变更,必须提供幂等初始化和回滚说明。 - P0 测试只做契约和兼容快照:现有三类规则解析、无规则时不启动后台告警、legacy JSON 仍可运行。 ### P1:Alert API MVP 新增最小 API 表面,先覆盖已有三类规则,不一次性支持全部技术指标。 - 新增 `api/v1/endpoints/alerts.py` 并挂载到 v1 router。 - 新增 `api/v1/schemas/alerts.py`,定义规则、触发、通知和测试响应 schema。 - API 初始范围: - `GET /api/v1/alerts/rules` - `POST /api/v1/alerts/rules` - `PATCH /api/v1/alerts/rules/{rule_id}` - `DELETE /api/v1/alerts/rules/{rule_id}` - `POST /api/v1/alerts/rules/{rule_id}/enable` - `POST /api/v1/alerts/rules/{rule_id}/disable` - `POST /api/v1/alerts/rules/{rule_id}/test` - `GET /api/v1/alerts/triggers` - `GET /api/v1/alerts/notifications` - `test` 接口只执行一次规则评估,不写入真实触发记录,除非请求显式要求保存 dry-run 结果。 - API 返回必须脱敏,不回显 webhook URL、token、邮箱密码、cookie、bot secret。 - 首版支持 `price_cross`、`price_change_percent`、`volume_spike`;其他类型返回结构化 unsupported 错误。 ### P2:告警评估 Worker 与运行时统一 将 Web/API 创建的规则接入后台评估,同时保持 legacy 配置兼容。 - schedule 模式从持久化规则加载 active rules,并继续兼容 `AGENT_EVENT_ALERT_RULES_JSON`。 - 规则评估必须逐条隔离异常:单条规则失败只写 degraded / failed 状态,不影响同轮其他规则。 - 明确市场日历和交易时段策略:非交易日跳过盘中规则;需要日线数据的规则可在收盘后或 schedule 窗口评估。 - 实时行情缺失、字段缺失、数据过旧时记录 skipped/degraded,不触发误报。 - 避免每条规则重复初始化数据源;同轮评估可共享行情快照,但不得污染其他主流程缓存语义。 - 初始 worker 不引入 LLM 调用;高阶新闻/事件解释留到后续 digest 或 Agent 联动。 - legacy JSON 规则和持久化规则的合并、去重和优先级必须文档化。 ### P3:Web 告警中心 MVP 新增独立 Web 入口,让用户能不用编辑 JSON 就管理告警。 - 侧边栏新增“告警”入口,页面放在 `apps/dsa-web/` 对应路由下。 - 页面包含规则列表:名称、类型、目标、状态、严重级别、最近触发、下次可触发时间、最近评估状态。 - 规则创建表单支持现有三类规则: - 价格突破:above / below + price - 涨跌幅:up / down + change_pct - 成交量放大:multiplier - 支持启停、删除、测试、查看详情。 - 触发历史表展示观察值、阈值、原因、数据时间、数据源、通知状态。 - 先支持手工输入标的;持仓/自选股批量目标在 P5 做。 - Web 表单不直接暴露 legacy JSON 编辑体验,避免用户在两套入口之间产生冲突。 ### P4:触发历史、通知结果与冷却状态 让告警可排障、可降噪。 - 每次真实触发写入 `alert_trigger`,包括 observed value、threshold、reason、source、data_timestamp。 - 每个通知渠道写入 `alert_notification`,包括 channel、success、error_code、retryable、latency_ms、attempt。 - 规则级冷却:同一 rule + target 在冷却期内不重复推送。 - 目标级冷却:同一 stock/portfolio/market 状态可按 severity 做合并或抑制。 - 冷却配置先做规则内字段,不先接全局通知网关复杂策略;等 #1200 的降噪能力落地后再复用。 - 冷却判断失败时默认 fail-open 到“记录但不阻断主流程”,避免误伤高风险告警。 ### P5:技术指标规则 扩展到用户在 [#1132](https://github.com/ZhuLinsen/daily_stock_analysis/issues/1132) 中提到的自定义指标推送场景。 - 支持 MA / 均线规则:上穿、下穿、价格跌破/突破指定均线。 - 支持 RSI:超买、超卖、回落、突破阈值。 - 支持 MACD:金叉、死叉、柱体放大/收缩。 - 支持 KDJ:金叉、死叉、超买/超卖。 - 支持 CCI:突破阈值、回落阈值。 - 技术指标规则优先基于确定性日线/分钟线数据计算,不用 LLM 判断。 - 数据源缺失或周期不支持时返回 unsupported/degraded,并在 Web 上显示原因。 - 首版不做任意表达式 DSL,避免安全和可维护性风险。 ### P6:持仓与自选股联动 把告警从“单个手工标的”扩展到用户真实持仓和 watchlist。 - 支持 target scope:single symbol、watchlist、portfolio holdings、portfolio account。 - 接入持仓风险摘要: - 止损接近 / 跌破止损 - 集中度超过阈值 - 回撤超过阈值 - 持仓价格数据过旧 - 支持财报日前提醒、分红/除权日前提醒(只在数据源可明确提供日期时启用)。 - 持仓联动规则必须标明账户、币种、估值日期和数据状态,避免跨市场误判。 - 自选股和持仓目标扩展不得改变现有持仓页面的计算口径。 ### P7:大盘红绿灯与市场联动 复用大盘复盘输出,让告警能覆盖市场级风险。 - 先补齐 `MarketLightSnapshot` 稳定 schema:region、trade_date、status、score、dimensions、reasons、guidance、data_quality。 - 支持大盘红灯/黄灯触发风险告警。 - 支持 score 大幅下降、指数跌幅超过阈值、板块异动、涨跌停结构恶化等市场规则。 - 大盘联动必须记录市场日期和数据来源;不得把昨日红灯当作今日状态。 - 如果 Market Light 仅存在 Markdown 文本,不允许通过解析 prose 作为长期实现;必须使用结构化 payload。 - 该 Phase 依赖 Market Review 2.0 的结构化快照,不要求本 issue 内完整重做大盘复盘。 ### P8:告警文档、迁移与收口 在 API、Web、worker、通知和联动能力稳定后做完整收口。 - 完善 `docs/alerts.md`,按场景分节: - `## 本地配置` - `## Docker` - `## GitHub Actions` - `## Web 使用` - `## Desktop` - 文档覆盖: - 规则类型和字段契约 - legacy `AGENT_EVENT_ALERT_RULES_JSON` 兼容关系 - Web 告警中心使用方式 - 触发历史和通知结果解释 - 冷却/去重语义 - 持仓联动边界 - 大盘红绿灯联动边界 - 数据源缺失和 degraded 状态 - 回滚方式 - 若最终决定支持 legacy JSON 导入,提供显式导入按钮或 CLI,不自动修改用户 `.env`。 - 所有新增用户可见能力同步 `.env.example`、相关 docs 和 `docs/CHANGELOG.md`。 ## Progress | Phase | 状态 | PR | 说明 | | --- | --- | --- | --- | | Baseline | 已合并 | [#1178](https://github.com/ZhuLinsen/daily_stock_analysis/pull/1178) | `price_change_percent` 事件告警规则,复用现有 EventMonitor | | Baseline | 已合并 | [#1177](https://github.com/ZhuLinsen/daily_stock_analysis/pull/1177) | 大盘复盘 Market Light 文本块基础能力 | | Related | 已关闭 | [#1132](https://github.com/ZhuLinsen/daily_stock_analysis/issues/1132) | 自定义指标推送需求:涨跌幅、MACD、KDJ、CCI 等 | | Related | 已关闭 | [#1200](https://github.com/ZhuLinsen/daily_stock_analysis/issues/1200) | 通知渠道网关:测试、路由、降噪、长尾渠道 | | P0 | 已合并 | #1301 | 告警中心基线、模型契约、兼容边界、docs 骨架 | | P1 | 已合并 | #1314 | Alert API MVP | | P2 | 已合并 | #1323 | 告警评估 worker 与运行时统一 | | P3 | 已合并 | #1334 | Web 告警中心 MVP | | P4 | 已合并 | #1337 | 触发历史、通知结果、冷却状态 | | P5 | 已合并 | #1345 | 技术指标规则 | | P6 | 已合并 | #1379 | 持仓与自选股联动 | | P7 | 已合并 | #1419 | 大盘红绿灯与市场联动 | | P8 | 已合并 | #1430 | 文档、迁移与收口 | ## Acceptance Criteria - [x] [P0] `docs/alerts.md` 说明现有 EventMonitor 基线、legacy 配置、实体模型和 Phase 边界。 - [x] [P0] 告警规则、触发记录、通知记录、冷却状态的数据契约已明确,并有 focused tests。 - [x] [P0] `AGENT_EVENT_ALERT_RULES_JSON` 兼容行为未被破坏。 - [x] [P1] Alert API 支持规则 CRUD、启停、测试、触发历史和通知结果查询。 - [x] [P1] API 不回显任何 token、webhook URL、邮箱密码或 bot secret。 - [x] [P1] API 首版覆盖 `price_cross`、`price_change_percent`、`volume_spike`。 - [x] [P2] schedule / background worker 能评估持久化 active rules,并与 legacy JSON 规则共存。 - [x] [P2] 单条规则失败不影响其他规则或主分析流程。 - [x] [P2] stale/missing data 会记录 skipped/degraded 状态,不产生误报。 - [x] [P3] Web 新增告警中心入口,支持规则列表、创建、启停、删除、测试。 - [x] [P3] Web 可展示触发历史、观察值、阈值、原因、数据源和通知状态。 - [x] [P4] 真实触发会写入 trigger 和 notification attempt 记录。 - [x] [P4] 冷却机制可避免同一 rule + target 在短时间内重复推送。 - [x] [P5] MA、RSI、MACD、KDJ、CCI 至少各有一个确定性规则实现和测试。 - [x] [P6] 告警可作用于持仓和 watchlist,并支持止损、集中度、回撤等风险规则。 - [x] [P7] 告警可消费结构化 `MarketLightSnapshot`,支持红灯/黄灯或 score 变化触发。 - [x] [P8] `.env.example`、config registry、Web 文案、docs、`docs/CHANGELOG.md` 同步。 - [x] [全局] 每个 PR 使用 `Refs #<issue>`,不在单个 Phase PR 中关闭 umbrella issue。 ## Test Plan - Backend:`./scripts/ci_gate.sh`。 - EventMonitor tests:现有三类规则解析、校验、序列化、异步评估、异常隔离。 - Storage tests:规则、触发、通知记录、冷却状态的创建、查询、更新、删除和幂等初始化。 - API tests:规则 CRUD、启停、测试、分页、过滤、422/404/500、脱敏和 unsupported 类型。 - Worker tests:legacy JSON + 持久化规则共存、单规则失败隔离、stale data、非交易日跳过、冷却生效。 - Web:`cd apps/dsa-web && npm ci && npm run lint && npm run build`。 - Web tests:告警导航、规则列表、创建表单、测试按钮、触发历史、错误状态展示。 - Indicator tests:MA、RSI、MACD、KDJ、CCI 的确定性样本数据回归。 - Portfolio tests:持仓止损、集中度、回撤、价格过旧等规则。 - Market tests:`MarketLightSnapshot` schema、红黄绿状态触发、日期/数据源标记。 - Notification tests:告警通知成功/失败记录、partial failure、敏感信息脱敏、冷却抑制。 - Docs:`git diff --check`,确认 `docs/CHANGELOG.md` `[Unreleased]` 扁平格式。 - Workflow:若新增 GitHub Actions env 或定时行为,补 `.github/workflows/daily_analysis.yml` 映射和静态测试。 ## Non-goals - 不实现自动交易、自动下单或券商委托。 - 不重写 `NotificationService`;通知路由、长尾渠道和通用降噪以 #1200 为主线。 - 不把大盘复盘 2.0 放进本 issue 完整实现;本 issue 只消费结构化 Market Light 快照。 - 不在首版实现任意表达式 DSL 或用户上传脚本,避免安全和维护风险。 - 不要求用户必须配置告警才能继续使用每日分析、问股、大盘复盘或持仓功能。 - 不在 P0/P1 中实现所有技术指标、所有市场、所有数据源和所有通知策略。 - 不自动迁移、删除或覆盖用户现有 `AGENT_EVENT_ALERT_RULES_JSON`。 - 不在 README 扩写告警细节;详细内容进入 `docs/alerts.md`。 - 不在一个 PR 中完成所有 Phase。
Summary
本 issue 只解决图片中的「实时告警中心」规划,不实现「通知渠道网关」和「大盘复盘 2.0」。但告警通知投递会复用现有
NotificationService,后续也可以接入 #1200 的通知路由、测试与降噪能力;大盘红绿灯联动则依赖 #1177 已合入的 Market Light 基础能力,并在后续 Phase 中要求补齐可复用结构化快照。目标不是重写现有
EventMonitor,而是在当前src/agent/events.py、schedule 后台轮询、系统配置、通知发送和 Web 设置页基础上,补齐产品化告警闭环:可管理规则、可测试、可追踪触发历史、可记录通知结果、可冷却降噪,并逐步覆盖技术指标、持仓风险和大盘红绿灯联动。当前基线:
EventMonitor运行时已存在,当前支持三类规则:price_cross、price_change_percent、volume_spike。AGENT_EVENT_MONITOR_ENABLED、AGENT_EVENT_MONITOR_INTERVAL_MINUTES、AGENT_EVENT_ALERT_RULES_JSON已进入配置加载、config registry 和系统配置校验。EventMonitor并通过后台任务定时执行,触发后复用NotificationService.send()。risk_alerts是分析报告/Agent 情报里的风险文案,不等同于用户可管理的告警规则。MarketLightSnapshotpayload 供 API、Web、Agent 和告警规则复用。默认兼容规则:
AGENT_EVENT_ALERT_RULES_JSON配置行为不变。.env/ Web 配置。Key Changes
P0:告警中心基线、模型契约与兼容边界
先建立真实基线和数据契约,不做 Web 大改,也不重写通知框架。
docs/alerts.md骨架,包含目录、现有 EventMonitor 基线、规则类型表、Phase 规划和兼容说明。alert_rule、alert_trigger、alert_notification、alert_cooldown。AGENT_EVENT_ALERT_RULES_JSONlegacy 配置路径,先作为运行时兼容来源,不在 P0 做自动迁移。P1:Alert API MVP
新增最小 API 表面,先覆盖已有三类规则,不一次性支持全部技术指标。
api/v1/endpoints/alerts.py并挂载到 v1 router。api/v1/schemas/alerts.py,定义规则、触发、通知和测试响应 schema。GET /api/v1/alerts/rulesPOST /api/v1/alerts/rulesPATCH /api/v1/alerts/rules/{rule_id}DELETE /api/v1/alerts/rules/{rule_id}POST /api/v1/alerts/rules/{rule_id}/enablePOST /api/v1/alerts/rules/{rule_id}/disablePOST /api/v1/alerts/rules/{rule_id}/testGET /api/v1/alerts/triggersGET /api/v1/alerts/notificationstest接口只执行一次规则评估,不写入真实触发记录,除非请求显式要求保存 dry-run 结果。price_cross、price_change_percent、volume_spike;其他类型返回结构化 unsupported 错误。P2:告警评估 Worker 与运行时统一
将 Web/API 创建的规则接入后台评估,同时保持 legacy 配置兼容。
AGENT_EVENT_ALERT_RULES_JSON。P3:Web 告警中心 MVP
新增独立 Web 入口,让用户能不用编辑 JSON 就管理告警。
apps/dsa-web/对应路由下。P4:触发历史、通知结果与冷却状态
让告警可排障、可降噪。
alert_trigger,包括 observed value、threshold、reason、source、data_timestamp。alert_notification,包括 channel、success、error_code、retryable、latency_ms、attempt。P5:技术指标规则
扩展到用户在 #1132 中提到的自定义指标推送场景。
P6:持仓与自选股联动
把告警从“单个手工标的”扩展到用户真实持仓和 watchlist。
P7:大盘红绿灯与市场联动
复用大盘复盘输出,让告警能覆盖市场级风险。
MarketLightSnapshot稳定 schema:region、trade_date、status、score、dimensions、reasons、guidance、data_quality。P8:告警文档、迁移与收口
在 API、Web、worker、通知和联动能力稳定后做完整收口。
docs/alerts.md,按场景分节:## 本地配置## Docker## GitHub Actions## Web 使用## DesktopAGENT_EVENT_ALERT_RULES_JSON兼容关系.env。.env.example、相关 docs 和docs/CHANGELOG.md。Progress
price_change_percent事件告警规则,复用现有 EventMonitorAcceptance Criteria
docs/alerts.md说明现有 EventMonitor 基线、legacy 配置、实体模型和 Phase 边界。AGENT_EVENT_ALERT_RULES_JSON兼容行为未被破坏。price_cross、price_change_percent、volume_spike。MarketLightSnapshot,支持红灯/黄灯或 score 变化触发。.env.example、config registry、Web 文案、docs、docs/CHANGELOG.md同步。Refs #<issue>,不在单个 Phase PR 中关闭 umbrella issue。Test Plan
./scripts/ci_gate.sh。cd apps/dsa-web && npm ci && npm run lint && npm run build。MarketLightSnapshotschema、红黄绿状态触发、日期/数据源标记。git diff --check,确认docs/CHANGELOG.md[Unreleased]扁平格式。.github/workflows/daily_analysis.yml映射和静态测试。Non-goals
NotificationService;通知路由、长尾渠道和通用降噪以 [Feature] DSA 后续开发规划:[通知渠道网关] 渠道基线、测试、Body 模板、路由、降噪与长尾渠道扩展 #1200 为主线。AGENT_EVENT_ALERT_RULES_JSON。docs/alerts.md。