From 3678168283fa4c98a81f79689ea6e23333edca5b Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:07:47 -0700 Subject: [PATCH 1/6] fix ddos Missing Generated Client: The server/utils/prisma.ts file imports from '../../generated/client', but this directory didn't exist Import Failures: When login routes tried to load, they would hang indefinitely trying to resolve the broken import --- prisma/schema.prisma | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 066b0f5..a4fa676 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,11 +1,12 @@ generator client { - provider = "prisma-client" + provider = "prisma-client-js" output = "../generated" moduleFormat = "esm" } datasource db { provider = "postgresql" + url = env("DATABASE_URL") } model bookmarks { From d543997db74702e5d122f087b83c956764b4c069 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:12:54 -0700 Subject: [PATCH 2/6] re init metrics after clearing --- server/routes/metrics/daily.ts | 16 ++++++++++++++-- server/routes/metrics/monthly.ts | 16 ++++++++++++++-- server/routes/metrics/weekly.ts | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/server/routes/metrics/daily.ts b/server/routes/metrics/daily.ts index 68c7793..05591d1 100644 --- a/server/routes/metrics/daily.ts +++ b/server/routes/metrics/daily.ts @@ -1,13 +1,25 @@ -import { getRegistry } from '../../utils/metrics'; +import { getRegistry, initializeAllMetrics } from '../../utils/metrics'; import { scopedLogger } from '../../utils/logger'; const log = scopedLogger('metrics-daily-endpoint'); +let isInitialized = false; + +async function ensureMetricsInitialized() { + if (!isInitialized) { + log.info('Initializing metrics from daily endpoint...', { evt: 'init_start' }); + await initializeAllMetrics(); + isInitialized = true; + log.info('Metrics initialized from daily endpoint', { evt: 'init_complete' }); + } +} + export default defineEventHandler(async event => { try { + await ensureMetricsInitialized(); // Get the daily registry const dailyRegistry = getRegistry('daily'); - + const metrics = await dailyRegistry.metrics(); event.node.res.setHeader('Content-Type', dailyRegistry.contentType); return metrics; diff --git a/server/routes/metrics/monthly.ts b/server/routes/metrics/monthly.ts index 94f5347..acb323b 100644 --- a/server/routes/metrics/monthly.ts +++ b/server/routes/metrics/monthly.ts @@ -1,13 +1,25 @@ -import { getRegistry } from '../../utils/metrics'; +import { getRegistry, initializeAllMetrics } from '../../utils/metrics'; import { scopedLogger } from '../../utils/logger'; const log = scopedLogger('metrics-monthly-endpoint'); +let isInitialized = false; + +async function ensureMetricsInitialized() { + if (!isInitialized) { + log.info('Initializing metrics from monthly endpoint...', { evt: 'init_start' }); + await initializeAllMetrics(); + isInitialized = true; + log.info('Metrics initialized from monthly endpoint', { evt: 'init_complete' }); + } +} + export default defineEventHandler(async event => { try { + await ensureMetricsInitialized(); // Get the monthly registry const monthlyRegistry = getRegistry('monthly'); - + const metrics = await monthlyRegistry.metrics(); event.node.res.setHeader('Content-Type', monthlyRegistry.contentType); return metrics; diff --git a/server/routes/metrics/weekly.ts b/server/routes/metrics/weekly.ts index e3237fa..4e66002 100644 --- a/server/routes/metrics/weekly.ts +++ b/server/routes/metrics/weekly.ts @@ -1,13 +1,25 @@ -import { getRegistry } from '../../utils/metrics'; +import { getRegistry, initializeAllMetrics } from '../../utils/metrics'; import { scopedLogger } from '../../utils/logger'; const log = scopedLogger('metrics-weekly-endpoint'); +let isInitialized = false; + +async function ensureMetricsInitialized() { + if (!isInitialized) { + log.info('Initializing metrics from weekly endpoint...', { evt: 'init_start' }); + await initializeAllMetrics(); + isInitialized = true; + log.info('Metrics initialized from weekly endpoint', { evt: 'init_complete' }); + } +} + export default defineEventHandler(async event => { try { + await ensureMetricsInitialized(); // Get the weekly registry const weeklyRegistry = getRegistry('weekly'); - + const metrics = await weeklyRegistry.metrics(); event.node.res.setHeader('Content-Type', weeklyRegistry.contentType); return metrics; From 4939becabfaa33026bfe9fcb2d7a0fe307951a42 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:30:24 -0700 Subject: [PATCH 3/6] fix lint and import error --- server/utils/prisma.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/utils/prisma.ts b/server/utils/prisma.ts index 0f6b09a..747890f 100644 --- a/server/utils/prisma.ts +++ b/server/utils/prisma.ts @@ -1,5 +1,5 @@ import { PrismaPg } from '@prisma/adapter-pg'; -import { PrismaClient } from '../../generated/client'; +import { PrismaClient } from '../generated'; const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL, @@ -9,6 +9,8 @@ const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined; }; -export const prisma = new PrismaClient({ adapter }); +export const prisma = new PrismaClient({ + adapter, +} as any); if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma; From 1621d65be202712ef0b041401b084336a42f4e86 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:30:27 -0700 Subject: [PATCH 4/6] Update watch-history.ts --- server/routes/users/[id]/watch-history.ts | 112 ---------------------- 1 file changed, 112 deletions(-) diff --git a/server/routes/users/[id]/watch-history.ts b/server/routes/users/[id]/watch-history.ts index 426808e..a47b76c 100644 --- a/server/routes/users/[id]/watch-history.ts +++ b/server/routes/users/[id]/watch-history.ts @@ -76,118 +76,6 @@ export default defineEventHandler(async event => { })); } - if (event.path.includes('/watch-history/')) { - const segments = event.path.split('/'); - const tmdbId = segments[segments.length - 1]; - - if (method === 'PUT') { - const body = await readBody(event); - const validatedBody = watchHistoryItemSchema.parse(body); - - const watchedAt = defaultAndCoerceDateTime(validatedBody.watchedAt); - const now = new Date(); - - const existingItem = await prisma.watch_history.findUnique({ - where: { - tmdb_id_user_id_season_id_episode_id: { - tmdb_id: tmdbId, - user_id: userId, - season_id: validatedBody.seasonId || null, - episode_id: validatedBody.episodeId || null, - }, - }, - }); - - let watchHistoryItem; - - if (existingItem) { - watchHistoryItem = await prisma.watch_history.update({ - where: { - id: existingItem.id, - }, - data: { - duration: BigInt(validatedBody.duration), - watched: BigInt(validatedBody.watched), - watched_at: watchedAt, - completed: validatedBody.completed, - meta: validatedBody.meta, - updated_at: now, - }, - }); - } else { - watchHistoryItem = await prisma.watch_history.create({ - data: { - id: randomUUID(), - tmdb_id: tmdbId, - user_id: userId, - season_id: validatedBody.seasonId || null, - episode_id: validatedBody.episodeId || null, - season_number: validatedBody.seasonNumber || null, - episode_number: validatedBody.episodeNumber || null, - duration: BigInt(validatedBody.duration), - watched: BigInt(validatedBody.watched), - watched_at: watchedAt, - completed: validatedBody.completed, - meta: validatedBody.meta, - updated_at: now, - }, - }); - } - - return { - id: watchHistoryItem.id, - tmdbId: watchHistoryItem.tmdb_id, - userId: watchHistoryItem.user_id, - seasonId: watchHistoryItem.season_id, - episodeId: watchHistoryItem.episode_id, - seasonNumber: watchHistoryItem.season_number, - episodeNumber: watchHistoryItem.episode_number, - meta: watchHistoryItem.meta, - duration: Number(watchHistoryItem.duration), - watched: Number(watchHistoryItem.watched), - watchedAt: watchHistoryItem.watched_at.toISOString(), - completed: watchHistoryItem.completed, - updatedAt: watchHistoryItem.updated_at.toISOString(), - }; - } - - if (method === 'DELETE') { - const body = await readBody(event).catch(() => ({})); - - const whereClause: any = { - user_id: userId, - tmdb_id: tmdbId, - }; - - 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 { - count: 0, - tmdbId, - episodeId: body.episodeId, - seasonId: body.seasonId, - }; - } - - await prisma.watch_history.deleteMany({ - where: whereClause, - }); - - return { - count: itemsToDelete.length, - tmdbId, - episodeId: body.episodeId, - seasonId: body.seasonId, - }; - } - } - throw createError({ statusCode: 405, message: 'Method not allowed', From 1fe3400aa23ccb03b1fcc889f36d98a22793c5da Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:33:47 -0700 Subject: [PATCH 5/6] meow why build fine locally but git workflow not --- prisma/schema.prisma | 1 - 1 file changed, 1 deletion(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a4fa676..04bf512 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -6,7 +6,6 @@ generator client { datasource db { provider = "postgresql" - url = env("DATABASE_URL") } model bookmarks { From f026c3a2742526aa38233c5652c929c1c5bc7ee1 Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Sun, 14 Dec 2025 21:36:35 -0700 Subject: [PATCH 6/6] Update schema.prisma --- prisma/schema.prisma | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 04bf512..a8fd294 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,6 +1,6 @@ generator client { provider = "prisma-client-js" - output = "../generated" + output = "../server/generated" moduleFormat = "esm" }