import { DispoStagedRecordType, ImportBatchStatus, StagedRecordStatus, } from "@capakraken/db"; import { assessDispoImportReadiness, stageDispoImportBatch as stageDispoImportBatchApplication, } from "@capakraken/application"; import { z } from "zod"; import type { TRPCContext } from "../trpc.js"; import { cancelImportBatch as cancelImportBatchMutation, commitImportBatch as commitImportBatchMutation, resolveStagedRecord as resolveStagedRecordMutation, } from "./dispo-management.js"; import { getImportBatch as getImportBatchQuery, listImportBatches as listImportBatchesQuery, listStagedAssignments as listStagedAssignmentsQuery, listStagedProjects as listStagedProjectsQuery, listStagedResources as listStagedResourcesQuery, listStagedUnresolvedRecords as listStagedUnresolvedRecordsQuery, listStagedVacations as listStagedVacationsQuery, } from "./dispo-read.js"; type DispoProcedureContext = Pick; const paginationSchema = z.object({ cursor: z.string().optional(), limit: z.number().int().min(1).max(200).default(50), }); const importBatchStatusSchema = z.nativeEnum(ImportBatchStatus); const stagedRecordStatusSchema = z.nativeEnum(StagedRecordStatus); const stagedRecordTypeSchema = z.nativeEnum(DispoStagedRecordType); const workbookPathSchema = z .string() .trim() .min(1, "Workbook path is required.") .refine((value) => value.toLowerCase().endsWith(".xlsx"), { message: "Only .xlsx workbook paths are supported.", }); export const stageImportBatchInputSchema = z.object({ chargeabilityWorkbookPath: workbookPathSchema, costWorkbookPath: workbookPathSchema.optional(), notes: z.string().nullish(), planningWorkbookPath: workbookPathSchema, referenceWorkbookPath: workbookPathSchema, rosterWorkbookPath: workbookPathSchema.optional(), }); export const validateImportBatchInputSchema = z.object({ chargeabilityWorkbookPath: workbookPathSchema, costWorkbookPath: workbookPathSchema.optional(), importBatchId: z.string().optional(), notes: z.string().nullish(), planningWorkbookPath: workbookPathSchema, referenceWorkbookPath: workbookPathSchema, rosterWorkbookPath: workbookPathSchema.optional(), }); export const listImportBatchesInputSchema = paginationSchema.extend({ status: importBatchStatusSchema.optional(), }); export const importBatchIdInputSchema = z.object({ id: z.string(), }); export const listStagedResourcesInputSchema = paginationSchema.extend({ importBatchId: z.string(), status: stagedRecordStatusSchema.optional(), }); export const listStagedProjectsInputSchema = paginationSchema.extend({ importBatchId: z.string(), isTbd: z.boolean().optional(), status: stagedRecordStatusSchema.optional(), }); export const listStagedAssignmentsInputSchema = paginationSchema.extend({ importBatchId: z.string(), resourceExternalId: z.string().optional(), status: stagedRecordStatusSchema.optional(), }); export const listStagedVacationsInputSchema = paginationSchema.extend({ importBatchId: z.string(), resourceExternalId: z.string().optional(), }); export const listStagedUnresolvedRecordsInputSchema = paginationSchema.extend({ importBatchId: z.string(), recordType: stagedRecordTypeSchema.optional(), }); export const resolveStagedRecordInputSchema = z.object({ action: z.enum(["APPROVE", "REJECT", "SKIP"]), id: z.string(), recordType: stagedRecordTypeSchema, }); export const commitImportBatchInputSchema = z.object({ allowTbdUnresolved: z.boolean().optional(), importBatchId: z.string(), importTbdProjects: z.boolean().optional(), }); type StageImportBatchInput = z.infer; type ValidateImportBatchInput = z.infer; type ListImportBatchesInput = z.infer; type ImportBatchIdInput = z.infer; type ListStagedResourcesInput = z.infer; type ListStagedProjectsInput = z.infer; type ListStagedAssignmentsInput = z.infer; type ListStagedVacationsInput = z.infer; type ListStagedUnresolvedRecordsInput = z.infer; type ResolveStagedRecordInput = z.infer; type CommitImportBatchInput = z.infer; export async function stageImportBatch( ctx: DispoProcedureContext, input: StageImportBatchInput, ) { return stageDispoImportBatchApplication(ctx.db, { chargeabilityWorkbookPath: input.chargeabilityWorkbookPath, planningWorkbookPath: input.planningWorkbookPath, referenceWorkbookPath: input.referenceWorkbookPath, ...(input.costWorkbookPath !== undefined ? { costWorkbookPath: input.costWorkbookPath } : {}), ...(input.notes !== undefined ? { notes: input.notes } : {}), ...(input.rosterWorkbookPath !== undefined ? { rosterWorkbookPath: input.rosterWorkbookPath } : {}), }); } export async function validateImportBatch(input: ValidateImportBatchInput) { return assessDispoImportReadiness({ chargeabilityWorkbookPath: input.chargeabilityWorkbookPath, planningWorkbookPath: input.planningWorkbookPath, referenceWorkbookPath: input.referenceWorkbookPath, ...(input.costWorkbookPath !== undefined ? { costWorkbookPath: input.costWorkbookPath } : {}), ...(input.importBatchId !== undefined ? { importBatchId: input.importBatchId } : {}), ...(input.notes !== undefined ? { notes: input.notes } : {}), ...(input.rosterWorkbookPath !== undefined ? { rosterWorkbookPath: input.rosterWorkbookPath } : {}), }); } export async function listImportBatches(ctx: DispoProcedureContext, input: ListImportBatchesInput) { return listImportBatchesQuery(ctx.db, input); } export async function getImportBatch(ctx: DispoProcedureContext, input: ImportBatchIdInput) { return getImportBatchQuery(ctx.db, input.id); } export async function cancelImportBatch(ctx: DispoProcedureContext, input: ImportBatchIdInput) { return cancelImportBatchMutation(ctx.db, { id: input.id, userId: ctx.dbUser?.id }); } export async function listStagedResources( ctx: DispoProcedureContext, input: ListStagedResourcesInput, ) { return listStagedResourcesQuery(ctx.db, input); } export async function listStagedProjects( ctx: DispoProcedureContext, input: ListStagedProjectsInput, ) { return listStagedProjectsQuery(ctx.db, input); } export async function listStagedAssignments( ctx: DispoProcedureContext, input: ListStagedAssignmentsInput, ) { return listStagedAssignmentsQuery(ctx.db, input); } export async function listStagedVacations( ctx: DispoProcedureContext, input: ListStagedVacationsInput, ) { return listStagedVacationsQuery(ctx.db, input); } export async function listStagedUnresolvedRecords( ctx: DispoProcedureContext, input: ListStagedUnresolvedRecordsInput, ) { return listStagedUnresolvedRecordsQuery(ctx.db, input); } export async function resolveStagedRecord( ctx: DispoProcedureContext, input: ResolveStagedRecordInput, ) { return resolveStagedRecordMutation(ctx.db, input); } export async function commitImportBatch( ctx: DispoProcedureContext, input: CommitImportBatchInput, ) { return commitImportBatchMutation(ctx.db, { importBatchId: input.importBatchId, allowTbdUnresolved: input.allowTbdUnresolved, importTbdProjects: input.importTbdProjects, userId: ctx.dbUser?.id, }); }