From 14cfd535056ad8e6b9a44c25e843f62a28e690e7 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Thu, 31 Jul 2025 10:37:34 -0600 Subject: [PATCH] add group order and fixes --- .../migration.sql | 13 +++++ prisma/schema.prisma | 10 ++++ server/routes/users/[id]/bookmarks.ts | 11 ++++ .../users/[id]/bookmarks/[tmdbid]/index.ts | 32 +++++++---- server/routes/users/[id]/group-order.ts | 54 +++++++++++++++++++ 5 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 prisma/migrations/20250731030214_add_user_group_order/migration.sql create mode 100644 server/routes/users/[id]/group-order.ts diff --git a/prisma/migrations/20250731030214_add_user_group_order/migration.sql b/prisma/migrations/20250731030214_add_user_group_order/migration.sql new file mode 100644 index 0000000..7b61d60 --- /dev/null +++ b/prisma/migrations/20250731030214_add_user_group_order/migration.sql @@ -0,0 +1,13 @@ +-- CreateTable +CREATE TABLE "user_group_order" ( + "id" UUID NOT NULL, + "user_id" VARCHAR(255) NOT NULL, + "group_order" TEXT[] DEFAULT ARRAY[]::TEXT[], + "created_at" TIMESTAMPTZ(0) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMPTZ(0) NOT NULL, + + CONSTRAINT "user_group_order_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "user_group_order_user_id_unique" ON "user_group_order"("user_id"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 03619a6..a19b47d 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -114,3 +114,13 @@ model list_items { @@unique([list_id, tmdb_id], map: "list_items_list_id_tmdb_id_unique") } + +model user_group_order { + id String @id @default(uuid()) @db.Uuid + user_id String @db.VarChar(255) + group_order String[] @default([]) + created_at DateTime @default(now()) @db.Timestamptz(0) + updated_at DateTime @updatedAt @db.Timestamptz(0) + + @@unique([user_id], map: "user_group_order_user_id_unique") +} diff --git a/server/routes/users/[id]/bookmarks.ts b/server/routes/users/[id]/bookmarks.ts index 3d8ef08..d48537e 100644 --- a/server/routes/users/[id]/bookmarks.ts +++ b/server/routes/users/[id]/bookmarks.ts @@ -11,6 +11,7 @@ const bookmarkMetaSchema = z.object({ const bookmarkDataSchema = z.object({ tmdbId: z.string(), meta: bookmarkMetaSchema, + group: z.union([z.string(), z.array(z.string())]).optional(), }); export default defineEventHandler(async event => { @@ -34,6 +35,7 @@ export default defineEventHandler(async event => { return bookmarks.map(bookmark => ({ tmdbId: bookmark.tmdb_id, meta: bookmark.meta, + group: bookmark.group, updatedAt: bookmark.updated_at, })); } @@ -46,6 +48,11 @@ export default defineEventHandler(async event => { const results = []; for (const item of validatedBody) { + // Normalize group to always be an array + const normalizedGroup = item.group + ? (Array.isArray(item.group) ? item.group : [item.group]) + : []; + const bookmark = await prisma.bookmarks.upsert({ where: { tmdb_id_user_id: { @@ -55,12 +62,14 @@ export default defineEventHandler(async event => { }, update: { meta: item.meta, + group: normalizedGroup, updated_at: now, }, create: { tmdb_id: item.tmdbId, user_id: userId, meta: item.meta, + group: normalizedGroup, updated_at: now, }, }); @@ -68,6 +77,7 @@ export default defineEventHandler(async event => { results.push({ tmdbId: bookmark.tmdb_id, meta: bookmark.meta, + group: bookmark.group, updatedAt: bookmark.updated_at, }); } @@ -110,6 +120,7 @@ export default defineEventHandler(async event => { return { tmdbId: bookmark.tmdb_id, meta: bookmark.meta, + group: bookmark.group, updatedAt: bookmark.updated_at, }; } diff --git a/server/routes/users/[id]/bookmarks/[tmdbid]/index.ts b/server/routes/users/[id]/bookmarks/[tmdbid]/index.ts index cfa9ec9..be4ec4b 100644 --- a/server/routes/users/[id]/bookmarks/[tmdbid]/index.ts +++ b/server/routes/users/[id]/bookmarks/[tmdbid]/index.ts @@ -9,13 +9,13 @@ const bookmarkMetaSchema = z.object({ year: z.number(), poster: z.string().optional(), type: z.enum(['movie', 'show']), - group: z.union([z.string(), z.array(z.string())]).optional(), }); // Support both formats: direct fields or nested under meta const bookmarkRequestSchema = z.object({ meta: bookmarkMetaSchema.optional(), tmdbId: z.string().optional(), + group: z.union([z.string(), z.array(z.string())]).optional(), }); export default defineEventHandler(async event => { @@ -45,18 +45,31 @@ export default defineEventHandler(async event => { // Validate the meta data separately const validatedMeta = bookmarkMetaSchema.parse(metaData); - // Normalize group to always be an array if present - if (validatedMeta.group) { - validatedMeta.group = Array.isArray(validatedMeta.group) - ? validatedMeta.group - : [validatedMeta.group]; - } + // Extract group from the validated request + const groupFromBody = validatedRequest.group; - const bookmark = await prisma.bookmarks.create({ - data: { + // Normalize group to always be an array if present + const normalizedGroup = groupFromBody + ? (Array.isArray(groupFromBody) ? groupFromBody : [groupFromBody]) + : []; + + const bookmark = await prisma.bookmarks.upsert({ + where: { + tmdb_id_user_id: { + tmdb_id: tmdbId, + user_id: session.user, + }, + }, + update: { + meta: validatedMeta, + group: normalizedGroup, + updated_at: new Date(), + }, + create: { user_id: session.user, tmdb_id: tmdbId, meta: validatedMeta, + group: normalizedGroup, updated_at: new Date(), }, }); @@ -66,6 +79,7 @@ export default defineEventHandler(async event => { return { tmdbId: bookmark.tmdb_id, meta: bookmark.meta, + group: bookmark.group, updatedAt: bookmark.updated_at, }; } catch (error) { diff --git a/server/routes/users/[id]/group-order.ts b/server/routes/users/[id]/group-order.ts new file mode 100644 index 0000000..3a1fe61 --- /dev/null +++ b/server/routes/users/[id]/group-order.ts @@ -0,0 +1,54 @@ +import { useAuth } from '~/utils/auth'; +import { z } from 'zod'; + +const groupOrderSchema = z.array(z.string()); + +export default defineEventHandler(async event => { + const userId = event.context.params?.id; + const method = event.method; + + const session = await useAuth().getCurrentSession(); + + if (session.user !== userId) { + throw createError({ + statusCode: 403, + message: 'Cannot access other user information', + }); + } + + if (method === 'GET') { + const groupOrder = await prisma.user_group_order.findUnique({ + where: { user_id: userId }, + }); + + return { + groupOrder: groupOrder?.group_order || [], + }; + } + + if (method === 'PUT') { + const body = await readBody(event); + const validatedGroupOrder = groupOrderSchema.parse(body); + + const groupOrder = await prisma.user_group_order.upsert({ + where: { user_id: userId }, + update: { + group_order: validatedGroupOrder, + updated_at: new Date(), + }, + create: { + user_id: userId, + group_order: validatedGroupOrder, + }, + }); + + return { + groupOrder: groupOrder.group_order, + }; + } + + throw createError({ + statusCode: 405, + message: 'Method not allowed', + }); +}); \ No newline at end of file