const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-customer-master-')); process.env.QIWEI_OUTPUTS_DIR = tempDir; process.env.QIWEI_AGENT_DB_PATH = path.join(tempDir, 'messages', 'agent-workbench.db'); async function main() { let updateCall = null; const conversation = { id: 'conversation-live-1', channelId: 'external-contact-1', displayName: '测试客户', maskedId: '16***34', source: 'live', mode: 'review', analysis: { completenessScore: 50 }, messages: [{ id: 'm1', role: 'customer', content: '预算 20 万,想了解企业培训服务', timestamp: '2026-07-17T01:00:00Z' }], customerIntelligence: { profile: { budgetWan: 20, need: '企业培训服务', timeline: '本月内' }, profileEvidence: { budgetWan: { text: '预算 20 万', sourceMessageId: 'm1', updatedAt: '2026-07-17T01:00:00Z' } }, profileUpdatedAt: '2026-07-17T01:00:00Z', tags: ['高预算'], tasks: [{ id: 't1', title: '确认用途', status: 'open', evidence: '用途尚未明确' }], alerts: [{ id: 'a1', title: '需求已成形', status: 'open', severity: 'high', evidence: '预算和服务需求明确' }], summary: { openTasks: 1, openAlerts: 1, highAlerts: 1 }, }, lastMessageAt: '2026-07-17T01:00:00Z', updatedAt: '2026-07-17T01:00:00Z', }; const { createCustomerMasterService } = require('../mcp/src/dashboard/customer-master-service'); const projectionPath = path.join(tempDir, 'customers', 'index.json'); const service = createCustomerMasterService({ projectionPath, getConversations: () => ({ status: 'ok', data: { conversations: [conversation] } }), updateCustomerProfile: (id, input) => { updateCall = { id, input }; return { status: 'ok', assistantMessage: '主档已更新', summary: { changedFields: Object.keys(input.profile || {}) } }; }, }); const hub = service.hub(); assert.equal(hub.status, 'ok'); assert.equal(hub.summary.customerCount, 1); assert.equal(hub.summary.profiledCount, 1); assert.equal(hub.summary.priorityCount, 1); assert.equal(hub.data.customers[0].source, '真实企微会话'); assert.equal(hub.data.customers[0].evidenceCoverage, 33); assert.equal(hub.data.customers[0].externalUserId, 'external-contact-1'); assert.equal(hub.data.customers[0].openTaskCount, 1); assert(fs.existsSync(projectionPath)); const projection = fs.readFileSync(projectionPath, 'utf8'); assert.doesNotMatch(projection, /预算 20 万,想了解企业培训服务|预算 20 万/); assert.doesNotMatch(projection, /externalUserId|contact_id/); const updated = service.update('conversation-live-1', { profile: { intent: '采购服务' }, reason: '人工确认' }); assert.equal(updated.status, 'ok'); assert.equal(updateCall.id, 'conversation-live-1'); assert.equal(updateCall.input.profile.intent, '采购服务'); assert.equal(updateCall.input.reason, '人工确认'); process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 14, customers: hub.summary.customerCount, evidenceProjectionSafe: true }, null, 2)}\n`); } main().catch(error => { process.stderr.write(`${error.stack || error.message}\n`); process.exitCode = 1; }).finally(() => { try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch {} });