refactor(api): extract timeline allocation mutation payload helpers

This commit is contained in:
2026-03-31 15:44:09 +02:00
parent 93e03e0f65
commit 231d3f3124
3 changed files with 149 additions and 45 deletions
@@ -2,11 +2,14 @@ import { TRPCError } from "@trpc/server";
import { describe, expect, it } from "vitest";
import {
assertTimelineDateRangeValid,
buildTimelineAllocationEntryUpdate,
buildTimelineAllocationMetadata,
buildTimelineBatchShiftAuditChanges,
buildTimelineQuickAssignAssignmentInput,
buildTimelineQuickAssignMetadata,
calculateTimelineAllocationPercentage,
shiftTimelineAllocationWindow,
validateTimelineAllocationDateRanges,
} from "../router/timeline-allocation-mutation-support.js";
describe("timeline allocation mutation support", () => {
@@ -46,6 +49,33 @@ describe("timeline allocation mutation support", () => {
expect(buildTimelineQuickAssignMetadata("batchQuickAssign")).toEqual({ source: "batchQuickAssign" });
});
it("builds assignment create payloads for quick assign flows", () => {
expect(
buildTimelineQuickAssignAssignmentInput({
resourceId: "resource_1",
projectId: "project_1",
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-05T00:00:00.000Z"),
hoursPerDay: 6,
role: "Engineer",
roleId: "role_1",
status: "PROPOSED",
source: "quickAssign",
}),
).toEqual({
resourceId: "resource_1",
projectId: "project_1",
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-05T00:00:00.000Z"),
hoursPerDay: 6,
percentage: 75,
role: "Engineer",
roleId: "role_1",
status: "PROPOSED",
metadata: { source: "quickAssign" },
});
});
it("shifts and clamps allocation windows for each batch-shift mode", () => {
expect(
shiftTimelineAllocationWindow({
@@ -98,4 +128,47 @@ describe("timeline allocation mutation support", () => {
count: 2,
});
});
it("validates date ranges in bulk", () => {
expect(() =>
validateTimelineAllocationDateRanges([
{
startDate: new Date("2026-04-10T00:00:00.000Z"),
endDate: new Date("2026-04-11T00:00:00.000Z"),
},
{
startDate: new Date("2026-04-12T00:00:00.000Z"),
endDate: new Date("2026-04-09T00:00:00.000Z"),
},
])).toThrowError(TRPCError);
});
it("builds shared update payloads for demand and assignment changes", () => {
expect(
buildTimelineAllocationEntryUpdate({
hoursPerDay: 7.5,
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
metadata: { includeSaturday: true },
dailyCostCents: 48000,
role: "Architect",
}),
).toEqual({
demandRequirementUpdate: {
hoursPerDay: 7.5,
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
metadata: { includeSaturday: true },
role: "Architect",
},
assignmentUpdate: {
hoursPerDay: 7.5,
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
dailyCostCents: 48000,
metadata: { includeSaturday: true },
role: "Architect",
},
});
});
});