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, }; }), };