forked from wangziqi/gongxue-base
feat: add CRM lead assignment strategies
This commit is contained in:
@@ -6789,11 +6789,28 @@ async function testReferralAndCrmGrowth() {
|
||||
formName: '集成测试客资',
|
||||
examType: '专升本',
|
||||
delaySec: 1,
|
||||
assignmentMode: 'round_robin',
|
||||
assignmentPool: [TENANT_SALES_USER_ID, TENANT_AGENT_USER_ID],
|
||||
},
|
||||
});
|
||||
assert.equal(crmConfig.item?.enabled, true, 'tenant admin should enable CRM config');
|
||||
assert.equal(crmConfig.item?.assignmentMode, 'round_robin', 'CRM config should persist lead assignment mode');
|
||||
assert.deepEqual(crmConfig.item?.assignmentPool, [TENANT_SALES_USER_ID, TENANT_AGENT_USER_ID], 'CRM config should persist assignment pool');
|
||||
assert.ok(!JSON.stringify(crmConfig).includes('crm-secret-smoke'), 'CRM config response should not leak secret');
|
||||
|
||||
const invalidCrmAssignment = await request('/api/crm/config', {
|
||||
userId: TENANT_ADMIN_USER_ID,
|
||||
method: 'PUT',
|
||||
body: {
|
||||
enabled: true,
|
||||
url: 'https://crm.example.test/webhook',
|
||||
assignmentMode: 'direct',
|
||||
assignmentPool: [PARTNER_TENANT_ADMIN_USER_ID],
|
||||
},
|
||||
expectStatus: 400,
|
||||
});
|
||||
assert.equal(invalidCrmAssignment.code, 'CRM_ASSIGNMENT_POOL_INVALID', 'CRM assignment pool must reject cross-tenant users');
|
||||
|
||||
const tracked = await request('/api/referral/track-event', {
|
||||
userId: false,
|
||||
method: 'POST',
|
||||
@@ -6808,6 +6825,8 @@ async function testReferralAndCrmGrowth() {
|
||||
assert.equal(tracked.item?.refUserId, TENANT_SALES_USER_ID, 'tracking event should resolve referrer');
|
||||
assert.equal(tracked.lead?.bound, true, 'first referral event should bind lead');
|
||||
assert.equal(tracked.lead?.item?.referrerUserId, TENANT_SALES_USER_ID, 'lead should be bound to sales user');
|
||||
assert.equal(tracked.lead?.item?.assignedToUserId, TENANT_SALES_USER_ID, 'round-robin should assign first lead to first sales member');
|
||||
assert.equal(tracked.lead?.assignment?.userId, TENANT_SALES_USER_ID, 'track response should expose assignment assignee');
|
||||
assert.ok(tracked.crmQueue?.id, 'first lead binding should enqueue CRM task');
|
||||
|
||||
const secondBind = await request('/api/referral/bind', {
|
||||
@@ -6853,6 +6872,7 @@ async function testReferralAndCrmGrowth() {
|
||||
});
|
||||
assert.equal(manual.lead?.bound, true, 'tenant admin should be able to force manual bind');
|
||||
assert.equal(manual.lead?.item?.referrerUserId, TENANT_AGENT_USER_ID, 'manual bind should move lead to agent');
|
||||
assert.equal(manual.lead?.item?.assignedToUserId, TENANT_AGENT_USER_ID, 'round-robin should assign second lead to next pool member');
|
||||
|
||||
const qrcode = await request('/api/referral/qrcode', {
|
||||
userId: TENANT_AGENT_USER_ID,
|
||||
@@ -7082,6 +7102,7 @@ async function testReferralAndCrmGrowth() {
|
||||
query: { status: 'pending' },
|
||||
});
|
||||
assert.ok(crmQueue.items?.some(item => item.leadId === manual.lead.item.id || item.leadId === tracked.lead.item.id), 'CRM queue should include referral lead task');
|
||||
assert.ok(crmQueue.items?.some(item => item.payload?.assignee?.id === TENANT_AGENT_USER_ID), 'CRM queue payload should include assigned follow-up user');
|
||||
assert.ok(!JSON.stringify(crmQueue).includes('crm-secret-smoke'), 'CRM queue should not leak secret');
|
||||
|
||||
const partnerReferralDenied = await request('/api/referral/sales-stats', {
|
||||
|
||||
Reference in New Issue
Block a user