diff --git a/packages/lib/server-only/document/handle-document-ownership-on-deletion.ts b/packages/lib/server-only/document/handle-document-ownership-on-deletion.ts new file mode 100644 index 000000000..d78c0d52a --- /dev/null +++ b/packages/lib/server-only/document/handle-document-ownership-on-deletion.ts @@ -0,0 +1,78 @@ +import { deletedAccountServiceAccount } from '@documenso/lib/server-only/user/service-accounts/deleted-account'; +import { prisma } from '@documenso/prisma'; +import { DocumentStatus } from '@documenso/prisma/client'; + +type MoveDocumentsOptions = { + documentIds: number[]; + organisationOwnerId: number; +}; + +export const handleDocumentOwnershipOnDeletion = async ({ + documentIds, + organisationOwnerId, +}: MoveDocumentsOptions) => { + if (documentIds.length === 0) { + return; + } + + const serviceAccount = await deletedAccountServiceAccount(); + const serviceAccountTeam = serviceAccount.ownedOrganisations[0].teams[0]; + + await prisma.document.deleteMany({ + where: { + id: { + in: documentIds, + }, + status: DocumentStatus.DRAFT, + }, + }); + + const organisationOwner = await prisma.user.findUnique({ + where: { + id: organisationOwnerId, + }, + include: { + ownedOrganisations: { + include: { + teams: true, + }, + }, + }, + }); + + if (organisationOwner && organisationOwner.ownedOrganisations.length > 0) { + const ownerPersonalTeam = organisationOwner.ownedOrganisations[0].teams[0]; + + await prisma.document.updateMany({ + where: { + id: { + in: documentIds, + }, + status: { + not: DocumentStatus.DRAFT, + }, + }, + data: { + userId: organisationOwner.id, + teamId: ownerPersonalTeam.id, + deletedAt: new Date(), + }, + }); + } else { + await prisma.document.updateMany({ + where: { + id: { + in: documentIds, + }, + status: { + not: DocumentStatus.DRAFT, + }, + }, + data: { + userId: serviceAccount.id, + teamId: serviceAccountTeam.id, + deletedAt: new Date(), + }, + }); + } +}; diff --git a/packages/trpc/server/organisation-router/delete-organisation.ts b/packages/trpc/server/organisation-router/delete-organisation.ts index 91dd46f1a..9b39f3c58 100644 --- a/packages/trpc/server/organisation-router/delete-organisation.ts +++ b/packages/trpc/server/organisation-router/delete-organisation.ts @@ -1,9 +1,8 @@ import { ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP } from '@documenso/lib/constants/organisations'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; -import { deletedAccountServiceAccount } from '@documenso/lib/server-only/user/service-accounts/deleted-account'; +import { handleDocumentOwnershipOnDeletion } from '@documenso/lib/server-only/document/move-documents-to-owner-or-service'; import { buildOrganisationWhereQuery } from '@documenso/lib/utils/organisations'; import { prisma } from '@documenso/prisma'; -import { DocumentStatus } from '@documenso/prisma/client'; import { authenticatedProcedure } from '../trpc'; import { @@ -18,8 +17,6 @@ export const deleteOrganisationRoute = authenticatedProcedure .mutation(async ({ input, ctx }) => { const { organisationId } = input; const { user } = ctx; - const serviceAccount = await deletedAccountServiceAccount(); - const serviceAccountTeam = serviceAccount.ownedOrganisations[0].teams[0]; ctx.logger.info({ input: { @@ -59,66 +56,13 @@ export const deleteOrganisationRoute = authenticatedProcedure }); } - const organisationOwner = await prisma.user.findUnique({ - where: { - id: organisation.owner.id, - }, - include: { - ownedOrganisations: { - include: { - teams: true, - }, - }, - }, - }); - const documentIds = organisation.teams.flatMap((team) => team.documents.map((doc) => doc.id)); - if (documentIds.length > 0) { - await prisma.document.deleteMany({ - where: { - id: { - in: documentIds, - }, - status: DocumentStatus.DRAFT, - }, + if (documentIds && documentIds.length > 0) { + await handleDocumentOwnershipOnDeletion({ + documentIds, + organisationOwnerId: organisation.owner.id, }); - - if (organisationOwner && organisationOwner.ownedOrganisations.length > 0) { - const ownerPersonalTeam = organisationOwner.ownedOrganisations[0].teams[0]; - - await prisma.document.updateMany({ - where: { - id: { - in: documentIds, - }, - status: { - not: DocumentStatus.DRAFT, - }, - }, - data: { - userId: organisationOwner.id, - teamId: ownerPersonalTeam.id, - deletedAt: new Date(), - }, - }); - } else { - await prisma.document.updateMany({ - where: { - id: { - in: documentIds, - }, - status: { - not: DocumentStatus.DRAFT, - }, - }, - data: { - userId: serviceAccount.id, - teamId: serviceAccountTeam.id, - deletedAt: new Date(), - }, - }); - } } await prisma.organisation.delete({ diff --git a/packages/trpc/server/team-router/delete-team.ts b/packages/trpc/server/team-router/delete-team.ts index 2624a902b..38fce763e 100644 --- a/packages/trpc/server/team-router/delete-team.ts +++ b/packages/trpc/server/team-router/delete-team.ts @@ -1,4 +1,8 @@ +import { ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP } from '@documenso/lib/constants/organisations'; +import { handleDocumentOwnershipOnDeletion } from '@documenso/lib/server-only/document/move-documents-to-owner-or-service'; import { deleteTeam } from '@documenso/lib/server-only/team/delete-team'; +import { buildOrganisationWhereQuery } from '@documenso/lib/utils/organisations'; +import { prisma } from '@documenso/prisma'; import { authenticatedProcedure } from '../trpc'; import { ZDeleteTeamRequestSchema, ZDeleteTeamResponseSchema } from './delete-team.types'; @@ -11,12 +15,53 @@ export const deleteTeamRoute = authenticatedProcedure const { teamId } = input; const { user } = ctx; + const team = await prisma.team.findUnique({ + where: { + id: teamId, + }, + }); + + const organisation = await prisma.organisation.findFirst({ + where: buildOrganisationWhereQuery({ + organisationId: team?.organisationId, + userId: user.id, + roles: ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP['DELETE_ORGANISATION'], + }), + select: { + id: true, + owner: { + select: { + id: true, + }, + }, + teams: { + select: { + id: true, + documents: { + select: { + id: true, + }, + }, + }, + }, + }, + }); + ctx.logger.info({ input: { teamId, }, }); + const documentIds = organisation?.teams.flatMap((team) => team.documents.map((doc) => doc.id)); + + if (documentIds && documentIds.length > 0 && organisation) { + await handleDocumentOwnershipOnDeletion({ + documentIds, + organisationOwnerId: organisation.owner.id, + }); + } + await deleteTeam({ userId: user.id, teamId,