refactor(api): extract timeline entry query support
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
import { buildSplitAllocationReadModel } from "@capakraken/application";
|
||||
import { Prisma } from "@capakraken/db";
|
||||
import type { PrismaClient } from "@capakraken/db";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { z } from "zod";
|
||||
import { anonymizeResource, getAnonymizationDirectory } from "../lib/anonymization.js";
|
||||
import type { TRPCContext } from "../trpc.js";
|
||||
import {
|
||||
PROJECT_PLANNING_DEMAND_INCLUDE,
|
||||
TIMELINE_ASSIGNMENT_INCLUDE,
|
||||
} from "./project-planning-read-model.js";
|
||||
import { loadTimelineEntryRecords } from "./timeline-entry-query-support.js";
|
||||
|
||||
export type ShiftDbClient = Pick<
|
||||
PrismaClient,
|
||||
@@ -318,71 +314,6 @@ export async function loadTimelineEntriesReadModel(
|
||||
db: TimelineEntriesDbClient,
|
||||
input: TimelineEntriesFilters,
|
||||
) {
|
||||
const { startDate, endDate, resourceIds, projectIds, clientIds, chapters, eids, countryCodes } = input;
|
||||
|
||||
const effectiveResourceIds = await (async () => {
|
||||
if (resourceIds && resourceIds.length > 0) return resourceIds;
|
||||
const hasChapters = chapters && chapters.length > 0;
|
||||
const hasEids = eids && eids.length > 0;
|
||||
const hasCountry = countryCodes && countryCodes.length > 0;
|
||||
if (!hasChapters && !hasEids && !hasCountry) return undefined;
|
||||
|
||||
const andConditions: Record<string, unknown>[] = [];
|
||||
if (hasChapters) andConditions.push({ chapter: { in: chapters } });
|
||||
if (hasEids) andConditions.push({ eid: { in: eids } });
|
||||
if (hasCountry) andConditions.push({ country: { code: { in: countryCodes } } });
|
||||
|
||||
const matching = await db.resource.findMany({
|
||||
where: (andConditions.length === 1 ? andConditions[0]! : { AND: andConditions }) as Prisma.ResourceWhereInput,
|
||||
select: { id: true },
|
||||
});
|
||||
return matching.map((resource) => resource.id);
|
||||
})();
|
||||
|
||||
const effectiveProjectIds = await (async () => {
|
||||
if (!clientIds || clientIds.length === 0) return projectIds;
|
||||
|
||||
const matchingProjects = await db.project.findMany({
|
||||
where: { clientId: { in: clientIds } },
|
||||
select: { id: true },
|
||||
});
|
||||
const clientProjectIds = matchingProjects.map((project) => project.id);
|
||||
|
||||
if (!projectIds || projectIds.length === 0) {
|
||||
return clientProjectIds;
|
||||
}
|
||||
|
||||
const allowedIds = new Set(clientProjectIds);
|
||||
return projectIds.filter((projectId) => allowedIds.has(projectId));
|
||||
})();
|
||||
|
||||
const excludeDemands = effectiveResourceIds !== undefined;
|
||||
|
||||
const [demandRequirements, assignments] = await Promise.all([
|
||||
excludeDemands
|
||||
? Promise.resolve([])
|
||||
: db.demandRequirement.findMany({
|
||||
where: {
|
||||
status: { not: "CANCELLED" },
|
||||
startDate: { lte: endDate },
|
||||
endDate: { gte: startDate },
|
||||
...(effectiveProjectIds ? { projectId: { in: effectiveProjectIds } } : {}),
|
||||
},
|
||||
include: PROJECT_PLANNING_DEMAND_INCLUDE,
|
||||
orderBy: [{ startDate: "asc" }, { projectId: "asc" }],
|
||||
}),
|
||||
db.assignment.findMany({
|
||||
where: {
|
||||
status: { not: "CANCELLED" },
|
||||
startDate: { lte: endDate },
|
||||
endDate: { gte: startDate },
|
||||
...(effectiveResourceIds ? { resourceId: { in: effectiveResourceIds } } : {}),
|
||||
...(effectiveProjectIds ? { projectId: { in: effectiveProjectIds } } : {}),
|
||||
},
|
||||
include: TIMELINE_ASSIGNMENT_INCLUDE,
|
||||
orderBy: [{ startDate: "asc" }, { resourceId: "asc" }],
|
||||
}),
|
||||
]);
|
||||
|
||||
const { demandRequirements, assignments } = await loadTimelineEntryRecords(db, input);
|
||||
return buildSplitAllocationReadModel({ demandRequirements, assignments });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user