diagnosis-action-center-smoke-test.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. 'use strict';
  2. const assert = require('assert');
  3. const fs = require('fs');
  4. const os = require('os');
  5. const path = require('path');
  6. const { createUnifiedTaskService } = require('../mcp/src/dashboard/unified-task-service');
  7. const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-diagnosis-actions-'));
  8. async function main() {
  9. try {
  10. const service = createUnifiedTaskService({
  11. outputsDir: tempDir,
  12. getConversations: () => ({ status: 'ok', data: { conversations: [] } })
  13. });
  14. const input = {
  15. question: '哪些客户今天必须跟进?',
  16. diagnosisType: 'customer-operations',
  17. scope: { date: '2026-07-24' },
  18. action: { id: 'open-customer-master', label: '打开客户主档', description: '按任务与画像完整度处理', route: '#customer-ops', priority: 'high' },
  19. evidence: [{ label: '画像覆盖率', value: 40, source: 'dashboard-state' }],
  20. dataGaps: [{ code: 'LOW_PORTRAIT_COVERAGE', label: '画像覆盖不足' }]
  21. };
  22. const created = service.createDiagnosisCandidate(input);
  23. assert.equal(created.status, 'ok');
  24. assert.equal(created.summary.created, true);
  25. assert.equal(created.summary.requiresPromotion, true);
  26. assert.match(created.data.candidate.sourceKey, /^diagnosis:/);
  27. const duplicate = service.createDiagnosisCandidate(input);
  28. assert.equal(duplicate.summary.created, false);
  29. assert.equal(duplicate.summary.duplicate, true);
  30. const firstHub = service.hub();
  31. assert.equal(firstHub.summary.candidates, 1);
  32. const candidate = firstHub.data.tasks.find(task => task.source === 'diagnosis-candidate');
  33. assert(candidate);
  34. assert.equal(candidate.actions.promote, true);
  35. const promoted = service.createLocalTask({
  36. title: candidate.title,
  37. priority: candidate.priority,
  38. evidence: candidate.evidence,
  39. sourceTitle: candidate.sourceTitle,
  40. source: candidate.source,
  41. sourceKey: candidate.id
  42. });
  43. assert.equal(promoted.summary.created, true);
  44. const prematureFeedback = service.updateDiagnosisOutcome({ taskId: promoted.data.task.id, outcome: 'effective' });
  45. assert.equal(prematureFeedback.status, 'error');
  46. const completed = await service.update({ source: 'local', taskId: promoted.data.task.id, status: 'done' });
  47. assert.equal(completed.status, 'ok');
  48. const feedback = service.updateDiagnosisOutcome({
  49. taskId: promoted.data.task.id,
  50. outcome: 'effective',
  51. note: '跟进任务按计划完成,复盘确认流程有效。',
  52. actor: 'smoke-test'
  53. });
  54. assert.equal(feedback.status, 'ok');
  55. assert.equal(feedback.summary.internalOnly, true);
  56. assert.equal(feedback.summary.customerMessageSent, false);
  57. const secondHub = service.hub();
  58. assert.equal(secondHub.summary.promotedCandidates, 1);
  59. assert.equal(secondHub.summary.diagnosisFeedback.candidates, 1);
  60. assert.equal(secondHub.summary.diagnosisFeedback.promoted, 1);
  61. assert.equal(secondHub.summary.diagnosisFeedback.completed, 1);
  62. assert.equal(secondHub.summary.diagnosisFeedback.effective, 1);
  63. assert.equal(secondHub.summary.diagnosisFeedback.adoptionRate, 1);
  64. assert.equal(secondHub.summary.diagnosisFeedback.effectivenessRate, 1);
  65. assert.equal(secondHub.data.tasks.find(task => task.id === candidate.id).actions.promote, false);
  66. const completedTask = secondHub.data.tasks.find(task => task.id === promoted.data.task.id);
  67. assert.equal(completedTask.diagnosisOutcome.value, 'effective');
  68. assert.equal(completedTask.actions.diagnosisFeedback, true);
  69. const candidateStore = service.readDiagnosisCandidates();
  70. assert(candidateStore.candidates[0].lifecycle.some(item => item.event === 'promoted'));
  71. assert(candidateStore.candidates[0].lifecycle.some(item => item.event === 'completed'));
  72. assert(candidateStore.candidates[0].lifecycle.some(item => item.event === 'outcome_recorded'));
  73. assert(fs.existsSync(path.join(tempDir, 'knowledge', 'diagnoses', 'action-candidates.json')));
  74. process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 30, candidateSource: candidate.source, promotedCandidates: secondHub.summary.promotedCandidates, effectivenessRate: secondHub.summary.diagnosisFeedback.effectivenessRate }, null, 2)}\n`);
  75. } finally {
  76. fs.rmSync(tempDir, { recursive: true, force: true });
  77. }
  78. }
  79. main().catch(error => {
  80. process.stderr.write(`${error.stack || error.message}\n`);
  81. process.exit(1);
  82. });