feat(R-013+重构): 策略自定义字段需求文档 + 结构归类优化

需求与文档:
- R-013 策略自定义字段配置(定义随策略 configSchema 存 settings、值落
  strategy_holdings.values JSON、类型化文本/数字/布尔/枚举)定稿并进入
  PLAN-012 / 迭代 11(含目标数据模型 + 端到端示例 + 技术方案 + 验收标准)
- R-011(Tab设置)/ R-012(UI主题适配)归档至 已完成/,索引标记已归档
- 沉淀约束: 产品约束-010 / 技术约束-015 / 技术约束-016 / UI约束-005

结构重构(技术约束-016):
- src/component/ 平铺还原为语义分域目录: data-source/ storage/ position/
  market/ trades/(git rename 保留历史)
- 清理死代码: 删除 AllocationStorage.js(0 引用)、DataStore
  setDataset/removeDataset(无调用方)
- 同步更新 src/index.js / scripts/*.mjs / tsdown.config.ts 引用
- typecheck + build + test-r009 回归 14/14 通过
This commit is contained in:
2026-09-02 15:38:51 +08:00
parent f1e7e785a1
commit a4902bb730
31 changed files with 509 additions and 198 deletions
@@ -0,0 +1,58 @@
# 计划:策略自定义字段配置(定义随策略,值落库)(阶段航点)
> 编号:PLAN-012 | 粒度:阶段航点 创建:2026-09-02 状态:**执行中**
> 派生自终极目标:目标-002(策略定义能力)、目标-007(人机合一)
> 依据需求:**R-013(已定稿,2026-09-02,老师确认 Q1-Q4 + D6)** —— 符合入范围门槛
> 设计约束:技术约束-012(策略定义仍存 DSH settings / SQLite 存储)沿用;本次新增 产品约束-010、技术约束-015、UI约束-005
## 目标
策略可**自定义、可扩展**:每个策略在设置页「策略分组」子 tab 配置自己的自定义字段定义(configSchema,含类型/枚举/默认值,随策略定义存 settings 不落库);该策略下的每个持仓(strategy_holdings 行)按定义存取一份键值对值(新增 values JSON 列落库);策略持仓 tab 持仓行展开区按定义渲染并编辑值。旧策略无定义的行为与现状完全一致。
## 范围
**做**
1. settings.strategies 扩展 configSchemaschemasteryarray of objecttype union text|number|boolean|enum + enum 选项 + def 默认值),读取归一化(旧项缺省 []);
2. strategy_holdings 新增 values TEXT(JSON) 列(幂等 ALTER,沿用 _ensureTradeAttributionColumns 模式,只读容忍);新增 readValues(holdingId) / writeValues(holdingId, values);现有 openHolding/addShares/reduceShares/closeHolding 保持 values 不随份额操作变动;
3. APIstrategy-positions 每行附 values;新增 holdings/values-update {holdingId, values} 写回(服务端按 configSchema 校验:数字有限数、枚举在选项内、布尔为布尔;允许额外键=可扩展;空值/缺省可写入);
4. 设置页「策略分组」子 tab:策略行可展开 → 展开区字段列表(label/key/type/enum/def+ 添加/编辑/删除字段(字段名/类型/选项/默认值表单)+ 保存走 strategies/update(整表);
5. 策略持仓 tab:持仓行展开区(R-010 基础上)增加「自定义字段」区块:按该策略 configSchema 渲染输入控件(文本=输入框、数字=数字输入、布尔=开关、枚举=下拉),值来自该行 values,编辑即保存调 values-update,保存成功 Toast 反馈;
6. 回归脚本(独立数据目录,技术约束-011):定义字段 → 批量写/改持仓行 values → 校验存储与读取、校验过界值拒绝。
**不做**
- 字段定义落库(定义随策略定义走,D1);
- 策略级(整策略一份)值(值=持仓级,Q1);
- T-006 数据池 / 表格列动态配置(独立需求,起草中);
- T-003 策略配置文件骨架(被本需求吸收,不另做);
- 删除策略时字段定义联动处理之外的数据迁移(兼容:旧策略无定义、旧行 NULL,不迁移,Q4)。
## 涉及文件
```
src/
├── settings.js # strategySchema 扩展 configSchema + 归一化
├── component/SqliteStore.js # _ensureHoldingValuesColumn + readValues/writeValues
├── api/strategies.js # strategy-positions 附加 values + holdings/values-update 端点
├── client/views/SettingsSection.jsx # 「策略分组」子 tab 策略行展开配置字段
└── client/views/StrategyTab.jsx # 持仓行展开区「自定义字段」编辑
scripts/
└── test-r013-custom-fields.mjs # 回归脚本(独立数据目录)
```
## 实现步骤
1. **文档骨架**PLAN-012 + 迭代 11(迭代目标 / 技术实现方案 / 验收标准)+ 约束条目(产品约束-010、技术约束-015、UI约束-005)(本步);
2. **数据层**settings.js configSchema 扩展 + SqliteStore 补列/读写(幂等迁移验证);
3. **API 层**strategy-positions 附加 values + holdings/values-update(含 configSchema 校验);
4. **设置页 UI**:「策略分组」展开配置字段;
5. **策略持仓 UI**:展开区自定义字段编辑(文本/数字/布尔/枚举);
6. **回归脚本 + 验证 + 验收复盘**
## 验收要点
- 设置页「策略分组」:策略行可展开,添加/编辑/删除字段(四种类型 + 枚举选项 + 默认值)后保存,重启后定义仍在;
- 策略持仓 tab:持仓行展开可见「自定义字段」区块,四种类型控件按定义渲染,编辑值保存后刷新仍在(落库);
- 同策略多行各有各的值;不同策略字段集互不影响;
- 旧策略(无 configSchema)持仓行不出现字段区,现有操作(加仓/减仓/清仓/展开交易记录)不受影响;
- 服务端校验生效:数字填非数字、枚举填选项外拒绝并提示;
- typecheck + build 通过;回归脚本全绿。