feat: finish swapping drizzle for supabase
This commit is contained in:
@@ -9,7 +9,7 @@ export const authRouter = createTRPCRouter({
|
||||
login: publicProcedure
|
||||
.input(z.object({ email: z.string() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const { data } = await ctx.supabase.auth.signInWithOtp({
|
||||
const { data } = await ctx.db.auth.signInWithOtp({
|
||||
email: input.email,
|
||||
options: {
|
||||
emailRedirectTo: '/boards',
|
||||
|
||||
@@ -10,7 +10,7 @@ export const boardRouter = createTRPCRouter({
|
||||
all: publicProcedure
|
||||
.input(z.object({ workspacePublicId: z.string().min(12) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const workspace = await ctx.supabase
|
||||
const workspace = await ctx.db
|
||||
.from('workspace')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.workspacePublicId)
|
||||
@@ -19,7 +19,7 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
if (!workspace.data) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('board')
|
||||
.select(`
|
||||
publicId,
|
||||
@@ -33,7 +33,7 @@ export const boardRouter = createTRPCRouter({
|
||||
byId: publicProcedure
|
||||
.input(z.object({ id: z.string().min(12) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('board')
|
||||
.select(`
|
||||
publicId,
|
||||
@@ -100,7 +100,7 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const workspace = await ctx.supabase
|
||||
const workspace = await ctx.db
|
||||
.from('workspace')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.workspacePublicId)
|
||||
@@ -109,7 +109,7 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
if (!workspace.data) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('board')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -135,7 +135,7 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('board')
|
||||
.update({ name: input.name })
|
||||
.eq('publicId', input.boardId);
|
||||
@@ -152,7 +152,7 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const board = await ctx.supabase
|
||||
const board = await ctx.db
|
||||
.from('board')
|
||||
.select(`
|
||||
id,
|
||||
@@ -168,20 +168,20 @@ export const boardRouter = createTRPCRouter({
|
||||
|
||||
const deletedAt = new Date().toISOString();
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('board')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('id', board.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
if (listIds.length) {
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('list')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('boardId', board.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.in('listId', listIds)
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { z } from "zod";
|
||||
import { and, desc, eq, isNull, inArray, sql } from "drizzle-orm";
|
||||
|
||||
import { cards, cardsToLabels, cardToWorkspaceMembers, labels, lists, workspaceMembers } from "~/server/db/schema";
|
||||
import { generateUID } from "~/utils/generateUID";
|
||||
|
||||
import {
|
||||
@@ -24,7 +21,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const list = await ctx.supabase
|
||||
const list = await ctx.db
|
||||
.from('list')
|
||||
.select(`id, cards:card (index)`)
|
||||
.eq('publicId', input.listPublicId)
|
||||
@@ -36,7 +33,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
const latestCard = list.data.cards.length && list.data.cards[0]
|
||||
|
||||
const newCard = await ctx.supabase
|
||||
const newCard = await ctx.db
|
||||
.from('card')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -52,7 +49,7 @@ export const cardRouter = createTRPCRouter({
|
||||
const newCardId = newCard.data?.id;
|
||||
|
||||
if (newCardId && input.labelsPublicIds.length) {
|
||||
const labels = await ctx.supabase
|
||||
const labels = await ctx.db
|
||||
.from('label')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.labelsPublicIds);
|
||||
@@ -61,13 +58,13 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
const labelsInsert = labels.data.map((label) => ({ cardId: newCardId, labelId: label.id }));
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_labels')
|
||||
.insert(labelsInsert);
|
||||
}
|
||||
|
||||
if (newCardId && input.memberPublicIds.length) {
|
||||
const members = await ctx.supabase
|
||||
const members = await ctx.db
|
||||
.from('workspace_members')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.memberPublicIds);
|
||||
@@ -76,7 +73,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
const membersInsert = members.data.map((member) => ({ cardId: newCardId, workspaceMemberId: member.id }));
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_workspace_members')
|
||||
.insert(membersInsert);
|
||||
}
|
||||
@@ -95,14 +92,14 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const card = await ctx.supabase
|
||||
const card = await ctx.db
|
||||
.from('card')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.cardPublicId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
const label = await ctx.supabase
|
||||
const label = await ctx.db
|
||||
.from('label')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.labelPublicId)
|
||||
@@ -111,7 +108,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!card.data || !label.data) return;
|
||||
|
||||
const existingLabel = await ctx.supabase
|
||||
const existingLabel = await ctx.db
|
||||
.from('_card_labels')
|
||||
.select()
|
||||
.eq('cardId', card.data.id)
|
||||
@@ -120,7 +117,7 @@ export const cardRouter = createTRPCRouter({
|
||||
.single();
|
||||
|
||||
if (existingLabel.data) {
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_labels')
|
||||
.delete()
|
||||
.eq('cardId', card.data.id)
|
||||
@@ -129,7 +126,7 @@ export const cardRouter = createTRPCRouter({
|
||||
return { newLabel: false };
|
||||
}
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_labels')
|
||||
.insert({
|
||||
cardId: card.data.id,
|
||||
@@ -150,14 +147,14 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const card = await ctx.supabase
|
||||
const card = await ctx.db
|
||||
.from('card')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.cardPublicId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
const member = await ctx.supabase
|
||||
const member = await ctx.db
|
||||
.from('workspace_members')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.workspaceMemberPublicId)
|
||||
@@ -166,7 +163,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!card.data || !member.data) return;
|
||||
|
||||
const existingMember = await ctx.supabase
|
||||
const existingMember = await ctx.db
|
||||
.from('_card_workspace_members')
|
||||
.select()
|
||||
.eq('cardId', card.data.id)
|
||||
@@ -175,7 +172,7 @@ export const cardRouter = createTRPCRouter({
|
||||
.single();
|
||||
|
||||
if (existingMember.data) {
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_workspace_members')
|
||||
.delete()
|
||||
.eq('cardId', card.data.id)
|
||||
@@ -184,7 +181,7 @@ export const cardRouter = createTRPCRouter({
|
||||
return { newMember: false };
|
||||
}
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_workspace_members')
|
||||
.insert({
|
||||
cardId: card.data.id,
|
||||
@@ -196,7 +193,7 @@ export const cardRouter = createTRPCRouter({
|
||||
byId: publicProcedure
|
||||
.input(z.object({ id: z.string().min(12) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('card')
|
||||
.select(`
|
||||
publicId,
|
||||
@@ -262,7 +259,7 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('card')
|
||||
.update({ title: input.title, description: input.description })
|
||||
.eq('publicId', input.cardId)
|
||||
@@ -275,22 +272,37 @@ export const cardRouter = createTRPCRouter({
|
||||
z.object({
|
||||
cardPublicId: z.string().min(12),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
.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: eq(cards.publicId, input.cardPublicId),
|
||||
})
|
||||
const card = await ctx.db
|
||||
.from('card')
|
||||
.select(`id, index, listId`)
|
||||
.eq('publicId', input.cardPublicId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!card) return;
|
||||
if (!card.data) return;
|
||||
|
||||
await tx.update(cards).set({ deletedAt: new Date(), deletedBy: userId}).where(eq(cards.publicId, input.cardPublicId));
|
||||
const deletedAt = new Date().toISOString();
|
||||
|
||||
await tx.execute(sql`UPDATE ${cards} SET ${cards.index} = ${cards.index} - 1 WHERE ${cards.listId} = ${card.listId} AND ${cards.index} > ${card.index} AND ${cards.deletedAt} IS NULL;`);
|
||||
})
|
||||
await ctx.db
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId})
|
||||
.eq('publicId', input.cardPublicId);
|
||||
|
||||
await ctx.db
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId})
|
||||
.eq('publicId', input.cardPublicId);
|
||||
|
||||
await ctx.db
|
||||
.rpc('shift_card_index', {
|
||||
list_id: card.data.listId,
|
||||
card_index: card.data.index,
|
||||
});
|
||||
}),
|
||||
reorder: publicProcedure
|
||||
.input(
|
||||
@@ -299,69 +311,54 @@ export const cardRouter = createTRPCRouter({
|
||||
newListId: z.string().min(12),
|
||||
newIndex: z.number().optional(),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
.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({
|
||||
with: {
|
||||
list: true,
|
||||
},
|
||||
where: and(eq(cards.publicId, input.cardId), isNull(cards.deletedAt)),
|
||||
const card = await ctx.db
|
||||
.from('card')
|
||||
.select(`id, index, list (id)`)
|
||||
.eq('publicId', input.cardId)
|
||||
.is('deletedAt', null)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!card.data) return;
|
||||
|
||||
const currentList = card.data.list;
|
||||
const currentIndex = card.data.index;
|
||||
|
||||
let newIndex = input.newIndex;
|
||||
|
||||
const newList = await ctx.db
|
||||
.from('list')
|
||||
.select(`id, cards:card (index)`)
|
||||
.eq('publicId', input.newListId)
|
||||
.is('deletedAt', null)
|
||||
.order('index', { foreignTable: 'card', ascending: false })
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
if (!newList.data) return;
|
||||
|
||||
if (newIndex === undefined) {
|
||||
const lastCardIndex = newList.data.cards.length ? newList.data.cards[0]?.index : undefined;
|
||||
|
||||
newIndex = lastCardIndex !== undefined ? lastCardIndex + 1 : 0;
|
||||
}
|
||||
|
||||
if (!currentList?.id || !newList?.data.id) return;
|
||||
|
||||
const { error } = await ctx.db
|
||||
.rpc('reorder_cards', {
|
||||
current_list_id: currentList.id,
|
||||
new_list_id: newList.data.id,
|
||||
current_index: currentIndex,
|
||||
new_index: newIndex,
|
||||
card_id: card.data.id,
|
||||
});
|
||||
|
||||
if (!card) return;
|
||||
|
||||
const currentList = card.list;
|
||||
const currentIndex = card.index;
|
||||
|
||||
let newIndex = input.newIndex;
|
||||
|
||||
const newList = await tx.query.lists.findFirst({
|
||||
with: {
|
||||
cards: {
|
||||
orderBy: [desc(cards.index)],
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
where: and(eq(lists.publicId, input.newListId), isNull(cards.deletedAt)),
|
||||
});
|
||||
|
||||
if (!newList) return;
|
||||
|
||||
if (newIndex === undefined) {
|
||||
const lastCardIndex = newList.cards.length ? newList.cards[0]?.index : undefined;
|
||||
|
||||
newIndex = lastCardIndex !== undefined ? lastCardIndex + 1 : 0;
|
||||
}
|
||||
|
||||
if (!currentList?.id || !newList?.id) return;
|
||||
|
||||
|
||||
if (currentList.id === newList.id) {
|
||||
await tx.execute(sql`
|
||||
UPDATE ${cards}
|
||||
SET index =
|
||||
CASE
|
||||
WHEN ${cards.index} = ${currentIndex} THEN ${newIndex}
|
||||
WHEN ${currentIndex} < ${newIndex} AND ${cards.index} > ${currentIndex} AND ${cards.index} <= ${newIndex} THEN ${cards.index} - 1
|
||||
WHEN ${currentIndex} > ${newIndex} AND ${cards.index} >= ${newIndex} AND ${cards.index} < ${currentIndex} THEN ${cards.index} + 1
|
||||
ELSE ${cards.index}
|
||||
END
|
||||
WHERE ${cards.listId} = ${currentList.id} AND ${cards.deletedAt} IS NULL;
|
||||
`);
|
||||
} else {
|
||||
await tx.execute(sql`UPDATE ${cards} SET index = index + 1 WHERE ${cards.listId} = ${newList.id} AND ${cards.index} >= ${newIndex} AND ${cards.deletedAt} IS NULL;`)
|
||||
|
||||
await tx.execute(sql`UPDATE ${cards} SET index = index - 1 WHERE ${cards.listId} = ${currentList.id} AND ${cards.index} >= ${currentIndex} AND ${cards.deletedAt} IS NULL;`)
|
||||
|
||||
await tx
|
||||
.update(cards)
|
||||
.set({ listId: newList.id, index: newIndex })
|
||||
.where(and(eq(cards.publicId, input.cardId), isNull(cards.deletedAt)));
|
||||
}
|
||||
})
|
||||
return { success: !!error }
|
||||
})
|
||||
});
|
||||
@@ -87,7 +87,7 @@ export const importRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const newImport = await ctx.supabase
|
||||
const newImport = await ctx.db
|
||||
.from('import')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -103,7 +103,7 @@ export const importRouter = createTRPCRouter({
|
||||
|
||||
let boardsCreated = 0;
|
||||
|
||||
const workspace = await ctx.supabase
|
||||
const workspace = await ctx.db
|
||||
.from('workspace')
|
||||
.select(`id`)
|
||||
.eq('publicId', input.workspacePublicId)
|
||||
@@ -130,7 +130,7 @@ export const importRouter = createTRPCRouter({
|
||||
}))
|
||||
}
|
||||
|
||||
const newBoard = await ctx.supabase
|
||||
const newBoard = await ctx.db
|
||||
.from('board')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -150,7 +150,7 @@ export const importRouter = createTRPCRouter({
|
||||
let listIndex = 0;
|
||||
|
||||
for (const list of formattedData.lists) {
|
||||
const newList = await ctx.supabase
|
||||
const newList = await ctx.db
|
||||
.from('list')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -177,7 +177,7 @@ export const importRouter = createTRPCRouter({
|
||||
importId: newImportId
|
||||
}))
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('card')
|
||||
.insert(cardsInsert);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ export const importRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
if (boardsCreated > 0 && newImportId) {
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('import')
|
||||
.update({ status: 'success' })
|
||||
.eq('importId', newImportId);
|
||||
|
||||
@@ -20,7 +20,7 @@ export const labelRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const card = await ctx.supabase
|
||||
const card = await ctx.db
|
||||
.from('card')
|
||||
.select(`id, list (boardId)`)
|
||||
.eq('publicId', input.cardPublicId)
|
||||
@@ -30,7 +30,7 @@ export const labelRouter = createTRPCRouter({
|
||||
|
||||
if (!card.data?.list) return;
|
||||
|
||||
const newLabel = await ctx.supabase
|
||||
const newLabel = await ctx.db
|
||||
.from('label')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -45,7 +45,7 @@ export const labelRouter = createTRPCRouter({
|
||||
|
||||
if (!newLabel.data) return;
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('_card_labels')
|
||||
.insert({
|
||||
cardId: card.data.id,
|
||||
|
||||
@@ -19,7 +19,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const board = await ctx.supabase
|
||||
const board = await ctx.db
|
||||
.from('board')
|
||||
.select(`id, lists:list (index)`)
|
||||
.eq('publicId', input.boardPublicId)
|
||||
@@ -32,7 +32,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
const latestListIndex = board.data.lists[0]?.index
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('list')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -61,7 +61,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const list = await ctx.supabase
|
||||
const list = await ctx.db
|
||||
.from('list')
|
||||
.select(`id, boardId`)
|
||||
.eq('publicId', input.listId)
|
||||
@@ -70,7 +70,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
if (!list?.data) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.rpc('reorder_list', {
|
||||
board_id: list.data.boardId,
|
||||
list_id: list.data.id,
|
||||
@@ -90,7 +90,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const list = await ctx.supabase
|
||||
const list = await ctx.db
|
||||
.from('list')
|
||||
.select(`id, boardId, index`)
|
||||
.eq('publicId', input.listPublicId)
|
||||
@@ -101,19 +101,19 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
const deletedAt = new Date().toISOString();
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('list')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('id', list.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('card')
|
||||
.update({ deletedAt, deletedBy: userId })
|
||||
.eq('listId', list.data.id)
|
||||
.is('deletedAt', null);
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.rpc('shift_list_index', {
|
||||
board_id: list.data.boardId,
|
||||
list_index: list.data.index
|
||||
@@ -132,7 +132,7 @@ export const listRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('list')
|
||||
.update({ name: input.name })
|
||||
.eq('publicId', input.listPublicId)
|
||||
|
||||
@@ -13,7 +13,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('workspace_members')
|
||||
.select(`
|
||||
role,
|
||||
@@ -34,7 +34,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const { data } = await ctx.supabase
|
||||
const { data } = await ctx.db
|
||||
.from('workspace')
|
||||
.select(`
|
||||
publicId,
|
||||
@@ -66,7 +66,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
const workspace = await ctx.supabase
|
||||
const workspace = await ctx.db
|
||||
.from('workspace')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
@@ -86,7 +86,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
|
||||
if (!newWorkspaceId) return;
|
||||
|
||||
await ctx.supabase
|
||||
await ctx.db
|
||||
.from('workspace_members')
|
||||
.insert({
|
||||
publicId: generateUID(),
|
||||
|
||||
@@ -11,10 +11,9 @@ import { type CreateNextContextOptions } from "@trpc/server/adapters/next";
|
||||
import superjson from "superjson";
|
||||
import { ZodError } from "zod";
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import createClient from "~/utils/supabase/api";
|
||||
import { type Database } from "~/types/database.types";
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
import { type SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
/**
|
||||
* 1. CONTEXT
|
||||
@@ -30,8 +29,7 @@ type User = {
|
||||
|
||||
interface CreateContextOptions {
|
||||
user: User | null;
|
||||
supabase: SupabaseClient<Database>
|
||||
db: any;
|
||||
db: SupabaseClient<Database>
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,8 +46,7 @@ interface CreateContextOptions {
|
||||
export const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
||||
return {
|
||||
user: opts.user,
|
||||
supabase: opts.supabase,
|
||||
db,
|
||||
db: opts.db,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -60,11 +57,11 @@ export const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
||||
* @see https://trpc.io/docs/context
|
||||
*/
|
||||
export const createTRPCContext = async (_opts: CreateNextContextOptions) => {
|
||||
const supabase = createClient(_opts.req, _opts.res);
|
||||
const db = createClient(_opts.req, _opts.res);
|
||||
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
const { data: { user } } = await db.auth.getUser()
|
||||
|
||||
return createInnerTRPCContext({ user, supabase });
|
||||
return createInnerTRPCContext({ user, db });
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import { render } from '@react-email/render';
|
||||
import { MagicLinkEmail } from "~/email/emails/magic-link";
|
||||
|
||||
import { DrizzleAdapter } from "@auth/drizzle-adapter";
|
||||
import NextAuth, { type DefaultSession } from "next-auth";
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { pgTable} from "drizzle-orm/pg-core";
|
||||
|
||||
/**
|
||||
* Module augmentation for `next-auth` types. Allows us to add custom properties to the `session`
|
||||
* object and keep type safety.
|
||||
*
|
||||
* @see https://next-auth.js.org/getting-started/typescript#module-augmentation
|
||||
*/
|
||||
declare module "next-auth" {
|
||||
interface Session extends DefaultSession {
|
||||
user: {
|
||||
id: string;
|
||||
// ...other properties
|
||||
// role: UserRole;
|
||||
} & DefaultSession["user"];
|
||||
}
|
||||
|
||||
// interface User {
|
||||
// // ...other properties
|
||||
// // role: UserRole;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const {
|
||||
handlers: { GET, POST },
|
||||
auth,
|
||||
} = NextAuth({
|
||||
callbacks: {
|
||||
session: ({ session, user }) => ({
|
||||
...session,
|
||||
user: {
|
||||
id: user.id,
|
||||
name: session.user.name,
|
||||
email: session.user.email,
|
||||
image: session.user.image,
|
||||
},
|
||||
}),
|
||||
},
|
||||
adapter: DrizzleAdapter(db, pgTable),
|
||||
pages: {
|
||||
signIn: "/auth/login",
|
||||
// signOut: "/auth/signout",
|
||||
// error: "/auth/error",
|
||||
verifyRequest: "/auth/verify",
|
||||
},
|
||||
providers: [
|
||||
{
|
||||
id: 'email',
|
||||
type: 'email',
|
||||
from: process.env.EMAIL_FROM ?? '',
|
||||
server: {},
|
||||
maxAge: 24 * 60 * 60,
|
||||
name: 'Email',
|
||||
options: {},
|
||||
async sendVerificationRequest({ identifier: email, url }) {
|
||||
const magicLinkEmail = MagicLinkEmail({ loginUrl: url });
|
||||
const response = await fetch(process.env.EMAIL_URL ?? '', {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${process.env.EMAIL_TOKEN}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: process.env.EMAIL_FROM,
|
||||
to: [email],
|
||||
subject: 'Login via email',
|
||||
html: render(magicLinkEmail),
|
||||
}),
|
||||
})
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Error sending magic login')
|
||||
}
|
||||
},
|
||||
}
|
||||
],
|
||||
});
|
||||
@@ -12,8 +12,6 @@ import {
|
||||
bigint,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
import { type AdapterAccount } from "@auth/core/adapters";
|
||||
|
||||
export const importSourceEnum = pgEnum('source', ['trello']);
|
||||
export const importStatusEnum = pgEnum('status', ['started', 'success', 'failed']);
|
||||
export const memberRoleEnum = pgEnum('role', ['admin', 'member', 'guest']);
|
||||
@@ -236,7 +234,6 @@ export const users = pgTable("user", {
|
||||
});
|
||||
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
accounts: many(accounts),
|
||||
boards: many(boards),
|
||||
cards: many(cards),
|
||||
imports: many(imports),
|
||||
@@ -244,61 +241,6 @@ export const usersRelations = relations(users, ({ many }) => ({
|
||||
workspaces: many(workspaces),
|
||||
}));
|
||||
|
||||
export const accounts = pgTable(
|
||||
"account",
|
||||
{
|
||||
userId: uuid("userId")
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
type: varchar("type", { length: 255 })
|
||||
.$type<AdapterAccount["type"]>()
|
||||
.notNull(),
|
||||
provider: varchar("provider", { length: 255 }).notNull(),
|
||||
providerAccountId: varchar("providerAccountId", { length: 255 }).notNull(),
|
||||
refresh_token: text("refresh_token"),
|
||||
access_token: text("access_token"),
|
||||
expires_at: integer("expires_at"),
|
||||
token_type: varchar("token_type", { length: 255 }),
|
||||
scope: varchar("scope", { length: 255 }),
|
||||
id_token: text("id_token"),
|
||||
session_state: varchar("session_state", { length: 255 }),
|
||||
},
|
||||
(account) => ({
|
||||
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
||||
})
|
||||
);
|
||||
|
||||
export const accountsRelations = relations(accounts, ({ one }) => ({
|
||||
user: one(users, { fields: [accounts.userId], references: [users.id] }),
|
||||
}));
|
||||
|
||||
export const sessions = pgTable(
|
||||
"session",
|
||||
{
|
||||
sessionToken: varchar("sessionToken", { length: 255 })
|
||||
.notNull()
|
||||
.primaryKey(),
|
||||
userId: uuid("userId").notNull().references(() => users.id),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
},
|
||||
);
|
||||
|
||||
export const sessionsRelations = relations(sessions, ({ one }) => ({
|
||||
user: one(users, { fields: [sessions.userId], references: [users.id] }),
|
||||
}));
|
||||
|
||||
export const verificationTokens = pgTable(
|
||||
"verificationToken",
|
||||
{
|
||||
identifier: varchar("identifier", { length: 255 }).notNull(),
|
||||
token: varchar("token", { length: 255 }).notNull(),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
},
|
||||
(vt) => ({
|
||||
compoundKey: primaryKey(vt.identifier, vt.token),
|
||||
})
|
||||
);
|
||||
|
||||
export const workspaces = pgTable(
|
||||
"workspace",
|
||||
{
|
||||
|
||||
@@ -600,7 +600,17 @@ export type Database = {
|
||||
[_ in never]: never
|
||||
}
|
||||
Functions: {
|
||||
reorder_list: {
|
||||
reorder_cards: {
|
||||
Args: {
|
||||
card_id: number
|
||||
current_list_id: number
|
||||
new_list_id: number
|
||||
current_index: number
|
||||
new_index: number
|
||||
}
|
||||
Returns: undefined
|
||||
}
|
||||
reorder_lists: {
|
||||
Args: {
|
||||
board_id: number
|
||||
list_id: number
|
||||
@@ -609,6 +619,13 @@ export type Database = {
|
||||
}
|
||||
Returns: undefined
|
||||
}
|
||||
shift_card_index: {
|
||||
Args: {
|
||||
list_id: number
|
||||
card_index: number
|
||||
}
|
||||
Returns: undefined
|
||||
}
|
||||
shift_list_index: {
|
||||
Args: {
|
||||
board_id: number
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CREATE OR REPLACE FUNCTION reorder_list(board_id BIGINT, list_id BIGINT, current_index INT, new_index INT)
|
||||
CREATE OR REPLACE FUNCTION reorder_lists(board_id BIGINT, list_id BIGINT, current_index INT, new_index INT)
|
||||
RETURNS VOID
|
||||
LANGUAGE SQL
|
||||
AS $$
|
||||
@@ -13,6 +13,41 @@ AS $$
|
||||
WHERE "boardId" = board_id;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION reorder_cards(card_id BIGINT, current_list_id BIGINT, new_list_id BIGINT, current_index INT, new_index INT)
|
||||
RETURNS VOID
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
DECLARE
|
||||
card_index INT;
|
||||
BEGIN
|
||||
SELECT index INTO card_index FROM card WHERE "listId" = current_list_id AND id = card_id AND "deletedAt" IS NULL;
|
||||
|
||||
IF current_list_id = new_list_id THEN
|
||||
UPDATE card
|
||||
SET index =
|
||||
CASE
|
||||
WHEN index = current_index THEN new_index
|
||||
WHEN current_index < new_index AND index > current_index AND index <= new_index THEN index - 1
|
||||
WHEN current_index > new_index AND index >= new_index AND index < current_index THEN index + 1
|
||||
ELSE index
|
||||
END
|
||||
WHERE "listId" = current_list_id AND "deletedAt" IS NULL;
|
||||
ELSE
|
||||
UPDATE card
|
||||
SET index = index + 1
|
||||
WHERE "listId" = new_list_id AND index >= new_index AND "deletedAt" IS NULL;
|
||||
|
||||
UPDATE card
|
||||
SET index = index - 1
|
||||
WHERE "listId" = current_list_id AND index >= current_index AND "deletedAt" IS NULL;
|
||||
|
||||
UPDATE card
|
||||
SET "listId" = new_list_id, index = new_index
|
||||
WHERE id = card_id AND "deletedAt" IS NULL;
|
||||
END IF;
|
||||
END;
|
||||
$$
|
||||
|
||||
CREATE OR REPLACE FUNCTION shift_list_index(board_id BIGINT, list_index INT)
|
||||
RETURNS VOID
|
||||
LANGUAGE SQL
|
||||
@@ -20,4 +55,14 @@ 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;
|
||||
$$;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user