[SEN] 修复设备编辑请求包含新建专用字段 #56

Closed
opened 2026-08-13 22:34:12 +08:00 by ila · 2 comments
Owner

状态

已完成

原始需求

  • 来源:用户于 2026-08-13 在 Sense 设备管理编辑安装位置。
  • 脱敏摘要:填写中文安装位置保存时提示“请求内容格式不正确”;用户确认“建工单,做”。
  • 只读诊断:中文 UTF-8 请求可由后端正常保存。真实根因是编辑表单使用对象展开,把只允许新建时提交的 modality 一并发送;后端 DecodeJSON 启用未知字段拒绝,因此 PATCH 返回 invalid_request。英文编辑也会触发,中文不是根因。

目标

  • 设备编辑仅发送后端 PATCH 契约允许的字段。
  • 新建设备仍发送设备类型。
  • 增加前端 payload 契约测试,覆盖中文名称/位置和新建、编辑字段差异。
  • 保持后端严格拒绝未知字段,不通过放宽解析掩盖前端契约错误。

非目标

  • 不修改设备数据结构、数据库或凭据逻辑。
  • 不放宽后端 DisallowUnknownFields。
  • 不修改视频接入、MediaMTX、Brain、Bell 或共享契约。
  • 不重构整个设备管理页面。

主项目与写路径

  • 主项目:Sense
  • 主 agent:root / Codex
  • 独立运行:Brain、Bell 不启动也可验收。
  • write_paths:
    • Sense/ui/src/views/sense/device/Devices.vue
    • Sense/ui/src/views/sense/device/devicePayload.mjs
    • Sense/ui/tests/devicePayload.test.mjs
    • Sense/ui/package.json
    • docs/03-business-rules-and-glossary.md
    • docs/06-troubleshooting.md
    • docs/task/**
    • wiki-docs.json

前置依赖

  • #23:设备台账与凭据边界已有实现。
  • 当前修复只影响 Sense 设备编辑请求,不依赖其他项目。

已确认方案

  1. 新建 payload 显式包含 name、location、modality、capabilities。
  2. 编辑 payload 显式仅包含 name、location、capabilities、version,不使用表单对象展开。
  3. 提取纯 payload 构造函数,用 Node 内置测试运行器覆盖中文值原样保留及编辑字段白名单。
  4. 保持后端严格 JSON 契约;执行前端测试、lint/build、Go 回归及真实中文保存/读取验证。

风险与回退

  • 风险:遗漏编辑接口必需字段会造成保存失败;通过精确契约测试和真实 API 回读验证。
  • 回退:撤销本工单提交即可;无数据库迁移。
  • 不记录或修改摄像机凭据。

验收标准

  • 编辑设备保存中文名称和安装位置成功。
  • PATCH payload 不包含 modality 或其他只读/新建专用字段。
  • 新建设备 payload 仍包含 modality。
  • payload 单元测试、前端 lint/build 和 Go 回归通过。
  • 后端未知字段严格拒绝策略保持不变。
  • 保存后重新查询能读取中文安装位置。

文档影响

更新 Wiki 业务规则和排错页面,说明新建/编辑 payload 边界及“请求内容格式不正确”的排查方法;完成后创建任务归档并导出镜像。

## 状态 已完成 ## 原始需求 - 来源:用户于 2026-08-13 在 Sense 设备管理编辑安装位置。 - 脱敏摘要:填写中文安装位置保存时提示“请求内容格式不正确”;用户确认“建工单,做”。 - 只读诊断:中文 UTF-8 请求可由后端正常保存。真实根因是编辑表单使用对象展开,把只允许新建时提交的 `modality` 一并发送;后端 `DecodeJSON` 启用未知字段拒绝,因此 PATCH 返回 `invalid_request`。英文编辑也会触发,中文不是根因。 ## 目标 - 设备编辑仅发送后端 PATCH 契约允许的字段。 - 新建设备仍发送设备类型。 - 增加前端 payload 契约测试,覆盖中文名称/位置和新建、编辑字段差异。 - 保持后端严格拒绝未知字段,不通过放宽解析掩盖前端契约错误。 ## 非目标 - 不修改设备数据结构、数据库或凭据逻辑。 - 不放宽后端 `DisallowUnknownFields`。 - 不修改视频接入、MediaMTX、Brain、Bell 或共享契约。 - 不重构整个设备管理页面。 ## 主项目与写路径 - 主项目:Sense - 主 agent:root / Codex - 独立运行:Brain、Bell 不启动也可验收。 - `write_paths`: - `Sense/ui/src/views/sense/device/Devices.vue` - `Sense/ui/src/views/sense/device/devicePayload.mjs` - `Sense/ui/tests/devicePayload.test.mjs` - `Sense/ui/package.json` - `docs/03-business-rules-and-glossary.md` - `docs/06-troubleshooting.md` - `docs/task/**` - `wiki-docs.json` ## 前置依赖 - #23:设备台账与凭据边界已有实现。 - 当前修复只影响 Sense 设备编辑请求,不依赖其他项目。 ## 已确认方案 1. 新建 payload 显式包含 `name`、`location`、`modality`、`capabilities`。 2. 编辑 payload 显式仅包含 `name`、`location`、`capabilities`、`version`,不使用表单对象展开。 3. 提取纯 payload 构造函数,用 Node 内置测试运行器覆盖中文值原样保留及编辑字段白名单。 4. 保持后端严格 JSON 契约;执行前端测试、lint/build、Go 回归及真实中文保存/读取验证。 ## 风险与回退 - 风险:遗漏编辑接口必需字段会造成保存失败;通过精确契约测试和真实 API 回读验证。 - 回退:撤销本工单提交即可;无数据库迁移。 - 不记录或修改摄像机凭据。 ## 验收标准 - [x] 编辑设备保存中文名称和安装位置成功。 - [x] PATCH payload 不包含 `modality` 或其他只读/新建专用字段。 - [x] 新建设备 payload 仍包含 `modality`。 - [x] payload 单元测试、前端 lint/build 和 Go 回归通过。 - [x] 后端未知字段严格拒绝策略保持不变。 - [x] 保存后重新查询能读取中文安装位置。 ## 文档影响 更新 Wiki 业务规则和排错页面,说明新建/编辑 payload 边界及“请求内容格式不正确”的排查方法;完成后创建任务归档并导出镜像。
ila added the kind/taskproject/sensescope/independentpriority/p0area/ux labels 2026-08-13 22:34:12 +08:00
ila referenced this issue from a commit 2026-08-13 22:40:19 +08:00
ila referenced this issue from a commit 2026-08-13 22:40:19 +08:00
Author
Owner

实施完成,等待验收

根因与修复

设备编辑页此前通过展开整个表单对象构造 PATCH 请求,因而携带了只允许新建时提交的 modality。后端启用了未知字段严格拒绝,返回 invalid_request;中文值本身没有问题,英文编辑同样会失败。

现已改为显式 payload 白名单:

  • 新建:name、location、modality、capabilities
  • 编辑:name、location、capabilities、version
  • 后端 DisallowUnknownFields 保持不变

验证证据

  • payload 单元测试:2/2 通过,覆盖中文值、新建包含 modality、编辑排除 modality / id
  • 前端 lint:0 error;806 条既有 warning
  • 前端 build:通过;3 条既有体积 warning
  • go test ./...:通过
  • PostgreSQL 实际 API:中文安装位置 PATCH 返回成功,GET 可回读;当前测试设备位置为“教学楼一楼东门”,版本已递增
  • Windows 发布目录已重新构建并启动;端口 18080、8554、8889、9997 正常监听
  • git diff --check:通过

代码、文档与合并请求

  • 本地实现提交:8e3a25d
  • 本地归档提交:a9f8a55
  • PR:#57
  • Wiki:
    • Business-Rules-and-Glossary revision f9c089d2b993478e586f4abdb1845952a3cd3c51
    • Troubleshooting revision 7deb549d8b0ae87cdca0c7494e36150d261248a1
    • Task-56 revision 212cf0a998afb41adfb1d671df07a1362580ea9e

未验证与既有阻塞

  • 尚需用户在浏览器中执行最终点击保存验收。
  • check_harness.py --strict 被既有 #44 归档缺少“最终方案”阻塞,与本任务代码无关。
  • sync_wiki_docs.py --check 使用本地旧 Wiki 地址并返回 404;本任务 Wiki 已通过 Gitea MCP 写入并读取确认。

状态保持“待验收”,工单不关闭。

## 实施完成,等待验收 ### 根因与修复 设备编辑页此前通过展开整个表单对象构造 PATCH 请求,因而携带了只允许新建时提交的 `modality`。后端启用了未知字段严格拒绝,返回 `invalid_request`;中文值本身没有问题,英文编辑同样会失败。 现已改为显式 payload 白名单: - 新建:`name`、`location`、`modality`、`capabilities` - 编辑:`name`、`location`、`capabilities`、`version` - 后端 `DisallowUnknownFields` 保持不变 ### 验证证据 - payload 单元测试:2/2 通过,覆盖中文值、新建包含 `modality`、编辑排除 `modality` / `id` - 前端 lint:0 error;806 条既有 warning - 前端 build:通过;3 条既有体积 warning - `go test ./...`:通过 - PostgreSQL 实际 API:中文安装位置 PATCH 返回成功,GET 可回读;当前测试设备位置为“教学楼一楼东门”,版本已递增 - Windows 发布目录已重新构建并启动;端口 18080、8554、8889、9997 正常监听 - `git diff --check`:通过 ### 代码、文档与合并请求 - 本地实现提交:`8e3a25d` - 本地归档提交:`a9f8a55` - PR:#57 - Wiki: - Business-Rules-and-Glossary revision `f9c089d2b993478e586f4abdb1845952a3cd3c51` - Troubleshooting revision `7deb549d8b0ae87cdca0c7494e36150d261248a1` - Task-56 revision `212cf0a998afb41adfb1d671df07a1362580ea9e` ### 未验证与既有阻塞 - 尚需用户在浏览器中执行最终点击保存验收。 - `check_harness.py --strict` 被既有 #44 归档缺少“最终方案”阻塞,与本任务代码无关。 - `sync_wiki_docs.py --check` 使用本地旧 Wiki 地址并返回 404;本任务 Wiki 已通过 Gitea MCP 写入并读取确认。 状态保持“待验收”,工单不关闭。
ila referenced this issue from a commit 2026-08-14 09:08:23 +08:00
Author
Owner

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

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

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

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

No dependencies set.

Reference: ila/yovision#56