mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 09:36:08 +00:00
feat: add video watch progress tracking with resume functionality
Implements a complete watch progress system that allows users to: - Save playback position automatically every 5 seconds while watching - Resume from last position when returning to a video - Save progress on page leave using sendBeacon for reliability Also includes: - Optimized slug generation in projects and workspaces APIs (single query vs loop) - Added isActive filter to version queries across all video endpoints - Added pagination support for video and comment queries - Enhanced database pool management with connection limits and graceful shutdown - New WatchProgress Prisma model with user-version relations
This commit is contained in:
@@ -31,6 +31,7 @@ model User {
|
||||
comments Comment[]
|
||||
projectMemberships ProjectMember[]
|
||||
notificationSetting NotificationSetting?
|
||||
watchProgress WatchProgress[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -158,6 +159,7 @@ model Project {
|
||||
@@index([ownerId])
|
||||
@@index([slug])
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, updatedAt(sort: Desc)])
|
||||
@@map("projects")
|
||||
}
|
||||
|
||||
@@ -239,9 +241,11 @@ model VideoVersion {
|
||||
|
||||
// Relations
|
||||
comments Comment[]
|
||||
watchProgress WatchProgress[]
|
||||
|
||||
@@unique([videoParentId, versionNumber])
|
||||
@@index([videoParentId])
|
||||
@@index([videoParentId, isActive])
|
||||
@@map("video_versions")
|
||||
}
|
||||
|
||||
@@ -293,6 +297,8 @@ model Comment {
|
||||
@@index([authorId])
|
||||
@@index([timestamp])
|
||||
@@index([tagId])
|
||||
@@index([versionId, isResolved, timestamp])
|
||||
@@index([versionId, parentId, createdAt])
|
||||
@@map("comments")
|
||||
}
|
||||
|
||||
@@ -345,6 +351,7 @@ model ShareLink {
|
||||
|
||||
@@index([projectId])
|
||||
@@index([token])
|
||||
@@index([token, expiresAt])
|
||||
@@map("share_links")
|
||||
}
|
||||
|
||||
@@ -386,6 +393,37 @@ model NotificationSetting {
|
||||
@@map("notification_settings")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// WATCH PROGRESS
|
||||
// ============================================
|
||||
|
||||
model WatchProgress {
|
||||
id String @id @default(cuid())
|
||||
|
||||
// User relation (optional for guest progress, though typically requires auth)
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Video version relation
|
||||
versionId String
|
||||
version VideoVersion @relation(fields: [versionId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Progress data
|
||||
progress Float // Current playback position in seconds
|
||||
duration Float // Total video duration at time of save
|
||||
percentage Float // Progress as percentage (0-100)
|
||||
|
||||
// Timestamps
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// One progress record per user per version
|
||||
@@unique([userId, versionId])
|
||||
@@index([userId])
|
||||
@@index([versionId])
|
||||
@@map("watch_progress")
|
||||
}
|
||||
|
||||
// Rate limiting table (created as UNLOGGED via raw SQL migration)
|
||||
// Defined here so `prisma db push` doesn't drop it
|
||||
model RateLimit {
|
||||
|
||||
Reference in New Issue
Block a user