|
|
@@ -0,0 +1,1295 @@
|
|
|
+# S8 九宫格异常权威数据与模块灯态根治执行任务书
|
|
|
+
|
|
|
+> 文档状态:已执行
|
|
|
+> 编制日期:2026-09-30
|
|
|
+> 执行版本:server `1.0.596`、Web `2.4.415`
|
|
|
+> 当前基线:server `1.0.595`、Web `2.4.414`、HEAD `294e32e1d`
|
|
|
+> 适用入口:FUNC-S9-005 九宫格智慧运营看板、S8 异常监控看板、FUNC-S8-008 异常列表
|
|
|
+> 目标读者:可直接修改本仓库并执行测试、构建、提交和推送的其它大模型/开发者
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 0. 执行前硬约束
|
|
|
+
|
|
|
+1. 先读取 `AGENTS.md` 及 `.cursor/rules/` 下全部 `alwaysApply` 规则。
|
|
|
+2. 修改前重新核对 HEAD、版本和全部工作区状态;不得覆盖或提交他人改动。
|
|
|
+3. 按仓库协作规则先向用户列出精确改动清单,得到确认后再应用补丁。
|
|
|
+4. 本任务默认交付根治方案,禁止:
|
|
|
+ - 给 `ado_s8_alert_record` 回填数据;
|
|
|
+ - 新增异常到旧表的双写链路;
|
|
|
+ - 把“未监测”“规则暂停”“检测过期”显示成绿色;
|
|
|
+ - 用 KPI 是否达标推断 S8 监控灯态;
|
|
|
+ - 用 `last_detected_at` 或每次轮询产生的 `REFRESHED` 次数统计“每日新增异常”;
|
|
|
+ - 直接修改 `ado_s8_exception`、`ado_s8_watch_rule` 业务数据来让页面变色;
|
|
|
+ - 复制其它租户异常或监控规则;
|
|
|
+ - 在前端写死 S1–S7 红黄绿状态。
|
|
|
+5. 若实际基线已不再是 server `1.0.595` / Web `2.4.414`,版本号按当前版本顺延,不得覆盖或降号。
|
|
|
+6. 本任务涉及前后端运行代码。执行提交时:
|
|
|
+ - server patch `+1`;
|
|
|
+ - Web patch `+1`;
|
|
|
+ - 锁文件若因版本更新发生变化,须与 `package.json` 一并提交。
|
|
|
+7. 用户说“提交”即 commit + push。不得使用 `git add .`,不得提交:
|
|
|
+ - `bin/`、`obj/`、`TestResults/`;
|
|
|
+ - `_tmp_*.log`、`frontend-dev.log`;
|
|
|
+ - `~$*.docx`;
|
|
|
+ - 口令、连接串、JWT、Cookie 或其它秘密。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 任务目标
|
|
|
+
|
|
|
+本任务同时根治两个同源问题:
|
|
|
+
|
|
|
+1. 九宫格 S8 区域显示“暂无异常告警”和 7 日 0 趋势,但 S8 当前异常主表实际存在未关闭异常。
|
|
|
+2. S8 区域内 S1–S7 七个模块灯全部硬编码为 `unknown`,不能表达:
|
|
|
+ - 当前是否有未关闭异常;
|
|
|
+ - 是否存在严重异常;
|
|
|
+ - 模块是否配置监控;
|
|
|
+ - 监控规则是否正常、暂停、失败或陈旧。
|
|
|
+
|
|
|
+最终要求:
|
|
|
+
|
|
|
+- S8 告警列表、区间汇总、每日趋势统一读取当前异常权威表 `ado_s8_exception`。
|
|
|
+- S1–S7 灯态使用“双维度表达”:
|
|
|
+ - **灯芯**:业务异常状态;
|
|
|
+ - **外圈/徽标**:监控运行状态。
|
|
|
+- 用户点击模块灯后进入 FUNC-S8-008 异常列表,并按对应 `stageCode=S1..S7` 自动过滤。
|
|
|
+- 所有数字都来自真实异常和真实规则状态,不造数、不回填旧表。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 已取证事实
|
|
|
+
|
|
|
+### 2.1 代码层
|
|
|
+
|
|
|
+#### 2.1.1 九宫格 S8 当前读取旧表
|
|
|
+
|
|
|
+调用链:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/dashboard/home.vue
|
|
|
+ ├─ fetchS8Alerts()
|
|
|
+ │ └─ GET /api/AidopKanban/s8-alerts
|
|
|
+ └─ fetchS8HomeTrend()
|
|
|
+ └─ GET /api/AidopKanban/s8-home-trend
|
|
|
+```
|
|
|
+
|
|
|
+后端 `AidopKanbanController.cs` 中:
|
|
|
+
|
|
|
+- `GetS8Alerts` 查询 `ado_s8_alert_record`;
|
|
|
+- `GetS8AlertSummary` 查询 `ado_s8_alert_record`;
|
|
|
+- `GetS8HomeTrend` 查询 `ado_s8_alert_record`。
|
|
|
+
|
|
|
+全仓现状:
|
|
|
+
|
|
|
+- `ado_s8_alert_record` 只有读取方;
|
|
|
+- 当前 `server/` 下无正常业务 INSERT 产出链;
|
|
|
+- 因而该表不能作为当前 S8 告警 Authority。
|
|
|
+
|
|
|
+#### 2.1.2 当前异常 Authority 已是 `ado_s8_exception`
|
|
|
+
|
|
|
+下列现行能力均读取或写入 `ado_s8_exception`:
|
|
|
+
|
|
|
+- `S8MonitoringService`;
|
|
|
+- `S8DashboardService`;
|
|
|
+- `S8ExceptionService`;
|
|
|
+- `S8KpiSnapshotService`;
|
|
|
+- `S8OrderFlowService`;
|
|
|
+- 智慧诊断 S8 证据;
|
|
|
+- 规则检测、异常建单、处理闭环。
|
|
|
+
|
|
|
+实体:
|
|
|
+
|
|
|
+```text
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S8/AdoS8Exception.cs
|
|
|
+```
|
|
|
+
|
|
|
+关键字段:
|
|
|
+
|
|
|
+- `tenant_id`
|
|
|
+- `factory_id`(S8 tenant-only 终态下恒为全局工厂值 `0`)
|
|
|
+- `title`
|
|
|
+- `description`
|
|
|
+- `status`
|
|
|
+- `severity`
|
|
|
+- `created_at`
|
|
|
+- `closed_at`
|
|
|
+- `last_detected_at`
|
|
|
+- `module_code`
|
|
|
+- `stage_code`
|
|
|
+- `related_object_code`
|
|
|
+- `source_object_type`
|
|
|
+- `source_object_id`
|
|
|
+- `source_payload`
|
|
|
+
|
|
|
+#### 2.1.3 七个灯当前全部硬编码
|
|
|
+
|
|
|
+`Web/src/views/dashboard/home.vue` 中 `s8ModuleStatus` 固定为:
|
|
|
+
|
|
|
+```ts
|
|
|
+[
|
|
|
+ { code: 'S1', level: 'unknown', route: 's1' },
|
|
|
+ // ...
|
|
|
+ { code: 'S7', level: 'unknown', route: 's7' }
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+现状行为:
|
|
|
+
|
|
|
+- 颜色统一中性灰;
|
|
|
+- tooltip 为“未监测(暂无模块健康数据)”;
|
|
|
+- 不请求后端;
|
|
|
+- 点击只跳普通模块页面。
|
|
|
+
|
|
|
+#### 2.1.4 异常列表后端已支持 `StageCode`
|
|
|
+
|
|
|
+`AdoS8ExceptionQueryDto.StageCode` 已存在,`S8ExceptionService` 已按:
|
|
|
+
|
|
|
+```csharp
|
|
|
+e.StageCode == q.StageCode
|
|
|
+```
|
|
|
+
|
|
|
+过滤。
|
|
|
+
|
|
|
+但 `S8ExceptionListPage.vue` 当前:
|
|
|
+
|
|
|
+- 未从路由读取 `stageCode`;
|
|
|
+- `loadList()` 未把 `stageCode` 传给 `s8ExceptionApi.list()`。
|
|
|
+
|
|
|
+因此灯态下钻仍需补前端路由接收。
|
|
|
+
|
|
|
+### 2.2 配置层
|
|
|
+
|
|
|
+2026-09-29 对租户 `838257186181189` 的只读取证:
|
|
|
+
|
|
|
+| 项目 | 结果 |
|
|
|
+|---|---:|
|
|
|
+| S8 场景 | 7 条启用 |
|
|
|
+| 监控指标 | 平台/租户合计 13 条,8 条启用 |
|
|
|
+| 监控规则 | 3 条 |
|
|
|
+| 启用且可运行规则 | 2 条 |
|
|
|
+| S1 规则 | 启用,最近 `SUCCESS` |
|
|
|
+| S2 规则 | 启用,最近 `SUCCESS` |
|
|
|
+| S4 规则 | 停用/自动暂停 |
|
|
|
+| S3/S5/S6/S7 | 没有启用规则 |
|
|
|
+
|
|
|
+这证明“页面为空是因为完全没有监控项”不成立。
|
|
|
+
|
|
|
+### 2.3 数据层
|
|
|
+
|
|
|
+同一租户只读取证:
|
|
|
+
|
|
|
+| 表/事实 | 结果 |
|
|
|
+|---|---:|
|
|
|
+| `ado_s8_alert_record` 当前有效行 | 0 |
|
|
|
+| `ado_s8_exception` 未删除异常 | 34 |
|
|
|
+| S1 `FOLLOW` 未关闭异常 | 2 |
|
|
|
+| S2 `SERIOUS` 未关闭异常 | 3 |
|
|
|
+| S4 `SERIOUS` 未关闭异常 | 29 |
|
|
|
+
|
|
|
+规则检测日志最近持续产生 `REFRESHED`,说明检测链在运行;首页为空是读错 Authority,不是检测链完全没有数据。
|
|
|
+
|
|
|
+### 2.4 可重跑基线 SQL
|
|
|
+
|
|
|
+执行前必须重新运行并保存结果。只允许 SELECT:
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 1. 旧表是否仍为空
|
|
|
+SELECT COUNT(*) AS active_alert_count,
|
|
|
+ MAX(alert_time) AS latest_alert_time
|
|
|
+FROM ado_s8_alert_record
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND is_deleted = 0
|
|
|
+ AND is_active = 1;
|
|
|
+```
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 2. 当前异常按阶段和严重度分布
|
|
|
+SELECT stage_code,
|
|
|
+ severity,
|
|
|
+ COUNT(*) AS cnt,
|
|
|
+ MAX(COALESCE(last_detected_at, created_at)) AS latest_seen
|
|
|
+FROM ado_s8_exception
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND is_deleted = 0
|
|
|
+ AND status NOT IN ('CLOSED', 'REJECTED', 'RECOVERED')
|
|
|
+GROUP BY stage_code, severity
|
|
|
+ORDER BY stage_code, severity;
|
|
|
+```
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 3. 规则覆盖和运行态
|
|
|
+SELECT stage_code,
|
|
|
+ enabled,
|
|
|
+ COUNT(*) AS rule_count,
|
|
|
+ MAX(last_run_at) AS latest_run,
|
|
|
+ GROUP_CONCAT(DISTINCT IFNULL(last_status, 'NULL')) AS statuses,
|
|
|
+ MAX(paused_until) AS max_paused_until
|
|
|
+FROM ado_s8_watch_rule
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+GROUP BY stage_code, enabled
|
|
|
+ORDER BY stage_code, enabled;
|
|
|
+```
|
|
|
+
|
|
|
+```sql
|
|
|
+-- 4. 最近 24 小时检测结果;REFRESHED 只能证明检测刷新,不能作为新增异常趋势
|
|
|
+SELECT rule_code,
|
|
|
+ detect_result,
|
|
|
+ COUNT(*) AS cnt,
|
|
|
+ MAX(detected_at) AS latest_detected
|
|
|
+FROM ado_s8_detection_log
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND detected_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)
|
|
|
+GROUP BY rule_code, detect_result
|
|
|
+ORDER BY rule_code, detect_result;
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 冻结架构决策
|
|
|
+
|
|
|
+执行者不得在实现时重新设计以下口径。
|
|
|
+
|
|
|
+### 3.1 唯一 Authority
|
|
|
+
|
|
|
+| 能力 | Authority |
|
|
|
+|---|---|
|
|
|
+| 当前异常、异常标题、严重度、状态 | `ado_s8_exception` |
|
|
|
+| 模块监控覆盖、启停、最近运行结果 | `ado_s8_watch_rule` |
|
|
|
+| 规则每次检测审计 | `ado_s8_detection_log` |
|
|
|
+| 旧首页告警表 | `ado_s8_alert_record`,停止作为运行期 Authority |
|
|
|
+
|
|
|
+禁止给旧表补写入链路。旧表是否后续物理删除属于独立迁移任务,本任务不 DROP。
|
|
|
+
|
|
|
+### 3.2 三种时间语义必须分开
|
|
|
+
|
|
|
+1. **重点告警列表排序时间**
|
|
|
+ - `COALESCE(last_detected_at, created_at)`;
|
|
|
+ - 用于把最近仍被命中的当前异常排到前面。
|
|
|
+2. **今日/区间新增预警数**
|
|
|
+ - 只按 `created_at`;
|
|
|
+ - 表示该窗口内新建了多少异常。
|
|
|
+3. **每日异常趋势**
|
|
|
+ - 只按 `DATE(created_at)`;
|
|
|
+ - 表示每日新增异常数。
|
|
|
+
|
|
|
+禁止:
|
|
|
+
|
|
|
+- 用 `last_detected_at` 聚合趋势;
|
|
|
+- 把每轮 `REFRESHED` 算成一条新异常;
|
|
|
+- 用当前 34 条异常的最后刷新时间全部堆到今天。
|
|
|
+
|
|
|
+### 3.3 当前异常集合
|
|
|
+
|
|
|
+灯态和“重点告警列表”的当前异常定义固定为:
|
|
|
+
|
|
|
+```text
|
|
|
+is_deleted = 0
|
|
|
+AND status NOT IN ('CLOSED', 'REJECTED', 'RECOVERED')
|
|
|
+```
|
|
|
+
|
|
|
+说明:
|
|
|
+
|
|
|
+- `RESOLVED`、`PENDING_VERIFICATION` 仍未闭环,应继续属于当前异常;
|
|
|
+- `CLOSED` 已闭环;
|
|
|
+- `REJECTED` 不应继续作为当前有效异常;
|
|
|
+- `RECOVERED` 在部分现行服务中仍作为兼容状态使用,即使字典未展示,也必须排除。
|
|
|
+
|
|
|
+区间汇总和历史趋势不排除已关闭项,因为它们统计的是窗口内“新增异常”,不是当前未闭环存量。
|
|
|
+
|
|
|
+### 3.4 S8 tenant-only 作用域
|
|
|
+
|
|
|
+S8 当前终态是租户级规则和异常:
|
|
|
+
|
|
|
+- 租户来自认证上下文;
|
|
|
+- 不信任客户端 `tenantId`;
|
|
|
+- `factory_id=0` 是租户级兼容值;
|
|
|
+- 新接口不要再把页面传入的 `factoryId=1` 当作过滤 Authority。
|
|
|
+
|
|
|
+禁止为让数据出现而写:
|
|
|
+
|
|
|
+```sql
|
|
|
+factory_id IN (0, @factoryId)
|
|
|
+```
|
|
|
+
|
|
|
+并把它当成长期口径。应明确按 tenant-only Authority 查询。
|
|
|
+
|
|
|
+### 3.5 严重度映射
|
|
|
+
|
|
|
+S8 当前业务枚举只有:
|
|
|
+
|
|
|
+- `FOLLOW`:关注;
|
|
|
+- `SERIOUS`:严重。
|
|
|
+
|
|
|
+保持现有前端告警行契约:
|
|
|
+
|
|
|
+| S8 severity | API level | 前端颜色 |
|
|
|
+|---|---|---|
|
|
|
+| `SERIOUS` | `critical` | 红 |
|
|
|
+| `FOLLOW` | `medium` | 黄 |
|
|
|
+
|
|
|
+兼容历史值时必须调用或等价复用 `S8SeverityCode.Normalize`,不得另写一套互相矛盾的映射。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. S1–S7 双维度灯态设计
|
|
|
+
|
|
|
+### 4.1 为什么不能只做一个红黄绿字段
|
|
|
+
|
|
|
+单一颜色无法区分:
|
|
|
+
|
|
|
+- 没有异常且监控正常;
|
|
|
+- 没有异常但根本没有监控;
|
|
|
+- 异常仍存在但规则已暂停;
|
|
|
+- 异常仍存在且监控结果已经过期。
|
|
|
+
|
|
|
+因此必须拆成:
|
|
|
+
|
|
|
+```text
|
|
|
+灯芯 businessState:业务异常状态
|
|
|
+外圈 monitorState:监控运行状态
|
|
|
+```
|
|
|
+
|
|
|
+### 4.2 灯芯 `businessState`
|
|
|
+
|
|
|
+固定枚举:
|
|
|
+
|
|
|
+```text
|
|
|
+CRITICAL
|
|
|
+WARNING
|
|
|
+NORMAL
|
|
|
+UNKNOWN
|
|
|
+```
|
|
|
+
|
|
|
+判定优先级:
|
|
|
+
|
|
|
+1. 当前异常中 `SERIOUS > 0` → `CRITICAL`
|
|
|
+2. 否则当前异常中 `FOLLOW > 0` → `WARNING`
|
|
|
+3. 否则 `monitorState == HEALTHY` → `NORMAL`
|
|
|
+4. 其它情况 → `UNKNOWN`
|
|
|
+
|
|
|
+对应展示:
|
|
|
+
|
|
|
+| businessState | 灯芯 | 语义 |
|
|
|
+|---|---|---|
|
|
|
+| `CRITICAL` | 红 | 有严重未关闭异常 |
|
|
|
+| `WARNING` | 黄 | 有关注未关闭异常,无严重异常 |
|
|
|
+| `NORMAL` | 绿 | 有有效监控且新鲜,当前无未关闭异常 |
|
|
|
+| `UNKNOWN` | 灰 | 不能证明正常 |
|
|
|
+
|
|
|
+硬规则:只有 `monitorState=HEALTHY` 且当前异常为 0 时才允许绿色。
|
|
|
+
|
|
|
+### 4.3 外圈 `monitorState`
|
|
|
+
|
|
|
+固定枚举:
|
|
|
+
|
|
|
+```text
|
|
|
+HEALTHY
|
|
|
+DEGRADED
|
|
|
+PAUSED
|
|
|
+UNMONITORED
|
|
|
+```
|
|
|
+
|
|
|
+规则级健康定义:
|
|
|
+
|
|
|
+```text
|
|
|
+runnable =
|
|
|
+ enabled = 1
|
|
|
+ AND (paused_until IS NULL OR paused_until <= now)
|
|
|
+
|
|
|
+freshWindowSeconds = MAX(poll_interval_seconds * 2, 600)
|
|
|
+
|
|
|
+healthyRule =
|
|
|
+ runnable
|
|
|
+ AND last_status = 'SUCCESS'
|
|
|
+ AND last_run_at IS NOT NULL
|
|
|
+ AND now - last_run_at <= freshWindowSeconds
|
|
|
+```
|
|
|
+
|
|
|
+模块级聚合:
|
|
|
+
|
|
|
+1. 该模块没有任何规则 → `UNMONITORED`
|
|
|
+2. 有规则,但没有 runnable 规则 → `PAUSED`
|
|
|
+3. 有 runnable 规则,但任一规则:
|
|
|
+ - `last_status='FAILED'`;
|
|
|
+ - `last_run_at IS NULL`;
|
|
|
+ - 超出 `freshWindowSeconds`;
|
|
|
+ → `DEGRADED`
|
|
|
+4. 所有 runnable 规则均 healthy → `HEALTHY`
|
|
|
+
|
|
|
+展示规范:
|
|
|
+
|
|
|
+| monitorState | 外圈/徽标 | 禁止误解 |
|
|
|
+|---|---|---|
|
|
|
+| `HEALTHY` | 实线正常外圈 | 正在正常检测 |
|
|
|
+| `DEGRADED` | 橙色虚线或时钟/警告徽标 | 检测失败或过期 |
|
|
|
+| `PAUSED` | 灰色虚线 + 暂停徽标 | 有规则但未运行 |
|
|
|
+| `UNMONITORED` | 无外圈或灰色空心外圈 | 未配置监控 |
|
|
|
+
|
|
|
+异常颜色不得被外圈覆盖。例如:
|
|
|
+
|
|
|
+```text
|
|
|
+S4 = 红色灯芯 + 暂停外圈
|
|
|
+```
|
|
|
+
|
|
|
+表示“严重异常仍在,但规则已经暂停”,不能显示灰灯掩盖 29 条严重异常。
|
|
|
+
|
|
|
+### 4.4 当前基线的预期灯态
|
|
|
+
|
|
|
+若执行时数据未变化,UAT 租户应为:
|
|
|
+
|
|
|
+| 模块 | 业务异常 | 监控态 | 预期 |
|
|
|
+|---|---|---|---|
|
|
|
+| S1 | 2 条 FOLLOW | HEALTHY | 黄灯芯 + 正常外圈 |
|
|
|
+| S2 | 3 条 SERIOUS | HEALTHY | 红灯芯 + 正常外圈 |
|
|
|
+| S3 | 0 | UNMONITORED | 灰灯,无监控 |
|
|
|
+| S4 | 29 条 SERIOUS | PAUSED | 红灯芯 + 暂停外圈 |
|
|
|
+| S5 | 0 | UNMONITORED | 灰灯,无监控 |
|
|
|
+| S6 | 0 | UNMONITORED | 灰灯,无监控 |
|
|
|
+| S7 | 0 | UNMONITORED | 灰灯,无监控 |
|
|
|
+
|
|
|
+数据可能随检测和处理变化。验收必须按同一时刻 SQL 结果计算预期,禁止把上表数字写死进测试或前端。
|
|
|
+
|
|
|
+### 4.5 Tooltip
|
|
|
+
|
|
|
+前端根据结构化字段生成,不由后端返回整段中文。
|
|
|
+
|
|
|
+示例:
|
|
|
+
|
|
|
+```text
|
|
|
+S1:关注异常 2 条;监控正常;最后检测 2026-09-29 23:41
|
|
|
+S4:严重异常 29 条;监控规则已暂停;最后成功检测 2026-09-23 14:57
|
|
|
+S5:未配置监控规则;当前状态未知
|
|
|
+```
|
|
|
+
|
|
|
+至少显示:
|
|
|
+
|
|
|
+- 模块码和模块名;
|
|
|
+- 严重/关注/当前异常总数;
|
|
|
+- 监控态;
|
|
|
+- 最近运行时间;
|
|
|
+- 规则数;
|
|
|
+- 暂停或降级原因码。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 后端接口设计
|
|
|
+
|
|
|
+### 5.1 新增统一查询服务
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```text
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/S8HomeAlertQueryService.cs
|
|
|
+```
|
|
|
+
|
|
|
+职责:
|
|
|
+
|
|
|
+1. 统一当前异常 Authority;
|
|
|
+2. 统一活动状态集合;
|
|
|
+3. 统一 severity 映射;
|
|
|
+4. 统一基础查询文本过滤;
|
|
|
+5. 提供:
|
|
|
+ - 最近重点异常;
|
|
|
+ - 区间新增汇总;
|
|
|
+ - 每日新增趋势;
|
|
|
+ - S1–S7 灯态。
|
|
|
+
|
|
|
+禁止把三套 SQL 继续散落在 Controller 中独立演进。
|
|
|
+
|
|
|
+服务使用当前 DI 模式实现为 `ITransient`。可注入:
|
|
|
+
|
|
|
+- `ISqlSugarClient`;或
|
|
|
+- `SqlSugarRepository<AdoS8Exception>` + `SqlSugarRepository<AdoS8WatchRule>`。
|
|
|
+
|
|
|
+选择须与同目录服务风格一致。不得自行创建静态连接或第二套 DbContext。
|
|
|
+
|
|
|
+### 5.2 保留现有三个 API 契约
|
|
|
+
|
|
|
+#### `GET /api/AidopKanban/s8-alerts`
|
|
|
+
|
|
|
+响应字段保持:
|
|
|
+
|
|
|
+```json
|
|
|
+[
|
|
|
+ {
|
|
|
+ "time": "23:41",
|
|
|
+ "module": "S1",
|
|
|
+ "message": "异常标题",
|
|
|
+ "level": "medium",
|
|
|
+ "levelLabel": "关注"
|
|
|
+ }
|
|
|
+]
|
|
|
+```
|
|
|
+
|
|
|
+规则:
|
|
|
+
|
|
|
+- 数据源改为 `ado_s8_exception`;
|
|
|
+- 只返回当前异常;
|
|
|
+- 按 `COALESCE(last_detected_at, created_at) DESC, id DESC`;
|
|
|
+- `LIMIT 6`;
|
|
|
+- `module` 优先 `stage_code`,其次 `module_code`,最后 `S8`;
|
|
|
+- `message` 优先 `title`,空时回落 `description`,再回落“异常告警”;
|
|
|
+- `SERIOUS → critical/严重`;
|
|
|
+- `FOLLOW → medium/关注`。
|
|
|
+
|
|
|
+#### `GET /api/AidopKanban/s8-alert-summary`
|
|
|
+
|
|
|
+响应契约保持:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "windowStart": "2026-09-30",
|
|
|
+ "windowEnd": "2026-09-30",
|
|
|
+ "isToday": true,
|
|
|
+ "total": 3,
|
|
|
+ "critical": 2
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+规则:
|
|
|
+
|
|
|
+- 按 `created_at` 半开窗口 `[windowStart, windowEnd)`;
|
|
|
+- `total` = 该窗口新建异常数;
|
|
|
+- `critical` = 该窗口新建 `SERIOUS` 异常数;
|
|
|
+- 不带 `LIMIT`;
|
|
|
+- 不按当前状态过滤,避免异常关闭后历史新增数被改写。
|
|
|
+
|
|
|
+#### `GET /api/AidopKanban/s8-home-trend`
|
|
|
+
|
|
|
+响应契约保持:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "title": "近 7 日异常趋势",
|
|
|
+ "points": [
|
|
|
+ { "date": "09/24", "count": 0 }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+规则:
|
|
|
+
|
|
|
+- 按 `DATE(created_at)` 聚合;
|
|
|
+- 没有新增异常的日期补 0;
|
|
|
+- 默认最近 7 个服务器自然日;
|
|
|
+- 继续保留当前最大日期跨度保护;
|
|
|
+- 不按当前状态过滤;
|
|
|
+- 不使用 `last_detected_at`;
|
|
|
+- 不读取 `ado_s8_detection_log` 的 `REFRESHED` 次数。
|
|
|
+
|
|
|
+### 5.3 新增灯态接口
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+```http
|
|
|
+GET /api/AidopKanban/s8-module-lamps
|
|
|
+```
|
|
|
+
|
|
|
+不接受客户端 `tenantId`。租户从认证上下文读取。
|
|
|
+
|
|
|
+推荐响应:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "asOf": "2026-09-30T00:10:00+08:00",
|
|
|
+ "items": [
|
|
|
+ {
|
|
|
+ "code": "S1",
|
|
|
+ "name": "S1 产销协同",
|
|
|
+ "businessState": "WARNING",
|
|
|
+ "monitorState": "HEALTHY",
|
|
|
+ "seriousCount": 0,
|
|
|
+ "followCount": 2,
|
|
|
+ "openCount": 2,
|
|
|
+ "configuredRuleCount": 1,
|
|
|
+ "enabledRuleCount": 1,
|
|
|
+ "runnableRuleCount": 1,
|
|
|
+ "latestRunAt": "2026-09-29T23:41:07+08:00",
|
|
|
+ "monitorReasonCode": "OK"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+`items` 必须始终按 S1–S7 返回 7 条。没有异常/规则的模块也要返回结构化 `UNKNOWN + UNMONITORED`,前端不得自行补假状态。
|
|
|
+
|
|
|
+`monitorReasonCode` 固定建议:
|
|
|
+
|
|
|
+```text
|
|
|
+OK
|
|
|
+NO_RULE
|
|
|
+RULE_PAUSED
|
|
|
+RULE_DISABLED
|
|
|
+NEVER_RUN
|
|
|
+RUN_FAILED
|
|
|
+RUN_STALE
|
|
|
+```
|
|
|
+
|
|
|
+一个模块多规则时,按最差运行态返回原因;同时保留计数,便于 tooltip 解释。
|
|
|
+
|
|
|
+### 5.4 基础查询过滤
|
|
|
+
|
|
|
+原 `BuildS8AlertTextFilterSql()` 针对旧表的:
|
|
|
+
|
|
|
+- `message`
|
|
|
+- `metric_code`
|
|
|
+- `alert_code`
|
|
|
+
|
|
|
+必须替换为异常 Authority 字段:
|
|
|
+
|
|
|
+- `title`
|
|
|
+- `description`
|
|
|
+- `related_object_code`
|
|
|
+- `source_object_id`
|
|
|
+- `source_payload`
|
|
|
+- `exception_code`
|
|
|
+
|
|
|
+筛选语义:
|
|
|
+
|
|
|
+- `product`
|
|
|
+- `orderNo`
|
|
|
+- `productionLine`
|
|
|
+
|
|
|
+均在上述可追溯文本字段中匹配。
|
|
|
+
|
|
|
+参数必须参数化。禁止字符串拼接用户输入。
|
|
|
+
|
|
|
+若 `source_payload` 数据量导致性能问题,先通过真实 `EXPLAIN ANALYZE` 取证,再另立结构化投影/索引任务;本任务不得默默删掉筛选能力。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 前端设计
|
|
|
+
|
|
|
+### 6.1 API 与类型
|
|
|
+
|
|
|
+修改:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/aidop/api/kanbanData.ts
|
|
|
+```
|
|
|
+
|
|
|
+新增:
|
|
|
+
|
|
|
+- `S8ModuleLampItem`
|
|
|
+- `S8ModuleLampPayload`
|
|
|
+- `fetchS8ModuleLamps()`
|
|
|
+
|
|
|
+枚举用联合类型,不使用任意字符串:
|
|
|
+
|
|
|
+```ts
|
|
|
+type S8BusinessState = 'CRITICAL' | 'WARNING' | 'NORMAL' | 'UNKNOWN'
|
|
|
+type S8MonitorState = 'HEALTHY' | 'DEGRADED' | 'PAUSED' | 'UNMONITORED'
|
|
|
+```
|
|
|
+
|
|
|
+### 6.2 九宫格 S8
|
|
|
+
|
|
|
+修改:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/dashboard/home.vue
|
|
|
+```
|
|
|
+
|
|
|
+要求:
|
|
|
+
|
|
|
+1. 删除硬编码 `s8ModuleStatus` 状态;
|
|
|
+2. 初始化为结构化“加载中/未知”,不得闪现绿色;
|
|
|
+3. `loadS8Data()` 同时加载:
|
|
|
+ - 告警列表;
|
|
|
+ - 趋势;
|
|
|
+ - 模块灯态;
|
|
|
+4. 灯芯颜色只由 `businessState` 决定;
|
|
|
+5. 外圈/徽标只由 `monitorState` 决定;
|
|
|
+6. 请求失败:
|
|
|
+ - 不显示绿色;
|
|
|
+ - 统一显示灰色 `UNKNOWN`;
|
|
|
+ - tooltip 为“监控状态加载失败”,不得写“正常”;
|
|
|
+7. 保留 S1–S7 七项顺序;
|
|
|
+8. 使用后端 `asOf/latestRunAt`,不要前端猜服务端当前时间。
|
|
|
+
|
|
|
+### 6.3 下钻
|
|
|
+
|
|
|
+灯点击后跳转:
|
|
|
+
|
|
|
+```text
|
|
|
+/aidop/s8/exceptions?stageCode=S1
|
|
|
+```
|
|
|
+
|
|
|
+修改:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/aidop/s8/exceptions/S8ExceptionListPage.vue
|
|
|
+```
|
|
|
+
|
|
|
+要求:
|
|
|
+
|
|
|
+- `query` 增加 `stageCode`;
|
|
|
+- `onMounted` 和 `onActivated` 能读取路由 `stageCode`;
|
|
|
+- `loadList()` 传给后端;
|
|
|
+- reset 时清空;
|
|
|
+- 页面应有可见的阶段筛选状态,至少在查询条件摘要或筛选控件中展示,避免用户不知道为何只看到一个模块;
|
|
|
+- keep-alive 页面从 S1 灯切到 S2 灯时必须响应路由 query 变化,不得仍保留 S1 数据。
|
|
|
+
|
|
|
+不得新增 FUNC 编号:目标页已经登记为 FUNC-S8-008,详情页为 FUNC-S8-019。
|
|
|
+
|
|
|
+### 6.4 样式
|
|
|
+
|
|
|
+修改范围优先留在:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/dashboard/home.vue
|
|
|
+```
|
|
|
+
|
|
|
+建议 class:
|
|
|
+
|
|
|
+```text
|
|
|
+s8-mod__dot--critical
|
|
|
+s8-mod__dot--warning
|
|
|
+s8-mod__dot--normal
|
|
|
+s8-mod__dot--unknown
|
|
|
+s8-mod--monitor-healthy
|
|
|
+s8-mod--monitor-degraded
|
|
|
+s8-mod--monitor-paused
|
|
|
+s8-mod--monitor-unmonitored
|
|
|
+```
|
|
|
+
|
|
|
+无障碍要求:
|
|
|
+
|
|
|
+- 不能只靠颜色;
|
|
|
+- tooltip/title 必须写出“严重/关注/正常/未监测/暂停/过期”;
|
|
|
+- 暂停和降级有形状或徽标差异;
|
|
|
+- 键盘可聚焦并可进入异常列表。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 精确文件清单
|
|
|
+
|
|
|
+### 7.1 固定修改
|
|
|
+
|
|
|
+后端:
|
|
|
+
|
|
|
+```text
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/S8HomeAlertQueryService.cs 新增
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/AidopKanbanController.cs 修改
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP.Tests/S8/S8DashboardSemanticsTests.cs 修改
|
|
|
+server/Plugins/Admin.NET.Plugin.AiDOP.Tests/S8/S8HomeAlertQueryServiceTests.cs 新增
|
|
|
+server/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj 提交时升 patch
|
|
|
+```
|
|
|
+
|
|
|
+前端:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/aidop/api/kanbanData.ts
|
|
|
+Web/src/views/dashboard/home.vue
|
|
|
+Web/src/views/aidop/s8/exceptions/S8ExceptionListPage.vue
|
|
|
+Web/src/views/dashboard/home.s8-empty.spec.ts
|
|
|
+Web/src/views/aidop/kanban/dashboardSemantics.spec.ts
|
|
|
+Web/package.json 提交时升 patch
|
|
|
+```
|
|
|
+
|
|
|
+### 7.2 条件修改
|
|
|
+
|
|
|
+只有在现有测试布局明显不适合时才新增:
|
|
|
+
|
|
|
+```text
|
|
|
+Web/src/views/dashboard/home.s8-module-lamps.spec.ts
|
|
|
+```
|
|
|
+
|
|
|
+若 Controller 构造函数注入 `S8HomeAlertQueryService`:
|
|
|
+
|
|
|
+- 全仓检索 `new AidopKanbanController(`;
|
|
|
+- 有手工构造点则同步改;
|
|
|
+- 无调用点则在交付报告写明全仓零匹配。
|
|
|
+
|
|
|
+### 7.3 明确不改
|
|
|
+
|
|
|
+- `AdoS8Exception` 表结构;
|
|
|
+- `AdoS8WatchRule` 表结构;
|
|
|
+- 历史成功迁移;
|
|
|
+- 规则启停数据;
|
|
|
+- 异常业务数据;
|
|
|
+- `ado_s8_alert_record` 数据;
|
|
|
+- S1–S7 KPI 计算;
|
|
|
+- S8 规则 Provider;
|
|
|
+- 菜单种子和 FUNC 编号。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 工作包
|
|
|
+
|
|
|
+### WP-A:Authority 收口
|
|
|
+
|
|
|
+1. 新建 `S8HomeAlertQueryService`。
|
|
|
+2. 将列表、汇总、趋势迁入服务。
|
|
|
+3. Controller 只负责:
|
|
|
+ - 认证租户解析;
|
|
|
+ - 查询参数转换;
|
|
|
+ - 返回 HTTP 结果。
|
|
|
+4. 删除或改写 `BuildS8AlertTextFilterSql()`,不得保留旧表字段残渣。
|
|
|
+5. 全仓检索 `ado_s8_alert_record`:
|
|
|
+ - 本任务三个端点不得再命中;
|
|
|
+ - 其它遗留读取点逐条报告,未经确认不顺手扩大范围。
|
|
|
+
|
|
|
+验收:
|
|
|
+
|
|
|
+```text
|
|
|
+s8-alerts → 当前未关闭异常
|
|
|
+s8-alert-summary → created_at 窗口新增数
|
|
|
+s8-home-trend → created_at 每日新增数
|
|
|
+```
|
|
|
+
|
|
|
+### WP-B:灯态聚合
|
|
|
+
|
|
|
+1. 服务一次读取租户的 S1–S7 当前异常;
|
|
|
+2. 一次读取该租户规则;
|
|
|
+3. 内存按 7 个模块聚合;
|
|
|
+4. 不允许每模块两次查询造成 N+1;
|
|
|
+5. 按 §4 固定优先级计算。
|
|
|
+
|
|
|
+必须使用单一 `now` 快照,避免 7 个模块判定跨秒漂移。
|
|
|
+
|
|
|
+### WP-C:前端双维度展示
|
|
|
+
|
|
|
+1. 接入新接口;
|
|
|
+2. 删除硬编码 `unknown` 数组;
|
|
|
+3. 实现灯芯和外圈;
|
|
|
+4. 请求失败 fail-closed;
|
|
|
+5. tooltip 使用结构化字段。
|
|
|
+
|
|
|
+### WP-D:下钻
|
|
|
+
|
|
|
+1. 点击灯跳 FUNC-S8-008;
|
|
|
+2. 路由带 `stageCode`;
|
|
|
+3. 异常列表页解析并透传;
|
|
|
+4. keep-alive 和路由切换正确刷新;
|
|
|
+5. 返回列表后筛选条件仍可解释。
|
|
|
+
|
|
|
+### WP-E:回归与真实数据验收
|
|
|
+
|
|
|
+1. 重跑基线 SQL;
|
|
|
+2. 用同一时刻数据计算预期灯态;
|
|
|
+3. 登录 UATAdminA 验证;
|
|
|
+4. 截图必须同时显示:
|
|
|
+ - S1 黄色;
|
|
|
+ - S2 红色;
|
|
|
+ - S4 红色且有暂停外圈;
|
|
|
+ - 无规则模块灰色;
|
|
|
+5. 点击 S1/S2/S4 分别验证列表过滤;
|
|
|
+6. 不得因数据之后变化而把具体数量写死为测试断言。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 9. 测试要求
|
|
|
+
|
|
|
+### 9.1 后端服务单元测试
|
|
|
+
|
|
|
+新增 `S8HomeAlertQueryServiceTests.cs`,至少覆盖:
|
|
|
+
|
|
|
+1. `SERIOUS` 优先于 `FOLLOW`;
|
|
|
+2. 只有 FOLLOW → WARNING;
|
|
|
+3. 无异常 + 所有 runnable 规则新鲜成功 → NORMAL;
|
|
|
+4. 无规则 → UNKNOWN + UNMONITORED;
|
|
|
+5. 有规则但全停用/暂停 → PAUSED;
|
|
|
+6. 最近状态失败 → DEGRADED;
|
|
|
+7. 从未运行 → DEGRADED;
|
|
|
+8. `last_run_at` 超过 `max(2*poll, 600s)` → DEGRADED;
|
|
|
+9. S4 严重异常 + 规则暂停 → CRITICAL + PAUSED;
|
|
|
+10. `CLOSED/REJECTED/RECOVERED` 不计当前异常;
|
|
|
+11. 7 个模块总是完整、排序稳定;
|
|
|
+12. 同一 `now` 参与全部判定。
|
|
|
+
|
|
|
+### 9.2 后端契约测试
|
|
|
+
|
|
|
+更新 `S8DashboardSemanticsTests.cs`:
|
|
|
+
|
|
|
+- 三个端点不再包含 `FROM ado_s8_alert_record`;
|
|
|
+- 读取 `ado_s8_exception`;
|
|
|
+- summary/trend 使用 `created_at`;
|
|
|
+- trend 不使用 `last_detected_at`;
|
|
|
+- list 仍 `LIMIT 6`;
|
|
|
+- summary 不带 `LIMIT`;
|
|
|
+- 租户来自 `AidopTenantHelper`;
|
|
|
+- 灯态端点存在;
|
|
|
+- 无客户端 tenant 过滤入口;
|
|
|
+- 严重度契约仍返回 `critical/medium`。
|
|
|
+
|
|
|
+旧测试 `T23_LegacyAlertsEndpoint_StillReturnsRecentList` 应改名并改语义,禁止留下“旧端点不得改”的过期断言。
|
|
|
+
|
|
|
+### 9.3 前端测试
|
|
|
+
|
|
|
+至少覆盖:
|
|
|
+
|
|
|
+1. API 参数及类型;
|
|
|
+2. S1–S7 顺序;
|
|
|
+3. CRITICAL 红灯;
|
|
|
+4. WARNING 黄灯;
|
|
|
+5. HEALTHY 且 0 异常才绿;
|
|
|
+6. UNMONITORED 灰灯;
|
|
|
+7. CRITICAL + PAUSED 同时显示;
|
|
|
+8. 请求失败不显示绿;
|
|
|
+9. tooltip 含数量、监控态、最近时间;
|
|
|
+10. 点击生成 `/aidop/s8/exceptions?stageCode=Sx`;
|
|
|
+11. 异常列表读取并透传 `stageCode`;
|
|
|
+12. 从 S1 灯切 S2 灯会刷新;
|
|
|
+13. 旧 Demo 告警不会恢复;
|
|
|
+14. S8 真 0 行时仍显示“暂无异常告警”,请求失败显示“异常数据加载失败”。
|
|
|
+
|
|
|
+### 9.4 全量测试基线
|
|
|
+
|
|
|
+当前已知后端固定失败集合为 7 条;执行前重新确认:
|
|
|
+
|
|
|
+1. `S0DimContractTests.ProductDesign_bom_and_routing_sql_must_carry_tenant_predicate_everywhere`
|
|
|
+2. `S1RequirementExamineDwdContractTests.Table_HasNoS8SpecificColumns`
|
|
|
+3. `S1RequirementExamineDwdContractTests.CurrentSnapshotIndex_ExistsInBothInlineDdlAndMigration`
|
|
|
+4. `S1RequirementExamineDwdContractTests.BooleanColumn_FollowsRepoFlagConvention_NotBit`
|
|
|
+5. `S1RequirementExamineDwdContractTests.NewColumns_ExistInBothInlineDdlAndMigration`
|
|
|
+6. `S1RequirementExamineDwdContractTests.QuantityColumns_DocumentedAsStandardNames`
|
|
|
+7. `S6ProductionInstructionContractTests.Std_Schedule_HasNewNullableColumns`
|
|
|
+
|
|
|
+新增测试可以增加总数,但失败名字集合不得扩大。
|
|
|
+
|
|
|
+执行:
|
|
|
+
|
|
|
+```powershell
|
|
|
+dotnet build server\Admin.NET.Web.Entry\Admin.NET.Web.Entry.csproj -v q --nologo
|
|
|
+dotnet build server\Plugins\Admin.NET.Plugin.AiDOP.Tests\Admin.NET.Plugin.AiDOP.Tests.csproj -v q --nologo
|
|
|
+dotnet test server\Plugins\Admin.NET.Plugin.AiDOP.Tests\Admin.NET.Plugin.AiDOP.Tests.csproj `
|
|
|
+ --no-build --nologo --logger "trx;LogFileName=s8-home-lamps.trx"
|
|
|
+
|
|
|
+Set-Location Web
|
|
|
+npm run test:run
|
|
|
+npm run build
|
|
|
+```
|
|
|
+
|
|
|
+用 TRX 比较失败用例名。测试完成后删除本轮 `TestResults`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 10. 接口与 SQL 验收
|
|
|
+
|
|
|
+### 10.1 API 验收
|
|
|
+
|
|
|
+以 UATAdminA 登录态调用:
|
|
|
+
|
|
|
+```http
|
|
|
+GET /api/AidopKanban/s8-alerts
|
|
|
+GET /api/AidopKanban/s8-alert-summary
|
|
|
+GET /api/AidopKanban/s8-home-trend
|
|
|
+GET /api/AidopKanban/s8-module-lamps
|
|
|
+```
|
|
|
+
|
|
|
+检查:
|
|
|
+
|
|
|
+- 响应不包含其它租户;
|
|
|
+- 列表最多 6 条;
|
|
|
+- summary 今日窗口正确;
|
|
|
+- trend 连续补齐日期;
|
|
|
+- module lamps 恰好 7 条;
|
|
|
+- 无秘密、连接串、payload 全文泄漏。
|
|
|
+
|
|
|
+### 10.2 同时刻对账 SQL
|
|
|
+
|
|
|
+#### 当前异常灯芯
|
|
|
+
|
|
|
+```sql
|
|
|
+SELECT stage_code,
|
|
|
+ SUM(CASE WHEN severity = 'SERIOUS' THEN 1 ELSE 0 END) AS serious_count,
|
|
|
+ SUM(CASE WHEN severity = 'FOLLOW' THEN 1 ELSE 0 END) AS follow_count,
|
|
|
+ COUNT(*) AS open_count
|
|
|
+FROM ado_s8_exception
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND is_deleted = 0
|
|
|
+ AND status NOT IN ('CLOSED', 'REJECTED', 'RECOVERED')
|
|
|
+ AND stage_code IN ('S1','S2','S3','S4','S5','S6','S7')
|
|
|
+GROUP BY stage_code
|
|
|
+ORDER BY stage_code;
|
|
|
+```
|
|
|
+
|
|
|
+#### 今日新增
|
|
|
+
|
|
|
+```sql
|
|
|
+SELECT COUNT(*) AS total,
|
|
|
+ SUM(CASE WHEN severity = 'SERIOUS' THEN 1 ELSE 0 END) AS critical
|
|
|
+FROM ado_s8_exception
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND is_deleted = 0
|
|
|
+ AND created_at >= CURDATE()
|
|
|
+ AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
|
|
|
+```
|
|
|
+
|
|
|
+#### 7 日趋势
|
|
|
+
|
|
|
+```sql
|
|
|
+SELECT DATE(created_at) AS biz_date,
|
|
|
+ COUNT(*) AS cnt
|
|
|
+FROM ado_s8_exception
|
|
|
+WHERE tenant_id = 838257186181189
|
|
|
+ AND is_deleted = 0
|
|
|
+ AND created_at >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
|
|
|
+ AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
|
|
|
+GROUP BY DATE(created_at)
|
|
|
+ORDER BY biz_date;
|
|
|
+```
|
|
|
+
|
|
|
+API 与 SQL 必须能解释性对账。趋势补 0 日由 API 完成。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 11. 提交与版本
|
|
|
+
|
|
|
+建议拆成两个可独立回滚的提交,但必须在同一发布窗口部署:
|
|
|
+
|
|
|
+### 提交 1:后端 Authority + 灯态接口
|
|
|
+
|
|
|
+范围:
|
|
|
+
|
|
|
+- `S8HomeAlertQueryService.cs`
|
|
|
+- `AidopKanbanController.cs`
|
|
|
+- 后端测试
|
|
|
+- server 版本
|
|
|
+
|
|
|
+若基线仍为 `1.0.595`:
|
|
|
+
|
|
|
+```text
|
|
|
+server → 1.0.596
|
|
|
+```
|
|
|
+
|
|
|
+建议提交信息:
|
|
|
+
|
|
|
+```text
|
|
|
+fix(s8): 首页告警改读异常权威表并提供模块灯态
|
|
|
+```
|
|
|
+
|
|
|
+### 提交 2:前端双维度灯 + 下钻
|
|
|
+
|
|
|
+范围:
|
|
|
+
|
|
|
+- `kanbanData.ts`
|
|
|
+- `home.vue`
|
|
|
+- `S8ExceptionListPage.vue`
|
|
|
+- 前端测试
|
|
|
+- Web 版本和对应锁文件
|
|
|
+
|
|
|
+若基线仍为 `2.4.414`:
|
|
|
+
|
|
|
+```text
|
|
|
+Web → 2.4.415
|
|
|
+```
|
|
|
+
|
|
|
+建议提交信息:
|
|
|
+
|
|
|
+```text
|
|
|
+fix(s8): 九宫格展示异常灯芯与监控运行外圈
|
|
|
+```
|
|
|
+
|
|
|
+两个提交均须 push。若用户明确要求只 commit 不 push,才停止在本地。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 12. 反向影响推演
|
|
|
+
|
|
|
+### 12.1 代码调用面
|
|
|
+
|
|
|
+**需同步改:**
|
|
|
+
|
|
|
+- `s8-alerts` 被九宫格首页使用;
|
|
|
+- `s8-alert-summary` 被独立 S8 看板使用;
|
|
|
+- `s8-home-trend` 被九宫格首页使用;
|
|
|
+- `HomeModule` 灯下钻影响 FUNC-S8-008 异常列表;
|
|
|
+- `AidopKanbanController` 构造函数若加服务,须全仓检索手工构造调用方。
|
|
|
+
|
|
|
+### 12.2 数据契约面
|
|
|
+
|
|
|
+**需同步改但保持兼容:**
|
|
|
+
|
|
|
+- 三个既有接口 JSON 字段不变;
|
|
|
+- Authority 从旧告警表切到异常主表;
|
|
|
+- 严重度由 `SERIOUS/FOLLOW` 映射到现有 `critical/medium`;
|
|
|
+- 新增灯态接口是增量契约;
|
|
|
+- 智慧诊断、ChatBI、导出当前未发现直接调用灯态接口;执行时须再次全仓检索。
|
|
|
+
|
|
|
+### 12.3 多数据源面
|
|
|
+
|
|
|
+**无直接影响:**
|
|
|
+
|
|
|
+- 本任务不直接读取 T8、165、自建单或标准 API;
|
|
|
+- 各来源先由现有规则 Provider 形成 S8 异常;
|
|
|
+- 页面只消费 S8 统一异常 Authority。
|
|
|
+
|
|
|
+若某来源没有配置规则,应显示 `UNMONITORED`,不得在展示层特判来源。
|
|
|
+
|
|
|
+### 12.4 多租户 / Domain 面
|
|
|
+
|
|
|
+**需同步核查:**
|
|
|
+
|
|
|
+- 只按认证租户读取;
|
|
|
+- S8 规则和异常遵循 tenant-only;
|
|
|
+- 不信任请求 tenantId;
|
|
|
+- 不把普通业务 `factoryId=1` 强套到 S8 `factory_id=0`;
|
|
|
+- `stage_code` 只允许 S1–S7。
|
|
|
+
|
|
|
+### 12.5 运行面
|
|
|
+
|
|
|
+**无迁移、无种子、无定时任务改动。**
|
|
|
+
|
|
|
+但需注意:
|
|
|
+
|
|
|
+- 页面状态随规则最近运行时间变化;
|
|
|
+- 后端或 Scheduler 停止后灯外圈应自动转 `DEGRADED`;
|
|
|
+- 重启后不得短暂闪绿;
|
|
|
+- 旧表仍保留但不再供这三个端点读取。
|
|
|
+
|
|
|
+### 12.6 验证面
|
|
|
+
|
|
|
+**需同步改:**
|
|
|
+
|
|
|
+- 过期的 legacy Authority 契约测试;
|
|
|
+- 服务级灯态矩阵;
|
|
|
+- 前端双状态组合;
|
|
|
+- 下钻路由;
|
|
|
+- UATAdminA 实际数据对账。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 13. 风险与回滚
|
|
|
+
|
|
|
+### 13.1 主要风险
|
|
|
+
|
|
|
+1. 把 `last_detected_at` 当新增日期导致趋势膨胀。
|
|
|
+2. 只看异常、不看规则健康,把未监测模块显示绿色。
|
|
|
+3. 规则暂停后把仍存在的异常隐藏。
|
|
|
+4. 前端 keep-alive 不响应路由 query,点击不同灯仍显示旧模块。
|
|
|
+5. tenant-only 语义被旧 `factoryId=1` 过滤掉。
|
|
|
+6. 直接显示 `source_payload` 导致敏感业务报文泄漏。
|
|
|
+
|
|
|
+### 13.2 回滚
|
|
|
+
|
|
|
+- 前端可回滚到灰色 unknown,但不应回写假灯态;
|
|
|
+- 后端可暂时回滚接口实现,但禁止通过向旧表造数据回滚;
|
|
|
+- 新接口为增量接口,不涉及 DROP;
|
|
|
+- 不删除历史异常和规则;
|
|
|
+- 回滚后需明确页面重新失去 Authority,不能把空白称为“无异常”。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 14. 总验收清单
|
|
|
+
|
|
|
+### Authority
|
|
|
+
|
|
|
+- [ ] 三个首页/S8 接口不再读取 `ado_s8_alert_record`
|
|
|
+- [ ] 当前异常读取 `ado_s8_exception`
|
|
|
+- [ ] 规则健康读取 `ado_s8_watch_rule`
|
|
|
+- [ ] 未新增旧表写入方
|
|
|
+
|
|
|
+### 时间语义
|
|
|
+
|
|
|
+- [ ] 列表按最后命中时间排序
|
|
|
+- [ ] summary 按 `created_at`
|
|
|
+- [ ] trend 按 `created_at`
|
|
|
+- [ ] `REFRESHED` 未被当成新增异常
|
|
|
+
|
|
|
+### 灯态
|
|
|
+
|
|
|
+- [ ] SERIOUS 红
|
|
|
+- [ ] FOLLOW 黄
|
|
|
+- [ ] 监控健康且 0 异常才绿
|
|
|
+- [ ] 无规则灰
|
|
|
+- [ ] 暂停有独立外圈/徽标
|
|
|
+- [ ] 失败/陈旧有 DEGRADED 外圈
|
|
|
+- [ ] 异常颜色不会被暂停状态覆盖
|
|
|
+- [ ] 七灯不硬编码业务状态
|
|
|
+
|
|
|
+### 下钻
|
|
|
+
|
|
|
+- [ ] 点击进入 FUNC-S8-008
|
|
|
+- [ ] 带 `stageCode`
|
|
|
+- [ ] 列表实际按 stage 过滤
|
|
|
+- [ ] keep-alive 路由切换刷新
|
|
|
+- [ ] 筛选条件对用户可见
|
|
|
+
|
|
|
+### 真实性
|
|
|
+
|
|
|
+- [ ] 未改异常业务数据
|
|
|
+- [ ] 未改规则启停数据
|
|
|
+- [ ] 未复制其它租户
|
|
|
+- [ ] 未回填旧告警表
|
|
|
+- [ ] 同时刻 API 与 SQL 可对账
|
|
|
+
|
|
|
+### 工程
|
|
|
+
|
|
|
+- [ ] 后端构建 0 error
|
|
|
+- [ ] 前端构建成功
|
|
|
+- [ ] 新增测试通过
|
|
|
+- [ ] 既有失败集合未扩大
|
|
|
+- [ ] server/Web 版本正确
|
|
|
+- [ ] commit + push 成功
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 15. 交付报告模板
|
|
|
+
|
|
|
+执行者最终必须按以下结构汇报:
|
|
|
+
|
|
|
+```text
|
|
|
+1. 提交与版本
|
|
|
+2. 实际改动文件
|
|
|
+3. Authority 收口结果
|
|
|
+4. 三个既有接口验收
|
|
|
+5. S1–S7 逐灯验收
|
|
|
+6. 下钻验收
|
|
|
+7. 同时刻 SQL 对账
|
|
|
+8. 测试结果与既有失败对比
|
|
|
+9. 反向影响推演
|
|
|
+ - 代码调用面:无影响 / 需同步改(文件)
|
|
|
+ - 数据契约面:无影响 / 需同步改(接口/表)
|
|
|
+ - 多数据源面:无影响 / 需同步改(来源)
|
|
|
+ - 多租户/Domain:无影响 / 需同步改
|
|
|
+ - 运行面:无影响 / 需同步改
|
|
|
+ - 验证面:无影响 / 需同步改
|
|
|
+10. 未覆盖模块及原因
|
|
|
+```
|
|
|
+
|
|
|
+不得只汇报“灯亮了”或“页面有数据”。必须同时解释:
|
|
|
+
|
|
|
+- 异常来自哪里;
|
|
|
+- 为什么是红/黄/绿/灰;
|
|
|
+- 监控是否正常;
|
|
|
+- 最近一次检测时间;
|
|
|
+- 点击后能否看到对应异常。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 16. 给执行模型的启动指令
|
|
|
+
|
|
|
+将本段与本文件路径一并交给新的执行模型:
|
|
|
+
|
|
|
+```text
|
|
|
+请严格执行:
|
|
|
+doc/plan/S8九宫格异常权威数据与模块灯态根治执行任务书.md
|
|
|
+
|
|
|
+开始时:
|
|
|
+1. 读取 AGENTS.md 和所有 alwaysApply 规则。
|
|
|
+2. 核对 HEAD、server/Web 版本、完整 git status,不覆盖或提交他人改动。
|
|
|
+3. 重新运行任务书 §2.4 的只读 SQL,按代码层/配置层/数据层分别记录证据。
|
|
|
+4. 全仓检索三个既有接口和 AidopKanbanController 手工构造调用方。
|
|
|
+5. 按 §7 列精确改动文件、跨模块影响和不做事项,等待用户确认后再改。
|
|
|
+
|
|
|
+实现时严格遵守冻结决策:
|
|
|
+- ado_s8_exception 是异常 Authority;
|
|
|
+- ado_s8_watch_rule 是监控覆盖和运行态 Authority;
|
|
|
+- 不写 ado_s8_alert_record;
|
|
|
+- list 可按 last_detected_at 排序,但 summary/trend 必须按 created_at;
|
|
|
+- 绿色只允许“监控健康且当前异常为 0”;
|
|
|
+- 异常灯芯与监控外圈必须分开;
|
|
|
+- S4 即使规则暂停,只要严重异常未关闭仍保持红灯;
|
|
|
+- 点击灯进入 FUNC-S8-008,并按 stageCode 过滤;
|
|
|
+- 不造数、不改异常和规则业务数据。
|
|
|
+
|
|
|
+完成后:
|
|
|
+- 后端、前端分别测试和构建;
|
|
|
+- 用 TRX 对比固定失败集合;
|
|
|
+- 用同一时刻 SQL 对账 S1-S7 灯态;
|
|
|
+- 按 §11 升版本、分提交并 push;
|
|
|
+- 按 §15 模板交付。
|
|
|
+```
|
|
|
+
|