refactor(api): extract timeline project detail artifact loader

This commit is contained in:
2026-03-31 15:44:13 +02:00
parent 231d3f3124
commit 49bf3f3214
3 changed files with 234 additions and 30 deletions
@@ -1,6 +1,10 @@
import { TRPCError } from "@trpc/server";
import type { Allocation } from "@capakraken/shared";
import { summarizeHolidayOverlays, type formatHolidayOverlays } from "./timeline-holiday-read.js";
import {
formatHolidayOverlays,
loadTimelineHolidayOverlays,
summarizeHolidayOverlays,
} from "./timeline-holiday-read.js";
import {
anonymizeResourceOnEntry,
createTimelineDateRange,
@@ -316,6 +320,70 @@ export function buildTimelineProjectContextDetailResponse<
};
}
export async function loadTimelineProjectContextDetailArtifacts(
db: Parameters<typeof loadTimelineHolidayOverlays>[0],
input: {
projectId: string;
requestedStartDate?: string | undefined;
requestedEndDate?: string | undefined;
durationDays?: number | undefined;
projectStartDate?: Date | null | undefined;
projectEndDate?: Date | null | undefined;
firstAssignmentStartDate?: Date | string | null | undefined;
firstDemandStartDate?: Date | string | null | undefined;
assignments: Array<{
id: string;
resourceId: string | null;
resource?: { displayName?: string | null } | null;
startDate: Date | string;
endDate: Date | string;
hoursPerDay: number;
}>;
allResourceAllocations: Array<{
id: string;
resourceId: string | null;
projectId: string | null;
project?: { name?: string | null; shortCode?: string | null } | null;
startDate: Date | string;
endDate: Date | string;
hoursPerDay: number;
status: string;
}>;
resourceIds: string[];
},
) {
const period = resolveTimelineProjectContextPeriod({
requestedStartDate: input.requestedStartDate,
requestedEndDate: input.requestedEndDate,
durationDays: input.durationDays,
projectStartDate: input.projectStartDate,
projectEndDate: input.projectEndDate,
firstAssignmentStartDate: input.firstAssignmentStartDate,
firstDemandStartDate: input.firstDemandStartDate,
});
const holidayOverlays = input.resourceIds.length > 0
? formatHolidayOverlays(await loadTimelineHolidayOverlays(db, {
startDate: period.startDate,
endDate: period.endDate,
resourceIds: input.resourceIds,
projectIds: [input.projectId],
}))
: [];
const assignmentConflicts = buildTimelineProjectAssignmentConflicts({
projectId: input.projectId,
assignments: input.assignments,
allResourceAllocations: input.allResourceAllocations,
});
return {
period,
holidayOverlays,
assignmentConflicts,
};
}
export function buildTimelineShiftPreviewDetailResponse<TPreview>(input: {
project: {
id: string;