[BEL] 实现 Alert 并发 ack、close 与审计时间线 #20

Closed
opened 2026-08-12 09:53:52 +08:00 by ila · 4 comments
Owner

当前状态:已完成

用户于 2026-08-14 明确验收通过。

基本信息

  • 类型:需求
  • 任务类型:单项目
  • 主项目:Bell
  • 主 agent:Bell agent
  • 所属 Epic:#7
  • 所属 MVP / 版本:#8
  • 阶段:三项目首个独立纵切

依赖与并行

  • 前置工单:#12、#19
  • 是否允许与前置工单并行:否
  • 原因:ack/close 必须基于 Bell 独立处置身份、权限和已建立的 Alert;并发语义影响安全审计,不能先于前置事实实施。

子项目影响

  • 仅影响的子项目 / 交付单元:Bell
  • 是否跨子项目:否
  • 是否修改共享接口或契约:否;唯一事实来源:不适用,本工单只维护 Bell 内部实现
  • write_paths:Bell/server/app/alert-lifecycle/**、Bell/server/app/alert/lifecycle/**、Bell/server/migrations/*alert_lifecycle*、Bell/web/src/views/alert/actions/**、Bell/web/src/views/alert/timeline/**
  • 各子项目需要执行的验证:仅执行 Bell 后端、前端及 PostgreSQL 测试;Sense/Brain 无需启动或验证

协同接口

  • 生产者:不适用
  • 消费者:不适用
  • 契约/共享事实源:不适用
  • 兼容策略:不适用
  • 被阻塞或需要适配的工单:不适用
  • 集成顺序:不适用

原始需求

  • 来源:用户对话、Epic #7、MVP #8、Product-Requirements、Product-Roadmap、Requirements-Migration-Matrix
  • 提出时间:2026-08-12
  • 关键原话或脱敏摘要:先创建三个项目各自独立任务的全部工单,标题包含项目英文简称;Bell 首个纵切须在 Sense/Brain 不在线时以合成事件完成 Event → Alert → ack → close。

要解决什么

Bell 首个纵切需要让处置员从 Alert 详情完成 open → ack → close。并发 ack 只能由首个服务端成功者成为处置人,后到者必须看到真实结果;所有状态变化应只追加、可审计并在重启后保持。

做什么 / 不做什么

  • 做:实现明确的 Alert 状态机、并发安全 ack、close 前置条件、追加式生命周期事实/审计、详情时间线和冲突反馈;用两个处置员并发与 PostgreSQL 重启测试完成纵切验收。
  • 不做:不实现自动升级、通知投递、sent/delivered/seen、联系人、排班、交接、静默、批量处置;不修改 Event;不接入其他项目。

已确认方案

当前状态是可查询投影,状态迁移事实仅追加。ack 由数据库事务/条件更新或等价并发控制保证单一胜者,并记录服务端身份与时间;后到者返回已被谁 ack 的真实结果,不覆盖处置人。close 仅允许符合权限和前置状态的请求,重复请求幂等。UI 详情复用现有状态、按钮、确认和时间线样式。

预计修改文件:

  • Bell/server/app/alert-lifecycle/**
  • Bell/server/app/alert/**
  • Bell/server/migrations/*alert_lifecycle*
  • Bell/web/src/views/alert/**

需求变化记录

日期 变化内容 原因 用户确认
2026-08-12 无 初始建单 是

文档影响

  • 不影响长期文档,原因:不适用
  • 更新项目档案或本地开发与验证
  • 更新架构与代码地图
  • 更新业务规则与术语
  • 更新常见修改或故障排查
  • 更新其他 Wiki 页面:Alert 状态机、并发 ack、close、时间线与审计语义

交付文档影响

  • 无交付文档影响,原因:不适用
  • 更新已有交付文档,受众与页面:Bell 处置员/管理员,Alert ack/close 操作与冲突说明
  • 新增交付文档,受众与页面:
  • 需要目标岗位或客户代表验证:是;验证方式:两个处置账号并发 ack,随后完成 close 并核对时间线

验收标准

  • Sense/Brain 不启动时,从合成事件可完整完成 Event → Rule → open Alert → ack → close
  • 两个处置员并发 ack 仅一个成为处置人,后到者看到真实胜者且不能覆盖
  • 非法迁移、越权、重复 ack/close 返回稳定可理解结果,不制造重复状态事实
  • 每次成功/失败尝试按安全边界留下不含秘密的可定位审计,成功状态事实仅追加
  • 服务重启后 Alert 状态、处置人和时间线保持一致,可继续合法操作
  • Alert 详情正确呈现状态、关联 Event、处置人和时间线,视觉/交互与 Bell 一致

验证方式

Set-Location Bell/server
go test ./...
Set-Location ../web
pnpm lint
pnpm build:prod

在独立 PostgreSQL 测试库运行状态转移表、重复请求、角色越权、双客户端并发 ack、事务失败回滚与服务重启恢复测试;再以合成事件人工完成整条 Bell 纵切。

未验证边界:Sense/Brain 的正式事件生产、跨项目机器身份、共享事件/证据契约、根级部署与端到端链路不在本工单验证;这些内容留待独立协同工单。

风险和回退

风险:并发控制缺陷会覆盖处置人或产生虚假状态,属于高风险并发/审计边界。实施前必须明确事务与唯一性方案并等待工单方案确认。回退:关闭 ack/close 写入口并回退 UI;已有生命周期事实不得删除或改写,需以前一稳定投影只读运行,数据迁移另建高风险工单。

后续协同需求摘要

生产者:未来通知/升级模块;消费者:Bell Alert 生命周期;目的:后续将投递、自动升级、联系人/排班接入状态时间线但保持 sent/delivered/seen 与 ack 分离;候选事实源:Bell 内部版本化生命周期接口,跨产品部分另由协调工单裁决;阻塞工单:本 MVP 无,自动升级/通知属于后续阶段;建议验证:重启恢复、升级不中断及通知回执与 ack 分离。

## 当前状态:已完成 用户于 2026-08-14 明确验收通过。 ## 基本信息 - 类型:需求 - 任务类型:单项目 - 主项目:Bell - 主 agent:Bell agent - 所属 Epic:#7 - 所属 MVP / 版本:#8 - 阶段:三项目首个独立纵切 ## 依赖与并行 - 前置工单:#12、#19 - 是否允许与前置工单并行:否 - 原因:ack/close 必须基于 Bell 独立处置身份、权限和已建立的 Alert;并发语义影响安全审计,不能先于前置事实实施。 ## 子项目影响 - 仅影响的子项目 / 交付单元:Bell - 是否跨子项目:否 - 是否修改共享接口或契约:否;唯一事实来源:不适用,本工单只维护 Bell 内部实现 - write_paths:`Bell/server/app/alert-lifecycle/**`、`Bell/server/app/alert/lifecycle/**`、`Bell/server/migrations/*alert_lifecycle*`、`Bell/web/src/views/alert/actions/**`、`Bell/web/src/views/alert/timeline/**` - 各子项目需要执行的验证:仅执行 Bell 后端、前端及 PostgreSQL 测试;Sense/Brain 无需启动或验证 ## 协同接口 - 生产者:不适用 - 消费者:不适用 - 契约/共享事实源:不适用 - 兼容策略:不适用 - 被阻塞或需要适配的工单:不适用 - 集成顺序:不适用 ## 原始需求 - 来源:用户对话、Epic #7、MVP #8、Product-Requirements、Product-Roadmap、Requirements-Migration-Matrix - 提出时间:2026-08-12 - 关键原话或脱敏摘要:先创建三个项目各自独立任务的全部工单,标题包含项目英文简称;Bell 首个纵切须在 Sense/Brain 不在线时以合成事件完成 Event → Alert → ack → close。 ## 要解决什么 Bell 首个纵切需要让处置员从 Alert 详情完成 open → ack → close。并发 ack 只能由首个服务端成功者成为处置人,后到者必须看到真实结果;所有状态变化应只追加、可审计并在重启后保持。 ## 做什么 / 不做什么 - 做:实现明确的 Alert 状态机、并发安全 ack、close 前置条件、追加式生命周期事实/审计、详情时间线和冲突反馈;用两个处置员并发与 PostgreSQL 重启测试完成纵切验收。 - 不做:不实现自动升级、通知投递、sent/delivered/seen、联系人、排班、交接、静默、批量处置;不修改 Event;不接入其他项目。 ## 已确认方案 当前状态是可查询投影,状态迁移事实仅追加。ack 由数据库事务/条件更新或等价并发控制保证单一胜者,并记录服务端身份与时间;后到者返回已被谁 ack 的真实结果,不覆盖处置人。close 仅允许符合权限和前置状态的请求,重复请求幂等。UI 详情复用现有状态、按钮、确认和时间线样式。 预计修改文件: - `Bell/server/app/alert-lifecycle/**` - `Bell/server/app/alert/**` - `Bell/server/migrations/*alert_lifecycle*` - `Bell/web/src/views/alert/**` ## 需求变化记录 | 日期 | 变化内容 | 原因 | 用户确认 | |---|---|---|---| | 2026-08-12 | 无 | 初始建单 | 是 | ## 文档影响 - [ ] 不影响长期文档,原因:不适用 - [ ] 更新项目档案或本地开发与验证 - [x] 更新架构与代码地图 - [x] 更新业务规则与术语 - [x] 更新常见修改或故障排查 - [x] 更新其他 Wiki 页面:Alert 状态机、并发 ack、close、时间线与审计语义 ## 交付文档影响 - [ ] 无交付文档影响,原因:不适用 - [x] 更新已有交付文档,受众与页面:Bell 处置员/管理员,Alert ack/close 操作与冲突说明 - [ ] 新增交付文档,受众与页面: - [x] 需要目标岗位或客户代表验证:是;验证方式:两个处置账号并发 ack,随后完成 close 并核对时间线 ## 验收标准 - [ ] Sense/Brain 不启动时,从合成事件可完整完成 Event → Rule → open Alert → ack → close - [ ] 两个处置员并发 ack 仅一个成为处置人,后到者看到真实胜者且不能覆盖 - [ ] 非法迁移、越权、重复 ack/close 返回稳定可理解结果,不制造重复状态事实 - [ ] 每次成功/失败尝试按安全边界留下不含秘密的可定位审计,成功状态事实仅追加 - [ ] 服务重启后 Alert 状态、处置人和时间线保持一致,可继续合法操作 - [ ] Alert 详情正确呈现状态、关联 Event、处置人和时间线,视觉/交互与 Bell 一致 ## 验证方式 ```powershell Set-Location Bell/server go test ./... Set-Location ../web pnpm lint pnpm build:prod ``` 在独立 PostgreSQL 测试库运行状态转移表、重复请求、角色越权、双客户端并发 ack、事务失败回滚与服务重启恢复测试;再以合成事件人工完成整条 Bell 纵切。 未验证边界:Sense/Brain 的正式事件生产、跨项目机器身份、共享事件/证据契约、根级部署与端到端链路不在本工单验证;这些内容留待独立协同工单。 ## 风险和回退 风险:并发控制缺陷会覆盖处置人或产生虚假状态,属于高风险并发/审计边界。实施前必须明确事务与唯一性方案并等待工单方案确认。回退:关闭 ack/close 写入口并回退 UI;已有生命周期事实不得删除或改写,需以前一稳定投影只读运行,数据迁移另建高风险工单。 ## 后续协同需求摘要 生产者:未来通知/升级模块;消费者:Bell Alert 生命周期;目的:后续将投递、自动升级、联系人/排班接入状态时间线但保持 sent/delivered/seen 与 ack 分离;候选事实源:Bell 内部版本化生命周期接口,跨产品部分另由协调工单裁决;阻塞工单:本 MVP 无,自动升级/通知属于后续阶段;建议验证:重启恢复、升级不中断及通知回执与 ack 分离。
ila added the kind/taskpriority/p0project/bellscope/independent labels 2026-08-12 09:58:48 +08:00
Author
Owner

状态:进行中(2026-08-12)

前置 #12、#19 已完成并推送。开始实现数据库条件更新保证 ack 单一胜者、后来者真实获知处理人、合法 close 与现场结果必填、幂等重复请求、仅追加生命周期事实及成功/失败/拒绝审计。

## 状态:进行中(2026-08-12) 前置 #12、#19 已完成并推送。开始实现数据库条件更新保证 ack 单一胜者、后来者真实获知处理人、合法 close 与现场结果必填、幂等重复请求、仅追加生命周期事实及成功/失败/拒绝审计。
Author
Owner

实施结果:待验收

Alert ack/close 与审计时间线已按已确认方案完成,并已推送到 PR #35。

  • 实现提交:10225f4
  • UI 信息架构对齐:9ee06e3
  • 并发 ack:PostgreSQL 条件更新只产生一个处置人,后来者得到真实获胜者且不能覆盖
  • close:仅处置人或管理员可执行,必须选择确认有危险、误报、现场正常、无法确认之一
  • 幂等:相同重复 close 返回原结果;改变结果或越权请求被拒绝并审计
  • 生命周期:成功 ack/close 事实只追加,数据库拒绝更新/删除;失败、重复、拒绝尝试进入安全审计
  • 页面:预警列表/详情提供“开始处理 → 记录现场结果”两步动作和时间线

验证证据:

  • PostgreSQL 集成测试:20 个并发 ack 请求仅产生 1 条成功事实
  • 非处置人 close 被拒绝;处置人 close 成功;相同重复 close 幂等
  • 生命周期 delete 被数据库触发器拒绝;进程/连接重建后处置状态保留
  • API:ack 200、后来者 409、缺少结果 400、close 200、重复 close 200;最终 status=closed,timeline=2
  • Go 全包测试、Vue lint/build、Harness、31 项仓库 unittest、git diff --check 均通过
  • 前端 build 仅有 Element Plus vendor 体积警告,不影响产物

未验证:真实多人浏览器并发、生产规模压测、正式通知/升级流程和用户人工验收。

长期文档与任务归档由协调工单 #36 处理;人工验收前本工单保持开启。

## 实施结果:待验收 Alert ack/close 与审计时间线已按已确认方案完成,并已推送到 PR #35。 - 实现提交:`10225f4` - UI 信息架构对齐:`9ee06e3` - 并发 ack:PostgreSQL 条件更新只产生一个处置人,后来者得到真实获胜者且不能覆盖 - close:仅处置人或管理员可执行,必须选择确认有危险、误报、现场正常、无法确认之一 - 幂等:相同重复 close 返回原结果;改变结果或越权请求被拒绝并审计 - 生命周期:成功 ack/close 事实只追加,数据库拒绝更新/删除;失败、重复、拒绝尝试进入安全审计 - 页面:预警列表/详情提供“开始处理 → 记录现场结果”两步动作和时间线 验证证据: - PostgreSQL 集成测试:20 个并发 ack 请求仅产生 1 条成功事实 - 非处置人 close 被拒绝;处置人 close 成功;相同重复 close 幂等 - 生命周期 delete 被数据库触发器拒绝;进程/连接重建后处置状态保留 - API:ack 200、后来者 409、缺少结果 400、close 200、重复 close 200;最终 status=closed,timeline=2 - Go 全包测试、Vue lint/build、Harness、31 项仓库 unittest、`git diff --check` 均通过 - 前端 build 仅有 Element Plus vendor 体积警告,不影响产物 未验证:真实多人浏览器并发、生产规模压测、正式通知/升级流程和用户人工验收。 长期文档与任务归档由协调工单 #36 处理;人工验收前本工单保持开启。
Author
Owner

最终证据:待验收

  • 实现提交:10225f4 / 9ee06e3(PR #35)
  • 长期文档与归档协调:#36 / PR #38
  • Wiki 归档 revision:b7ed3e488bf2
  • 本地只读镜像:docs/task/20-Bell-Alert并发处置与审计时间线.md
  • 文档镜像提交:e2a4345、3c245e1
  • 文档验证:36 个 Wiki 映射一致;DevHarness 通过;31 项 unittest 通过;git diff --check 通过

实现、自动测试、Wiki、镜像、提交、推送与 PR 证据已齐。人工验收前本工单保持开启,不关闭、不勾选父工单。

## 最终证据:待验收 - 实现提交:`10225f4 / 9ee06e3`(PR #35) - 长期文档与归档协调:#36 / PR #38 - Wiki 归档 revision:`b7ed3e488bf2` - 本地只读镜像:`docs/task/20-Bell-Alert并发处置与审计时间线.md` - 文档镜像提交:`e2a4345`、`3c245e1` - 文档验证:36 个 Wiki 映射一致;DevHarness 通过;31 项 unittest 通过;`git diff --check` 通过 实现、自动测试、Wiki、镜像、提交、推送与 PR 证据已齐。人工验收前本工单保持开启,不关闭、不勾选父工单。
Author
Owner

用户验收通过(2026-08-14)

用户已明确确认当前未验收工单通过验收。本工单的实现、测试与既有证据按记录接受,Wiki 归档状态已更新为“已完成”(revision e21232d1b89a)。该交付属于重建前历史实现;Wiki 归档已完成,代码与原归档镜像继续保留在 explore 追溯。

此验收不改变 #58 的架构决定:旧自研基础框架不会恢复为 dev 基线,Sense/Bell 后续仍分别由 #61/#62 从冻结 GoAdmin 源码重建。

## 用户验收通过(2026-08-14) 用户已明确确认当前未验收工单通过验收。本工单的实现、测试与既有证据按记录接受,Wiki 归档状态已更新为“已完成”(revision `e21232d1b89a`)。该交付属于重建前历史实现;Wiki 归档已完成,代码与原归档镜像继续保留在 `explore` 追溯。 此验收不改变 #58 的架构决定:旧自研基础框架不会恢复为 `dev` 基线,Sense/Bell 后续仍分别由 #61/#62 从冻结 GoAdmin 源码重建。
ila closed this issue 2026-08-14 10:06:45 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ila/yovision#20