fix(tasks): skip audit log on zero-template runs, add POLICY/CLIENT/multi-section test coverage
- runGenerateAndAssign now returns early (no audit log write, no client-name lookup) when no active templates match the resolved designation, mirroring the existing early return for zero matched clients. - Add tests for: zero-template real run writes no audit log; POLICY-level template against an ungrouped policy; CLIENT-level template created via prisma.task.create; and a single client accumulating estimatedTasks from both a group-level and a policy-level template in the same run.
This commit is contained in:
parent
fd38e0c148
commit
06842f9031
2 changed files with 271 additions and 146 deletions
|
|
@ -138,6 +138,121 @@ describe('runGenerateAndAssign — advocate-designation mode', () => {
|
|||
status: 404,
|
||||
})
|
||||
})
|
||||
|
||||
it('does not write an audit log and returns zero counts when no templates match', async () => {
|
||||
mockUserFindUnique.mockResolvedValue({ id: 'adv-1', displayName: 'Jane Smith', isActive: true })
|
||||
mockClientsForAdvocateDesignation()
|
||||
mockTaskTemplateFindMany.mockResolvedValue([])
|
||||
|
||||
const result = await runGenerateAndAssign(target, { dryRun: false, actorUserId: 'user-1' })
|
||||
|
||||
expect(mockAuditLogCreate).not.toHaveBeenCalled()
|
||||
expect(result.totalEstimatedTasks).toBe(0)
|
||||
expect(result.tasksCreated).toBe(0)
|
||||
})
|
||||
|
||||
it('creates and counts a POLICY-level task for an ungrouped policy', async () => {
|
||||
mockUserFindUnique.mockResolvedValue({ id: 'adv-1', displayName: 'Jane Smith', isActive: true })
|
||||
mockClientsForAdvocateDesignation()
|
||||
mockTaskTemplateFindMany.mockResolvedValue([
|
||||
{
|
||||
id: 'template-policy',
|
||||
name: 'Review policy renewal',
|
||||
description: null,
|
||||
department: 'Personal Lines',
|
||||
timing: 'PRE_RENEWAL',
|
||||
daysOffset: -1,
|
||||
defaultPriority: 'NORMAL',
|
||||
level: 'POLICY',
|
||||
},
|
||||
])
|
||||
mockPolicyFindMany.mockResolvedValue([
|
||||
{ id: 'policy-1', clientId: 'client-1', policyType: 'AUTO', expirationDate: new Date('2026-08-01') },
|
||||
])
|
||||
mockTaskCreateMany.mockResolvedValue({ count: 1 })
|
||||
mockTaskFindMany.mockResolvedValue([{ id: 'task-policy-1' }])
|
||||
mockTaskAssignmentCreateMany.mockResolvedValue({ count: 1 })
|
||||
|
||||
const dryRunResult = await runGenerateAndAssign(target, { dryRun: true, actorUserId: 'user-1' })
|
||||
const realResult = await runGenerateAndAssign(target, { dryRun: false, actorUserId: 'user-1' })
|
||||
|
||||
expect(dryRunResult.totalEstimatedTasks).toBe(1)
|
||||
expect(dryRunResult.clients).toEqual([{ id: 'client-1', name: 'Client One', estimatedTasks: 1 }])
|
||||
expect(mockTaskCreateMany).toHaveBeenCalledTimes(1)
|
||||
expect(realResult.tasksCreated).toBe(1)
|
||||
})
|
||||
|
||||
it('creates and counts a CLIENT-level task via prisma.task.create', async () => {
|
||||
mockUserFindUnique.mockResolvedValue({ id: 'adv-1', displayName: 'Jane Smith', isActive: true })
|
||||
mockClientsForAdvocateDesignation()
|
||||
mockTaskTemplateFindMany.mockResolvedValue([
|
||||
{
|
||||
id: 'template-client',
|
||||
name: 'Send client renewal letter',
|
||||
description: null,
|
||||
department: 'Commercial Lines',
|
||||
timing: 'PRE_RENEWAL',
|
||||
daysOffset: -1,
|
||||
defaultPriority: 'NORMAL',
|
||||
level: 'CLIENT',
|
||||
},
|
||||
])
|
||||
mockClientFindUnique.mockResolvedValue({
|
||||
policyGroups: [{ renewalDate: new Date('2026-08-01') }],
|
||||
policies: [],
|
||||
})
|
||||
mockTaskFindFirst.mockResolvedValue(null)
|
||||
mockTaskCreate.mockResolvedValue({ id: 'task-client-1' })
|
||||
mockTaskAssignmentCreate.mockResolvedValue({})
|
||||
|
||||
const dryRunResult = await runGenerateAndAssign(target, { dryRun: true, actorUserId: 'user-1' })
|
||||
const realResult = await runGenerateAndAssign(target, { dryRun: false, actorUserId: 'user-1' })
|
||||
|
||||
expect(dryRunResult.totalEstimatedTasks).toBe(1)
|
||||
expect(dryRunResult.clients).toEqual([{ id: 'client-1', name: 'Client One', estimatedTasks: 1 }])
|
||||
expect(mockTaskCreate).toHaveBeenCalledTimes(1)
|
||||
expect(mockTaskCreateMany).not.toHaveBeenCalled()
|
||||
expect(realResult.tasksCreated).toBe(1)
|
||||
expect(realResult.tasksAssigned).toBe(1)
|
||||
})
|
||||
|
||||
it('sums estimatedTasks for a client that gets tasks from both group- and policy-level templates', async () => {
|
||||
mockUserFindUnique.mockResolvedValue({ id: 'adv-1', displayName: 'Jane Smith', isActive: true })
|
||||
mockClientsForAdvocateDesignation()
|
||||
mockTaskTemplateFindMany.mockResolvedValue([
|
||||
{
|
||||
id: 'template-group',
|
||||
name: 'Prepare loss summary',
|
||||
description: null,
|
||||
department: 'Commercial Lines',
|
||||
timing: 'PRE_RENEWAL',
|
||||
daysOffset: -1,
|
||||
defaultPriority: 'NORMAL',
|
||||
level: 'RENEWAL_GROUP',
|
||||
},
|
||||
{
|
||||
id: 'template-policy',
|
||||
name: 'Review policy renewal',
|
||||
description: null,
|
||||
department: 'Personal Lines',
|
||||
timing: 'PRE_RENEWAL',
|
||||
daysOffset: -1,
|
||||
defaultPriority: 'NORMAL',
|
||||
level: 'POLICY',
|
||||
},
|
||||
])
|
||||
mockPolicyGroupFindMany.mockResolvedValue([
|
||||
{ id: 'group-1', clientId: 'client-1', renewalDate: new Date('2026-08-01') },
|
||||
])
|
||||
mockPolicyFindMany.mockResolvedValue([
|
||||
{ id: 'policy-1', clientId: 'client-1', policyType: 'AUTO', expirationDate: new Date('2026-08-01') },
|
||||
])
|
||||
|
||||
const result = await runGenerateAndAssign(target, { dryRun: true, actorUserId: 'user-1' })
|
||||
|
||||
expect(result.clients).toEqual([{ id: 'client-1', name: 'Client One', estimatedTasks: 2 }])
|
||||
expect(result.totalEstimatedTasks).toBe(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseGenerateAndAssignTarget', () => {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,18 @@ export async function runGenerateAndAssign(
|
|||
orderBy: [{ department: 'asc' }, { daysOffset: 'asc' }],
|
||||
})
|
||||
|
||||
if (allTemplates.length > 0) {
|
||||
if (allTemplates.length === 0) {
|
||||
return {
|
||||
dryRun: options.dryRun,
|
||||
clientsFound: resolved.clientIds.length,
|
||||
totalEstimatedTasks: 0,
|
||||
advocateName: resolved.advocateName,
|
||||
clients: [],
|
||||
tasksCreated: 0,
|
||||
tasksAssigned: 0,
|
||||
}
|
||||
}
|
||||
|
||||
const groupTemplates = allTemplates.filter((t) => t.level === 'BOTH' || t.level === 'RENEWAL_GROUP')
|
||||
const policyTemplates = allTemplates.filter((t) => t.level === 'BOTH' || t.level === 'POLICY')
|
||||
const clientTemplates = allTemplates.filter((t) => t.level === 'CLIENT')
|
||||
|
|
@ -302,7 +313,6 @@ export async function runGenerateAndAssign(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.dryRun) {
|
||||
await prisma.auditLog.create({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue