Files
NixMsg/docs/DEVIATIONS.md
T

104 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现与文档的偏差
开发中凡是实现和 [PRD.md](./PRD.md)、[DEVELOPMENT.md](./DEVELOPMENT.md) 不一致的地方,以及文档没写清、开发中自己拿主意的地方,都记在这里,交给负责人事后审阅。开发全程自动推进,记下来就继续,不等审阅。
每条写清:日期、原条款(文档和小节)、实际做法、原因、备选方案、影响。各线只写自己那一节,避免多条线同时改同一段。
## 总控 L
### T0.1 2026-09-30
1. **前端嵌入方式**
- 原条款:DEVELOPMENT 第 3 节 `web/embed.go` 用 `//go:embed all:dist`;TASKS T0.1;`.gitignore` 忽略 `web/dist`。
- 实际做法:默认构建用 `-tags` 以外的 `embed_stub.go` 嵌入 `web/stub/`;`task build` 加 `-tags embeddist` 嵌入真实 `web/dist`。
- 原因:`web/dist` 不进仓库,且要求没有前端产物时也能 `go build`。
- 备选方案:提交最小 `dist`;或构建前脚本生成占位目录。
- 影响:裸 `go build` 不含真实前端;正式产物必须走 `task build`。
2. **listen.addr 写入时机**
- 原条款:DEVELOPMENT 4.1「端口写 0 时」写 `<data_dir>/listen.addr`。
- 实际做法:只要 `serve` 启动成功就写入实际监听地址。
- 原因:测试启动器统一读取该文件更简单,固定端口场景也无害。
- 备选方案:仅当配置端口为 0 时写入。
- 影响:多一个小文件;行为超集,兼容文档要求。
3. **迁移占位**
- 原条款:T0.3 才写完整表与 `VACUUM INTO` 备份;T0.1 允许空执行器加空 0001。
- 实际做法:`internal/store.Migrate` 建 `schema_migrations` 并应用 `0001_init.sql`(内容为 `SELECT 1;`);不做迁移前备份。
- 原因:保证 serve 可跑通迁移路径,表结构留给 T0.3。
- 备选方案:完全空文件 + 只记版本。
- 影响:T0.3 需替换 0001 正文并补备份逻辑;已应用的占位版本号仍为 1。
4. **Taskfile 引入 taskfiles**
- 原条款:TASKS T0.1 / 4.2 引入 `taskfiles/*.yml`。
- 实际做法:`includes: '*': taskfile: taskfiles/*.yml, optional: true`,并放 `_init.yml` 占位。
- 原因:空目录 glob 可能失败;各线稍后加自己的 yml。
- 备选方案:主文件逐条 optional include 各线文件名。
- 影响:无。
5. **deploy/Dockerfile**
- 原条款:完整多架构镜像属 Q4;T0.1 需要 `task docker` 目标。
- 实际做法:提供单架构多阶段 Dockerfile 骨架,供 `task docker` 使用;T0.1 验证另用官方 `golang` 镜像跑 `task check`。
- 原因:让 docker 目标可执行,又不抢 Q4 范围。
- 备选方案:docker 目标仅 echo 提示。
- 影响:镜像发布流程仍由 Q4 定稿。
### T0.5 2026-09-30
1. **admin init / 管理员密码**
- 原条款:TASKS T0.5「自动执行 `admin init` 拿到管理员密码」;命令行启动器 JSON 含管理员密码。
- 实际做法:定义 `AdminInitializer`(默认 `CLIAdminInit`);二进制尚无 `admin` 子命令时返回 `ErrAdminInitUnsupported`,启动器跳过并继续起 serve;`admin_password` 字段为空字符串。示例集成测试只验 `/healthz`。
- 原因:`admin init` 属 P1,当前 main 仅有 `version`/`serve`。
- 备选方案:harness 内嵌假密码写入库(无表结构可写);或阻塞等 P1。
- 影响:P1 合入后无需改调用方接口,密码解析约定见 `parseAdminPassword`;Q/SDK 集成测试在拿到非空密码前勿依赖管理登录。
2. **MQTT 测试客户端范围**
- 原条款:能收发 DEVELOPMENT 第 6 节应用帧。
- 实际做法:提供 TCP / WebSocket(`/mqtt`,子协议 `mqtt`)传输层 `MQTTClient`,收发原始 MQTT 控制包字节;不实现 CONNECT/hello/主题业务。
- 原因:内置 broker 与协议处理尚未合入(连接 N / 后续任务);T0.5 先给可连传输与占位 API。
- 备选方案:引入完整 MQTT 客户端库并编假 broker。
- 影响:业务级帧测试在 broker 可用后由各线基于 `Send`/`Recv` 或再包一层完成。
3. **进程停止方式**
- 原条款:优雅停机(DEVELOPMENT 7.8 / P1)。
- 实际做法:测试启动器对子进程使用 `Kill`(Windows 上 `Interrupt` 不可靠)。
- 原因:保证并行测试与清理在 Windows 上稳定。
- 备选方案:Unix 发 SIGTERM;Windows 用 Job Object / Ctrl+Break。
- 影响:不覆盖优雅停机验收;该验收仍归 P1/Q。
## 平台 P
暂无。
## 连接 N
暂无。
## 消息 M
暂无。
## 身份 I
暂无。
## 后台接口 A
暂无。
## 后台网页 W
暂无。
## SDK 一 S1
暂无。
## SDK 二 S2
暂无。
## 测试交付 Q
暂无。