diff --git a/server/videoSync.ts b/server/videoSync.ts index 806e1c1..17491f5 100644 --- a/server/videoSync.ts +++ b/server/videoSync.ts @@ -96,18 +96,18 @@ class VideoSyncService { for (const video of batch) { try { - // Check if video exists in database using raw SQL - const existingVideo = await db.execute(sql`SELECT id FROM videos WHERE id = ${video.id} LIMIT 1`); + // Check if video exists in database using Drizzle ORM + const existingVideo = await db.select({ id: videos.id }).from(videos).where(eq(videos.id, video.id)).limit(1); const videoData = { id: video.id, - title: video.title, + title: video.title || '', description: video.description || '', - thumbnailUrl: video.thumbnailUrl, + thumbnailUrl: video.thumbnailUrl || '', customThumbnailUrl: video.customThumbnailUrl || null, - videoUrl: video.videoUrl, - duration: video.duration, - views: video.views, + videoUrl: video.videoUrl || '', + duration: video.duration || 0, + views: video.views || 0, category: video.category || '', tags: Array.isArray(video.tags) ? video.tags : [], isPublic: video.isPublic !== false, @@ -115,23 +115,27 @@ class VideoSyncService { updatedAt: new Date(), }; - if (existingVideo.rows.length === 0) { - // Insert new video using raw SQL to avoid schema issues - await db.execute(sql` - INSERT INTO videos (id, title, description, thumbnail_url, video_url, duration, views, category, custom_thumbnail_url, tags, is_public, created_at, updated_at) - VALUES (${videoData.id}, ${videoData.title}, ${videoData.description}, ${videoData.thumbnailUrl}, ${videoData.videoUrl}, ${videoData.duration}, ${videoData.views}, ${videoData.category}, ${videoData.customThumbnailUrl}, ${'{' + videoData.tags.join(',') + '}'}, ${videoData.isPublic}, ${videoData.createdAt.toISOString()}, ${videoData.updatedAt.toISOString()}) - `); + if (existingVideo.length === 0) { + // Insert new video using Drizzle ORM + await db.insert(videos).values(videoData); insertedCount++; } else { - // Update existing video using raw SQL - await db.execute(sql` - UPDATE videos - SET title = ${videoData.title}, description = ${videoData.description}, thumbnail_url = ${videoData.thumbnailUrl}, - video_url = ${videoData.videoUrl}, duration = ${videoData.duration}, views = ${videoData.views}, - category = ${videoData.category}, custom_thumbnail_url = ${videoData.customThumbnailUrl}, - tags = ${'{' + videoData.tags.join(',') + '}'}, is_public = ${videoData.isPublic}, updated_at = ${videoData.updatedAt.toISOString()} - WHERE id = ${video.id} - `); + // Update existing video using Drizzle ORM + await db.update(videos) + .set({ + title: videoData.title, + description: videoData.description, + thumbnailUrl: videoData.thumbnailUrl, + customThumbnailUrl: videoData.customThumbnailUrl, + videoUrl: videoData.videoUrl, + duration: videoData.duration, + views: videoData.views, + category: videoData.category, + tags: videoData.tags, + isPublic: videoData.isPublic, + updatedAt: videoData.updatedAt, + }) + .where(eq(videos.id, video.id)); updatedCount++; } } catch (error) { @@ -171,17 +175,24 @@ class VideoSyncService { setTimeout(() => reject(new Error('Database sync timeout after 30 seconds')), 30000) ); - await Promise.race([ - this.syncVideosToDatabase(), - syncTimeout - ]); + try { + await Promise.race([ + this.syncVideosToDatabase(), + syncTimeout + ]); + console.log('✅ Database sync completed successfully'); + } catch (syncError) { + console.error('❌ Database sync failed:', syncError); + console.log('⚠️ Continuing with cached data only - videos will still be available from Bunny.net'); + // Don't throw here, just log the error and continue + } this.startPeriodicSync(); console.log('✅ Video sync service initialized successfully'); } catch (error) { console.error('❌ Failed to initialize video sync service:', error); - console.log('⚠️ Continuing without database sync - app will still work with cached data'); - // Continue without crashing the server + console.log('⚠️ Continuing without video sync - app will work but videos might not be available'); + // Continue without crashing the server - this ensures the app starts even if video sync fails } }