import assert from 'node:assert/strict'; import test from 'node:test'; import { buildPersonalMemoryCandidateSchemaSql, createPersonalMemoryCandidateStore, ensurePersonalMemoryCandidateSchema, } from './memory-v2-personal-store.mjs'; test('candidate schema is explicit and idempotent', async () => { const calls = []; const pool = { async query(sql, params) { calls.push({ sql, params }); return [[], []]; } }; await ensurePersonalMemoryCandidateSchema(pool); assert.match(calls[0].sql, /CREATE TABLE IF NOT EXISTS/); assert.match(calls[0].sql, /h5_memory_v2_candidates/); assert.throws(() => buildPersonalMemoryCandidateSchemaSql({ table: 'bad-name' }), /Invalid/); }); test('candidate store saves, lists, counts, and reviews with parameterized SQL', async () => { const calls = []; const pool = { async query(sql, params = []) { calls.push({ sql, params }); if (sql.startsWith('INSERT')) return [{ affectedRows: 1 }, []]; if (sql.startsWith('SELECT *')) return [[{ id: 'pmc_1', user_id: 'u1', session_id: 's1', memory_type: 'episodic', content: '决定使用 main 发布', importance: '0.9', confidence: '0.9', status: 'candidate', policy_reason: 'decision_signal', evidence_json: '{"sourceId":"s1:0"}', reviewed_by: null, reviewed_at: null, created_at: 1, updated_at: 1, }], []]; if (sql.startsWith('SELECT status')) return [[{ status: 'candidate', count: 1 }], []]; if (sql.startsWith('UPDATE')) return [{ affectedRows: 1 }, []]; throw new Error(`Unexpected SQL: ${sql}`); }, }; const store = createPersonalMemoryCandidateStore(pool, { now: () => 10 }); assert.deepEqual(await store.saveCandidate({ id: 'pmc_1', userId: 'u1', sessionId: 's1', memoryType: 'episodic', content: '决定使用 main 发布', importance: 0.9, confidence: 0.9, policyReason: 'decision_signal', evidence: { sourceId: 's1:0' }, createdAt: 1, }, { autoAccept: true }), { inserted: true, status: 'accepted' }); const rows = await store.listCandidates({ limit: 20 }); assert.equal(rows[0].evidence.sourceId, 's1:0'); assert.deepEqual(await store.countByStatus(), { candidate: 1 }); assert.equal((await store.reviewCandidate('pmc_1', 'accepted', { reviewedBy: 'admin-1' })).updated, true); assert.ok(calls.every((call) => !call.sql.includes('admin-1'))); });