fix: add cascade delete for card-related foreign keys and invalidate … (#31)

* fix: add cascade delete for card-related foreign keys and invalidate workspace cache after deletion

* fix: use refetch instead of invalidate for workspace deletion to ensure immediate UI update

* feat: add cascade delete to card relations and activity tables
This commit is contained in:
LovelessCodes
2025-06-05 22:20:31 +02:00
committed by GitHub
parent 116fefcaf3
commit 2043a8f98c
5 changed files with 2189 additions and 11 deletions

View File

@@ -15,14 +15,19 @@ export function DeleteWorkspaceConfirmation() {
const [isAcknowledgmentChecked, setIsAcknowledgmentChecked] = useState(false); const [isAcknowledgmentChecked, setIsAcknowledgmentChecked] = useState(false);
const utils = api.useUtils();
const deleteWorkspaceMutation = api.workspace.delete.useMutation({ const deleteWorkspaceMutation = api.workspace.delete.useMutation({
onSuccess: () => { onSuccess: async () => {
closeModal(); closeModal();
showPopup({ showPopup({
header: "Workspace deleted", header: "Workspace deleted",
message: "Your workspace has been deleted.", message: "Your workspace has been deleted.",
icon: "success", icon: "success",
}); });
await utils.workspace.all.refetch();
const filteredWorkspaces = availableWorkspaces.filter( const filteredWorkspaces = availableWorkspaces.filter(
(ws) => ws.publicId !== workspace.publicId, (ws) => ws.publicId !== workspace.publicId,
); );

View File

@@ -0,0 +1,79 @@
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_fromListId_list_id_fk";
--> statement-breakpoint
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_toListId_list_id_fk";
--> statement-breakpoint
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_labelId_label_id_fk";
--> statement-breakpoint
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_workspaceMemberId_workspace_members_id_fk";
--> statement-breakpoint
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_createdBy_user_id_fk";
--> statement-breakpoint
ALTER TABLE "card_activity" DROP CONSTRAINT "card_activity_commentId_card_comments_id_fk";
--> statement-breakpoint
ALTER TABLE "_card_workspace_members" DROP CONSTRAINT "_card_workspace_members_cardId_card_id_fk";
--> statement-breakpoint
ALTER TABLE "_card_labels" DROP CONSTRAINT "_card_labels_cardId_card_id_fk";
--> statement-breakpoint
ALTER TABLE "card_comments" DROP CONSTRAINT "card_comments_createdBy_user_id_fk";
--> statement-breakpoint
ALTER TABLE "card_comments" DROP CONSTRAINT "card_comments_deletedBy_user_id_fk";
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_fromListId_list_id_fk" FOREIGN KEY ("fromListId") REFERENCES "public"."list"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_toListId_list_id_fk" FOREIGN KEY ("toListId") REFERENCES "public"."list"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_labelId_label_id_fk" FOREIGN KEY ("labelId") REFERENCES "public"."label"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_workspaceMemberId_workspace_members_id_fk" FOREIGN KEY ("workspaceMemberId") REFERENCES "public"."workspace_members"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_activity" ADD CONSTRAINT "card_activity_commentId_card_comments_id_fk" FOREIGN KEY ("commentId") REFERENCES "public"."card_comments"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "_card_workspace_members" ADD CONSTRAINT "_card_workspace_members_cardId_card_id_fk" FOREIGN KEY ("cardId") REFERENCES "public"."card"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "_card_labels" ADD CONSTRAINT "_card_labels_cardId_card_id_fk" FOREIGN KEY ("cardId") REFERENCES "public"."card"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_comments" ADD CONSTRAINT "card_comments_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "card_comments" ADD CONSTRAINT "card_comments_deletedBy_user_id_fk" FOREIGN KEY ("deletedBy") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,13 @@
"when": 1748378293342, "when": 1748378293342,
"tag": "20250527203813_AddDeletedAtToLabel", "tag": "20250527203813_AddDeletedAtToLabel",
"breakpoints": true "breakpoints": true
},
{
"idx": 3,
"version": "7",
"when": 1749118315675,
"tag": "20250605101155_AddCascadeDeleteToCardRelations",
"breakpoints": true
} }
] ]
} }

View File

@@ -90,23 +90,23 @@ export const cardActivities = pgTable("card_activity", {
fromIndex: integer("fromIndex"), fromIndex: integer("fromIndex"),
toIndex: integer("toIndex"), toIndex: integer("toIndex"),
fromListId: bigint("fromListId", { mode: "number" }).references( fromListId: bigint("fromListId", { mode: "number" }).references(
() => lists.id, () => lists.id, { onDelete: "cascade" },
), ),
toListId: bigint("toListId", { mode: "number" }).references(() => lists.id), toListId: bigint("toListId", { mode: "number" }).references(() => lists.id, { onDelete: "cascade" }),
labelId: bigint("labelId", { mode: "number" }).references(() => labels.id), labelId: bigint("labelId", { mode: "number" }).references(() => labels.id, { onDelete: "cascade" }),
workspaceMemberId: bigint("workspaceMemberId", { workspaceMemberId: bigint("workspaceMemberId", {
mode: "number", mode: "number",
}).references(() => workspaceMembers.id), }).references(() => workspaceMembers.id, { onDelete: "cascade" }),
fromTitle: varchar("fromTitle", { length: 255 }), fromTitle: varchar("fromTitle", { length: 255 }),
toTitle: varchar("toTitle", { length: 255 }), toTitle: varchar("toTitle", { length: 255 }),
fromDescription: text("fromDescription"), fromDescription: text("fromDescription"),
toDescription: text("toDescription"), toDescription: text("toDescription"),
createdBy: uuid("createdBy") createdBy: uuid("createdBy")
.notNull() .notNull()
.references(() => users.id), .references(() => users.id, { onDelete: "cascade" }),
createdAt: timestamp("createdAt").defaultNow().notNull(), createdAt: timestamp("createdAt").defaultNow().notNull(),
commentId: bigint("commentId", { mode: "number" }).references( commentId: bigint("commentId", { mode: "number" }).references(
() => comments.id, () => comments.id, { onDelete: "cascade" },
), ),
fromComment: text("fromComment"), fromComment: text("fromComment"),
toComment: text("toComment"), toComment: text("toComment"),
@@ -152,7 +152,7 @@ export const cardsToLabels = pgTable(
{ {
cardId: bigint("cardId", { mode: "number" }) cardId: bigint("cardId", { mode: "number" })
.notNull() .notNull()
.references(() => cards.id), .references(() => cards.id, { onDelete: "cascade" }),
labelId: bigint("labelId", { mode: "number" }) labelId: bigint("labelId", { mode: "number" })
.notNull() .notNull()
.references(() => labels.id, { onDelete: "cascade" }), .references(() => labels.id, { onDelete: "cascade" }),
@@ -176,7 +176,7 @@ export const cardToWorkspaceMembers = pgTable(
{ {
cardId: bigint("cardId", { mode: "number" }) cardId: bigint("cardId", { mode: "number" })
.notNull() .notNull()
.references(() => cards.id), .references(() => cards.id, { onDelete: "cascade" }),
workspaceMemberId: bigint("workspaceMemberId", { mode: "number" }) workspaceMemberId: bigint("workspaceMemberId", { mode: "number" })
.notNull() .notNull()
.references(() => workspaceMembers.id, { onDelete: "cascade" }), .references(() => workspaceMembers.id, { onDelete: "cascade" }),
@@ -207,11 +207,11 @@ export const comments = pgTable("card_comments", {
.references(() => cards.id, { onDelete: "cascade" }), .references(() => cards.id, { onDelete: "cascade" }),
createdBy: uuid("createdBy") createdBy: uuid("createdBy")
.notNull() .notNull()
.references(() => users.id), .references(() => users.id, { onDelete: "cascade" }),
createdAt: timestamp("createdAt").defaultNow().notNull(), createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"), updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"), deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id), deletedBy: uuid("deletedBy").references(() => users.id, { onDelete: "cascade" }),
}).enableRLS(); }).enableRLS();
export const commentsRelations = relations(comments, ({ one }) => ({ export const commentsRelations = relations(comments, ({ one }) => ({