import { ImportBatchStatus, StagedRecordStatus, } from "@capakraken/db"; import { TRPCError } from "@trpc/server"; type PaginationInput = { cursor?: string | undefined; limit: number; }; function toPaginatedResult(items: T[], limit: number) { let nextCursor: string | undefined; if (items.length > limit) { const next = items.pop(); nextCursor = next?.id; } return { items, nextCursor }; } function toCursorPagination(input: PaginationInput) { return { take: input.limit + 1, ...(input.cursor ? { cursor: { id: input.cursor }, skip: 1 } : {}), }; } export async function listImportBatches( db: { importBatch: { findMany: Function } }, input: PaginationInput & { status?: ImportBatchStatus | undefined }, ) { const items = await db.importBatch.findMany({ where: { ...(input.status !== undefined ? { status: input.status } : {}), }, orderBy: { createdAt: "desc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); } export async function getImportBatch( db: { importBatch: { findUnique: Function }; stagedResource: { count: Function }; stagedClient: { count: Function }; stagedProject: { count: Function }; stagedAssignment: { count: Function }; stagedVacation: { count: Function }; stagedAvailabilityRule: { count: Function }; stagedUnresolvedRecord: { count: Function }; }, id: string, ) { const batch = await db.importBatch.findUnique({ where: { id }, }); if (!batch) { throw new TRPCError({ code: "NOT_FOUND", message: `Import batch "${id}" not found` }); } const [ resourceCount, clientCount, projectCount, assignmentCount, vacationCount, availabilityRuleCount, unresolvedCount, ] = await Promise.all([ db.stagedResource.count({ where: { importBatchId: id } }), db.stagedClient.count({ where: { importBatchId: id } }), db.stagedProject.count({ where: { importBatchId: id } }), db.stagedAssignment.count({ where: { importBatchId: id } }), db.stagedVacation.count({ where: { importBatchId: id } }), db.stagedAvailabilityRule.count({ where: { importBatchId: id } }), db.stagedUnresolvedRecord.count({ where: { importBatchId: id } }), ]); return { ...batch, counts: { assignmentCount, availabilityRuleCount, clientCount, projectCount, resourceCount, unresolvedCount, vacationCount, }, }; } export async function listStagedResources( db: { stagedResource: { findMany: Function } }, input: PaginationInput & { importBatchId: string; status?: StagedRecordStatus | undefined; }, ) { const items = await db.stagedResource.findMany({ where: { importBatchId: input.importBatchId, ...(input.status !== undefined ? { status: input.status } : {}), }, orderBy: { canonicalExternalId: "asc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); } export async function listStagedProjects( db: { stagedProject: { findMany: Function } }, input: PaginationInput & { importBatchId: string; isTbd?: boolean | undefined; status?: StagedRecordStatus | undefined; }, ) { const items = await db.stagedProject.findMany({ where: { importBatchId: input.importBatchId, ...(input.status !== undefined ? { status: input.status } : {}), ...(input.isTbd !== undefined ? { isTbd: input.isTbd } : {}), }, orderBy: { projectKey: "asc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); } export async function listStagedAssignments( db: { stagedAssignment: { findMany: Function } }, input: PaginationInput & { importBatchId: string; resourceExternalId?: string | undefined; status?: StagedRecordStatus | undefined; }, ) { const items = await db.stagedAssignment.findMany({ where: { importBatchId: input.importBatchId, ...(input.status !== undefined ? { status: input.status } : {}), ...(input.resourceExternalId !== undefined ? { resourceExternalId: input.resourceExternalId } : {}), }, orderBy: { createdAt: "asc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); } export async function listStagedVacations( db: { stagedVacation: { findMany: Function } }, input: PaginationInput & { importBatchId: string; resourceExternalId?: string | undefined; }, ) { const items = await db.stagedVacation.findMany({ where: { importBatchId: input.importBatchId, ...(input.resourceExternalId !== undefined ? { resourceExternalId: input.resourceExternalId } : {}), }, orderBy: { startDate: "asc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); } export async function listStagedUnresolvedRecords( db: { stagedUnresolvedRecord: { findMany: Function } }, input: PaginationInput & { importBatchId: string; recordType?: string | undefined; }, ) { const items = await db.stagedUnresolvedRecord.findMany({ where: { importBatchId: input.importBatchId, ...(input.recordType !== undefined ? { recordType: input.recordType } : {}), }, orderBy: { createdAt: "asc" }, ...toCursorPagination(input), }); return toPaginatedResult(items, input.limit); }