add group order and fixes

This commit is contained in:
Pas 2025-07-31 10:37:34 -06:00
parent 6ee37ff8f2
commit 14cfd53505
5 changed files with 111 additions and 9 deletions

View file

@ -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");

View file

@ -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")
}

View file

@ -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,
};
}

View file

@ -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) {

View file

@ -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',
});
});