Files
Nexus/packages/api/src/router/timeline-allocation-shift-support.ts
T
Hartmut b41c1d2501
CI / Architecture Guardrails (push) Successful in 2m38s
CI / Assistant Split Regression (push) Successful in 3m33s
CI / Typecheck (push) Successful in 3m51s
CI / Lint (push) Successful in 5m2s
CI / E2E Tests (push) Has been cancelled
CI / Fresh-Linux Docker Deploy (push) Has been cancelled
CI / Release Images (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)
rename(phase 1): CapaKraken → Nexus across code, UI, docs, CI (#61)

Co-authored-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
Co-committed-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
2026-05-21 16:28:40 +02:00

73 lines
2.1 KiB
TypeScript

import { findAllocationEntry, updateAllocationEntry } from "@nexus/application";
import type { PrismaClient } from "@nexus/db";
import { TRPCError } from "@trpc/server";
import {
buildTimelineBatchShiftAuditChanges,
shiftTimelineAllocationWindow,
type TimelineBatchShiftMode,
} from "./timeline-allocation-batch-shift-support.js";
export async function applyTimelineBatchAllocationShift(input: {
db: PrismaClient;
allocationIds: string[];
daysDelta: number;
mode: TimelineBatchShiftMode;
}) {
if (input.daysDelta === 0) {
return [];
}
const entries = await Promise.all(
input.allocationIds.map((allocationId) => findAllocationEntry(input.db, allocationId)),
);
const resolved = entries.filter((entry): entry is NonNullable<typeof entry> => entry !== null);
if (resolved.length === 0) {
throw new TRPCError({ code: "NOT_FOUND", message: "No allocations found" });
}
return input.db.$transaction(async (tx) => {
const updated = [];
for (const entry of resolved) {
const existing = entry.entry;
const shiftedWindow = shiftTimelineAllocationWindow({
startDate: existing.startDate,
endDate: existing.endDate,
daysDelta: input.daysDelta,
mode: input.mode,
});
const result = await updateAllocationEntry(
tx as unknown as Parameters<typeof updateAllocationEntry>[0],
{
id: existing.id,
demandRequirementUpdate: {
startDate: shiftedWindow.startDate,
endDate: shiftedWindow.endDate,
},
assignmentUpdate: {
startDate: shiftedWindow.startDate,
endDate: shiftedWindow.endDate,
},
},
);
updated.push(result.allocation);
}
await tx.auditLog.create({
data: {
entityType: "Allocation",
entityId: input.allocationIds.join(","),
action: "UPDATE",
changes: buildTimelineBatchShiftAuditChanges({
mode: input.mode,
daysDelta: input.daysDelta,
count: resolved.length,
}),
},
});
return updated;
});
}