customer-journey-smoke-test.js 5.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const assert = require('assert');
  2. const fs = require('fs');
  3. const os = require('os');
  4. const path = require('path');
  5. const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-customer-journey-'));
  6. process.env.QIWEI_OUTPUTS_DIR = tempDir;
  7. process.env.QIWEI_AGENT_DB_PATH = path.join(tempDir, 'messages', 'agent-workbench.db');
  8. async function main() {
  9. const { AgentWorkbenchDb } = require('../mcp/src/core/agent-workbench-db');
  10. const db = new AgentWorkbenchDb(process.env.QIWEI_AGENT_DB_PATH, { globalPaused: true, defaultMode: 'review' });
  11. const conversation = db.ensureConversation('external-test-1', '测试客户');
  12. const property = { id: 'P-101', community: '测试花园', district: '新北区', totalPrice: 188, layout: '三室', area: 96, decoration: '精装' };
  13. db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-1', status: 'recommended', evidence: '已向客户推荐测试花园 188 万', createdAt: '2026-07-17T01:00:00Z' });
  14. db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-1', status: 'recommended', evidence: '重复同步', createdAt: '2026-07-17T01:00:00Z' });
  15. assert.equal(db.listCustomerRecommendations(conversation.id)[0].recommend_count, 1);
  16. db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-2', status: 'recommended', evidence: '第二次推荐', createdAt: '2026-07-18T01:00:00Z' });
  17. assert.equal(db.listCustomerRecommendations(conversation.id)[0].recommend_count, 2);
  18. const recommendationId = db.listCustomerRecommendations(conversation.id)[0].id;
  19. const feedback = db.updateCustomerRecommendation(conversation.id, recommendationId, { status: 'rejected', feedbackReason: '楼层不合适' });
  20. assert.equal(feedback.status, 'rejected');
  21. assert.equal(feedback.feedback_reason, '楼层不合适');
  22. db.close();
  23. const { __testing: agentTesting } = require('../mcp/src/dashboard/agent-service');
  24. assert.equal(agentTesting.detectedPropertiesInMessage('推荐测试花园188万三室', [property]).length, 1);
  25. assert.equal(agentTesting.detectedPropertiesInMessage('推荐测试花园,但价格待确认', [property]).length, 0);
  26. let feedbackCall = null;
  27. const { createCustomerMasterService } = require('../mcp/src/dashboard/customer-master-service');
  28. const service = createCustomerMasterService({
  29. projectionPath: path.join(tempDir, 'customers', 'index.json'),
  30. getConversations: () => ({ data: { conversations: [{
  31. id: conversation.id,
  32. displayName: '测试客户',
  33. maskedId: 'ex***-1',
  34. source: 'live',
  35. mode: 'review',
  36. analysis: { completenessScore: 50 },
  37. messages: [{ id: 'm1', role: 'customer', source: 'live', content: '预算 200 万,想看三室', timestamp: '2026-07-17T00:00:00Z' }],
  38. customerIntelligence: {
  39. profile: { preferredRegion: '新北区', budgetWan: 200, layout: '三室', budgetType: '待确认' },
  40. profileEvidence: {},
  41. tags: [],
  42. tasks: [{ id: 't1', title: '确认用途与时间', status: 'open', evidence: '用途和时间未确认', updatedAt: '2026-07-17T00:10:00Z' }],
  43. alerts: [],
  44. recommendations: [{ id: recommendationId, propertyId: property.id, property, status: 'recommended', feedbackReason: '', recommendCount: 2, sources: [], firstRecommendedAt: '2026-07-17T01:00:00Z', lastRecommendedAt: '2026-07-18T01:00:00Z' }],
  45. summary: { openTasks: 1, openAlerts: 0, highAlerts: 0, recommendationCount: 1, pendingFeedbackCount: 1 },
  46. },
  47. lastMessageAt: '2026-07-17T00:00:00Z',
  48. updatedAt: '2026-07-17T00:00:00Z',
  49. }] } }),
  50. updateCustomerProfile: () => ({ status: 'ok' }),
  51. updateCustomerRecommendation: (customerId, id, input) => { feedbackCall = { customerId, id, input }; return { status: 'ok', assistantMessage: '反馈已记录', summary: { status: input.status } }; },
  52. });
  53. const hub = service.hub();
  54. const customer = hub.data.customers[0];
  55. assert(customer.nextActions.some(item => item.id === 'confirm-purpose'));
  56. assert(customer.nextActions.some(item => item.id === 'collect-property-feedback'));
  57. assert(customer.timeline.some(item => item.type === 'property'));
  58. assert(customer.timeline.some(item => item.type === 'inbound-message'));
  59. assert.equal(customer.pendingFeedbackCount, 1);
  60. const feedbackResult = service.updateRecommendation(conversation.id, recommendationId, { status: 'interested', feedbackReason: '小区合适' });
  61. assert.equal(feedbackResult.status, 'ok');
  62. assert.equal(feedbackCall.input.status, 'interested');
  63. process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 14, recommendationCount: customer.recommendationCount, nextActions: customer.nextActions.length, timelineEvents: customer.timeline.length }, null, 2)}\n`);
  64. }
  65. main().catch(error => {
  66. process.stderr.write(`${error.stack || error.message}\n`);
  67. process.exitCode = 1;
  68. }).finally(() => {
  69. try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch {}
  70. });