import type { Prisma, PrismaClient, VacationStatus } from "@capakraken/db"; import { TRPCError } from "@trpc/server"; type DbClient = Pick; export type RejectVacationDeps = { assertVacationRejectable: (status: VacationStatus) => void; buildRejectedVacationUpdateData: (input: { rejectionReason?: string | undefined; }) => Prisma.VacationUncheckedUpdateInput; }; export type RejectVacationInput = { id: string; rejectionReason?: string | undefined; }; export type RejectVacationResult = { vacation: Awaited>; }; export async function rejectVacation( db: DbClient, input: RejectVacationInput, deps: RejectVacationDeps, ): Promise { const existing = await db.vacation.findUnique({ where: { id: input.id } }); if (!existing) { throw new TRPCError({ code: "NOT_FOUND", message: "Vacation not found" }); } deps.assertVacationRejectable(existing.status); const updated = await db.vacation.update({ where: { id: input.id }, data: deps.buildRejectedVacationUpdateData({ rejectionReason: input.rejectionReason, }), }); return { vacation: updated }; } export type BatchRejectVacationDeps = { buildRejectedVacationUpdateData: (input: { rejectionReason?: string | undefined; }) => Prisma.VacationUncheckedUpdateInput; }; export type BatchRejectVacationInput = { ids: string[]; rejectionReason?: string | undefined; }; export type BatchRejectVacationResult = { rejected: number; vacations: Array<{ id: string; resourceId: string }>; }; export async function batchRejectVacations( db: DbClient, input: BatchRejectVacationInput, deps: BatchRejectVacationDeps, ): Promise { const vacations: Array<{ id: string; resourceId: string }> = await db.vacation.findMany({ where: { id: { in: input.ids }, status: "PENDING" }, select: { id: true, resourceId: true }, }); await db.vacation.updateMany({ where: { id: { in: vacations.map((v) => v.id) } }, data: deps.buildRejectedVacationUpdateData({ rejectionReason: input.rejectionReason, }), }); return { rejected: vacations.length, vacations }; }