# 迁移风险清单 本文档列出将当前 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 实现,整个重构路线就会可控很多。