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; process.env.QIWEI_AGENT_DB_PATH = path.join(tempDir, 'messages', 'agent-workbench.db'); async function main() { const { AgentWorkbenchDb } = require('../mcp/src/core/agent-workbench-db'); const db = new AgentWorkbenchDb(process.env.QIWEI_AGENT_DB_PATH, { globalPaused: true, defaultMode: 'review' }); const conversation = db.ensureConversation('external-test-1', '测试客户'); const property = { id: 'P-101', community: '测试花园', district: '新北区', totalPrice: 188, layout: '三室', area: 96, decoration: '精装' }; db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-1', status: 'recommended', evidence: '已向客户推荐测试花园 188 万', createdAt: '2026-07-17T01:00:00Z' }); db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-1', status: 'recommended', evidence: '重复同步', createdAt: '2026-07-17T01:00:00Z' }); assert.equal(db.listCustomerRecommendations(conversation.id)[0].recommend_count, 1); db.upsertCustomerRecommendations(conversation.id, [property], { type: 'outbound-message', entityId: 'message-2', status: 'recommended', evidence: '第二次推荐', createdAt: '2026-07-18T01:00:00Z' }); assert.equal(db.listCustomerRecommendations(conversation.id)[0].recommend_count, 2); const recommendationId = db.listCustomerRecommendations(conversation.id)[0].id; const feedback = db.updateCustomerRecommendation(conversation.id, recommendationId, { status: 'rejected', feedbackReason: '楼层不合适' }); assert.equal(feedback.status, 'rejected'); assert.equal(feedback.feedback_reason, '楼层不合适'); db.close(); const { __testing: agentTesting } = require('../mcp/src/dashboard/agent-service'); assert.equal(agentTesting.detectedPropertiesInMessage('推荐测试花园188万三室', [property]).length, 1); assert.equal(agentTesting.detectedPropertiesInMessage('推荐测试花园,但价格待确认', [property]).length, 0); let feedbackCall = null; const { createCustomerMasterService } = require('../mcp/src/dashboard/customer-master-service'); const service = createCustomerMasterService({ projectionPath: path.join(tempDir, 'customers', 'index.json'), getConversations: () => ({ data: { conversations: [{ id: conversation.id, displayName: '测试客户', maskedId: 'ex***-1', source: 'live', mode: 'review', analysis: { completenessScore: 50 }, messages: [{ id: 'm1', role: 'customer', source: 'live', content: '预算 200 万,想看三室', timestamp: '2026-07-17T00:00:00Z' }], customerIntelligence: { profile: { preferredRegion: '新北区', budgetWan: 200, layout: '三室', budgetType: '待确认' }, profileEvidence: {}, tags: [], tasks: [{ id: 't1', title: '确认用途与时间', status: 'open', evidence: '用途和时间未确认', updatedAt: '2026-07-17T00:10:00Z' }], alerts: [], 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' }], summary: { openTasks: 1, openAlerts: 0, highAlerts: 0, recommendationCount: 1, pendingFeedbackCount: 1 }, }, lastMessageAt: '2026-07-17T00:00:00Z', updatedAt: '2026-07-17T00:00:00Z', }] } }), updateCustomerProfile: () => ({ status: 'ok' }), updateCustomerRecommendation: (customerId, id, input) => { feedbackCall = { customerId, id, input }; return { status: 'ok', assistantMessage: '反馈已记录', summary: { status: input.status } }; }, }); const hub = service.hub(); const customer = hub.data.customers[0]; assert(customer.nextActions.some(item => item.id === 'confirm-purpose')); assert(customer.nextActions.some(item => item.id === 'collect-property-feedback')); assert(customer.timeline.some(item => item.type === 'property')); assert(customer.timeline.some(item => item.type === 'inbound-message')); assert.equal(customer.pendingFeedbackCount, 1); const feedbackResult = service.updateRecommendation(conversation.id, recommendationId, { status: 'interested', feedbackReason: '小区合适' }); assert.equal(feedbackResult.status, 'ok'); assert.equal(feedbackCall.input.status, 'interested'); process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 14, recommendationCount: customer.recommendationCount, 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 {} });