main
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled

This commit is contained in:
Harun CAN
2026-05-11 07:32:58 +02:00
parent 58832e99d1
commit 2e6c272eee
17 changed files with 1260 additions and 400 deletions
+383 -379
View File
@@ -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])
}