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:
@@ -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,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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 $$;
|
||||||
2087
packages/db/migrations/meta/20250605101155_snapshot.json
Normal file
2087
packages/db/migrations/meta/20250605101155_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -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 }) => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user