dd98b4d45b
- 新增 02-计划/计划-数据存储SQLite.md(PLAN-007) - 新增 04-迭代记录/06-数据存储SQLite/ 五份文档(迭代目标/技术实现方案/验收标准/UI交互调用分析/迭代复盘) - 归档 R-008 至 已完成/(含归档头 + 讨论记录索引),索引更新为已实现(已归档) - 设计约束更新:技术方案约束-012 标注 SQLite 变更、数据存储设计.md 第 9 节变更预告 - 需求池说明.md 新增「归档与转正规范」;迭代记录说明.md 新增「实现经验沉淀」 - 验收标准修正 db 文件名笔误(one-divine-lot.db → store.db)
3.6 KiB
3.6 KiB
迭代复盘:06-数据存储SQLite(JSON → SQLite)
复盘日期:2026-09-01 | 迭代状态:已完成(验收通过) 关联需求:R-008(数据存储管理 JSON → SQLite,已定稿) 关联计划:PLAN-007(数据存储 SQLite 化)
结果
迭代 06 达成:数据存储从 JSON data store(store.json / store.market.json / store.schema.json)升级为 SQLite(store.db,node:sqlite),仅存储引擎替换、对外行为不变。真实数据迁移完成(15 条持仓 + 13 条行情),JSON 清理废弃,份额/行情/设置功能全部不回归。
过程事实
- 技术选型验证:node:sqlite(Node 22.23.1 内置,DatabaseSync,SQLite 3.51.3)实测可用;better-sqlite3 需原生编译 → 选 node:sqlite(零依赖分发,experimental 风险由 SqliteStore 封装隔离);
- 表结构:strategy_holdings(持仓生命周期表:holding_id 自增 + strategy_id/code/shares/created_at/closed_at + 部分唯一索引)+ market_quotes_cache(code 主键 + last_price/last_close/updated_at 两列);不建 trades(R-007 再建);
- SqliteStore 封装:init/迁移/持仓生命周期(openHolding/addShares/reduceShares/closeHolding)/行情读写/close;
- DataStore 改造:门面委托 SqliteStore,保留兼容 API(getDataset/getAllDatasets/行情读写),启动检测自动迁移(幂等);
- PositionManager 适配:整策略 dataset 重写(_setShares)→ 单票生命周期(_applySharesForStrategy 绝对目标语义);
- 迁移脚本:scripts/migrate-json-to-sqlite.mjs + pnpm migrate 命令(一次性 + 启动自动迁移共用逻辑);
- 真实迁移:15 持仓 + 13 行情迁入 SQLite,与迁移前逐条一致;JSON 备份 .bak 后清理删除(仅留 store.db);
- 移除「一键清零」按钮(老师决定):前端按钮/弹窗 + 后端 remove-all-shares 端点移除;clearStrategyShares 保留(删除策略联动)。
经验教训(复盘沉淀)
1. 语义迁移必须逐方法核对(重要)
- 教训:改造 PositionManager 时,把 addToStrategy 的「新增量」误当「绝对目标份额」传给生命周期方法,导致加仓 100 变 100 —— 真实 API 验证时发现(600719.SH 手动做T 少了 100 股),已修复并回滚数据;
- 沉淀:方法语义变更(增量 vs 绝对量)必须显式命名(_applySharesForStrategy 接收 target 绝对目标),调用方逐处核对;改造后必须用真实 API 走一遍 CRUD 回归,不能只靠隔离单测。
2. node:sqlite 的锁行为
- 插件进程持有 SQLite 连接时,外部脚本再开连接写库会报
attempt to write a readonly database; - 沉淀:真实数据修正必须走插件自己的 API(或停机后操作),外部脚本只能读;测试写操作用 ODL_TEST_DATA_DIR 隔离(技术约束-011)。
3. 关闭连接
- 插件 dispose 时必须 storage.close()(关闭 SQLite 连接),避免资源泄漏。
4. 文档与实际必须一致
- 验收标准初稿写
one-divine-lot.db,实际实现用store.db—— 归档前已修正。
遗留/后续
- 盘中行情写 SQLite 验证:本次验收时已收盘,无实时推送;开盘后应确认行情防抖写回 store.db(观察 updated_at / 文件 mtime);
- R-007 交易记录关联:strategy_holdings.holding_id 已就绪,可作为 trades 表关联锚点(R-007 实现时建 trades 表);
- SqliteStore 迁移逻辑引用旧文件名:migrateJson 仍检查 store.json 等(幂等跳过),保留用于新环境初始化。