fix(types): replace structural DB types with Pick<PrismaClient> and remove Prisma boundary as any casts

Replace ~440 lines of hand-written structural DB client types across 7 lib files
with `Pick<PrismaClient, ...>` from @capakraken/db. This eliminates all `as any`
casts at Prisma boundaries (cron routes, allocation effects, vacation procedures)
and surfaces two pre-existing bugs:
- weekly-digest.ts: `db.allocation.count()` called non-existent model (fixed → demandRequirement)
- estimate-reminders.ts: `submittedAt` field doesn't exist on EstimateVersion (fixed → updatedAt)

Also adds root eslint.config.mjs so lint-staged can lint package files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 15:09:16 +02:00
parent 82acc56b8d
commit 9051ff73d0
17 changed files with 257 additions and 581 deletions
@@ -1,14 +1,11 @@
import type { Prisma, PrismaClient, VacationStatus } from "@capakraken/db";
import type { Prisma, PrismaClient, VacationStatus, VacationType } from "@capakraken/db";
import { TRPCError } from "@trpc/server";
type DbClient = Pick<
PrismaClient,
"vacation" | "user" | "resource" | "notification"
>;
type DbClient = PrismaClient;
export type VacationChargeableInput = {
resourceId: string;
type: string;
type: VacationType;
startDate: Date;
endDate: Date;
isHalfDay: boolean;
@@ -16,10 +13,7 @@ export type VacationChargeableInput = {
export type ApproveVacationDeps = {
assertVacationApprovable: (status: VacationStatus) => void;
assertVacationStillChargeable: (
db: DbClient,
vacation: VacationChargeableInput,
) => Promise<void>;
assertVacationStillChargeable: (db: DbClient, vacation: VacationChargeableInput) => Promise<void>;
buildVacationApprovalWriteData: (
db: DbClient,
vacation: VacationChargeableInput,
@@ -75,11 +69,7 @@ export async function approveVacation(
isHalfDay: existing.isHalfDay,
});
const conflictResult = await deps.checkVacationConflicts(
db,
input.id,
input.actorUserId,
);
const conflictResult = await deps.checkVacationConflicts(db, input.id, input.actorUserId);
const updated = await db.vacation.update({
where: { id: input.id },
@@ -98,10 +88,7 @@ export async function approveVacation(
}
export type BatchApproveVacationDeps = {
assertVacationStillChargeable: (
db: DbClient,
vacation: VacationChargeableInput,
) => Promise<void>;
assertVacationStillChargeable: (db: DbClient, vacation: VacationChargeableInput) => Promise<void>;
buildVacationApprovalWriteData: (
db: DbClient,
vacation: VacationChargeableInput,
@@ -139,14 +126,7 @@ export async function batchApproveVacations(
input: BatchApproveVacationInput,
deps: BatchApproveVacationDeps,
): Promise<BatchApproveVacationResult> {
const vacations: Array<{
id: string;
resourceId: string;
type: string;
startDate: Date;
endDate: Date;
isHalfDay: boolean;
}> = await db.vacation.findMany({
const vacations = await db.vacation.findMany({
where: { id: { in: input.ids }, status: "PENDING" },
select: {
id: true,
@@ -171,10 +151,7 @@ export async function batchApproveVacations(
const updatedVacations: BatchApproveVacationResult["updatedVacations"] = [];
for (const vacation of vacations) {
const deductionSnapshotWriteData = await deps.buildVacationApprovalWriteData(
db,
vacation,
);
const deductionSnapshotWriteData = await deps.buildVacationApprovalWriteData(db, vacation);
const updated = await db.vacation.update({
where: { id: vacation.id },