diff --git a/packages/trpc/server/document-router/get-documents-by-ids.ts b/packages/trpc/server/document-router/get-documents-by-ids.ts new file mode 100644 index 000000000..71e682542 --- /dev/null +++ b/packages/trpc/server/document-router/get-documents-by-ids.ts @@ -0,0 +1,74 @@ +import { EnvelopeType } from '@prisma/client'; + +import { getEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelope-by-id'; +import { mapEnvelopesToDocumentMany } from '@documenso/lib/utils/document'; +import { mapDocumentIdToSecondaryId } from '@documenso/lib/utils/envelope'; +import { prisma } from '@documenso/prisma'; + +import { authenticatedProcedure } from '../trpc'; +import { + ZGetDocumentsByIdsRequestSchema, + ZGetDocumentsByIdsResponseSchema, + getDocumentsByIdsMeta, +} from './get-documents-by-ids.types'; + +export const getDocumentsByIdsRoute = authenticatedProcedure + .meta(getDocumentsByIdsMeta) + .input(ZGetDocumentsByIdsRequestSchema) + .output(ZGetDocumentsByIdsResponseSchema) + .mutation(async ({ input, ctx }) => { + const { teamId, user } = ctx; + const { documentIds } = input; + + ctx.logger.info({ + input: { + documentIds, + }, + }); + + const { envelopeWhereInput } = await getEnvelopeWhereInput({ + id: { + type: 'documentId', + id: documentIds[0], + }, + userId: user.id, + teamId, + type: EnvelopeType.DOCUMENT, + }); + + const envelopeOrInput = envelopeWhereInput.OR!; + + const secondaryIds = documentIds.map((documentId) => mapDocumentIdToSecondaryId(documentId)); + + const envelopes = await prisma.envelope.findMany({ + where: { + type: EnvelopeType.DOCUMENT, + secondaryId: { + in: secondaryIds, + }, + OR: envelopeOrInput, + }, + include: { + user: { + select: { + id: true, + name: true, + email: true, + }, + }, + recipients: { + orderBy: { + id: 'asc', + }, + }, + team: { + select: { + id: true, + url: true, + }, + }, + }, + }); + + return envelopes.map((envelope) => mapEnvelopesToDocumentMany(envelope)); + }); diff --git a/packages/trpc/server/document-router/get-documents-by-ids.types.ts b/packages/trpc/server/document-router/get-documents-by-ids.types.ts new file mode 100644 index 000000000..2648897c1 --- /dev/null +++ b/packages/trpc/server/document-router/get-documents-by-ids.types.ts @@ -0,0 +1,24 @@ +import { z } from 'zod'; + +import { ZDocumentManySchema } from '@documenso/lib/types/document'; + +import type { TrpcRouteMeta } from '../trpc'; + +export const getDocumentsByIdsMeta: TrpcRouteMeta = { + openapi: { + method: 'POST', + path: '/document/get-many', + summary: 'Get multiple documents', + description: 'Retrieve multiple documents by their IDs', + tags: ['Document'], + }, +}; + +export const ZGetDocumentsByIdsRequestSchema = z.object({ + documentIds: z.array(z.number()).min(1), +}); + +export const ZGetDocumentsByIdsResponseSchema = z.array(ZDocumentManySchema); + +export type TGetDocumentsByIdsRequest = z.infer; +export type TGetDocumentsByIdsResponse = z.infer; diff --git a/packages/trpc/server/document-router/router.ts b/packages/trpc/server/document-router/router.ts index 2784c2ae7..ba512caac 100644 --- a/packages/trpc/server/document-router/router.ts +++ b/packages/trpc/server/document-router/router.ts @@ -19,6 +19,7 @@ import { findDocumentsInternalRoute } from './find-documents-internal'; import { findInboxRoute } from './find-inbox'; import { getDocumentRoute } from './get-document'; import { getDocumentByTokenRoute } from './get-document-by-token'; +import { getDocumentsByIdsRoute } from './get-documents-by-ids'; import { getInboxCountRoute } from './get-inbox-count'; import { redistributeDocumentRoute } from './redistribute-document'; import { searchDocumentRoute } from './search-document'; @@ -27,6 +28,7 @@ import { updateDocumentRoute } from './update-document'; export const documentRouter = router({ get: getDocumentRoute, + getMany: getDocumentsByIdsRoute, find: findDocumentsRoute, create: createDocumentRoute, update: updateDocumentRoute, diff --git a/packages/trpc/server/template-router/get-templates-by-ids.ts b/packages/trpc/server/template-router/get-templates-by-ids.ts new file mode 100644 index 000000000..593a52789 --- /dev/null +++ b/packages/trpc/server/template-router/get-templates-by-ids.ts @@ -0,0 +1,127 @@ +import { EnvelopeType } from '@prisma/client'; + +import { getEnvelopeWhereInput } from '@documenso/lib/server-only/envelope/get-envelope-by-id'; +import { + mapSecondaryIdToTemplateId, + mapTemplateIdToSecondaryId, +} from '@documenso/lib/utils/envelope'; +import { mapFieldToLegacyField } from '@documenso/lib/utils/fields'; +import { mapRecipientToLegacyRecipient } from '@documenso/lib/utils/recipients'; +import { prisma } from '@documenso/prisma'; + +import { authenticatedProcedure } from '../trpc'; +import { + ZGetTemplatesByIdsRequestSchema, + ZGetTemplatesByIdsResponseSchema, + getTemplatesByIdsMeta, +} from './get-templates-by-ids.types'; + +export const getTemplatesByIdsRoute = authenticatedProcedure + .meta(getTemplatesByIdsMeta) + .input(ZGetTemplatesByIdsRequestSchema) + .output(ZGetTemplatesByIdsResponseSchema) + .mutation(async ({ input, ctx }) => { + const { teamId, user } = ctx; + const { templateIds } = input; + + ctx.logger.info({ + input: { + templateIds, + }, + }); + + const { envelopeWhereInput } = await getEnvelopeWhereInput({ + id: { + type: 'templateId', + id: templateIds[0], + }, + userId: user.id, + teamId, + type: EnvelopeType.TEMPLATE, + }); + + const envelopeOrInput = envelopeWhereInput.OR!; + + const secondaryIds = templateIds.map((templateId) => mapTemplateIdToSecondaryId(templateId)); + + const envelopes = await prisma.envelope.findMany({ + where: { + type: EnvelopeType.TEMPLATE, + secondaryId: { + in: secondaryIds, + }, + OR: envelopeOrInput, + }, + include: { + recipients: { + orderBy: { + id: 'asc', + }, + }, + fields: true, + team: { + select: { + id: true, + url: true, + }, + }, + documentMeta: { + select: { + signingOrder: true, + distributionMethod: true, + }, + }, + directLink: { + select: { + token: true, + enabled: true, + }, + }, + }, + }); + + return envelopes.map((envelope) => { + const legacyTemplateId = mapSecondaryIdToTemplateId(envelope.secondaryId); + + return { + id: legacyTemplateId, + envelopeId: envelope.id, + type: envelope.templateType, + visibility: envelope.visibility, + externalId: envelope.externalId, + title: envelope.title, + userId: envelope.userId, + teamId: envelope.teamId, + authOptions: envelope.authOptions, + createdAt: envelope.createdAt, + updatedAt: envelope.updatedAt, + publicTitle: envelope.publicTitle, + publicDescription: envelope.publicDescription, + folderId: envelope.folderId, + useLegacyFieldInsertion: envelope.useLegacyFieldInsertion, + team: envelope.team + ? { + id: envelope.team.id, + url: envelope.team.url, + } + : null, + fields: envelope.fields.map((field) => mapFieldToLegacyField(field, envelope)), + recipients: envelope.recipients.map((recipient) => + mapRecipientToLegacyRecipient(recipient, envelope), + ), + templateMeta: envelope.documentMeta + ? { + signingOrder: envelope.documentMeta.signingOrder, + distributionMethod: envelope.documentMeta.distributionMethod, + } + : null, + directLink: envelope.directLink + ? { + token: envelope.directLink.token, + enabled: envelope.directLink.enabled, + } + : null, + templateDocumentDataId: '', // Backwards compatibility. + }; + }); + }); diff --git a/packages/trpc/server/template-router/get-templates-by-ids.types.ts b/packages/trpc/server/template-router/get-templates-by-ids.types.ts new file mode 100644 index 000000000..fa2701a03 --- /dev/null +++ b/packages/trpc/server/template-router/get-templates-by-ids.types.ts @@ -0,0 +1,24 @@ +import { z } from 'zod'; + +import { ZTemplateManySchema } from '@documenso/lib/types/template'; + +import type { TrpcRouteMeta } from '../trpc'; + +export const getTemplatesByIdsMeta: TrpcRouteMeta = { + openapi: { + method: 'POST', + path: '/template/get-many', + summary: 'Get multiple templates', + description: 'Retrieve multiple templates by their IDs', + tags: ['Template'], + }, +}; + +export const ZGetTemplatesByIdsRequestSchema = z.object({ + templateIds: z.array(z.number()).min(1), +}); + +export const ZGetTemplatesByIdsResponseSchema = z.array(ZTemplateManySchema); + +export type TGetTemplatesByIdsRequest = z.infer; +export type TGetTemplatesByIdsResponse = z.infer; diff --git a/packages/trpc/server/template-router/router.ts b/packages/trpc/server/template-router/router.ts index 44a66a349..75dbcaf10 100644 --- a/packages/trpc/server/template-router/router.ts +++ b/packages/trpc/server/template-router/router.ts @@ -30,6 +30,7 @@ import { mapEnvelopeToTemplateLite } from '@documenso/lib/utils/templates'; import { ZGenericSuccessResponse, ZSuccessResponseSchema } from '../schema'; import { authenticatedProcedure, maybeAuthenticatedProcedure, router } from '../trpc'; +import { getTemplatesByIdsRoute } from './get-templates-by-ids'; import { ZBulkSendTemplateMutationSchema, ZCreateDocumentFromDirectTemplateRequestSchema, @@ -154,6 +155,11 @@ export const templateRouter = router({ }); }), + /** + * @public + */ + getMany: getTemplatesByIdsRoute, + /** * Wait until RR7 so we can passthrough documents. *