Initial open-source self-hosted Songs2YT edition
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Plan" AS ENUM ('FREE', 'PREMIUM');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Privacy" AS ENUM ('PUBLIC', 'PRIVATE', 'UNLISTED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "JobStatus" AS ENUM ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'PARTIAL');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "JobItemStatus" AS ENUM ('PENDING', 'ENCODING', 'UPLOADING', 'COMPLETED', 'FAILED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"image" TEXT,
|
||||
"plan" "Plan" NOT NULL DEFAULT 'FREE',
|
||||
"videosUsed" INTEGER NOT NULL DEFAULT 0,
|
||||
"quotaResetAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "YouTubeConnection" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"accessToken" TEXT NOT NULL,
|
||||
"refreshToken" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"channelId" TEXT NOT NULL,
|
||||
"channelTitle" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "YouTubeConnection_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Job" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"status" "JobStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"imagePath" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "Job_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "JobItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"jobId" TEXT NOT NULL,
|
||||
"audioPath" TEXT NOT NULL,
|
||||
"audioFilename" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL DEFAULT '',
|
||||
"tags" TEXT NOT NULL DEFAULT '',
|
||||
"privacy" "Privacy" NOT NULL DEFAULT 'PUBLIC',
|
||||
"categoryId" TEXT NOT NULL DEFAULT '10',
|
||||
"resolution" TEXT NOT NULL DEFAULT '1280x720',
|
||||
"notifySubscribers" BOOLEAN NOT NULL DEFAULT true,
|
||||
"madeForKids" BOOLEAN NOT NULL DEFAULT false,
|
||||
"embeddable" BOOLEAN NOT NULL DEFAULT true,
|
||||
"creativeCommons" BOOLEAN NOT NULL DEFAULT false,
|
||||
"includeWatermark" BOOLEAN NOT NULL DEFAULT true,
|
||||
"status" "JobItemStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"outputPath" TEXT,
|
||||
"youtubeVideoId" TEXT,
|
||||
"error" TEXT,
|
||||
|
||||
CONSTRAINT "JobItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "YouTubeConnection_userId_key" ON "YouTubeConnection"("userId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "YouTubeConnection" ADD CONSTRAINT "YouTubeConnection_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Job" ADD CONSTRAINT "Job_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "JobItem" ADD CONSTRAINT "JobItem_jobId_fkey" FOREIGN KEY ("jobId") REFERENCES "Job"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "cardLast4" TEXT,
|
||||
ADD COLUMN "subscribedAt" TIMESTAMP(3);
|
||||
@@ -0,0 +1,21 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "QuotaExtensionRequestStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "bonusQuota" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "QuotaExtensionRequest" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"status" "QuotaExtensionRequestStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"message" TEXT NOT NULL DEFAULT '',
|
||||
"requestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"processedAt" TIMESTAMP(3),
|
||||
"adminNote" TEXT,
|
||||
|
||||
CONSTRAINT "QuotaExtensionRequest_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "QuotaExtensionRequest" ADD CONSTRAINT "QuotaExtensionRequest_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,6 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "apiKeyHash" TEXT,
|
||||
ADD COLUMN "apiKeyPrefix" TEXT;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_apiKeyHash_key" ON "User"("apiKeyHash");
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "JobItem" ADD COLUMN "playlistId" TEXT;
|
||||
@@ -0,0 +1,8 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "apiRateLimitBonus" INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "QuotaExtensionKind" AS ENUM ('VIDEO_QUOTA', 'API_RATE_LIMIT');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "QuotaExtensionRequest" ADD COLUMN "kind" "QuotaExtensionKind" NOT NULL DEFAULT 'VIDEO_QUOTA';
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
@@ -0,0 +1,152 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum Plan {
|
||||
FREE
|
||||
PREMIUM
|
||||
}
|
||||
|
||||
enum Privacy {
|
||||
PUBLIC
|
||||
PRIVATE
|
||||
UNLISTED
|
||||
}
|
||||
|
||||
enum JobStatus {
|
||||
PENDING
|
||||
PROCESSING
|
||||
COMPLETED
|
||||
FAILED
|
||||
PARTIAL
|
||||
}
|
||||
|
||||
enum JobItemStatus {
|
||||
PENDING
|
||||
ENCODING
|
||||
UPLOADING
|
||||
COMPLETED
|
||||
FAILED
|
||||
}
|
||||
|
||||
enum QuotaExtensionRequestStatus {
|
||||
PENDING
|
||||
APPROVED
|
||||
REJECTED
|
||||
}
|
||||
|
||||
enum QuotaExtensionKind {
|
||||
VIDEO_QUOTA
|
||||
API_RATE_LIMIT
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
name String?
|
||||
image String?
|
||||
plan Plan @default(FREE)
|
||||
videosUsed Int @default(0)
|
||||
quotaResetAt DateTime
|
||||
cardLast4 String?
|
||||
subscribedAt DateTime?
|
||||
bonusQuota Int @default(0)
|
||||
apiRateLimitBonus Int @default(0)
|
||||
/** Prepaid pay-as-you-go video credits (1 credit = 1 video). Cap: 1000. */
|
||||
videoCredits Int @default(0)
|
||||
apiKeyHash String? @unique
|
||||
apiKeyPrefix String?
|
||||
youtubeConnection YouTubeConnection?
|
||||
jobs Job[]
|
||||
quotaExtensionRequests QuotaExtensionRequest[]
|
||||
creditPurchases CreditPurchase[]
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
enum CreditPurchaseStatus {
|
||||
PENDING
|
||||
COMPLETED
|
||||
FAILED
|
||||
}
|
||||
|
||||
model CreditPurchase {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
credits Int
|
||||
amountCents Int
|
||||
status CreditPurchaseStatus @default(PENDING)
|
||||
stripeSessionId String? @unique
|
||||
stripePaymentIntentId String?
|
||||
createdAt DateTime @default(now())
|
||||
completedAt DateTime?
|
||||
}
|
||||
|
||||
enum JobItemBilling {
|
||||
QUOTA
|
||||
CREDIT
|
||||
}
|
||||
|
||||
model QuotaExtensionRequest {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
kind QuotaExtensionKind @default(VIDEO_QUOTA)
|
||||
status QuotaExtensionRequestStatus @default(PENDING)
|
||||
message String @default("")
|
||||
requestedAt DateTime @default(now())
|
||||
processedAt DateTime?
|
||||
adminNote String?
|
||||
}
|
||||
|
||||
model YouTubeConnection {
|
||||
id String @id @default(cuid())
|
||||
userId String @unique
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
accessToken String
|
||||
refreshToken String
|
||||
expiresAt DateTime
|
||||
channelId String
|
||||
channelTitle String
|
||||
}
|
||||
|
||||
model Job {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
status JobStatus @default(PENDING)
|
||||
imagePath String
|
||||
items JobItem[]
|
||||
createdAt DateTime @default(now())
|
||||
completedAt DateTime?
|
||||
}
|
||||
|
||||
model JobItem {
|
||||
id String @id @default(cuid())
|
||||
jobId String
|
||||
job Job @relation(fields: [jobId], references: [id], onDelete: Cascade)
|
||||
audioPath String
|
||||
audioFilename String
|
||||
title String
|
||||
description String @default("")
|
||||
tags String @default("")
|
||||
privacy Privacy @default(PUBLIC)
|
||||
categoryId String @default("10")
|
||||
resolution String @default("1280x720")
|
||||
notifySubscribers Boolean @default(true)
|
||||
madeForKids Boolean @default(false)
|
||||
embeddable Boolean @default(true)
|
||||
creativeCommons Boolean @default(false)
|
||||
includeWatermark Boolean @default(true)
|
||||
playlistId String?
|
||||
billingSource JobItemBilling @default(QUOTA)
|
||||
status JobItemStatus @default(PENDING)
|
||||
outputPath String?
|
||||
youtubeVideoId String?
|
||||
error String?
|
||||
}
|
||||
Reference in New Issue
Block a user