const path = require('path') process.chdir('d:/Trae_Files/TRAE-Toolbox') const http = require('http') const db = require(path.join(process.cwd(), 'src/server/mp_rep_clock/db')) const locks = require(path.join(process.cwd(), 'src/server/mp_rep_clock/locks')) const store = require(path.join(process.cwd(), 'src/server/mp_rep_clock/kits/rep_clock/store')) // 清锁先 locks.resetRunningLock() const nowIso = () => new Date().toISOString() db.getDb().prepare(`UPDATE rc_sessions SET status='abandoned', ended_at=?, updated_at=?, manual_stopped=1 WHERE status='running' AND deleted=0`).run(nowIso(), nowIso()) const cardId = 'rc_card_c6aebdfb-7330-43c1-b42c-a6a856a715f2' // 1. 直接 Node 层 reserve + createSession,模拟"第一发start成功" const s1 = store.createSession({ cardId }) const r1 = locks.reserveRunningLock(s1.id) console.log('== 1st createSession OK ==') console.log('session1 id:', s1.id, 'status=', s1.status) console.log('lock reserve1:', JSON.stringify(r1)) // 2. 再调用一次 createSession(第二发 start 模拟冲突),但不清锁 const s2 = store.createSession({ cardId }) const r2 = locks.reserveRunningLock(s2.id) console.log('\n== 2nd 故意冲突 ==') console.log('session2 id:', s2.id) console.log('lock reserve2:', JSON.stringify(r2)) console.log('字段检查:expiresInMs 存在?', typeof r2.expiresInMs, r2.expiresInMs, '秒=', Math.ceil(r2.expiresInMs/1000)) // 3. 再用 HTTP 调 sessions/start 直接看 409 body(等价于用户 curl) console.log('\n== 3rd HTTP POST sessions/start ==') const payload = JSON.stringify({ cardId }) const req = http.request({ hostname: '127.0.0.1', port: 8976, path: '/api/mp_rep_clock/kits/rep_clock/sessions/start', method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': Buffer.byteLength(payload), 'X-Mp-Timeassistant': 'probe_v1', } }, (res) => { let buf = '' res.on('data', c => buf += c) res.on('end', () => { console.log('HTTP', res.statusCode) console.log('BODY:', buf) try { const j = JSON.parse(buf) console.log('字段检查 expiresInMs =', j.expiresInMs, '秒=', Math.ceil(j.expiresInMs/1000)) console.log('字段检查 conflictSessionId =', j.conflictSessionId) console.log('字段检查 expiredLockCleared =', j.expiredLockCleared) } catch(e){ console.log('not json:', e.message) } }) }) req.on('error', e => console.log('err', e.message)) req.write(payload) req.end()