Fix: align task visibility filters across all API routes and dashboards

- api/tasks/route.ts: fix group-expiry filter to never hide open tasks;
  replace dueDate-based age filter with completedAt-based filter so open
  tasks are always visible regardless of how old they are
- api/dashboard/workload/route.ts: add dead-policy exclusion to base
  task filter so overdue counts and per-user workload rows exclude tasks
  on cancelled/expired/non-renewed policies
- manager/page.tsx: same dead-policy exclusion on teamMembers task query
- api/metrics/route.ts: fix horizon_tasks_overdue to exclude dead-policy tasks
This commit is contained in:
lorentz 2026-06-02 00:01:01 +00:00
parent 20f7ec1188
commit b1b0dfa64d
4 changed files with 16 additions and 6 deletions

View file

@ -56,6 +56,7 @@ export default async function ManagerPage() {
task: {
clientId: { in: shapeClientIds },
status: { notIn: ['COMPLETED', 'CANCELLED', 'NA'] },
NOT: { policy: { status: { in: ['Cancelled', 'Expired', 'Non-Renewed', 'Rewritten', 'Not taken'] } } },
}
},
select: {

View file

@ -30,9 +30,12 @@ export async function GET(request: NextRequest) {
})
const shapeClientIds = shapeClients.map((c) => c.id)
// Base task filter — scoped to Shape clients only
const DEAD_POLICY_STATUSES = ['Cancelled', 'Expired', 'Non-Renewed', 'Rewritten', 'Not taken']
// Base task filter — scoped to Shape clients only, excluding dead policies
const deptTaskWhere = {
clientId: { in: shapeClientIds },
NOT: { policy: { status: { in: DEAD_POLICY_STATUSES } } },
...(departmentFilter ? { department: departmentFilter.toUpperCase() as DepartmentType } : {}),
}

View file

@ -60,7 +60,7 @@ export async function GET(request: NextRequest) {
prisma.task.count(),
prisma.task.groupBy({ by: ['status'], _count: { id: true } }),
prisma.task.groupBy({ by: ['department'], _count: { id: true } }),
prisma.task.count({ where: { dueDate: { lt: now }, status: { notIn: ['COMPLETED', 'NA', 'CANCELLED'] } } }),
prisma.task.count({ where: { dueDate: { lt: now }, status: { notIn: ['COMPLETED', 'NA', 'CANCELLED'] }, NOT: { policy: { status: { in: ['Cancelled', 'Expired', 'Non-Renewed', 'Rewritten', 'Not taken'] } } } } }),
prisma.task.count({ where: { createdAt: { gte: todayStart } } }),
prisma.task.count({ where: { completedAt: { gte: todayStart } } }),
prisma.task.count({ where: { createdAt: { gte: weekAgo } } }),

View file

@ -36,18 +36,24 @@ export async function GET(request: NextRequest) {
policy: { status: { in: ['Cancelled', 'Expired', 'Non-Renewed', 'Rewritten', 'Not taken'] } },
},
},
// Exclude tasks on expired renewal groups
// Exclude tasks on expired renewal groups — but NEVER hide open tasks
{
OR: [
{ policyGroupId: null },
{ policyGroup: { renewalDate: { gte: cutoff } } },
{ status: { notIn: ['COMPLETED', 'CANCELLED', 'NA'] } },
],
},
// Exclude old non-terminal tasks
// Keep ALL open tasks regardless of age; only show terminal tasks completed/closed recently
{
OR: [
{ dueDate: { gte: cutoff } },
{ status: { in: ['COMPLETED', 'CANCELLED', 'NA'] } },
{ status: { notIn: ['COMPLETED', 'CANCELLED', 'NA'] } },
{
AND: [
{ status: { in: ['COMPLETED', 'CANCELLED', 'NA'] } },
{ completedAt: { gte: cutoff } },
],
},
],
},
]