diff --git a/app/settings/api/queue/delete-user-data.ts b/app/settings/api/queue/delete-user-data.ts index 26f3171..654be73 100644 --- a/app/settings/api/queue/delete-user-data.ts +++ b/app/settings/api/queue/delete-user-data.ts @@ -29,38 +29,12 @@ const deleteUserData = Queue("api/queue/delete-user-data", async ({ use switch (user.memberships[0]!.role) { case MembershipRole.OWNER: { const organization = user.memberships[0]!.organization; - const where = { organizationId: organization.id }; - await Promise.all([ - db.notificationSubscription.deleteMany({ where }), - db.phoneCall.deleteMany({ where }), - db.message.deleteMany({ where }), - db.processingPhoneNumber.deleteMany({ where }), - ]); - await db.phoneNumber.deleteMany({ where }); - - const orgMembers = organization.memberships - .map((membership) => membership.user!) - .filter((user) => user !== null); - await Promise.all( - orgMembers.map((member) => - Promise.all([ - db.token.deleteMany({ where: { userId: member.id } }), - db.session.deleteMany({ where: { userId: member.id } }), - db.membership.deleteMany({ where: { userId: member.id } }), - db.user.delete({ where: { id: member.id } }), - ]), - ), - ); await db.organization.delete({ where: { id: organization.id } }); + await db.user.delete({ where: { id: user.id } }); break; } case MembershipRole.USER: { - await Promise.all([ - db.token.deleteMany({ where: { userId: user.id } }), - db.session.deleteMany({ where: { userId: user.id } }), - db.user.delete({ where: { id: user.id } }), - db.membership.deleteMany({ where: { userId: user.id } }), - ]); + await db.user.delete({ where: { id: user.id } }); break; } case MembershipRole.ADMIN: diff --git a/db/migrations/20210924234954_use_referential_actions_to_cascade_deletions/migration.sql b/db/migrations/20210924234954_use_referential_actions_to_cascade_deletions/migration.sql new file mode 100644 index 0000000..5242f81 --- /dev/null +++ b/db/migrations/20210924234954_use_referential_actions_to_cascade_deletions/migration.sql @@ -0,0 +1,77 @@ +-- DropForeignKey +ALTER TABLE "Membership" DROP CONSTRAINT "Membership_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "Membership" DROP CONSTRAINT "Membership_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "Message" DROP CONSTRAINT "Message_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "Message" DROP CONSTRAINT "Message_phoneNumberId_fkey"; + +-- DropForeignKey +ALTER TABLE "NotificationSubscription" DROP CONSTRAINT "NotificationSubscription_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "NotificationSubscription" DROP CONSTRAINT "NotificationSubscription_phoneNumberId_fkey"; + +-- DropForeignKey +ALTER TABLE "PhoneCall" DROP CONSTRAINT "PhoneCall_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "PhoneCall" DROP CONSTRAINT "PhoneCall_phoneNumberId_fkey"; + +-- DropForeignKey +ALTER TABLE "PhoneNumber" DROP CONSTRAINT "PhoneNumber_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "ProcessingPhoneNumber" DROP CONSTRAINT "ProcessingPhoneNumber_organizationId_fkey"; + +-- DropForeignKey +ALTER TABLE "ProcessingPhoneNumber" DROP CONSTRAINT "ProcessingPhoneNumber_phoneNumberId_fkey"; + +-- DropForeignKey +ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "Token" DROP CONSTRAINT "Token_userId_fkey"; + +-- AddForeignKey +ALTER TABLE "Membership" ADD CONSTRAINT "Membership_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Membership" ADD CONSTRAINT "Membership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Message" ADD CONSTRAINT "Message_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Message" ADD CONSTRAINT "Message_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PhoneCall" ADD CONSTRAINT "PhoneCall_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PhoneCall" ADD CONSTRAINT "PhoneCall_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "PhoneNumber" ADD CONSTRAINT "PhoneNumber_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProcessingPhoneNumber" ADD CONSTRAINT "ProcessingPhoneNumber_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProcessingPhoneNumber" ADD CONSTRAINT "ProcessingPhoneNumber_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "NotificationSubscription" ADD CONSTRAINT "NotificationSubscription_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "NotificationSubscription" ADD CONSTRAINT "NotificationSubscription_phoneNumberId_fkey" FOREIGN KEY ("phoneNumberId") REFERENCES "PhoneNumber"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/db/schema.prisma b/db/schema.prisma index f219336..4b482a2 100644 --- a/db/schema.prisma +++ b/db/schema.prisma @@ -40,10 +40,10 @@ model Membership { id String @id @default(uuid()) role MembershipRole - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String - user User? @relation(fields: [userId], references: [id]) + user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId String? // When the user joins, we will clear out the name and email and set the user. @@ -95,7 +95,7 @@ model Session { publicData String? privateData String? - user User? @relation(fields: [userId], references: [id]) + user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId String? } @@ -108,7 +108,7 @@ model Token { expiresAt DateTime @db.Timestamptz sentTo String - user User @relation(fields: [userId], references: [id]) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String @@unique([hashedToken, type]) @@ -127,9 +127,9 @@ model Message { direction Direction status MessageStatus - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String - phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id]) + phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade) phoneNumberId String @@unique([organizationId, phoneNumberId, id]) @@ -167,9 +167,9 @@ model PhoneCall { direction Direction duration String - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String - phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id]) + phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade) phoneNumberId String @@unique([organizationId, phoneNumberId, id]) @@ -196,7 +196,7 @@ model PhoneNumber { notificationSubscriptions NotificationSubscription[] processingPhoneNumber ProcessingPhoneNumber? - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String @@unique([organizationId, id]) @@ -206,9 +206,9 @@ model ProcessingPhoneNumber { createdAt DateTime @default(now()) @db.Timestamptz hasFetchedMessages Boolean hasFetchedCalls Boolean - phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id]) + phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade) phoneNumberId String - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String @@id([organizationId, phoneNumberId]) @@ -223,8 +223,8 @@ model NotificationSubscription { keys_p256dh String keys_auth String - organization Organization @relation(fields: [organizationId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade) organizationId String - phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id]) + phoneNumber PhoneNumber @relation(fields: [phoneNumberId], references: [id], onDelete: Cascade) phoneNumberId String }