import assert from 'node:assert/strict'; import test from 'node:test'; import { MEMORY_V2_PRODUCT_EVENT_TYPES, aggregateMemoryV2ProductMetrics, recordMemoryV2ProductEvent, } from './memory-v2-product-events.mjs'; test('recordMemoryV2ProductEvent inserts typed rows', async () => { const inserts = []; const pool = { async query(sql, params) { inserts.push({ sql, params }); return [{ insertId: 1 }]; }, }; const result = await recordMemoryV2ProductEvent(pool, { eventType: MEMORY_V2_PRODUCT_EVENT_TYPES.CANDIDATE_SAVED, userId: 'user-1', sessionId: 'session-1', candidateId: 'cand-1', data: { policyReason: 'explicit_memory_request' }, createdAt: 1000, }); assert.equal(result.recorded, true); assert.match(inserts[0].sql, /h5_memory_v2_product_events/); assert.equal(inserts[0].params[0], 'memory_candidate_saved'); }); test('aggregateMemoryV2ProductMetrics falls back to legacy tables', async () => { const pool = { async query(sql, params) { if (String(sql).includes('information_schema.tables')) { if (String(params[0]).includes('product_events')) return [[]]; return [[{ ok: 1 }]]; } if (String(sql).includes('h5_memory_v2_candidates')) return [[{ count: 12 }]]; if (String(sql).includes('h5_user_memory_items')) return [[{ count: 8 }]]; if (String(sql).includes('agent_memory_resolved') && String(sql).includes('memoryCount')) { return [[{ count: 5 }]]; } if (String(sql).includes('agent_memory_resolved')) return [[{ count: 7 }]]; return [[]]; }, }; const metrics = await aggregateMemoryV2ProductMetrics(pool, { since: '7d', now: 1_700_000_000_000, }); assert.equal(metrics.events.memory_candidate_saved, 12); assert.equal(metrics.events.memory_promoted, 8); assert.equal(metrics.events.memory_resolved_injected, 7); assert.equal(metrics.events.memory_recall_hit, 5); assert.equal(metrics.sources.memory_candidate_saved, 'candidates_table'); });