mirror of
https://github.com/p-stream/backend.git
synced 2026-05-07 08:19:27 +00:00
Small updates
This commit is contained in:
parent
a5baed2ee4
commit
ed08f2daab
8 changed files with 102 additions and 84 deletions
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[user_id,name]` on the table `lists` will be added. If there are existing duplicate values, this will fail.
|
||||
- A unique constraint covering the columns `[user,device]` on the table `sessions` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- CreateIndex
|
||||
CREATE INDEX "bookmarks_user_id_idx" ON "bookmarks" USING HASH ("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "lists_user_id_name_unique" ON "lists"("user_id", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "progress_items_user_id_idx" ON "progress_items" USING HASH ("user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "sessions_user_idx" ON "sessions" USING HASH ("user");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "sessions_user_device_unique" ON "sessions"("user", "device");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "watch_history_user_id_watched_at_idx" ON "watch_history"("user_id", "watched_at" DESC);
|
||||
|
|
@ -51,6 +51,7 @@ model lists {
|
|||
public Boolean @default(false)
|
||||
list_items list_items[]
|
||||
|
||||
@@unique([user_id, name], map: "lists_user_id_name_unique")
|
||||
@@index([user_id], map: "lists_user_id_index")
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +87,7 @@ model sessions {
|
|||
device String
|
||||
user_agent String
|
||||
|
||||
@@unique([user, device], map: "sessions_user_device_unique")
|
||||
@@index([user], type: Hash)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { prisma } from '#imports';
|
|||
export default defineEventHandler(async event => {
|
||||
const id = event.context.params?.id;
|
||||
const listInfo = await prisma.lists.findUnique({
|
||||
relationLoadStrategy: 'join',
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -39,18 +39,13 @@ export default defineEventHandler(async event => {
|
|||
const body = await readBody(event);
|
||||
const validatedBody = updateSessionSchema.parse(body);
|
||||
|
||||
if (validatedBody.deviceName) {
|
||||
await prisma.sessions.update({
|
||||
where: { id: sessionId },
|
||||
data: {
|
||||
device: validatedBody.deviceName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const updatedSession = await prisma.sessions.findUnique({
|
||||
where: { id: sessionId },
|
||||
});
|
||||
// Use update return value directly — no redundant findUnique
|
||||
const updatedSession = validatedBody.deviceName
|
||||
? await prisma.sessions.update({
|
||||
where: { id: sessionId },
|
||||
data: { device: validatedBody.deviceName },
|
||||
})
|
||||
: targetedSession;
|
||||
|
||||
return {
|
||||
id: updatedSession.id,
|
||||
|
|
@ -65,16 +60,7 @@ export default defineEventHandler(async event => {
|
|||
}
|
||||
|
||||
if (event.method === 'DELETE') {
|
||||
const sid = event.context.params?.sid;
|
||||
const sessionExists = await prisma.sessions.findUnique({
|
||||
where: { id: sid },
|
||||
});
|
||||
|
||||
if (!sessionExists) {
|
||||
return { success: true };
|
||||
}
|
||||
const session = await useAuth().getSessionAndBump(sid);
|
||||
|
||||
// targetedSession already validated above — no redundant findUnique or session bump needed
|
||||
await prisma.sessions.delete({
|
||||
where: { id: sessionId },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ export default defineEventHandler(async event => {
|
|||
const validatedBody = updateListSchema.parse(body);
|
||||
|
||||
const list = await prisma.lists.findUnique({
|
||||
relationLoadStrategy: 'join',
|
||||
where: { id: validatedBody.list_id },
|
||||
include: { list_items: true },
|
||||
});
|
||||
|
|
@ -100,6 +101,7 @@ export default defineEventHandler(async event => {
|
|||
}
|
||||
|
||||
return tx.lists.findUnique({
|
||||
relationLoadStrategy: 'join',
|
||||
where: { id: list.id },
|
||||
include: { list_items: true },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,47 +40,57 @@ export default defineEventHandler(async event => {
|
|||
|
||||
const validatedBody = createListSchema.parse(parsedBody);
|
||||
|
||||
const result = await prisma.$transaction(async tx => {
|
||||
const existing = await tx.lists.findFirst({
|
||||
where: { user_id: userId, name: validatedBody.name }
|
||||
try {
|
||||
const result = await prisma.$transaction(async tx => {
|
||||
// App-level guard for a clean 409 message
|
||||
const existing = await tx.lists.findFirst({
|
||||
where: { user_id: userId, name: validatedBody.name },
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
throw createError({ statusCode: 409, message: 'A list with this name already exists' });
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const newList = await tx.lists.create({
|
||||
data: {
|
||||
id: uuidv7(),
|
||||
user_id: userId,
|
||||
name: validatedBody.name,
|
||||
description: validatedBody.description || null,
|
||||
public: validatedBody.public || false,
|
||||
updated_at: now,
|
||||
},
|
||||
});
|
||||
|
||||
if (validatedBody.items && validatedBody.items.length > 0) {
|
||||
await tx.list_items.createMany({
|
||||
data: validatedBody.items.map(item => ({
|
||||
id: uuidv7(),
|
||||
list_id: newList.id,
|
||||
tmdb_id: item.tmdb_id,
|
||||
type: item.type,
|
||||
})),
|
||||
skipDuplicates: true,
|
||||
});
|
||||
}
|
||||
|
||||
return tx.lists.findUnique({
|
||||
relationLoadStrategy: 'join',
|
||||
where: { id: newList.id },
|
||||
include: { list_items: true },
|
||||
});
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
return {
|
||||
list: result,
|
||||
message: 'List created successfully',
|
||||
};
|
||||
} catch (err: any) {
|
||||
// DB-level safety net: catch unique constraint violation from @@unique([user_id, name])
|
||||
if (err.code === 'P2002') {
|
||||
throw createError({ statusCode: 409, message: 'A list with this name already exists' });
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const newList = await tx.lists.create({
|
||||
data: {
|
||||
id: uuidv7(),
|
||||
user_id: userId,
|
||||
name: validatedBody.name,
|
||||
description: validatedBody.description || null,
|
||||
public: validatedBody.public || false,
|
||||
updated_at: now,
|
||||
},
|
||||
});
|
||||
|
||||
if (validatedBody.items && validatedBody.items.length > 0) {
|
||||
await tx.list_items.createMany({
|
||||
data: validatedBody.items.map(item => ({
|
||||
id: uuidv7(),
|
||||
list_id: newList.id,
|
||||
tmdb_id: item.tmdb_id,
|
||||
type: item.type, // Type is mapped here
|
||||
})),
|
||||
skipDuplicates: true,
|
||||
});
|
||||
}
|
||||
|
||||
return tx.lists.findUnique({
|
||||
where: { id: newList.id },
|
||||
include: { list_items: true },
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
list: result,
|
||||
message: 'List created successfully',
|
||||
};
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -144,27 +144,14 @@ export default defineEventHandler(async event => {
|
|||
if (body.seasonId) whereClause.season_id = body.seasonId;
|
||||
if (body.episodeId) whereClause.episode_id = body.episodeId;
|
||||
|
||||
const itemsToDelete = await prisma.watch_history.findMany({
|
||||
where: whereClause,
|
||||
});
|
||||
|
||||
if (itemsToDelete.length === 0) {
|
||||
return {
|
||||
success: true,
|
||||
count: 0,
|
||||
tmdbId,
|
||||
episodeId: body.episodeId,
|
||||
seasonId: body.seasonId,
|
||||
};
|
||||
}
|
||||
|
||||
await prisma.watch_history.deleteMany({
|
||||
// Use deleteMany return count directly — no redundant findMany
|
||||
const { count } = await prisma.watch_history.deleteMany({
|
||||
where: whereClause,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
count: itemsToDelete.length,
|
||||
count,
|
||||
tmdbId,
|
||||
episodeId: body.episodeId,
|
||||
seasonId: body.seasonId,
|
||||
|
|
|
|||
|
|
@ -40,13 +40,19 @@ export function useAuth() {
|
|||
const now = new Date();
|
||||
const expiryDate = new Date(now.getTime() + SESSION_EXPIRY_MS);
|
||||
|
||||
// Cleanup existing session for this device
|
||||
await prisma.sessions.deleteMany({
|
||||
where: { user, device },
|
||||
});
|
||||
|
||||
return await prisma.sessions.create({
|
||||
data: {
|
||||
// Atomic upsert — backed by @@unique([user, device]) in schema
|
||||
return await prisma.sessions.upsert({
|
||||
where: {
|
||||
sessions_user_device_unique: { user, device },
|
||||
},
|
||||
update: {
|
||||
id: uuidv7(),
|
||||
user_agent: userAgent,
|
||||
created_at: now,
|
||||
accessed_at: now,
|
||||
expires_at: expiryDate,
|
||||
},
|
||||
create: {
|
||||
id: uuidv7(),
|
||||
user,
|
||||
device,
|
||||
|
|
|
|||
Loading…
Reference in a new issue