| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- 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-journey-'));
- process.env.QIWEI_OUTPUTS_DIR = tempDir;
- async function main() {
- let updateCall = null;
- const conversation = {
- id: 'conversation-1',
- channelId: 'external-test-1',
- displayName: '测试客户',
- maskedId: 'ex***-1',
- source: 'live',
- mode: 'review',
- analysis: { completenessScore: 50 },
- messages: [
- { id: 'm1', role: 'customer', source: 'live', content: '预算 15 万,想了解企业服务方案', timestamp: '2026-07-17T00:00:00Z' },
- { id: 'm2', role: 'human', source: 'live', content: '收到,我先确认您的计划时间。', timestamp: '2026-07-17T00:05:00Z' },
- ],
- customerIntelligence: {
- profile: { need: '企业服务方案', budgetWan: 15, timeline: '待确认' },
- profileEvidence: {
- need: { text: '想了解企业服务方案', sourceMessageId: 'm1', source: 'live-message', updatedAt: '2026-07-17T00:00:00Z' },
- },
- tags: ['企业客户'],
- tasks: [{ id: 't1', title: '确认计划时间', status: 'open', evidence: '计划时间未确认', updatedAt: '2026-07-17T00:10:00Z' }],
- alerts: [{ id: 'a1', title: '重点跟进', severity: 'high', status: 'open', evidence: '客户已明确需求和预算', updatedAt: '2026-07-17T00:11:00Z' }],
- summary: { openTasks: 1, openAlerts: 1, highAlerts: 1 },
- },
- lastMessageAt: '2026-07-17T00:05:00Z',
- updatedAt: '2026-07-17T00:11:00Z',
- };
- const { createCustomerMasterService } = require('../mcp/src/dashboard/customer-master-service');
- const service = createCustomerMasterService({
- projectionPath: path.join(tempDir, 'customers', 'index.json'),
- getConversations: () => ({ data: { conversations: [conversation] } }),
- updateCustomerProfile: (customerId, input) => {
- updateCall = { customerId, input };
- conversation.customerIntelligence.profile = { ...conversation.customerIntelligence.profile, ...(input.profile || {}) };
- return { status: 'ok', assistantMessage: '客户主档已更新。', summary: { updated: true } };
- },
- });
- const hub = service.hub();
- const customer = hub.data.customers[0];
- assert.equal(hub.status, 'ok');
- assert.equal(hub.summary.customerCount, 1);
- assert.equal(hub.summary.priorityCount, 1);
- assert.equal(customer.stage.key, 'priority');
- assert.equal(customer.evidenceCoverage, 33);
- assert(customer.nextActions.some(item => item.id === 'confirm-purpose') === false);
- assert(customer.nextActions.some(item => item.id === 'confirm-timeline'));
- assert(customer.timeline.some(item => item.type === 'inbound-message'));
- assert(customer.timeline.some(item => item.type === 'outbound-message'));
- assert(customer.timeline.some(item => item.type === 'task'));
- assert(customer.timeline.some(item => item.type === 'alert'));
- assert.equal(customer.openTaskCount, 1);
- assert.equal(customer.highAlertCount, 1);
- assert.equal(fs.existsSync(path.join(tempDir, 'customers', 'index.json')), true);
- const updated = service.update(conversation.id, { profile: { timeline: '本月内' }, reason: '客户确认' });
- assert.equal(updated.status, 'ok');
- assert.equal(updateCall.customerId, conversation.id);
- assert.equal(updateCall.input.profile.timeline, '本月内');
- process.stdout.write(`${JSON.stringify({
- status: 'ok',
- checks: 16,
- customerCount: hub.summary.customerCount,
- nextActions: customer.nextActions.length,
- timelineEvents: customer.timeline.length,
- }, 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 {}
- });
|