[BEL] 联系人、通道验证与值班排班 #183

Closed
opened 2026-09-01 10:04:32 +08:00 by ila · 5 comments
Owner

状态

已完成(2026-09-01;用户验收通过,PR #189 已合并到 dev)

基本信息

  • 所属 Epic:#7
  • 所属 MVP:#174
  • 规划来源:#173
  • 主项目:Bell
  • 主 agent:Bell agent
  • 前置:#182 原型确认;现场时区和脱敏联系人规则依赖 #176

目标

基于已确认原型实现联系人、只写不读的通道地址、验证状态、值班组、站点时区、周轮换、生效日期、临时替班、空档/重叠检查、版本发布和审计;Bell 可在 Sense/Brain 离线时独立验收。

非目标

  • 不发送真实通知
  • 不实现自动升级、交接或静默
  • 不共享 Sense 用户/角色/数据库
  • 不回显完整手机号、地址或供应商秘密

精确 write_paths

  • Bell/server/app/bell/contact/
  • Bell/server/cmd/api/server.go(用户已确认:仅注册联系人通道请求体脱敏中间件)
  • Bell/server/app/bell/duty_schedule/
  • Bell/server/app/bell/router/contact.go
  • Bell/server/app/bell/router/duty_schedule.go
  • Bell/server/cmd/migrate/migration/version/2026090110000_contact_schedule.go
  • Bell/server/cmd/migrate/migration/version/2026090110000_contact_schedule_test.go
  • Bell/ui/src/api/bell/contact.js
  • Bell/ui/src/api/bell/duty-schedule.js
  • Bell/ui/src/views/bell/contacts/
  • Bell/ui/src/views/bell/duty-schedules/
  • Bell/server/tests/bell_contact_schedule/

除上述路径外禁止写入;新增路径必须先更新工单并取得确认。

验收标准

  • 联系人与通道分对象建模,敏感地址只写不读且脱敏展示
  • 通道验证事实与联系人启用状态分离
  • 时区、周轮换、生效期、替班、空档和重叠有明确校验
  • 发布新排班版本不改写历史版本
  • 权限、并发更新和审计通过 PostgreSQL 回归
  • 合成联系人/通道可独立验收且不发送外部消息

风险与回退

从当前 dev 建立独立任务分支;实施前复核前置和线上原型版本。状态迁移、通知和排班属于高风险业务事实,发现语义变化或客户参数缺失时停止。回退停用新增策略/Worker/通道,不删除联系人、排班版本、投递、Alert 或审计历史。

文档影响

更新 Bell Product-Requirements、Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;新页面菜单和权限入口需记录。

## 状态 已完成(2026-09-01;用户验收通过,PR #189 已合并到 dev) ## 基本信息 - 所属 Epic:#7 - 所属 MVP:#174 - 规划来源:#173 - 主项目:Bell - 主 agent:Bell agent - 前置:#182 原型确认;现场时区和脱敏联系人规则依赖 #176 ## 目标 基于已确认原型实现联系人、只写不读的通道地址、验证状态、值班组、站点时区、周轮换、生效日期、临时替班、空档/重叠检查、版本发布和审计;Bell 可在 Sense/Brain 离线时独立验收。 ## 非目标 - 不发送真实通知 - 不实现自动升级、交接或静默 - 不共享 Sense 用户/角色/数据库 - 不回显完整手机号、地址或供应商秘密 ## 精确 write_paths - `Bell/server/app/bell/contact/` - `Bell/server/cmd/api/server.go`(用户已确认:仅注册联系人通道请求体脱敏中间件) - `Bell/server/app/bell/duty_schedule/` - `Bell/server/app/bell/router/contact.go` - `Bell/server/app/bell/router/duty_schedule.go` - `Bell/server/cmd/migrate/migration/version/2026090110000_contact_schedule.go` - `Bell/server/cmd/migrate/migration/version/2026090110000_contact_schedule_test.go` - `Bell/ui/src/api/bell/contact.js` - `Bell/ui/src/api/bell/duty-schedule.js` - `Bell/ui/src/views/bell/contacts/` - `Bell/ui/src/views/bell/duty-schedules/` - `Bell/server/tests/bell_contact_schedule/` 除上述路径外禁止写入;新增路径必须先更新工单并取得确认。 ## 验收标准 - [x] 联系人与通道分对象建模,敏感地址只写不读且脱敏展示 - [x] 通道验证事实与联系人启用状态分离 - [x] 时区、周轮换、生效期、替班、空档和重叠有明确校验 - [x] 发布新排班版本不改写历史版本 - [x] 权限、并发更新和审计通过 PostgreSQL 回归 - [x] 合成联系人/通道可独立验收且不发送外部消息 ## 风险与回退 从当前 `dev` 建立独立任务分支;实施前复核前置和线上原型版本。状态迁移、通知和排班属于高风险业务事实,发现语义变化或客户参数缺失时停止。回退停用新增策略/Worker/通道,不删除联系人、排班版本、投递、Alert 或审计历史。 ## 文档影响 更新 Bell Product-Requirements、Architecture-and-Code-Map、Business-Rules-and-Glossary、Local-Development-and-Verification;新页面菜单和权限入口需记录。
ila added the kind/taskproject/bellpriority/p0 labels 2026-09-01 10:04:32 +08:00
Author
Owner

开始实施(2026-09-01)

  • 分支:feat/183-bell-contact-schedule,从最新 dev(5adee5c)创建
  • 工作区:切换前干净,无用户未提交改动
  • 原型基线:#182 Quant-UX v0.1,App ID 6a964071191a826306a7f4af
  • GoAdmin 冻结参考:
    • go-admin-doc/docs/intro/advanced/advanced.md:页面、菜单、API 与角色授权链
    • go-admin-doc/docs/intro/advanced/api.md:分页 CRUD Handler 结构
    • go-admin-doc/docs/intro/cmd/migrate.md:版本迁移、事务和模型约定
    • go-admin-doc/docs/guide/norm.md:app 业务模块目录边界
  • 继承路径:Bell 现有 app/bell/{rule,alert,router}、动态菜单/API/Casbin 迁移及 ui/src/views/bell/rules 的 GoAdmin/Element Plus 页面模式
  • 默认模块:继续只显示 Bell 业务入口;不启用系统管理、开发工具或框架演示模块
  • 现场参数边界:#176 尚未冻结的真实联系人和站点参数不写入代码;测试仅使用合成数据,不发送外部消息

实施严格限制在 #183 已声明的 write_paths。

## 开始实施(2026-09-01) - 分支:`feat/183-bell-contact-schedule`,从最新 `dev`(`5adee5c`)创建 - 工作区:切换前干净,无用户未提交改动 - 原型基线:#182 Quant-UX v0.1,App ID `6a964071191a826306a7f4af` - GoAdmin 冻结参考: - `go-admin-doc/docs/intro/advanced/advanced.md`:页面、菜单、API 与角色授权链 - `go-admin-doc/docs/intro/advanced/api.md`:分页 CRUD Handler 结构 - `go-admin-doc/docs/intro/cmd/migrate.md`:版本迁移、事务和模型约定 - `go-admin-doc/docs/guide/norm.md`:app 业务模块目录边界 - 继承路径:Bell 现有 `app/bell/{rule,alert,router}`、动态菜单/API/Casbin 迁移及 `ui/src/views/bell/rules` 的 GoAdmin/Element Plus 页面模式 - 默认模块:继续只显示 Bell 业务入口;不启用系统管理、开发工具或框架演示模块 - 现场参数边界:#176 尚未冻结的真实联系人和站点参数不写入代码;测试仅使用合成数据,不发送外部消息 实施严格限制在 #183 已声明的 `write_paths`。
Author
Owner

安全范围变化:等待确认(2026-09-01)

首轮实现与测试发现 GoAdmin 操作日志的真实安全缺口:

  • common/middleware.LoggerToFile 在路由处理前复制 POST/PUT 请求体,并把原文写入 sys_opera_log.oper_param。
  • 当前新增通道 API 的请求体包含完整号码;实际 HTTP 回归已证明响应不回显明文,但操作日志仍会保存明文。
  • #183 的安全目标要求通道地址“只写不读/脱敏展示”,项目永久规则也禁止个人数据进入日志,因此不能以当前状态提交。
  • 路由级中间件晚于 GoAdmin 全局日志中间件,无法可靠修复;需要在 Bell/server/cmd/api/server.go 中、common.InitMiddleware 之前注册 contact.RedactRequestBody()。
  • 脱敏实现文件仍位于已授权的 Bell/server/app/bell/contact/;唯一新增精确写路径是 Bell/server/cmd/api/server.go。
  • 回归将增加:HTTP 新增通道成功后查询 sys_opera_log,确认完整号码不存在且仅保留固定脱敏标记。

已完成且通过的证据(尚未提交):

  • Go 1.26.5 全量 go test ./... 通过。
  • 隔离 PostgreSQL 17:联系人/加密通道/验证、排班空档校验、发布版本不可变、替班冲突、审计和 RBAC 通过。
  • 实际 HTTP:管理员创建与只写通道成功;处置员读取 200、写入 403;新菜单可见。
  • pnpm 9.15.1 lint:0 error(30 个既有上游 warning);前端生产构建成功(4 个既有上游 warning)。
  • DevHarness 严格检查、48 项仓库测试、git diff --check 通过。

等待用户明确确认新增 Bell/server/cmd/api/server.go 写路径后继续。#184/#185 仍受 #183 验收门禁约束。

## 安全范围变化:等待确认(2026-09-01) 首轮实现与测试发现 GoAdmin 操作日志的真实安全缺口: - `common/middleware.LoggerToFile` 在路由处理前复制 POST/PUT 请求体,并把原文写入 `sys_opera_log.oper_param`。 - 当前新增通道 API 的请求体包含完整号码;实际 HTTP 回归已证明响应不回显明文,但操作日志仍会保存明文。 - #183 的安全目标要求通道地址“只写不读/脱敏展示”,项目永久规则也禁止个人数据进入日志,因此不能以当前状态提交。 - 路由级中间件晚于 GoAdmin 全局日志中间件,无法可靠修复;需要在 `Bell/server/cmd/api/server.go` 中、`common.InitMiddleware` 之前注册 `contact.RedactRequestBody()`。 - 脱敏实现文件仍位于已授权的 `Bell/server/app/bell/contact/`;唯一新增精确写路径是 `Bell/server/cmd/api/server.go`。 - 回归将增加:HTTP 新增通道成功后查询 `sys_opera_log`,确认完整号码不存在且仅保留固定脱敏标记。 已完成且通过的证据(尚未提交): - Go 1.26.5 全量 `go test ./...` 通过。 - 隔离 PostgreSQL 17:联系人/加密通道/验证、排班空档校验、发布版本不可变、替班冲突、审计和 RBAC 通过。 - 实际 HTTP:管理员创建与只写通道成功;处置员读取 200、写入 403;新菜单可见。 - pnpm 9.15.1 lint:0 error(30 个既有上游 warning);前端生产构建成功(4 个既有上游 warning)。 - DevHarness 严格检查、48 项仓库测试、`git diff --check` 通过。 等待用户明确确认新增 `Bell/server/cmd/api/server.go` 写路径后继续。#184/#185 仍受 #183 验收门禁约束。
Author
Owner

2026-09-01 用户已明确确认 #183 增加 Bell/server/cmd/api/server.go 写路径。继续实现全局联系人通道请求体脱敏,并验证 sys_opera_log 不保存完整号码;其余范围不变。

2026-09-01 用户已明确确认 #183 增加 `Bell/server/cmd/api/server.go` 写路径。继续实现全局联系人通道请求体脱敏,并验证 `sys_opera_log` 不保存完整号码;其余范围不变。
Author
Owner

最终实施证据(待用户验收)

  • 分支:feat/183-bell-contact-schedule
  • 提交:e81f00e(feat: 实现 Bell 联系人与值班排班 (#183))
  • PR:#189,目标分支 dev,当前可合并;未触碰 main
  • 差异:联系人/通道加密与验证、值班组与版本化周排班、临时替班、不可变事实、GoAdmin 菜单/API/Casbin、Element Plus 页面,以及在 LoggerToFile 前执行的通道请求体脱敏
  • 安全:API 不回显通道地址;PostgreSQL/HTTP 回归确认 sys_opera_log 不含完整地址;未写入真实联系人、密码、令牌或生产密钥
  • 非目标:未发送真实外部消息,#184/#185 未提前实施

验证结果

  • GOTOOLCHAIN=go1.26.5 go test ./... -count=1:通过
  • pwsh ./tests/bell_contact_schedule/run-postgres.ps1:通过;管理员写入、操作员读取 200/写入 403、菜单可见、只写通道、排班不可变与冲突约束均通过
  • corepack pnpm lint:通过,0 error、30 个既有上游 warning
  • corepack pnpm build:prod:成功,4 个既有上游 warning
  • python dev_scripts/harness.py check --strict:通过
  • python -m unittest discover -s tests -v:48 项通过
  • python dev_scripts/harness.py sync --check、git diff --check:通过
  • 首次最终 Go 回归因 C 盘临时空间不足导致链接失败;仅清理本工单可再生成的临时目录并把测试 TEMP/TMP 移到 D 盘后,原命令完整通过,无代码断言失败

长期文档

已按 Wiki 主源更新并在线回读,再同步只读镜像:

  • Product-Requirements:a2aada9db75909dc5fc85cc5d91c8c8bcab82c45
  • Architecture-and-Code-Map:0b760f2398ea4c1fd1d776b0cf869532b167c495
  • Business-Rules-and-Glossary:9be486cd2d3fe424cf389f65c2c868eacab6a020
  • Local-Development-and-Verification:e90d408200d7189771eeec35ae76a00837e2eedf

工单现为“待验收”。按依赖门禁,收到用户明确“#183 验收通过”后才合并/关闭并开始 #184。

## 最终实施证据(待用户验收) - 分支:`feat/183-bell-contact-schedule` - 提交:`e81f00e`(`feat: 实现 Bell 联系人与值班排班 (#183)`) - PR:#189,目标分支 `dev`,当前可合并;未触碰 `main` - 差异:联系人/通道加密与验证、值班组与版本化周排班、临时替班、不可变事实、GoAdmin 菜单/API/Casbin、Element Plus 页面,以及在 `LoggerToFile` 前执行的通道请求体脱敏 - 安全:API 不回显通道地址;PostgreSQL/HTTP 回归确认 `sys_opera_log` 不含完整地址;未写入真实联系人、密码、令牌或生产密钥 - 非目标:未发送真实外部消息,#184/#185 未提前实施 ### 验证结果 - `GOTOOLCHAIN=go1.26.5 go test ./... -count=1`:通过 - `pwsh ./tests/bell_contact_schedule/run-postgres.ps1`:通过;管理员写入、操作员读取 200/写入 403、菜单可见、只写通道、排班不可变与冲突约束均通过 - `corepack pnpm lint`:通过,0 error、30 个既有上游 warning - `corepack pnpm build:prod`:成功,4 个既有上游 warning - `python dev_scripts/harness.py check --strict`:通过 - `python -m unittest discover -s tests -v`:48 项通过 - `python dev_scripts/harness.py sync --check`、`git diff --check`:通过 - 首次最终 Go 回归因 C 盘临时空间不足导致链接失败;仅清理本工单可再生成的临时目录并把测试 TEMP/TMP 移到 D 盘后,原命令完整通过,无代码断言失败 ### 长期文档 已按 Wiki 主源更新并在线回读,再同步只读镜像: - Product-Requirements:`a2aada9db75909dc5fc85cc5d91c8c8bcab82c45` - Architecture-and-Code-Map:`0b760f2398ea4c1fd1d776b0cf869532b167c495` - Business-Rules-and-Glossary:`9be486cd2d3fe424cf389f65c2c868eacab6a020` - Local-Development-and-Verification:`e90d408200d7189771eeec35ae76a00837e2eedf` 工单现为“待验收”。按依赖门禁,收到用户明确“#183 验收通过”后才合并/关闭并开始 #184。
Author
Owner

用户验收结论

  • 验收结果:通过
  • 确认日期:2026-09-01
  • 用户原话:#183 验收通过
  • 合并结果:PR #189 已合并到 dev
  • 合并提交:5128f080b4f830c0b4e0a7aea049e528f5377cfe
  • 长期 Wiki 与本地镜像内容未发生新的验收后变化,无需重复同步。
## 用户验收结论 - 验收结果:通过 - 确认日期:2026-09-01 - 用户原话:`#183 验收通过` - 合并结果:PR #189 已合并到 `dev` - 合并提交:`5128f080b4f830c0b4e0a7aea049e528f5377cfe` - 长期 Wiki 与本地镜像内容未发生新的验收后变化,无需重复同步。
ila closed this issue 2026-09-01 14:14:59 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ila/yovision#183