import { ORPCError } from '@orpc/server' import { and, eq } from 'drizzle-orm' import { bookmarkTable, categoryTable } from '@/modules/bookmarks/schema' import { authMiddleware, db } from '@/server/api/middlewares' import { os } from '@/server/api/server' export const category = { list: os.bookmarks.category.list .use(db) .use(authMiddleware) .handler(async ({ context }) => { return await context.db.query.categoryTable.findMany({ where: { userId: context.user.id }, orderBy: { orderId: 'asc' }, with: { bookmarks: { orderBy: { orderId: 'asc' }, }, }, }) }), create: os.bookmarks.category.create .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [created] = await context.db .insert(categoryTable) .values({ ...input, userId: context.user.id }) .returning() if (!created) throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Failed to create category' }) return created }), update: os.bookmarks.category.update .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [updated] = await context.db .update(categoryTable) .set(input.data) .where(and(eq(categoryTable.id, input.id), eq(categoryTable.userId, context.user.id))) .returning() if (!updated) throw new ORPCError('NOT_FOUND') return updated }), remove: os.bookmarks.category.remove .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [deleted] = await context.db .delete(categoryTable) .where(and(eq(categoryTable.id, input.id), eq(categoryTable.userId, context.user.id))) .returning({ id: categoryTable.id }) if (!deleted) throw new ORPCError('NOT_FOUND') }), reorder: os.bookmarks.category.reorder .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { await context.db.transaction(async (tx) => { for (const item of input) { await tx .update(categoryTable) .set({ orderId: item.orderId }) .where(and(eq(categoryTable.id, item.id), eq(categoryTable.userId, context.user.id))) } }) }), } export const bookmark = { create: os.bookmarks.bookmark.create .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [created] = await context.db .insert(bookmarkTable) .values({ ...input, userId: context.user.id }) .returning() if (!created) throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Failed to create bookmark' }) return created }), update: os.bookmarks.bookmark.update .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [updated] = await context.db .update(bookmarkTable) .set(input.data) .where(and(eq(bookmarkTable.id, input.id), eq(bookmarkTable.userId, context.user.id))) .returning() if (!updated) throw new ORPCError('NOT_FOUND') return updated }), remove: os.bookmarks.bookmark.remove .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { const [deleted] = await context.db .delete(bookmarkTable) .where(and(eq(bookmarkTable.id, input.id), eq(bookmarkTable.userId, context.user.id))) .returning({ id: bookmarkTable.id }) if (!deleted) throw new ORPCError('NOT_FOUND') }), reorder: os.bookmarks.bookmark.reorder .use(db) .use(authMiddleware) .handler(async ({ context, input }) => { await context.db.transaction(async (tx) => { for (const item of input) { await tx .update(bookmarkTable) .set({ orderId: item.orderId }) .where(and(eq(bookmarkTable.id, item.id), eq(bookmarkTable.userId, context.user.id))) } }) }), }