Files
2026-07-17 02:23:59 +02:00

153 lines
4.2 KiB
Plaintext

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?
}