mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 09:36:08 +00:00
feat: enable S3 video uploads and update related configurations
- Added support for self-hosted S3 video uploads with new environment variables: OPENFRAME_ENABLE_S3_VIDEO_UPLOADS and OPENFRAME_MAX_VIDEO_UPLOAD_BYTES. - Updated .env.example and .env.docker.example to reflect new configuration options. - Enhanced Content Security Policy to include origins for S3-compatible storage. - Updated dependencies for AWS SDK to support new features. - Refactored upload logic to accommodate both Bunny and S3 upload providers. - Updated documentation to clarify the usage of direct uploads and S3 configurations. - Closes #11
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ALTER TABLE "video_versions" ADD COLUMN "size_bytes" BIGINT NOT NULL DEFAULT 0;
|
||||
@@ -0,0 +1,41 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "UploadSessionStatus" AS ENUM ('INITIATED', 'FINALIZED', 'CANCELLED', 'EXPIRED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "video_upload_sessions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"upload_jti" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"billed_user_id" TEXT NOT NULL,
|
||||
"object_key" TEXT NOT NULL,
|
||||
"thumbnail_object_key" TEXT NOT NULL,
|
||||
"declared_size_bytes" BIGINT NOT NULL,
|
||||
"content_type" TEXT NOT NULL,
|
||||
"reservation_id" TEXT,
|
||||
"expires_at" TIMESTAMP(3) NOT NULL,
|
||||
"status" "UploadSessionStatus" NOT NULL DEFAULT 'INITIATED',
|
||||
"consumed_at" TIMESTAMP(3),
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "video_upload_sessions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "video_upload_sessions_upload_jti_key" ON "video_upload_sessions"("upload_jti");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "video_upload_sessions_object_key_key" ON "video_upload_sessions"("object_key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "video_upload_sessions_projectId_status_idx" ON "video_upload_sessions"("projectId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "video_upload_sessions_userId_status_idx" ON "video_upload_sessions"("userId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "video_upload_sessions_billed_user_id_idx" ON "video_upload_sessions"("billed_user_id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "video_upload_sessions_expires_at_idx" ON "video_upload_sessions"("expires_at");
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Ensure a finalized R2 object key and proxy URL can only be claimed once.
|
||||
CREATE UNIQUE INDEX "video_versions_r2_videoid_unique"
|
||||
ON "video_versions" ("videoId")
|
||||
WHERE "providerId" = 'r2';
|
||||
|
||||
CREATE UNIQUE INDEX "video_versions_r2_originalurl_unique"
|
||||
ON "video_versions" ("originalUrl")
|
||||
WHERE "providerId" = 'r2' AND "originalUrl" LIKE '/api/upload/video/%';
|
||||
|
||||
CREATE UNIQUE INDEX "video_versions_r2_thumbnail_unique"
|
||||
ON "video_versions" ("thumbnailUrl")
|
||||
WHERE "providerId" = 'r2' AND "thumbnailUrl" LIKE '/api/upload/image/%';
|
||||
@@ -361,6 +361,7 @@ model VideoVersion {
|
||||
title String?
|
||||
thumbnailUrl String?
|
||||
duration Int? // Duration in seconds
|
||||
sizeBytes BigInt @default(0) @map("size_bytes") // R2-hosted video file size
|
||||
|
||||
// Status
|
||||
isActive Boolean @default(true) // Currently displayed version
|
||||
@@ -701,6 +702,37 @@ model UploadReservation {
|
||||
@@map("upload_reservations")
|
||||
}
|
||||
|
||||
enum UploadSessionStatus {
|
||||
INITIATED
|
||||
FINALIZED
|
||||
CANCELLED
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
model VideoUploadSession {
|
||||
id String @id @default(cuid())
|
||||
uploadJti String @unique @map("upload_jti")
|
||||
userId String
|
||||
projectId String
|
||||
billedUserId String @map("billed_user_id")
|
||||
objectKey String @unique @map("object_key")
|
||||
thumbnailObjectKey String @map("thumbnail_object_key")
|
||||
declaredSizeBytes BigInt @map("declared_size_bytes")
|
||||
contentType String @map("content_type")
|
||||
reservationId String? @map("reservation_id")
|
||||
expiresAt DateTime @map("expires_at")
|
||||
status UploadSessionStatus @default(INITIATED)
|
||||
consumedAt DateTime? @map("consumed_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([projectId, status])
|
||||
@@index([userId, status])
|
||||
@@index([billedUserId])
|
||||
@@index([expiresAt])
|
||||
@@map("video_upload_sessions")
|
||||
}
|
||||
|
||||
// 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