import { accountPayablePermissions, createContext, DomainError, ensurePermission, } from "@tailor-platform/erp-kit/app"; import { createResolver, t } from "@tailor-platform/sdk"; import { getDB } from "@/generated/kysely-tailordb"; const MAX_ATTACHMENTS = 3; export default createResolver({ name: "createAccountPayableDocumentAttachment", operation: "mutation", input: { accountPayableDocumentId: t.string().description("Account payable document ID"), originalFileName: t.string().description("Original name of the uploaded file"), }, body: async (context) => { const caller = createContext(context); if (!caller.actorId) throw new DomainError("Authentication is required"); try { ensurePermission( { ...caller, actorId: caller.actorId, permissions: caller.permissions ?? [] }, accountPayablePermissions.accountPayableDocument.updateAccountPayableDocument, ); } catch { throw new DomainError("You do not have permission to modify invoice attachments"); } const originalFileName = context.input.originalFileName.trim(); if (!originalFileName) throw new DomainError("The original file name is required"); return getDB("main-db") .transaction() .execute(async (trx) => { const document = await trx .selectFrom("AccountPayableDocument") .select("id") .where("id", "=", context.input.accountPayableDocumentId) .forUpdate() .executeTakeFirst(); if (!document) { throw new DomainError( `Account payable document not found: ${context.input.accountPayableDocumentId}`, ); } const attachmentCount = await trx .selectFrom("AccountPayableDocumentAttachment") .select((eb) => eb.fn.countAll().as("count")) .where("accountPayableDocumentId", "=", document.id) .executeTakeFirstOrThrow(); if (Number(attachmentCount.count) >= MAX_ATTACHMENTS) { throw new DomainError( `An account payable document can have at most ${MAX_ATTACHMENTS} attachments`, ); } const attachment = await trx .insertInto("AccountPayableDocumentAttachment") .values({ accountPayableDocumentId: document.id, originalFileName, }) .returning("id") .executeTakeFirstOrThrow(); return { id: attachment.id }; }) .catch((err: unknown) => { if (err instanceof DomainError) throw err; throw new Error("Failed to create the account payable document attachment", { cause: err, }); }); }, output: t .object({ id: t.uuid().description("Created attachment ID") }) .typeName("AccountPayableDocumentAttachment"), });