Files
CapaKraken/packages/application/src/use-cases/allocation/list-assignment-bookings.ts
T
Hartmut a83edb2f9d feat: timeline UI overhaul with project/resource panel redesign, quick filters, and API improvements
Redesigned timeline project and resource panels with expanded detail views,
added quick filter toolbar, improved drag handling, and enhanced vacation/entitlement
router logic. Includes e2e test updates and minor API fixes.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-15 09:28:59 +01:00

105 lines
2.9 KiB
TypeScript

import type { Prisma, PrismaClient } from "@planarchy/db";
type AssignmentBookingsDbClient = Pick<PrismaClient, "assignment">;
export interface ListAssignmentBookingsInput {
startDate?: Date | undefined;
endDate?: Date | undefined;
resourceIds?: string[] | undefined;
projectIds?: string[] | undefined;
excludeAssignmentIds?: string[] | undefined;
}
export interface AssignmentBookingWithFallback {
id: string;
projectId: string;
resourceId: string | null;
startDate: Date;
endDate: Date;
hoursPerDay: number;
dailyCostCents: number;
status: string;
project: {
id: string;
name: string;
shortCode: string;
status: string;
orderType: string;
clientId: string | null;
dynamicFields: Prisma.JsonValue | null;
};
resource: {
id: string;
displayName: string;
chapter: string | null;
} | null;
}
export async function listAssignmentBookings(
db: AssignmentBookingsDbClient,
input: ListAssignmentBookingsInput,
): Promise<AssignmentBookingWithFallback[]> {
const hasDateBounds = input.startDate !== undefined && input.endDate !== undefined;
if (!hasDateBounds && (input.startDate !== undefined || input.endDate !== undefined)) {
throw new Error("startDate and endDate must be provided together");
}
const excludeAssignmentIds = input.excludeAssignmentIds?.filter(Boolean) ?? [];
const assignmentWhere = {
status: { not: "CANCELLED" as const },
...(hasDateBounds
? {
startDate: { lte: input.endDate! },
endDate: { gte: input.startDate! },
}
: {}),
...(input.resourceIds?.length ? { resourceId: { in: input.resourceIds } } : {}),
...(input.projectIds?.length ? { projectId: { in: input.projectIds } } : {}),
...(excludeAssignmentIds.length ? { id: { notIn: excludeAssignmentIds } } : {}),
} satisfies Prisma.AssignmentWhereInput;
const assignmentSelect = {
id: true,
projectId: true,
resourceId: true,
startDate: true,
endDate: true,
hoursPerDay: true,
dailyCostCents: true,
status: true,
project: {
select: {
id: true,
name: true,
shortCode: true,
status: true,
orderType: true,
clientId: true,
dynamicFields: true,
},
},
resource: {
select: { id: true, displayName: true, chapter: true },
},
} satisfies Prisma.AssignmentSelect;
const assignments = await db.assignment.findMany({
where: assignmentWhere,
select: assignmentSelect,
});
return assignments.map((assignment) => ({
id: assignment.id,
projectId: assignment.projectId,
resourceId: assignment.resourceId,
startDate: assignment.startDate,
endDate: assignment.endDate,
hoursPerDay: assignment.hoursPerDay,
dailyCostCents: assignment.dailyCostCents,
status: assignment.status,
project: assignment.project,
resource: assignment.resource,
}));
}