239 lines
8.6 KiB
Markdown
239 lines
8.6 KiB
Markdown
|
|
# 迁移风险清单
|
||
|
|
|
||
|
|
本文档列出将当前 Go 后端重构为 Python 时的主要风险点。这里的风险判断,默认都是以“当前 Go 行为需要尽量兼容”为前提。
|
||
|
|
|
||
|
|
## 最高风险区域
|
||
|
|
|
||
|
|
### 1. `POST /homeassistant/publish` 存在隐式行为契约
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前 Home Assistant 网关使用 `target`、`action`、`content` 这种 envelope
|
||
|
|
- `content` 不是标准嵌套 JSON,而是字符串化 payload
|
||
|
|
- 有些 payload 明显依赖单引号 pseudo-JSON,再在代码中做归一化
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 如果 Python 版过早改成“严格、干净、标准化的嵌套 JSON”,现有 Home Assistant automations 可能直接失效
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- [`src/components/homeassistant/homeassistant.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/homeassistant/homeassistant.go:82)
|
||
|
|
- 测试见 [`src/components/homeassistant/homeassistant_test.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/homeassistant/homeassistant_test.go:129)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 在重构前先收集真实线上 payload 样例
|
||
|
|
- 第一阶段保留兼容性解析
|
||
|
|
- 为所有当前支持的 `target/action` 增加回归测试
|
||
|
|
|
||
|
|
### 2. TickTick OAuth 与 token 持久化流程
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- OAuth `state` 当前只保存在进程内
|
||
|
|
- token 获取后会直接写回 YAML 配置文件
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- Python 重构很容易在不自觉的情况下改变操作流程
|
||
|
|
- token 持久化语义一变,可能会带来难排查的鉴权失败
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- callback 与配置回写逻辑见 [`src/util/ticktickutil/ticktickutil.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/util/ticktickutil/ticktickutil.go:103)
|
||
|
|
- 授权 URL 初始化见 [`src/util/ticktickutil/ticktickutil.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/util/ticktickutil/ticktickutil.go:275)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 在编码前先确定 token storage 方案
|
||
|
|
- 保持 callback 契约稳定
|
||
|
|
- 在 staging 环境用真实 TickTick app 做端到端验证
|
||
|
|
|
||
|
|
### 3. Poo recorder 的副作用比 API 表面看起来更复杂
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- `POST /poo/record` 不只是写一条 DB
|
||
|
|
- 它还会镜像到 Notion、发布 Home Assistant sensor、并且可能触发 Home Assistant webhook
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 即使 Python 版 API 看起来兼容,如果漏掉这些副作用,也会导致真实自动化行为偏差
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:57)
|
||
|
|
- [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:97)
|
||
|
|
- [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:339)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 把 endpoint 契约和 side-effect 契约分开写清楚
|
||
|
|
- 在 Python 中通过显式 service / adapter 接口承接这些行为
|
||
|
|
- 用 mock Home Assistant / TickTick / Notion 的方式做测试
|
||
|
|
|
||
|
|
### 4. 移除 Notion 会改变当前运行预期
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- Notion 虽然已经被识别为“不计划继续保留”,但它现在并不是边缘代码
|
||
|
|
- 它当前参与启动、请求处理以及每日同步
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 去掉 Notion 会实质改变数据流
|
||
|
|
- 也可能影响历史镜像、人工运维方式以及启动要求
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- 启动时强依赖 `notion.token`,见 [`src/cmd/serve.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/cmd/serve.go:41)
|
||
|
|
- 每日同步逻辑见 [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:191)
|
||
|
|
- helper CLI 见 [`src/helper/poo_recorder_helper/cmd/reverse.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/helper/poo_recorder_helper/cmd/reverse.go:21)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 在文档里显式说明 Notion 将被下线 / 不迁移
|
||
|
|
- 先决定是否需要一次性历史导出或回填
|
||
|
|
- 确保移除 Notion 后,`pooRecorder.tableId` 和 `notion.token` 不再阻塞服务启动
|
||
|
|
|
||
|
|
## 中等风险区域
|
||
|
|
|
||
|
|
### 5. SQLite 兼容性与时间戳格式
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前代码把时间戳以文本形式存储
|
||
|
|
- `location` 和 `poo` 两个模块使用的时间格式并不相同
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- Python 重构若擅自统一时间格式,可能会破坏旧 DB 的可兼容读取
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- poo 时间戳写入逻辑见 [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:344)
|
||
|
|
- location 时间戳写入逻辑见 [`src/components/locationRecorder/locationRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/locationRecorder/locationRecorder.go:61)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 先决定 Python 第一阶段是否直接复用现有 DB 文件
|
||
|
|
- 如果要复用,就要保留当前时间戳序列化行为
|
||
|
|
- 为数据层建立回归样例
|
||
|
|
|
||
|
|
### 6. 输入校验行为可能与 FastAPI 默认习惯冲突
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- FastAPI / Pydantic 通常更倾向严格校验
|
||
|
|
- 当前 Go 代码的校验行为并不一致:
|
||
|
|
- 有些接口拒绝 unknown fields
|
||
|
|
- `location` 数值解析错误会被静默忽略
|
||
|
|
- 很多成功响应是空响应体
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 更“正确”的校验,也可能是破坏兼容性的改动
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- 多个 handler 都开启了严格字段检查
|
||
|
|
- `location` 的静默 float parsing 见 [`src/components/locationRecorder/locationRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/locationRecorder/locationRecorder.go:54)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 先明确哪些怪异行为是必须兼容的,哪些可以修正
|
||
|
|
- 第一阶段如果要保持兼容,可以在 Python 里用自定义校验逻辑模拟当前行为
|
||
|
|
|
||
|
|
### 7. 定时任务行为漂移
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前应用内嵌了一个每天 `0 5 * * *` 执行的 Notion 同步任务
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 如果 Python 版仍保留类似行为,时区、执行时机、幂等性处理差异都可能导致重复或漏同步
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- [`src/components/pooRecorder/pooRecorder.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/pooRecorder/pooRecorder.go:180)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 如果 Notion 被移除,就应有意识地同步移除 scheduler 相关逻辑,并写清楚原因
|
||
|
|
- 如果在过渡期暂时保留,就要明确 timezone 与幂等语义
|
||
|
|
|
||
|
|
### 8. self-HTTP 编排改成 direct service calls 的差异
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前 Home Assistant 网关通过调用 `localhost` 上的本地接口来驱动其它模块
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 改成直接函数 / service 调用本身是合理的,但可能改变 timeout、错误传播和日志行为
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- [`src/components/homeassistant/homeassistant.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/homeassistant/homeassistant.go:88)
|
||
|
|
- [`src/components/homeassistant/homeassistant.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/homeassistant/homeassistant.go:115)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 对外 HTTP 行为保持不变
|
||
|
|
- 但在内部重写后,补足状态码和失败语义测试
|
||
|
|
|
||
|
|
## 风险较低但仍重要的区域
|
||
|
|
|
||
|
|
### 9. 部署模型变化
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前部署方式是 supervisor-based
|
||
|
|
- 未来目标是容器化
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 启动文件路径、配置文件写入位置、token persistence 方式,在容器环境下都可能出问题
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- 安装脚本见 [`helper/install.sh`](/home/tianyu/workspace/home-automation/legacy/go-backend/helper/install.sh:45)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 把运行时状态从镜像内容中解耦
|
||
|
|
- 预先定义 DB/config 是否需要挂载 volume
|
||
|
|
- 在 cutover 前先写清楚 container env vars 与文件挂载约定
|
||
|
|
|
||
|
|
### 10. 现有测试过少
|
||
|
|
|
||
|
|
风险:
|
||
|
|
|
||
|
|
- 当前大多数模块没有自动化测试
|
||
|
|
|
||
|
|
为什么重要:
|
||
|
|
|
||
|
|
- 没有安全网时,重构很容易改坏行为而不自知
|
||
|
|
|
||
|
|
当前证据:
|
||
|
|
|
||
|
|
- 当前只发现 [`src/components/homeassistant/homeassistant_test.go`](/home/tianyu/workspace/home-automation/legacy/go-backend/src/components/homeassistant/homeassistant_test.go:1)
|
||
|
|
|
||
|
|
缓解建议:
|
||
|
|
|
||
|
|
- 把 contract test 建设视作迁移工作的一部分,而不是迁移后的补票
|
||
|
|
- 每迁一个模块,就同步补该模块的测试
|
||
|
|
|
||
|
|
## 总结
|
||
|
|
|
||
|
|
这次重构最大的风险,不是“Go 改 Python”本身,而是几个隐藏得很深的行为契约:
|
||
|
|
|
||
|
|
- Home Assistant 命令 payload 的真实格式
|
||
|
|
- TickTick 的 OAuth / token 生命周期
|
||
|
|
- poo recorder 的一组副作用行为
|
||
|
|
- 当前仍活跃、但计划下线的 Notion 耦合
|
||
|
|
|
||
|
|
只要先把这些契约写清楚、测清楚,再开始 Python 实现,整个重构路线就会可控很多。
|