a4902bb730
需求与文档: - 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 通过
54 lines
2.6 KiB
JavaScript
54 lines
2.6 KiB
JavaScript
/**
|
||
* 真实数据完整链路验证 v3(只读,技术约束-011:真实库不做写操作)
|
||
* 手动归属模型:验证归属列(若已迁移)、历史查询、候选列表
|
||
* 注:归属列 ALTER 迁移由插件重启后自动执行(当前运行中的旧构建未含迁移逻辑)
|
||
*/
|
||
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); }
|
||
}
|
||
|
||
// 1. 历史查询
|
||
const hist = await storage.getTradeOrderHistory({ start: '20260901', end: '20260901' });
|
||
console.log(' 历史委托条数:', hist.length);
|
||
const o = hist[0];
|
||
assert(o && o.orderId === '645009273', '查到真实委托 645009273');
|
||
assert(o.code === '001330.SZ', 'code 归一化正确: ' + o.code);
|
||
|
||
// 2. 归属候选列表(只读)
|
||
const cands = await storage.getTradeAttributionCandidates('001330.SZ');
|
||
console.log(' 001330.SZ 候选:', JSON.stringify(cands));
|
||
assert(cands.some(c => c.strategyId === 'grid-supermarket'), '候选含 grid-supermarket(当前持仓)');
|
||
|
||
const cands2 = await storage.getTradeAttributionCandidates('300057.SZ');
|
||
console.log(' 300057.SZ 候选:', JSON.stringify(cands2));
|
||
assert(cands2.length >= 2, '一票多策略候选 ≥2(grid + manual)');
|
||
|
||
// 3. 归属列状态(只读 PRAGMA)
|
||
let cols = [];
|
||
try {
|
||
cols = storage.sqlite.db.prepare('PRAGMA table_info(trade_orders)').all().map(c => c.name);
|
||
} catch { cols = []; }
|
||
console.log(' trade_orders 归属列存在:', cols.includes('strategy_id'), cols.includes('holding_id'));
|
||
if (cols.includes('strategy_id') && cols.includes('holding_id')) {
|
||
// 委托 645009273 已由用户手动设置归属(grid-supermarket)→ 未关联应为 0,按策略过滤应命中
|
||
const unassigned = await storage.getTradeOrderHistory({ start: '20260901', end: '20260901', strategyId: '__unassigned__' });
|
||
const byGrid = await storage.getTradeOrderHistory({ start: '20260901', end: '20260901', strategyId: 'grid-supermarket' });
|
||
const o = hist[0];
|
||
if (o && o.strategyId) {
|
||
assert(byGrid.length >= 1 && byGrid.some((x) => x.orderId === o.orderId), '已设置归属的委托按策略过滤命中');
|
||
assert(unassigned.length === 0, '已设置归属的委托不在「未关联」中');
|
||
} else {
|
||
assert(unassigned.length === hist.length, '未设置归属的委托都在「未关联」过滤中');
|
||
}
|
||
}
|
||
|
||
storage.close();
|
||
console.log('\n结果: ' + pass + ' 通过, ' + fail + ' 失败');
|
||
process.exit(fail > 0 ? 1 : 0); |