Files
one_divine_lot/scripts/verify-real-attribution.mjs
kyugao a4902bb730 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 通过
2026-09-02 15:38:51 +08:00

48 lines
2.3 KiB
JavaScript
Raw Permalink 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.
/**
* 真实库归属闭环验证(写操作测试):设置归属 → 过滤 → UPSERT 保留 → 还原
* 注意:插件进程持锁时外部写会失败;若失败说明插件在运行(正常),跳过写操作
*/
import { DataStore } from '../src/storage/DataStore.js';
const storage = new DataStore({ dataDir: process.env.HOME + '/.dsh/one-divine-lot' });
await storage._ensure();
let pass = 0, fail = 0;
function assert(cond, msg) {
if (cond) { pass++; console.log(' ✅ ' + msg); }
else { fail++; console.log(' ❌ ' + msg); }
}
try {
// 1. 设置归属:博纳影业 001330.SZ → grid-supermarket(候选 holdingId=13
const ok = await storage.setTradeOrderAttribution('645009273', 'grid-supermarket', 13);
assert(ok, '手动设置归属成功(grid-supermarket / holding 13');
// 2. 读取确认持久化
const row = storage.sqlite.db.prepare('SELECT strategy_id, holding_id FROM trade_orders WHERE order_id=?').get('645009273');
assert(row.strategy_id === 'grid-supermarket' && row.holding_id === 13, '归属已持久化');
// 3. 按策略过滤命中
const byGrid = await storage.getTradeOrderHistory({ start: '20260901', end: '20260901', strategyId: 'grid-supermarket' });
assert(byGrid.length === 1 && byGrid[0].orderId === '645009273', '按 grid-supermarket 过滤命中');
// 4. 未关联过滤为空(该委托已设归属)
const unassigned = await storage.getTradeOrderHistory({ start: '20260901', end: '20260901', strategyId: '__unassigned__' });
assert(unassigned.length === 0, '未关联过滤为空');
// 5. 成交按委托归属过滤
const fills = await storage.getTradeFillHistory({ start: '20260901', end: '20260901', strategyId: 'grid-supermarket' });
assert(fills.length === 1, '成交按 grid-supermarket 过滤命中');
// 6. 还原为未关联(不污染真实数据)
await storage.setTradeOrderAttribution('645009273', null, null);
const restored = storage.sqlite.db.prepare('SELECT strategy_id FROM trade_orders WHERE order_id=?').get('645009273');
assert(restored.strategy_id === null, '归属已还原(未关联)');
} catch (e) {
console.log(' ⚠️ 写操作被锁(插件持锁中,正常):' + (e?.message ?? e));
fail++;
}
storage.close();
console.log('\n结果: ' + pass + ' 通过, ' + fail + ' 失败');
process.exit(fail > 0 ? 1 : 0);