feat: swap out drizzle for supabase in label, list and workspace routers
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { z } from "zod";
|
||||
import { generateUID } from "~/utils/generateUID";
|
||||
|
||||
import {
|
||||
createTRPCRouter,
|
||||
@@ -10,7 +9,7 @@ export const authRouter = createTRPCRouter({
|
||||
login: publicProcedure
|
||||
.input(z.object({ email: z.string() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const { data, error } = await ctx.supabase.auth.signInWithOtp({
|
||||
const { data } = await ctx.supabase.auth.signInWithOtp({
|
||||
email: input.email,
|
||||
options: {
|
||||
emailRedirectTo: '/boards',
|
||||
|
||||
@@ -107,11 +107,9 @@ export const boardRouter = createTRPCRouter({
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
console.log({ workspace })
|
||||
|
||||
if (!workspace.data) return;
|
||||
|
||||
const { data, error } = await ctx.supabase
|
||||
const { data } = await ctx.supabase
|
||||
.from('board')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -168,23 +166,26 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
const listIds = board.data.lists.map((list) => list.id);
|
||||
|
||||
const deletedAt = new Date().toString();
|
||||
const deletedAt = new Date().toISOString();
|
||||
|
||||
await ctx.supabase
|
||||
.from('board')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('id', board.data.id);
|
||||
.eq('id', board.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
if (listIds.length) {
|
||||
await ctx.supabase
|
||||
.from('list')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('boardId', board.data.id);
|
||||
.eq('boardId', board.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
await ctx.supabase
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.in('listId', listIds);
|
||||
.in('listId', listIds)
|
||||
.is('deletedAt', null);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { z } from "zod";
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
|
||||
import { cards, cardsToLabels, labels } from "~/server/db/schema";
|
||||
import { generateUID } from "~/utils/generateUID";
|
||||
|
||||
import {
|
||||
@@ -18,41 +15,43 @@ export const labelRouter = createTRPCRouter({
|
||||
colourCode: z.string().length(7),
|
||||
}),
|
||||
)
|
||||
.mutation(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.transaction(async (tx) => {
|
||||
const card = await tx.query.cards.findFirst({
|
||||
where: and(eq(cards.publicId, input.cardPublicId), isNull(cards.deletedAt)),
|
||||
with: {
|
||||
list: {
|
||||
with: {
|
||||
board: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const card = await ctx.supabase
|
||||
.from('card')
|
||||
.select(`id, list (boardId)`)
|
||||
.eq('publicId', input.cardPublicId)
|
||||
.is('deletedAt', null)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!card) return;
|
||||
if (!card.data?.list) return;
|
||||
|
||||
const newLabel = await tx.insert(labels).values({
|
||||
const newLabel = await ctx.supabase
|
||||
.from('label')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
name: input.name,
|
||||
colourCode: input.colourCode,
|
||||
createdBy: userId,
|
||||
boardId: card.list.boardId,
|
||||
}).returning({ id: labels.id });
|
||||
boardId: card.data.list.boardId,
|
||||
})
|
||||
.select(`id`)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
const newLabelId = newLabel[0]?.id
|
||||
if (!newLabel.data) return;
|
||||
|
||||
if (!newLabelId) return;
|
||||
await ctx.supabase
|
||||
.from('_card_labels')
|
||||
.insert({
|
||||
cardId: card.data.id,
|
||||
labelId: newLabel.data.id,
|
||||
})
|
||||
|
||||
return tx.insert(cardsToLabels).values({
|
||||
cardId: card.id,
|
||||
labelId: newLabelId,
|
||||
});
|
||||
})
|
||||
return newLabel.data;
|
||||
}),
|
||||
});
|
||||
@@ -1,7 +1,4 @@
|
||||
import { z } from "zod";
|
||||
import { and, desc, eq, sql, isNull } from "drizzle-orm";
|
||||
|
||||
import { boards, cards, lists } from "~/server/db/schema";
|
||||
import { generateUID } from "~/utils/generateUID";
|
||||
|
||||
import {
|
||||
@@ -17,37 +14,39 @@ export const listRouter = createTRPCRouter({
|
||||
boardPublicId: z.string().min(12)
|
||||
}),
|
||||
)
|
||||
.mutation(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.transaction(async (tx) => {
|
||||
const board = await tx.query.boards.findFirst({
|
||||
where: eq(boards.publicId, input.boardPublicId),
|
||||
columns: {
|
||||
id: true
|
||||
}
|
||||
});
|
||||
const board = await ctx.supabase
|
||||
.from('board')
|
||||
.select(`id, lists:list (index)`)
|
||||
.eq('publicId', input.boardPublicId)
|
||||
.order('index', { foreignTable: 'list', ascending: false })
|
||||
.is('list.deletedAt', null)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!board) return;
|
||||
if (!board.data) return;
|
||||
|
||||
const latestList = await tx.query.lists.findFirst({
|
||||
where: eq(lists.boardId, board.id),
|
||||
columns: {
|
||||
index: true
|
||||
},
|
||||
orderBy: desc(lists.index)
|
||||
});
|
||||
const latestListIndex = board.data.lists[0]?.index
|
||||
|
||||
return tx.insert(lists).values({
|
||||
const { data } = await ctx.supabase
|
||||
.from('list')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
name: input.name,
|
||||
createdBy: userId,
|
||||
boardId: board.id,
|
||||
index: latestList ? latestList.index + 1 : 0
|
||||
});
|
||||
})
|
||||
boardId: board.data.id,
|
||||
index: latestListIndex ? latestListIndex + 1 : 0
|
||||
})
|
||||
.select(`
|
||||
publicId,
|
||||
name
|
||||
`);
|
||||
|
||||
return data;
|
||||
}),
|
||||
reorder: publicProcedure
|
||||
.input(
|
||||
@@ -57,52 +56,70 @@ export const listRouter = createTRPCRouter({
|
||||
currentIndex: z.number(),
|
||||
newIndex: z.number(),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.transaction(async (tx) => {
|
||||
const [list] = await tx.select({ id: lists.id, boardId: lists.boardId }).from(lists).where(eq(lists.publicId, input.listId))
|
||||
const list = await ctx.supabase
|
||||
.from('list')
|
||||
.select(`id, boardId`)
|
||||
.eq('publicId', input.listId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!list) return;
|
||||
if (!list?.data) return;
|
||||
|
||||
await tx.execute(sql`
|
||||
UPDATE ${lists}
|
||||
SET index =
|
||||
CASE
|
||||
WHEN ${lists.index} = ${input.currentIndex} AND ${lists.id} = ${list.id} THEN ${input.newIndex}
|
||||
WHEN ${input.currentIndex} < ${input.newIndex} AND ${lists.index} > ${input.currentIndex} AND ${lists.index} <= ${input.newIndex} THEN ${lists.index} - 1
|
||||
WHEN ${input.currentIndex} > ${input.newIndex} AND ${lists.index} >= ${input.newIndex} AND ${lists.index} < ${input.currentIndex} THEN ${lists.index} + 1
|
||||
ELSE ${lists.index}
|
||||
END
|
||||
WHERE ${lists.boardId} = ${list.boardId};
|
||||
`);
|
||||
})
|
||||
const { data } = await ctx.supabase
|
||||
.rpc('reorder_list', {
|
||||
board_id: list.data.boardId,
|
||||
list_id: list.data.id,
|
||||
current_index: input.currentIndex,
|
||||
new_index: input.newIndex,
|
||||
})
|
||||
|
||||
return data;
|
||||
}),
|
||||
delete: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
listPublicId: z.string().min(12),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.transaction(async (tx) => {
|
||||
const list = await tx.query.lists.findFirst({
|
||||
where: eq(lists.publicId, input.listPublicId),
|
||||
const list = await ctx.supabase
|
||||
.from('list')
|
||||
.select(`id, boardId, index`)
|
||||
.eq('publicId', input.listPublicId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!list.data) return;
|
||||
|
||||
const deletedAt = new Date().toISOString();
|
||||
|
||||
await ctx.supabase
|
||||
.from('list')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('id', list.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
await ctx.supabase
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('listId', list.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
.rpc('shift_list_index', {
|
||||
board_id: list.data.boardId,
|
||||
list_index: list.data.index
|
||||
})
|
||||
|
||||
if (!list) return;
|
||||
|
||||
await tx.update(lists).set({ deletedAt: new Date(), deletedBy: userId}).where(eq(lists.id, list.id));
|
||||
|
||||
await tx.update(cards).set({ deletedAt: new Date(), deletedBy: userId}).where(eq(cards.listId, list.id));
|
||||
|
||||
await tx.execute(sql`UPDATE ${lists} SET ${lists.index} = ${lists.index} - 1 WHERE ${lists.boardId} = ${list.boardId} AND ${lists.index} > ${list.index} AND ${lists.deletedAt} IS NULL;`);
|
||||
})
|
||||
return data;
|
||||
}),
|
||||
update: publicProcedure
|
||||
.input(
|
||||
@@ -110,11 +127,18 @@ export const listRouter = createTRPCRouter({
|
||||
listPublicId: z.string().min(12),
|
||||
name: z.string().min(1),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.update(lists).set({ name: input.name }).where(and(eq(lists.publicId, input.listPublicId), isNull(lists.deletedAt)));
|
||||
const { data } = await ctx.supabase
|
||||
.from('list')
|
||||
.update({ name: input.name })
|
||||
.eq('publicId', input.listPublicId)
|
||||
.is('deletedAt', null)
|
||||
.select(`publicId, name`);
|
||||
|
||||
return data;
|
||||
}),
|
||||
});
|
||||
@@ -12,56 +12,52 @@ import {
|
||||
|
||||
export const workspaceRouter = createTRPCRouter({
|
||||
all: publicProcedure
|
||||
.query(({ ctx }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.query(async ({ ctx }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.query.workspaceMembers.findMany({
|
||||
where: and(eq(workspaceMembers.userId, userId), isNull(workspaceMembers.deletedAt)),
|
||||
columns: {
|
||||
role: true,
|
||||
},
|
||||
with: {
|
||||
workspace: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
name: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const { data } = await ctx.supabase
|
||||
.from('workspace_members')
|
||||
.select(`
|
||||
role,
|
||||
workspace (
|
||||
publicId,
|
||||
name
|
||||
)
|
||||
`)
|
||||
.eq('userId', userId)
|
||||
.is('deletedAt', null);
|
||||
|
||||
return data;
|
||||
}),
|
||||
byId: publicProcedure
|
||||
.input(z.object({ publicId: z.string().min(12) }))
|
||||
.query(({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
.query(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.query.workspaces.findFirst({
|
||||
where: and(eq(workspaces.publicId, input.publicId), isNull(workspaces.deletedAt)),
|
||||
columns: {
|
||||
publicId: true,
|
||||
},
|
||||
with: {
|
||||
members: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
role: true,
|
||||
},
|
||||
with: {
|
||||
user: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const { data, error } = await ctx.supabase
|
||||
.from('workspace')
|
||||
.select(`
|
||||
publicId,
|
||||
members: workspace_members (
|
||||
publicId,
|
||||
role,
|
||||
user (
|
||||
id,
|
||||
name,
|
||||
email
|
||||
)
|
||||
)
|
||||
`)
|
||||
.eq('publicId', input.publicId)
|
||||
.is('deletedAt', null)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
return data;
|
||||
}),
|
||||
create: publicProcedure
|
||||
.input(
|
||||
@@ -70,35 +66,47 @@ export const workspaceRouter = createTRPCRouter({
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.session?.user.id;
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
|
||||
console.log('>>> here <<<')
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const workspace = await ctx.db.insert(workspaces).values({
|
||||
publicId: generateUID(),
|
||||
name: input.name,
|
||||
slug: input.name.toLowerCase(),
|
||||
createdBy: userId,
|
||||
}).returning({ id: workspaces.id });
|
||||
const workspace = await ctx.supabase
|
||||
.from('workspace')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
name: input.name,
|
||||
slug: input.name.toLowerCase(),
|
||||
createdBy: userId,
|
||||
})
|
||||
.select(`
|
||||
id,
|
||||
publicId,
|
||||
name
|
||||
`)
|
||||
.limit(1)
|
||||
.single()
|
||||
|
||||
const workspaceId = workspace[0]?.id;
|
||||
const newWorkspaceId = workspace.data?.id
|
||||
|
||||
if (!workspaceId) return;
|
||||
if (!newWorkspaceId) return;
|
||||
|
||||
await ctx.db.insert(workspaceMembers).values({
|
||||
publicId: generateUID(),
|
||||
userId,
|
||||
workspaceId: workspaceId,
|
||||
createdBy: userId,
|
||||
role: 'admin'
|
||||
})
|
||||
await ctx.supabase
|
||||
.from('workspace_members')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
userId,
|
||||
workspaceId: newWorkspaceId,
|
||||
createdBy: userId,
|
||||
role: 'admin'
|
||||
})
|
||||
|
||||
return ctx.db.query.workspaces.findFirst({
|
||||
where: eq(workspaces.id, workspaceId),
|
||||
columns: {
|
||||
publicId: true,
|
||||
name: true,
|
||||
},
|
||||
});
|
||||
const newWorkspace = { ...workspace.data };
|
||||
|
||||
delete newWorkspace.id;
|
||||
|
||||
return newWorkspace;
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user