Files
Nexus/packages/api/src/router/timeline-read-shared.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

80 lines
2.2 KiB
TypeScript

import { buildSplitAllocationReadModel } from "@nexus/application";
import type { PrismaClient } from "@nexus/db";
import { z } from "zod";
import { TimelineWindowFiltersSchema } from "./timeline-read-schema-support.js";
import { loadTimelineEntryRecords } from "./timeline-entry-query-support.js";
export {
buildSelfServiceTimelineInput,
buildTimelineEntriesDetailInput,
createTimelineDateRange,
createTimelineFilters,
} from "./timeline-filter-support.js";
export type ShiftDbClient = Pick<PrismaClient, "project" | "demandRequirement" | "assignment">;
export type TimelineEntriesDbClient = Pick<
PrismaClient,
| "demandRequirement"
| "assignment"
| "resource"
| "project"
| "holidayCalendar"
| "country"
| "metroCity"
>;
export type TimelineEntriesFilters = {
startDate: Date;
endDate: Date;
resourceIds?: string[] | undefined;
projectIds?: string[] | undefined;
clientIds?: string[] | undefined;
chapters?: string[] | undefined;
eids?: string[] | undefined;
countryCodes?: string[] | undefined;
};
type TimelineWindowFiltersInput = z.infer<typeof TimelineWindowFiltersSchema>;
export function getAssignmentResourceIds(
readModel: ReturnType<typeof buildSplitAllocationReadModel>,
): string[] {
return [
...new Set(
readModel.assignments
.map((assignment) => assignment.resourceId)
.filter((resourceId): resourceId is string => resourceId !== null),
),
];
}
export { toIsoDateOrNull as fmtDate } from "@nexus/shared";
export function createEmptyTimelineEntriesView() {
return buildSplitAllocationReadModel({
demandRequirements: [],
assignments: [],
});
}
export function rangesOverlap(
leftStart: Date,
leftEnd: Date,
rightStart: Date,
rightEnd: Date,
): boolean {
return leftStart <= rightEnd && rightStart <= leftEnd;
}
export function toDate(value: Date | string): Date {
return value instanceof Date ? value : new Date(value);
}
export async function loadTimelineEntriesReadModel(
db: TimelineEntriesDbClient,
input: TimelineEntriesFilters,
) {
const { demandRequirements, assignments } = await loadTimelineEntryRecords(db, input);
return buildSplitAllocationReadModel({ demandRequirements, assignments });
}