import 'fake-indexeddb/auto' const BASE = 'http://127.0.0.1:3780' const store = new Map() ;(globalThis as any).localStorage = { getItem: (k: string) => (store.has(k) ? store.get(k) : null), setItem: (k: string, v: string) => { store.set(k, String(v)) }, removeItem: (k: string) => { store.delete(k) } } store.set('dsh_cloud_creds', JSON.stringify({ username: 'goal_smoke', password: 'goal123' })) store.set('dsh_sync_base', BASE) async function main() { const reg = await fetch(BASE + '/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'goal_smoke', password: 'goal123' }) }).catch(() => null) const schema = await import('../src/db/schema') const engine = await import('../src/sync/engine') schema.bindDatabase(new schema.WorklogDB('gs_a')) const a = schema.db // 设备 A:建 goal + plan(goal_id 指向本地 goal) const gid = await a.goal.add({ title: '产品文档学习', kind: '学习', start_date: '2026-10-16', end_date: '2026-10-18', note: null, uuid: '', created_at: '2026-10-16T08:00:00', updated_at: '2026-10-16T08:00:00' } as never) await a.plan.add({ date: '2026-10-16', start_time: '08:00', end_time: '09:00', title: '产品文档学习', kind: '学习', note: null, status: 'todo', actual_minutes: 0, timer_started_at: null, goal_id: gid, uuid: '', created_at: '2026-10-16T08:00:00', updated_at: '2026-10-16T08:00:00' } as never) const rA = await engine.runSync({ baseUrl: BASE, username: 'goal_smoke', password: 'goal123' }) console.log('A push:', JSON.stringify({ p: rA.pushed, e: rA.errors })) // 设备 B:空库拉取 schema.bindDatabase(new schema.WorklogDB('gs_b')) await engine.runSync({ baseUrl: BASE, username: 'goal_smoke', password: 'goal123' }) const b = schema.db const goals = await b.goal.toArray() const plans = await b.plan.toArray() const okGoal = goals.length === 1 const okFk = plans.length === 1 && plans[0].goal_id === goals[0].id && plans[0].title === '产品文档学习' console.log((okGoal ? 'PASS' : 'FAIL') + ' B 拉到长期计划') console.log((okFk ? 'PASS' : 'FAIL') + ' plan.goal_id 正确水合到本地 goal(' + JSON.stringify({ goalId: plans[0] && plans[0].goal_id, localGoalId: goals[0] && goals[0].id }) + ')') process.exit(okGoal && okFk ? 0 : 1) } main().catch(e => { console.error('FAILED:', (e && (e.stack || e.message)) || e); process.exit(1) })