generated from fahricansecer/boilerplate-be
+383
-379
@@ -15,72 +15,72 @@ datasource db {
|
||||
// ============================================
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
firstName String?
|
||||
lastName String?
|
||||
isActive Boolean @default(true)
|
||||
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
firstName String?
|
||||
lastName String?
|
||||
isActive Boolean @default(true)
|
||||
|
||||
// Core Relations
|
||||
roles UserRole[]
|
||||
refreshTokens RefreshToken[]
|
||||
|
||||
|
||||
// Video SaaS Relations
|
||||
projects Project[]
|
||||
subscriptions Subscription[]
|
||||
creditTransactions CreditTransaction[]
|
||||
templateUsages TemplateUsage[]
|
||||
notifications Notification[]
|
||||
preferences UserPreference?
|
||||
youtubeAnalyses YoutubeAnalysis[]
|
||||
youtubeSeoAnalyses YoutubeSeoAnalysis[]
|
||||
projects Project[]
|
||||
subscriptions Subscription[]
|
||||
creditTransactions CreditTransaction[]
|
||||
templateUsages TemplateUsage[]
|
||||
notifications Notification[]
|
||||
preferences UserPreference?
|
||||
youtubeAnalyses YoutubeAnalysis[]
|
||||
youtubeSeoAnalyses YoutubeSeoAnalysis[]
|
||||
tubeStrategistProjects TubeStrategistProject[]
|
||||
|
||||
|
||||
// Multi-tenancy (optional)
|
||||
tenantId String?
|
||||
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
||||
|
||||
tenantId String?
|
||||
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
||||
|
||||
// Timestamps & Soft Delete
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([email])
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
model Role {
|
||||
id String @id @default(uuid())
|
||||
name String @unique
|
||||
id String @id @default(uuid())
|
||||
name String @unique
|
||||
description String?
|
||||
isSystem Boolean @default(false)
|
||||
|
||||
isSystem Boolean @default(false)
|
||||
|
||||
// Relations
|
||||
users UserRole[]
|
||||
permissions RolePermission[]
|
||||
|
||||
|
||||
// Timestamps & Soft Delete
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([name])
|
||||
}
|
||||
|
||||
model Permission {
|
||||
id String @id @default(uuid())
|
||||
name String @unique
|
||||
id String @id @default(uuid())
|
||||
name String @unique
|
||||
description String?
|
||||
resource String // e.g., "users", "posts"
|
||||
action String // e.g., "create", "read", "update", "delete"
|
||||
|
||||
resource String // e.g., "users", "posts"
|
||||
action String // e.g., "create", "read", "update", "delete"
|
||||
|
||||
// Relations
|
||||
roles RolePermission[]
|
||||
|
||||
roles RolePermission[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([resource, action])
|
||||
@@index([resource])
|
||||
@@ -135,14 +135,14 @@ model RefreshToken {
|
||||
// ============================================
|
||||
|
||||
model Tenant {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
slug String @unique
|
||||
isActive Boolean @default(true)
|
||||
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
slug String @unique
|
||||
isActive Boolean @default(true)
|
||||
|
||||
// Relations
|
||||
users User[]
|
||||
|
||||
users User[]
|
||||
|
||||
// Timestamps & Soft Delete
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -156,12 +156,12 @@ model Tenant {
|
||||
// ============================================
|
||||
|
||||
model Translation {
|
||||
id String @id @default(uuid())
|
||||
id String @id @default(uuid())
|
||||
key String
|
||||
locale String // e.g., "en", "tr", "de"
|
||||
locale String // e.g., "en", "tr", "de"
|
||||
value String
|
||||
namespace String @default("common") // e.g., "common", "errors", "validation"
|
||||
|
||||
namespace String @default("common") // e.g., "common", "errors", "validation"
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -247,73 +247,73 @@ enum SourceType {
|
||||
// ============================================
|
||||
|
||||
model Project {
|
||||
id String @id @default(uuid())
|
||||
title String @db.VarChar(200)
|
||||
description String? @db.VarChar(1000)
|
||||
prompt String @db.Text
|
||||
|
||||
id String @id @default(uuid())
|
||||
title String @db.VarChar(200)
|
||||
description String? @db.VarChar(1000)
|
||||
prompt String @db.Text
|
||||
|
||||
// AI Generated Script
|
||||
scriptJson Json? // Gemini API raw JSON output
|
||||
scriptVersion Int @default(0)
|
||||
|
||||
scriptJson Json? // Gemini API raw JSON output
|
||||
scriptVersion Int @default(0)
|
||||
|
||||
// Configuration
|
||||
language String @default("tr") @db.VarChar(5) // ISO 639-1
|
||||
aspectRatio AspectRatio @default(PORTRAIT_9_16)
|
||||
videoStyle String @default("CINEMATIC") @db.VarChar(50)
|
||||
cinematicReference String? @db.VarChar(200)
|
||||
targetDuration Int @default(60) // saniye
|
||||
|
||||
language String @default("tr") @db.VarChar(5) // ISO 639-1
|
||||
aspectRatio AspectRatio @default(PORTRAIT_9_16)
|
||||
videoStyle String @default("CINEMATIC") @db.VarChar(50)
|
||||
cinematicReference String? @db.VarChar(200)
|
||||
targetDuration Int @default(60) // saniye
|
||||
|
||||
// SEO & Social Content (skill-enhanced)
|
||||
seoKeywords String[] // Hedeflenen SEO anahtar kelimeler
|
||||
seoTitle String? @db.VarChar(200)
|
||||
seoDescription String? @db.VarChar(500)
|
||||
seoTitleAlts String[] // 5 alternatif SEO başlığı (AI üretimi)
|
||||
seoScore Int? // 0-100 arası SEO güç skoru
|
||||
seoSchemaJson Json? // VideoObject structured data
|
||||
socialContent Json? // { youtubeTitle, tiktokCaption, instagramCaption, twitterText }
|
||||
referenceUrl String? @db.VarChar(500)
|
||||
|
||||
seoKeywords String[] // Hedeflenen SEO anahtar kelimeler
|
||||
seoTitle String? @db.VarChar(200)
|
||||
seoDescription String? @db.VarChar(500)
|
||||
seoTitleAlts String[] // 5 alternatif SEO başlığı (AI üretimi)
|
||||
seoScore Int? // 0-100 arası SEO güç skoru
|
||||
seoSchemaJson Json? // VideoObject structured data
|
||||
socialContent Json? // { youtubeTitle, tiktokCaption, instagramCaption, twitterText }
|
||||
referenceUrl String? @db.VarChar(500)
|
||||
|
||||
// İçerik Kaynağı
|
||||
sourceType SourceType @default(MANUAL) // MANUAL, X_TWEET, YOUTUBE
|
||||
sourceTweetData Json? // X/Twitter tweet verisi (id, author, metrics, media)
|
||||
|
||||
sourceType SourceType @default(MANUAL) // MANUAL, X_TWEET, YOUTUBE
|
||||
sourceTweetData Json? // X/Twitter tweet verisi (id, author, metrics, media)
|
||||
|
||||
// Processing
|
||||
status ProjectStatus @default(DRAFT)
|
||||
progress Int @default(0) // 0-100
|
||||
errorMessage String?
|
||||
|
||||
status ProjectStatus @default(DRAFT)
|
||||
progress Int @default(0) // 0-100
|
||||
errorMessage String?
|
||||
|
||||
// Output
|
||||
finalVideoUrl String?
|
||||
thumbnailUrl String?
|
||||
|
||||
finalVideoUrl String?
|
||||
thumbnailUrl String?
|
||||
|
||||
// Stats
|
||||
creditsUsed Int @default(0)
|
||||
viewCount Int @default(0)
|
||||
|
||||
creditsUsed Int @default(0)
|
||||
viewCount Int @default(0)
|
||||
|
||||
// Template Support
|
||||
isTemplate Boolean @default(false)
|
||||
templateId String? // Hangi şablondan klonlandı?
|
||||
template Template? @relation("ClonedFrom", fields: [templateId], references: [id])
|
||||
|
||||
isTemplate Boolean @default(false)
|
||||
templateId String? // Hangi şablondan klonlandı?
|
||||
template Template? @relation("ClonedFrom", fields: [templateId], references: [id])
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
scenes Scene[]
|
||||
mediaAssets MediaAsset[]
|
||||
renderJobs RenderJob[]
|
||||
templateEntry Template? @relation("SourceProject")
|
||||
templateEntry Template? @relation("SourceProject")
|
||||
seoScoreHistory SeoScoreHistory[]
|
||||
|
||||
|
||||
// Parent-Child relationship for translations and versions
|
||||
parentId String?
|
||||
parentProject Project? @relation("ProjectVersions", fields: [parentId], references: [id])
|
||||
childProjects Project[] @relation("ProjectVersions")
|
||||
|
||||
parentId String?
|
||||
parentProject Project? @relation("ProjectVersions", fields: [parentId], references: [id])
|
||||
childProjects Project[] @relation("ProjectVersions")
|
||||
|
||||
// Timestamps & Soft Delete
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
completedAt DateTime?
|
||||
deletedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
completedAt DateTime?
|
||||
deletedAt DateTime?
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@ -327,14 +327,14 @@ model Project {
|
||||
// ============================================
|
||||
|
||||
model SeoScoreHistory {
|
||||
id String @id @default(uuid())
|
||||
score Int // 0-100
|
||||
event String @db.VarChar(50) // script_generated, title_changed, seo_titles_regenerated
|
||||
metadata Json? // { selectedTitle, keywords, ... }
|
||||
|
||||
id String @id @default(uuid())
|
||||
score Int // 0-100
|
||||
event String @db.VarChar(50) // script_generated, title_changed, seo_titles_regenerated
|
||||
metadata Json? // { selectedTitle, keywords, ... }
|
||||
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([projectId])
|
||||
@@ -342,27 +342,27 @@ model SeoScoreHistory {
|
||||
}
|
||||
|
||||
model Scene {
|
||||
id String @id @default(uuid())
|
||||
order Int // Sahne sırası (1, 2, 3...)
|
||||
title String? @db.VarChar(200)
|
||||
|
||||
id String @id @default(uuid())
|
||||
order Int // Sahne sırası (1, 2, 3...)
|
||||
title String? @db.VarChar(200)
|
||||
|
||||
// Content
|
||||
narrationText String @db.Text // Hedef dildeki anlatım metni
|
||||
visualPrompt String @db.Text // İngilizce — Higgsfield AI prompt
|
||||
subtitleText String? @db.Text // Ekranda görünecek altyazı
|
||||
|
||||
narrationText String @db.Text // Hedef dildeki anlatım metni
|
||||
visualPrompt String @db.Text // İngilizce — Higgsfield AI prompt
|
||||
subtitleText String? @db.Text // Ekranda görünecek altyazı
|
||||
|
||||
// Timing
|
||||
duration Float @default(5.0) // saniye
|
||||
transitionType TransitionType @default(CUT)
|
||||
|
||||
duration Float @default(5.0) // saniye
|
||||
transitionType TransitionType @default(CUT)
|
||||
|
||||
// Relations
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
mediaAssets MediaAsset[]
|
||||
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
mediaAssets MediaAsset[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([projectId])
|
||||
@@index([order])
|
||||
@@ -373,33 +373,33 @@ model Scene {
|
||||
// ============================================
|
||||
|
||||
model MediaAsset {
|
||||
id String @id @default(uuid())
|
||||
type MediaType
|
||||
|
||||
id String @id @default(uuid())
|
||||
type MediaType
|
||||
|
||||
// Storage
|
||||
s3Key String? // Cloudflare R2 / S3 object key
|
||||
s3Bucket String? @db.VarChar(100)
|
||||
url String? // Public CDN URL
|
||||
|
||||
s3Key String? // Cloudflare R2 / S3 object key
|
||||
s3Bucket String? @db.VarChar(100)
|
||||
url String? // Public CDN URL
|
||||
|
||||
// Metadata
|
||||
fileName String? @db.VarChar(255)
|
||||
mimeType String? @db.VarChar(100)
|
||||
sizeBytes BigInt?
|
||||
durationMs Int? // Medya süresi (video/audio için)
|
||||
|
||||
fileName String? @db.VarChar(255)
|
||||
mimeType String? @db.VarChar(100)
|
||||
sizeBytes BigInt?
|
||||
durationMs Int? // Medya süresi (video/audio için)
|
||||
|
||||
// AI Provider Info
|
||||
aiProvider String? @db.VarChar(50) // higgsfield, elevenlabs, suno
|
||||
aiJobId String? // Dış API job ID'si
|
||||
|
||||
aiProvider String? @db.VarChar(50) // higgsfield, elevenlabs, suno
|
||||
aiJobId String? // Dış API job ID'si
|
||||
|
||||
// Relations
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
sceneId String? // null = proje genelinde (müzik, final vb.)
|
||||
scene Scene? @relation(fields: [sceneId], references: [id], onDelete: SetNull)
|
||||
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
sceneId String? // null = proje genelinde (müzik, final vb.)
|
||||
scene Scene? @relation(fields: [sceneId], references: [id], onDelete: SetNull)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([projectId])
|
||||
@@index([sceneId])
|
||||
@@ -407,37 +407,37 @@ model MediaAsset {
|
||||
}
|
||||
|
||||
model RenderJob {
|
||||
id String @id @default(uuid())
|
||||
status RenderJobStatus @default(QUEUED)
|
||||
currentStage RenderStage?
|
||||
|
||||
id String @id @default(uuid())
|
||||
status RenderJobStatus @default(QUEUED)
|
||||
currentStage RenderStage?
|
||||
|
||||
// Queue Info
|
||||
queueName String @default("video-generation") @db.VarChar(100)
|
||||
bullJobId String? @db.VarChar(100) // BullMQ job ID
|
||||
|
||||
queueName String @default("video-generation") @db.VarChar(100)
|
||||
bullJobId String? @db.VarChar(100) // BullMQ job ID
|
||||
|
||||
// Retry
|
||||
attemptNumber Int @default(1)
|
||||
maxAttempts Int @default(3)
|
||||
|
||||
attemptNumber Int @default(1)
|
||||
maxAttempts Int @default(3)
|
||||
|
||||
// Processing
|
||||
workerHostname String? @db.VarChar(100)
|
||||
processingTimeMs Int? // Toplam render süresi
|
||||
workerHostname String? @db.VarChar(100)
|
||||
processingTimeMs Int? // Toplam render süresi
|
||||
errorMessage String?
|
||||
|
||||
|
||||
// Output
|
||||
finalVideoUrl String?
|
||||
finalVideoS3Key String?
|
||||
|
||||
finalVideoUrl String?
|
||||
finalVideoS3Key String?
|
||||
|
||||
// Relations
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
logs RenderLog[]
|
||||
|
||||
projectId String
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
logs RenderLog[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
startedAt DateTime?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
startedAt DateTime?
|
||||
completedAt DateTime?
|
||||
|
||||
@@index([projectId])
|
||||
@@index([status])
|
||||
@@ -445,19 +445,19 @@ model RenderJob {
|
||||
}
|
||||
|
||||
model RenderLog {
|
||||
id String @id @default(uuid())
|
||||
stage RenderStage
|
||||
level String @default("info") @db.VarChar(10) // info, warn, error
|
||||
message String @db.Text
|
||||
durationMs Int? // Bu aşamanın süresi
|
||||
metadata Json? // Ek JSON veri
|
||||
|
||||
id String @id @default(uuid())
|
||||
stage RenderStage
|
||||
level String @default("info") @db.VarChar(10) // info, warn, error
|
||||
message String @db.Text
|
||||
durationMs Int? // Bu aşamanın süresi
|
||||
metadata Json? // Ek JSON veri
|
||||
|
||||
// Relations
|
||||
renderJobId String
|
||||
renderJob RenderJob @relation(fields: [renderJobId], references: [id], onDelete: Cascade)
|
||||
|
||||
renderJobId String
|
||||
renderJob RenderJob @relation(fields: [renderJobId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([renderJobId])
|
||||
@@index([stage])
|
||||
@@ -468,37 +468,37 @@ model RenderLog {
|
||||
// ============================================
|
||||
|
||||
model Template {
|
||||
id String @id @default(uuid())
|
||||
|
||||
id String @id @default(uuid())
|
||||
|
||||
// Display
|
||||
title String @db.VarChar(200)
|
||||
description String? @db.VarChar(500)
|
||||
thumbnailUrl String?
|
||||
previewVideoUrl String?
|
||||
|
||||
title String @db.VarChar(200)
|
||||
description String? @db.VarChar(500)
|
||||
thumbnailUrl String?
|
||||
previewVideoUrl String?
|
||||
|
||||
// Categorization
|
||||
category String @default("general") @db.VarChar(50)
|
||||
tags String[] // PostgreSQL array
|
||||
language String @default("tr") @db.VarChar(5)
|
||||
|
||||
category String @default("general") @db.VarChar(50)
|
||||
tags String[] // PostgreSQL array
|
||||
language String @default("tr") @db.VarChar(5)
|
||||
|
||||
// Source
|
||||
originalProjectId String @unique
|
||||
originalProject Project @relation("SourceProject", fields: [originalProjectId], references: [id])
|
||||
|
||||
originalProjectId String @unique
|
||||
originalProject Project @relation("SourceProject", fields: [originalProjectId], references: [id])
|
||||
|
||||
// Stats
|
||||
usageCount Int @default(0)
|
||||
rating Float @default(0)
|
||||
ratingCount Int @default(0)
|
||||
isFeatured Boolean @default(false)
|
||||
isPublished Boolean @default(true)
|
||||
|
||||
usageCount Int @default(0)
|
||||
rating Float @default(0)
|
||||
ratingCount Int @default(0)
|
||||
isFeatured Boolean @default(false)
|
||||
isPublished Boolean @default(true)
|
||||
|
||||
// Relations
|
||||
clonedProjects Project[] @relation("ClonedFrom")
|
||||
usages TemplateUsage[]
|
||||
|
||||
clonedProjects Project[] @relation("ClonedFrom")
|
||||
usages TemplateUsage[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([category])
|
||||
@@index([language])
|
||||
@@ -507,14 +507,14 @@ model Template {
|
||||
}
|
||||
|
||||
model TemplateUsage {
|
||||
id String @id @default(uuid())
|
||||
templateId String
|
||||
template Template @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
clonedProjectId String? // Oluşturulan projenin ID'si
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
id String @id @default(uuid())
|
||||
templateId String
|
||||
template Template @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
clonedProjectId String? // Oluşturulan projenin ID'si
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([templateId])
|
||||
@@index([userId])
|
||||
@@ -525,65 +525,65 @@ model TemplateUsage {
|
||||
// ============================================
|
||||
|
||||
model Plan {
|
||||
id String @id @default(uuid())
|
||||
name String @unique @db.VarChar(50) // free, pro, business
|
||||
displayName String @db.VarChar(100)
|
||||
description String? @db.VarChar(500)
|
||||
|
||||
id String @id @default(uuid())
|
||||
name String @unique @db.VarChar(50) // free, pro, business
|
||||
displayName String @db.VarChar(100)
|
||||
description String? @db.VarChar(500)
|
||||
|
||||
// Pricing
|
||||
monthlyPrice Int @default(0) // cent cinsinden (1900 = $19)
|
||||
yearlyPrice Int? // Yıllık indirimli fiyat
|
||||
currency String @default("usd") @db.VarChar(3)
|
||||
|
||||
monthlyPrice Int @default(0) // cent cinsinden (1900 = $19)
|
||||
yearlyPrice Int? // Yıllık indirimli fiyat
|
||||
currency String @default("usd") @db.VarChar(3)
|
||||
|
||||
// Limits
|
||||
monthlyCredits Int @default(3)
|
||||
maxDuration Int @default(30) // saniye
|
||||
maxResolution String @default("720p") @db.VarChar(10)
|
||||
maxProjects Int @default(5)
|
||||
|
||||
monthlyCredits Int @default(3)
|
||||
maxDuration Int @default(30) // saniye
|
||||
maxResolution String @default("720p") @db.VarChar(10)
|
||||
maxProjects Int @default(5)
|
||||
|
||||
// Stripe
|
||||
stripePriceId String? @db.VarChar(100)
|
||||
stripeYearlyPriceId String? @db.VarChar(100)
|
||||
|
||||
stripePriceId String? @db.VarChar(100)
|
||||
stripeYearlyPriceId String? @db.VarChar(100)
|
||||
|
||||
// Features
|
||||
features Json? // { "templates": true, "priorityQueue": false, ... }
|
||||
isActive Boolean @default(true)
|
||||
sortOrder Int @default(0)
|
||||
|
||||
features Json? // { "templates": true, "priorityQueue": false, ... }
|
||||
isActive Boolean @default(true)
|
||||
sortOrder Int @default(0)
|
||||
|
||||
// Relations
|
||||
subscriptions Subscription[]
|
||||
|
||||
subscriptions Subscription[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([name])
|
||||
@@index([isActive])
|
||||
}
|
||||
|
||||
model Subscription {
|
||||
id String @id @default(uuid())
|
||||
status String @default("active") @db.VarChar(20) // active, canceled, past_due, trialing
|
||||
|
||||
id String @id @default(uuid())
|
||||
status String @default("active") @db.VarChar(20) // active, canceled, past_due, trialing
|
||||
|
||||
// Stripe
|
||||
stripeSubscriptionId String? @unique @db.VarChar(100)
|
||||
stripeCustomerId String? @db.VarChar(100)
|
||||
|
||||
stripeSubscriptionId String? @unique @db.VarChar(100)
|
||||
stripeCustomerId String? @db.VarChar(100)
|
||||
|
||||
// Billing Cycle
|
||||
currentPeriodStart DateTime?
|
||||
currentPeriodEnd DateTime?
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
|
||||
currentPeriodStart DateTime?
|
||||
currentPeriodEnd DateTime?
|
||||
cancelAtPeriodEnd Boolean @default(false)
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
planId String
|
||||
plan Plan @relation(fields: [planId], references: [id])
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
planId String
|
||||
plan Plan @relation(fields: [planId], references: [id])
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
canceledAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
canceledAt DateTime?
|
||||
|
||||
@@index([userId])
|
||||
@@index([planId])
|
||||
@@ -592,21 +592,21 @@ model Subscription {
|
||||
}
|
||||
|
||||
model CreditTransaction {
|
||||
id String @id @default(uuid())
|
||||
amount Int // Pozitif: ekleme, Negatif: harcama
|
||||
type String @db.VarChar(30) // grant, usage, refund, bonus
|
||||
description String? @db.VarChar(200)
|
||||
|
||||
id String @id @default(uuid())
|
||||
amount Int // Pozitif: ekleme, Negatif: harcama
|
||||
type String @db.VarChar(30) // grant, usage, refund, bonus
|
||||
description String? @db.VarChar(200)
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
projectId String? // Hangi projede harcandı
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
projectId String? // Hangi projede harcandı
|
||||
|
||||
// Balance Snapshot
|
||||
balanceAfter Int @default(0)
|
||||
|
||||
balanceAfter Int @default(0)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([userId])
|
||||
@@index([type])
|
||||
@@ -618,43 +618,43 @@ model CreditTransaction {
|
||||
// ============================================
|
||||
|
||||
model UserPreference {
|
||||
id String @id @default(uuid())
|
||||
|
||||
id String @id @default(uuid())
|
||||
|
||||
// Defaults
|
||||
defaultLanguage String @default("tr") @db.VarChar(5)
|
||||
defaultVideoStyle String @default("CINEMATIC") @db.VarChar(50)
|
||||
defaultDuration Int @default(60)
|
||||
|
||||
defaultLanguage String @default("tr") @db.VarChar(5)
|
||||
defaultVideoStyle String @default("CINEMATIC") @db.VarChar(50)
|
||||
defaultDuration Int @default(60)
|
||||
|
||||
// UI
|
||||
theme String @default("dark") @db.VarChar(10)
|
||||
theme String @default("dark") @db.VarChar(10)
|
||||
emailNotifications Boolean @default(true)
|
||||
pushNotifications Boolean @default(true)
|
||||
|
||||
|
||||
// Relations
|
||||
userId String @unique
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
userId String @unique
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model Notification {
|
||||
id String @id @default(uuid())
|
||||
type String @db.VarChar(30) // render_complete, render_failed, credit_low, system
|
||||
title String @db.VarChar(200)
|
||||
message String? @db.Text
|
||||
isRead Boolean @default(false)
|
||||
metadata Json? // { projectId, renderJobId, ... }
|
||||
|
||||
id String @id @default(uuid())
|
||||
type String @db.VarChar(30) // render_complete, render_failed, credit_low, system
|
||||
title String @db.VarChar(200)
|
||||
message String? @db.Text
|
||||
isRead Boolean @default(false)
|
||||
metadata Json? // { projectId, renderJobId, ... }
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
readAt DateTime?
|
||||
|
||||
@@index([userId])
|
||||
@@ -667,23 +667,23 @@ model Notification {
|
||||
// ============================================
|
||||
|
||||
model YoutubeAnalysis {
|
||||
id String @id @default(uuid())
|
||||
videoUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
viewCount String? @db.VarChar(50)
|
||||
likeCount String? @db.VarChar(50)
|
||||
id String @id @default(uuid())
|
||||
videoUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
viewCount String? @db.VarChar(50)
|
||||
likeCount String? @db.VarChar(50)
|
||||
commentCount Int?
|
||||
analysisData Json // Bütün Gemini analizi burada duracak
|
||||
|
||||
analysisData Json // Bütün Gemini analizi burada duracak
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([videoId])
|
||||
@@ -694,21 +694,21 @@ model YoutubeAnalysis {
|
||||
// ============================================
|
||||
|
||||
model YoutubeSeoAnalysis {
|
||||
id String @id @default(uuid())
|
||||
videoUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
seoScore Int @default(0)
|
||||
analysisData Json // Bütün Gemini analizi (Başlık, Açıklama, Keywords, Shorts fikirleri) burada duracak
|
||||
|
||||
id String @id @default(uuid())
|
||||
videoUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
seoScore Int @default(0)
|
||||
analysisData Json // Bütün Gemini analizi (Başlık, Açıklama, Keywords, Shorts fikirleri) burada duracak
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
@@index([videoId])
|
||||
@@ -718,78 +718,82 @@ model YoutubeSeoAnalysis {
|
||||
// ============================================
|
||||
|
||||
model TubeStrategistProject {
|
||||
id String @id @default(uuid())
|
||||
name String @db.VarChar(500)
|
||||
status String @default("DRAFT") // DRAFT, ANALYZING, COMPLETED
|
||||
|
||||
// Settings
|
||||
tone String?
|
||||
duration String?
|
||||
speakerName String?
|
||||
targetAudience String?
|
||||
topicFocus String?
|
||||
formatDescription String? @db.Text
|
||||
id String @id @default(uuid())
|
||||
name String @db.VarChar(500)
|
||||
status String @default("DRAFT") // DRAFT, ANALYZING, COMPLETED
|
||||
|
||||
// Settings
|
||||
tone String?
|
||||
duration String?
|
||||
speakerName String?
|
||||
targetAudience String?
|
||||
topicFocus String?
|
||||
formatDescription String? @db.Text
|
||||
|
||||
masterAnalysis Json? // Bütün master analizi burada duracak
|
||||
communityInsights Json? // Yorum/Transkript analizinden çıkan gelecek bölüm fikirleri ve virallik skorları
|
||||
|
||||
masterAnalysis Json? // Bütün master analizi burada duracak
|
||||
|
||||
// Relations
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
videos TubeStrategistVideo[]
|
||||
episodes TubeStrategistEpisode[]
|
||||
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
videos TubeStrategistVideo[]
|
||||
episodes TubeStrategistEpisode[]
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model TubeStrategistVideo {
|
||||
id String @id @default(uuid())
|
||||
youtubeUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
|
||||
transcript String? @db.Text
|
||||
transcriptDuration Int? // in seconds
|
||||
|
||||
totalComments Int @default(0)
|
||||
mainComments Int @default(0)
|
||||
replyComments Int @default(0)
|
||||
viewCount String? @db.VarChar(50)
|
||||
likeCount String? @db.VarChar(50)
|
||||
|
||||
commentsJson Json? // Storing top comments or buckets
|
||||
tier1Analysis Json? // Individual video analysis
|
||||
|
||||
id String @id @default(uuid())
|
||||
youtubeUrl String @db.VarChar(500)
|
||||
videoId String @db.VarChar(100)
|
||||
title String? @db.VarChar(500)
|
||||
thumbnail String? @db.VarChar(500)
|
||||
|
||||
transcript String? @db.Text
|
||||
transcriptDuration Int? // in seconds
|
||||
|
||||
totalComments Int @default(0)
|
||||
mainComments Int @default(0)
|
||||
replyComments Int @default(0)
|
||||
viewCount String? @db.VarChar(50)
|
||||
likeCount String? @db.VarChar(50)
|
||||
|
||||
commentsJson Json? // Storing top comments or buckets
|
||||
tier1Analysis Json? // Individual video analysis
|
||||
|
||||
// Relations
|
||||
projectId String
|
||||
project TubeStrategistProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
projectId String
|
||||
project TubeStrategistProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([projectId])
|
||||
}
|
||||
|
||||
model TubeStrategistEpisode {
|
||||
id String @id @default(uuid())
|
||||
topic String @db.VarChar(500)
|
||||
targetAudience String? @db.VarChar(500)
|
||||
duration String? @db.VarChar(100)
|
||||
format String? @db.VarChar(100)
|
||||
|
||||
status String @default("DRAFT") // DRAFT, ANALYZING, COMPLETED
|
||||
masterAnalysis Json?
|
||||
|
||||
projectId String
|
||||
project TubeStrategistProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(uuid())
|
||||
topic String @db.VarChar(500)
|
||||
targetAudience String? @db.VarChar(500)
|
||||
duration String? @db.VarChar(100)
|
||||
format String? @db.VarChar(100)
|
||||
|
||||
status String @default("DRAFT") // DRAFT, ANALYZING, COMPLETED
|
||||
masterAnalysis Json?
|
||||
sponsorshipPitch Json? // Sponsorluk e-posta şablonları ve kitle analizleri
|
||||
thumbnailMatrix Json? // A/B Test başlıkları ve küçük resim konseptleri
|
||||
shortsConcepts Json? // Ana bölümden çıkarılmış 3-5 adet kısa içerik fikri
|
||||
|
||||
projectId String
|
||||
project TubeStrategistProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([projectId])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user