import type { Prisma, PrismaClient } from "@capakraken/db"; import { buildSplitAllocationReadModel } from "./build-split-allocation-read-model.js"; type DbClient = | Pick | Pick; export interface CountPlanningEntriesInput { projectIds?: string[]; roleIds?: string[]; } export interface CountPlanningEntriesResult { countsByProjectId: Map; countsByRoleId: Map; totalCount: number; } function normalizeIds(ids?: string[]): string[] | undefined { if (!ids) { return undefined; } const normalized = [...new Set(ids.filter(Boolean))]; return normalized.length > 0 ? normalized : undefined; } function buildScopedWhere(input: CountPlanningEntriesInput) { const projectIds = normalizeIds(input.projectIds); const roleIds = normalizeIds(input.roleIds); if (input.projectIds && !projectIds) { return null; } if (input.roleIds && !roleIds) { return null; } return { ...(projectIds ? { projectId: { in: projectIds } } : {}), ...(roleIds ? { roleId: { in: roleIds } } : {}), }; } export async function countPlanningEntries( db: DbClient, input: CountPlanningEntriesInput = {}, ): Promise { const scopedWhere = buildScopedWhere(input); if (scopedWhere === null) { return { countsByProjectId: new Map(), countsByRoleId: new Map(), totalCount: 0, }; } const [demandRequirements, assignments] = await Promise.all([ db.demandRequirement.findMany({ where: scopedWhere, select: { id: true, projectId: true, startDate: true, endDate: true, hoursPerDay: true, percentage: true, role: true, roleId: true, headcount: true, status: true, metadata: true, createdAt: true, updatedAt: true, }, }), db.assignment.findMany({ where: scopedWhere, select: { id: true, demandRequirementId: true, resourceId: true, projectId: true, startDate: true, endDate: true, hoursPerDay: true, percentage: true, role: true, roleId: true, dailyCostCents: true, status: true, metadata: true, createdAt: true, updatedAt: true, }, }), ]); const readModel = buildSplitAllocationReadModel({ demandRequirements, assignments, }); const countsByProjectId = new Map(); const countsByRoleId = new Map(); for (const allocation of readModel.allocations) { countsByProjectId.set( allocation.projectId, (countsByProjectId.get(allocation.projectId) ?? 0) + 1, ); if (allocation.roleId) { countsByRoleId.set( allocation.roleId, (countsByRoleId.get(allocation.roleId) ?? 0) + 1, ); } } return { countsByProjectId, countsByRoleId, totalCount: readModel.allocations.length, }; }