import { Prisma, type PrismaClient } from "@capakraken/db"; import { CreateCountrySchema, CreateMetroCitySchema, UpdateCountrySchema, UpdateMetroCitySchema, } from "@capakraken/shared"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; type CountryDb = Pick; type MetroCityDb = Pick; type CountryListInput = { isActive?: boolean | undefined; }; type MetroCityDeleteRecord = { _count: { resources: number; }; }; type CreateCountryInput = z.infer; type UpdateCountryInput = z.infer; type CreateMetroCityInput = z.infer; type UpdateMetroCityInput = z.infer; export function jsonOrNull(val: unknown): Prisma.InputJsonValue | typeof Prisma.JsonNull { if (val === null || val === undefined) return Prisma.JsonNull; return val as Prisma.InputJsonValue; } export function buildCountryListWhere( input: CountryListInput, ): Prisma.CountryWhereInput { return { ...(input.isActive !== undefined ? { isActive: input.isActive } : {}), }; } export async function findCountryByIdentifier( db: CountryDb, identifier: string, extraArgs: Record, ): Promise { const normalizedIdentifier = identifier.trim(); const upperIdentifier = normalizedIdentifier.toUpperCase(); let country = await db.country.findUnique({ where: { id: normalizedIdentifier }, ...extraArgs, }) as TCountry | null; if (!country) { country = await db.country.findFirst({ where: { code: { equals: upperIdentifier, mode: "insensitive" } }, ...extraArgs, }) as TCountry | null; } if (!country) { country = await db.country.findFirst({ where: { name: { equals: normalizedIdentifier, mode: "insensitive" } }, ...extraArgs, }) as TCountry | null; } if (!country) { country = await db.country.findFirst({ where: { name: { contains: normalizedIdentifier, mode: "insensitive" } }, ...extraArgs, }) as TCountry | null; } if (!country) { throw new TRPCError({ code: "NOT_FOUND", message: `Country not found: ${normalizedIdentifier}`, }); } return country; } export async function assertCountryCodeAvailable( db: CountryDb, code: string, ignoreId?: string, ): Promise { const existing = await db.country.findUnique({ where: { code } }); if (existing && existing.id !== ignoreId) { throw new TRPCError({ code: "CONFLICT", message: `Country code "${code}" already exists`, }); } } export function buildCountryCreateData( input: CreateCountryInput, ): Prisma.CountryUncheckedCreateInput { return { code: input.code, name: input.name, dailyWorkingHours: input.dailyWorkingHours, ...(input.scheduleRules !== undefined ? { scheduleRules: jsonOrNull(input.scheduleRules) } : {}), }; } export function buildCountryUpdateData( input: UpdateCountryInput, ): Prisma.CountryUncheckedUpdateInput { return { ...(input.code !== undefined ? { code: input.code } : {}), ...(input.name !== undefined ? { name: input.name } : {}), ...(input.dailyWorkingHours !== undefined ? { dailyWorkingHours: input.dailyWorkingHours } : {}), ...(input.scheduleRules !== undefined ? { scheduleRules: jsonOrNull(input.scheduleRules) } : {}), ...(input.isActive !== undefined ? { isActive: input.isActive } : {}), }; } export function buildMetroCityCreateData( input: CreateMetroCityInput, ): Prisma.MetroCityUncheckedCreateInput { return { name: input.name, countryId: input.countryId, }; } export function buildMetroCityUpdateData( input: UpdateMetroCityInput, ): Prisma.MetroCityUncheckedUpdateInput { return { ...(input.name !== undefined ? { name: input.name } : {}), }; } export function assertMetroCityDeletable( city: MetroCityDeleteRecord, ): void { if (city._count.resources > 0) { throw new TRPCError({ code: "PRECONDITION_FAILED", message: `Cannot delete metro city assigned to ${city._count.resources} resource(s)`, }); } }