112 lines
4.0 KiB
TypeScript
112 lines
4.0 KiB
TypeScript
import { z } from "zod";
|
|
import { getAnonymizationDirectory } from "../lib/anonymization.js";
|
|
import { controllerProcedure, protectedProcedure } from "../trpc.js";
|
|
import {
|
|
anonymizeResourceOnEntry,
|
|
buildSelfServiceTimelineInput,
|
|
createEmptyTimelineEntriesView,
|
|
createTimelineDateRange,
|
|
createTimelineFilters,
|
|
fmtDate,
|
|
loadTimelineEntriesReadModel,
|
|
summarizeTimelineEntries,
|
|
TimelineWindowFiltersSchema,
|
|
} from "./timeline-read-shared.js";
|
|
import {
|
|
formatHolidayOverlays,
|
|
loadTimelineHolidayOverlaysForReadModel,
|
|
summarizeHolidayOverlays,
|
|
} from "./timeline-holiday-read.js";
|
|
|
|
export const timelineEntryReadProcedures = {
|
|
getEntries: controllerProcedure
|
|
.input(TimelineWindowFiltersSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const readModel = await loadTimelineEntriesReadModel(ctx.db, input);
|
|
const directory = await getAnonymizationDirectory(ctx.db);
|
|
return readModel.allocations.map((allocation) => anonymizeResourceOnEntry(allocation, directory));
|
|
}),
|
|
|
|
getEntriesView: controllerProcedure
|
|
.input(TimelineWindowFiltersSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const [readModel, directory] = await Promise.all([
|
|
loadTimelineEntriesReadModel(ctx.db, input),
|
|
getAnonymizationDirectory(ctx.db),
|
|
]);
|
|
|
|
return {
|
|
...readModel,
|
|
allocations: readModel.allocations.map((allocation) => anonymizeResourceOnEntry(allocation, directory)),
|
|
assignments: readModel.assignments.map((assignment) => anonymizeResourceOnEntry(assignment, directory)),
|
|
};
|
|
}),
|
|
|
|
getMyEntriesView: protectedProcedure
|
|
.input(TimelineWindowFiltersSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const selfServiceInput = await buildSelfServiceTimelineInput(ctx, input);
|
|
if (!selfServiceInput) {
|
|
return createEmptyTimelineEntriesView();
|
|
}
|
|
|
|
const [readModel, directory] = await Promise.all([
|
|
loadTimelineEntriesReadModel(ctx.db, selfServiceInput),
|
|
getAnonymizationDirectory(ctx.db),
|
|
]);
|
|
|
|
return {
|
|
...readModel,
|
|
allocations: readModel.allocations.map((allocation) => anonymizeResourceOnEntry(allocation, directory)),
|
|
assignments: readModel.assignments.map((assignment) => anonymizeResourceOnEntry(assignment, directory)),
|
|
};
|
|
}),
|
|
|
|
getEntriesDetail: controllerProcedure
|
|
.input(
|
|
z.object({
|
|
startDate: z.string().optional(),
|
|
endDate: z.string().optional(),
|
|
durationDays: z.number().int().min(1).max(366).optional(),
|
|
resourceIds: z.array(z.string()).optional(),
|
|
projectIds: z.array(z.string()).optional(),
|
|
clientIds: z.array(z.string()).optional(),
|
|
chapters: z.array(z.string()).optional(),
|
|
eids: z.array(z.string()).optional(),
|
|
countryCodes: z.array(z.string()).optional(),
|
|
}),
|
|
)
|
|
.query(async ({ ctx, input }) => {
|
|
const { startDate, endDate } = createTimelineDateRange(input);
|
|
const filters = createTimelineFilters(input);
|
|
const timelineInput = { ...filters, startDate, endDate };
|
|
|
|
const [readModel, directory] = await Promise.all([
|
|
loadTimelineEntriesReadModel(ctx.db, timelineInput),
|
|
getAnonymizationDirectory(ctx.db),
|
|
]);
|
|
const holidayOverlays = await loadTimelineHolidayOverlaysForReadModel(
|
|
ctx.db,
|
|
timelineInput,
|
|
readModel,
|
|
);
|
|
const formattedHolidayOverlays = formatHolidayOverlays(holidayOverlays);
|
|
|
|
return {
|
|
period: {
|
|
startDate: fmtDate(startDate),
|
|
endDate: fmtDate(endDate),
|
|
},
|
|
filters,
|
|
summary: {
|
|
...summarizeTimelineEntries(readModel),
|
|
...summarizeHolidayOverlays(formattedHolidayOverlays),
|
|
},
|
|
allocations: readModel.allocations.map((allocation) => anonymizeResourceOnEntry(allocation, directory)),
|
|
demands: readModel.demands,
|
|
assignments: readModel.assignments.map((assignment) => anonymizeResourceOnEntry(assignment, directory)),
|
|
holidayOverlays: formattedHolidayOverlays,
|
|
};
|
|
}),
|
|
};
|