refactor: move shift index into transaction
This commit is contained in:
@@ -733,11 +733,6 @@ export const cardRouter = createTRPCRouter({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
});
|
||||
|
||||
await cardRepo.shiftIndex(ctx.supabaseClient, {
|
||||
listId: card.list.id,
|
||||
cardIndex: card.index,
|
||||
});
|
||||
|
||||
await cardActivityRepo.create(ctx.db, {
|
||||
type: "card.archived",
|
||||
cardId: card.id,
|
||||
|
||||
@@ -133,11 +133,6 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
await activityRepo.bulkCreate(ctx.db, activities);
|
||||
|
||||
await listRepo.shiftIndex(ctx.supabaseClient, {
|
||||
boardId: list.boardId,
|
||||
listIndex: list.index,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
update: protectedProcedure
|
||||
|
||||
@@ -1,21 +1,3 @@
|
||||
CREATE OR REPLACE FUNCTION shift_list_index(board_id BIGINT, list_index INT)
|
||||
RETURNS VOID
|
||||
LANGUAGE SQL
|
||||
AS $$
|
||||
UPDATE list
|
||||
SET index = index - 1
|
||||
WHERE "boardId" = board_id AND index > list_index AND "deletedAt" IS NULL;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION shift_card_index(list_id BIGINT, card_index INT)
|
||||
RETURNS VOID
|
||||
LANGUAGE SQL
|
||||
AS $$
|
||||
UPDATE card
|
||||
SET index = index - 1
|
||||
WHERE "listId" = list_id AND index > card_index AND "deletedAt" IS NULL;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION is_workspace_admin(user_id UUID, workspace_id BIGINT)
|
||||
RETURNS BOOLEAN
|
||||
LANGUAGE SQL
|
||||
|
||||
@@ -529,7 +529,7 @@ export const reorder = async (
|
||||
|
||||
const countExpr = sql<number>`COUNT(*)`.mapWith(Number);
|
||||
|
||||
const duplicateIndices = await db
|
||||
const duplicateIndices = await tx
|
||||
.select({
|
||||
index: cards.index,
|
||||
count: countExpr,
|
||||
@@ -567,22 +567,6 @@ export const reorder = async (
|
||||
});
|
||||
};
|
||||
|
||||
// Again should be handled in update transaction
|
||||
export const shiftIndex = async (
|
||||
db: SupabaseClient<Database>,
|
||||
args: {
|
||||
listId: number;
|
||||
cardIndex: number;
|
||||
},
|
||||
) => {
|
||||
const { data } = await db.rpc("shift_card_index", {
|
||||
list_id: args.listId,
|
||||
card_index: args.cardIndex,
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const softDelete = async (
|
||||
db: dbClient,
|
||||
args: {
|
||||
@@ -591,15 +575,46 @@ export const softDelete = async (
|
||||
deletedBy: string;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
.update(cards)
|
||||
.set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
|
||||
.where(eq(cards.id, args.cardId))
|
||||
.returning({
|
||||
id: cards.id,
|
||||
});
|
||||
return db.transaction(async (tx) => {
|
||||
const [result] = await tx
|
||||
.update(cards)
|
||||
.set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
|
||||
.where(eq(cards.id, args.cardId))
|
||||
.returning({
|
||||
id: cards.id,
|
||||
listId: cards.listId,
|
||||
index: cards.index,
|
||||
});
|
||||
|
||||
return result;
|
||||
if (!result)
|
||||
throw new Error(`Unable to soft delete card ID ${args.cardId}`);
|
||||
|
||||
await tx.execute(sql`
|
||||
UPDATE card
|
||||
SET index = index - 1
|
||||
WHERE "listId" = ${result.listId} AND index > ${result.index} AND "deletedAt" IS NULL;
|
||||
`);
|
||||
|
||||
const countExpr = sql<number>`COUNT(*)`.mapWith(Number);
|
||||
|
||||
const duplicateIndices = await tx
|
||||
.select({
|
||||
index: cards.index,
|
||||
count: countExpr,
|
||||
})
|
||||
.from(cards)
|
||||
.where(and(eq(cards.listId, result.listId), isNull(cards.deletedAt)))
|
||||
.groupBy(cards.listId, cards.index)
|
||||
.having(gt(countExpr, 1));
|
||||
|
||||
if (duplicateIndices.length > 0) {
|
||||
throw new Error(
|
||||
`Duplicate indices found after soft deleting ${result.id}`,
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
export const softDeleteAllByListIds = async (
|
||||
|
||||
@@ -122,7 +122,7 @@ export const reorder = async (
|
||||
|
||||
const countExpr = sql<number>`COUNT(*)`.mapWith(Number);
|
||||
|
||||
const duplicateIndices = await db
|
||||
const duplicateIndices = await tx
|
||||
.select({
|
||||
index: lists.index,
|
||||
count: countExpr,
|
||||
@@ -150,21 +150,6 @@ export const reorder = async (
|
||||
});
|
||||
};
|
||||
|
||||
export const shiftIndex = async (
|
||||
db: SupabaseClient<Database>,
|
||||
args: {
|
||||
boardId: number;
|
||||
listIndex: number;
|
||||
},
|
||||
) => {
|
||||
const { data } = await db.rpc("shift_list_index", {
|
||||
board_id: args.boardId,
|
||||
list_index: args.listIndex,
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const softDeleteAllByBoardId = async (
|
||||
db: dbClient,
|
||||
args: {
|
||||
@@ -192,13 +177,44 @@ export const softDeleteById = async (
|
||||
deletedBy: string;
|
||||
},
|
||||
) => {
|
||||
const [updatedList] = await db
|
||||
.update(lists)
|
||||
.set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
|
||||
.where(and(eq(lists.id, args.listId), isNull(lists.deletedAt)))
|
||||
.returning({
|
||||
id: lists.id,
|
||||
});
|
||||
return db.transaction(async (tx) => {
|
||||
const [result] = await tx
|
||||
.update(lists)
|
||||
.set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
|
||||
.where(and(eq(lists.id, args.listId), isNull(lists.deletedAt)))
|
||||
.returning({
|
||||
id: lists.id,
|
||||
index: lists.index,
|
||||
boardId: lists.boardId,
|
||||
});
|
||||
|
||||
return updatedList;
|
||||
if (!result)
|
||||
throw new Error(`Unable to soft delete list ID ${args.listId}`);
|
||||
|
||||
await tx.execute(sql`
|
||||
UPDATE list
|
||||
SET index = index - 1
|
||||
WHERE "boardId" = ${result.boardId} AND index > ${result.index} AND "deletedAt" IS NULL;
|
||||
`);
|
||||
|
||||
const countExpr = sql<number>`COUNT(*)`.mapWith(Number);
|
||||
|
||||
const duplicateIndices = await tx
|
||||
.select({
|
||||
index: lists.index,
|
||||
count: countExpr,
|
||||
})
|
||||
.from(lists)
|
||||
.where(and(eq(lists.boardId, result.boardId), isNull(lists.deletedAt)))
|
||||
.groupBy(lists.index)
|
||||
.having(gt(countExpr, 1));
|
||||
|
||||
if (duplicateIndices.length > 0) {
|
||||
throw new Error(
|
||||
`Duplicate indices found after reordering in board ${result.boardId}`,
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user