refactor(api): extract timeline shift mutation helpers

This commit is contained in:
2026-03-31 15:50:17 +02:00
parent 345e9dd623
commit ef3db11c35
3 changed files with 234 additions and 58 deletions
@@ -0,0 +1,70 @@
import type { SplitAssignmentRecord } from "@capakraken/application";
import { Prisma, type PrismaClient } from "@capakraken/db";
import type { ShiftValidationResult, WeekdayAvailability } from "@capakraken/shared";
import { calculateTimelineAllocationDailyCost } from "./timeline-cost-support.js";
import type { TimelineShiftProjectRecord } from "./timeline-shift-support.js";
export function buildTimelineProjectDateRangeUpdate(input: {
newStartDate: Date;
newEndDate: Date;
}) {
return {
startDate: input.newStartDate,
endDate: input.newEndDate,
};
}
export function buildTimelineShiftedAssignmentUpdate(input: {
newStartDate: Date;
newEndDate: Date;
dailyCostCents: number | undefined;
}) {
return {
...buildTimelineProjectDateRangeUpdate(input),
...(input.dailyCostCents !== undefined ? { dailyCostCents: input.dailyCostCents } : {}),
};
}
export function buildTimelineProjectShiftAuditChanges(input: {
project: TimelineShiftProjectRecord;
newStartDate: Date;
newEndDate: Date;
validation: ShiftValidationResult;
}): Prisma.InputJsonValue {
return {
before: {
startDate: input.project.startDate,
endDate: input.project.endDate,
},
after: {
startDate: input.newStartDate,
endDate: input.newEndDate,
},
costImpact: input.validation.costImpact,
} as unknown as Prisma.InputJsonValue;
}
export async function recalculateShiftedAssignmentDailyCost(input: {
db: PrismaClient;
assignment: SplitAssignmentRecord;
newStartDate: Date;
newEndDate: Date;
}): Promise<number | undefined> {
if (!input.assignment.resourceId || !input.assignment.resource) {
return undefined;
}
const metadata = (input.assignment.metadata as Record<string, unknown> | null | undefined) ?? {};
const includeSaturday = (metadata.includeSaturday as boolean | undefined) ?? false;
return calculateTimelineAllocationDailyCost({
db: input.db,
resourceId: input.assignment.resourceId,
lcrCents: input.assignment.resource.lcrCents,
hoursPerDay: input.assignment.hoursPerDay,
startDate: input.newStartDate,
endDate: input.newEndDate,
availability: input.assignment.resource.availability as WeekdayAvailability,
includeSaturday,
});
}