File size: 18,231 Bytes
333c51a
 
 
 
 
 
 
 
1eae852
333c51a
 
 
 
 
 
 
 
1eae852
 
 
 
 
 
 
 
 
 
 
 
 
3eebcd0
1eae852
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
 
1eae852
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
333c51a
 
 
 
 
 
 
 
 
3eebcd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
1eae852
 
 
333c51a
 
 
 
 
 
1eae852
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
 
 
 
333c51a
 
1eae852
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
1eae852
333c51a
 
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
 
 
 
1eae852
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
333c51a
1eae852
 
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
1eae852
333c51a
 
 
1eae852
 
333c51a
1eae852
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eae852
 
 
 
 
 
333c51a
 
1eae852
 
333c51a
 
 
3eebcd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
 
 
 
 
 
 
 
 
1eae852
 
 
 
333c51a
 
1eae852
 
 
333c51a
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

// ============================================
// MODELOS BASE
// ============================================

model User {
  id              String   @id @default(cuid())
  email           String?  @unique
  name            String?
  externalId      String?  // ID externo (Telegram chatId, etc.)
  source          String?  // "telegram", "web", "onlyfans", etc.
  tier            String   @default("free") // free, basic, premium, pro
  stripeCustomerId String?
  totalSpent      Float    @default(0)
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt

  chatSessions    ChatSession[]
  assetDeliveries AssetDelivery[]
  influencerSubscriptions InfluencerSubscription[]

  @@unique([externalId, source])
}

model Project {
  id          String     @id @default(cuid())
  name        String
  description String?
  style       String     @default("default")
  status      String     @default("active")
  createdAt   DateTime   @default(now())
  updatedAt   DateTime   @updatedAt
  repos       Repo[]
  analyses    Analysis[]
  contents    Content[]
}

model Repo {
  id        String     @id @default(cuid())
  url       String
  name      String
  status    String     @default("cloned")
  projectId String?
  project   Project?   @relation(fields: [projectId], references: [id])
  analyses  Analysis[]
  createdAt DateTime   @default(now())
  updatedAt DateTime   @updatedAt
}

model Analysis {
  id        String   @id @default(cuid())
  type      String
  result    String
  summary   String?
  repoId    String?
  repo      Repo?    @relation(fields: [repoId], references: [id])
  projectId String?
  project   Project? @relation(fields: [projectId], references: [id])
  createdAt DateTime @default(now())
}

model AgentTask {
  id          String    @id @default(cuid())
  type        String
  status      String    @default("pending")
  input       String
  output      String?
  createdAt   DateTime  @default(now())
  completedAt DateTime?
}

// ============================================
// MODELOS DE INFLUENCER (CHARACTER)
// ============================================

model Character {
  id               String     @id @default(cuid())
  name             String
  slug             String     @unique
  displayName      String?
  shortBio         String?
  description      String?
  referenceImage   String?    // Imagen can贸nica para consistencia facial
  bodyReference    String?    // Referencia corporal
  traits           String?    // JSON con rasgos de personalidad
  orientation      String?    // Orientaci贸n/estilo (mujer, hombre gay, etc.)
  styleDescription String?   // Descripci贸n visual para generaci贸n de im谩genes
  systemPrompt     String?    // Prompt base para el chat
  telegramBotToken String?    // Token del bot de Telegram espec铆fico
  // Storytelling
  backstory        String?    // Historia de fondo
  personality      String?    // Personalidad detallada
  interests        String?    // JSON array de intereses
  catchphrases     String?    // JSON array de frases t铆picas
  // Configuraci贸n de chat por tier
  chatFreeLimit    Int        @default(10)  // Mensajes gratis por d铆a
  chatBasicTone    String?    // Tono para tier basic
  chatPremiumTone  String?    // Tono para tier premium (铆ntimo)
  chatProTone      String?    // Tono para tier pro (novia IA)
  isActive         Boolean    @default(true)
  contents         Content[]
  pets             Pet[]
  chatSessions     ChatSession[]
  assetDeliveries  AssetDelivery[]
  createdAt        DateTime   @default(now())
  updatedAt        DateTime   @updatedAt
}

// ============================================
// MODELOS DE CHAT / NOVIA IA
// ============================================

model ChatSession {
  id           String        @id @default(cuid())
  userId       String
  user         User          @relation(fields: [userId], references: [id])
  characterId  String
  character    Character     @relation(fields: [characterId], references: [id])
  channel      String        @default("telegram") // telegram, web, etc.
  heatScore    Int           @default(0) // 0-100, sube con interacci贸n
  msgCountToday Int          @default(0)
  lastMessageAt DateTime?
  isActive     Boolean       @default(true)
  messages     ChatMessage[]
  createdAt    DateTime      @default(now())
  updatedAt    DateTime      @updatedAt

  @@unique([userId, characterId, channel])
}

model ChatMessage {
  id          String      @id @default(cuid())
  sessionId   String
  session     ChatSession @relation(fields: [sessionId], references: [id])
  role        String      // "user", "assistant", "system"
  content     String
  metadata    String?     // JSON (ej: si se envi贸 un asset)
  createdAt   DateTime    @default(now())
}

// ============================================
// MODELOS DE CONTENIDO MULTIMEDIA
// ============================================

model Content {
  id              String        @id @default(cuid())
  type            String        // "image", "video", "audio", "text", "reel", "story", "carousel"
  title           String
  description     String?
  prompt          String
  optimizedPrompt String?
  filePath        String?
  thumbnail       String?
  platform        String        @default("general")
  status          String        @default("pending")
  nsfwLevel       Int           @default(0) // 0=SFW, 1=suggestive, 2=NSFW, 3=explicit
  metadata        String?
  projectId       String?
  project         Project?      @relation(fields: [projectId], references: [id])
  characterId     String?
  character       Character?    @relation(fields: [characterId], references: [id])
  petId           String?
  pet             Pet?          @relation(fields: [petId], references: [id])
  censorFlags     CensorFlag[]
  posts           Post[]
  assetDeliveries AssetDelivery[]
  createdAt       DateTime      @default(now())
  updatedAt       DateTime      @updatedAt
}

// Tracking de qu茅 assets se han enviado a qu茅 usuario
model AssetDelivery {
  id          String    @id @default(cuid())
  contentId   String
  content     Content   @relation(fields: [contentId], references: [id])
  userId      String
  user        User      @relation(fields: [userId], references: [id])
  characterId String
  character   Character @relation(fields: [characterId], references: [id])
  channel     String    @default("telegram")
  deliveredAt DateTime  @default(now())

  @@unique([contentId, userId]) // No repetir el mismo asset al mismo usuario
}

// ============================================
// MODELOS DE CENSURA
// ============================================

model CensorRule {
  id         String   @id @default(cuid())
  platform   String
  category   String
  rule       String
  severity   String   @default("medium")
  autoAction String   @default("warn")
  isActive   Boolean  @default(true)
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt
}

model CensorFlag {
  id        String   @id @default(cuid())
  contentId String
  content   Content  @relation(fields: [contentId], references: [id])
  category  String
  reason    String
  severity  String
  action    String
  createdAt DateTime @default(now())
}

// ============================================
// MODELOS DE MONETIZACI脫N
// ============================================

model MonetizationPlatform {
  id              String   @id @default(cuid())
  name            String   // OnlyFans, Patreon, Fansly, etc.
  type            String   // "subscription", "tips", "ppv", "mixed"
  url             String?
  apiKey          String?
  accountId       String?
  accountName     String?
  legalTerms      String?  // JSON con t茅rminos legales
  contentRules    String?  // JSON con reglas de contenido
  feePercentage   Float?
  payoutSchedule  String?
  isActive        Boolean  @default(true)
  isVerified      Boolean  @default(false)
  metadata        String?
  posts           Post[]
  earnings        Earning[]
  subscribers     Subscriber[]
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

model Subscriber {
  id           String   @id @default(cuid())
  platformId   String
  platform     MonetizationPlatform @relation(fields: [platformId], references: [id])
  externalId   String?
  username     String?
  tier         String?
  status       String   @default("active")
  joinedAt     DateTime?
  expiresAt    DateTime?
  totalSpent   Float    @default(0)
  metadata     String?
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
}

model Earning {
  id                        String                       @id @default(cuid())
  platformId                String
  platform                  MonetizationPlatform         @relation(fields: [platformId], references: [id])
  subscriptionId            String?
  subscription              InfluencerSubscription?      @relation(fields: [subscriptionId], references: [id])
  type                      String // "subscription", "post", "tip", "ppv"
  amount                    Float
  currency                  String                       @default("USD")
  postId                    String?
  subscriberId              String?
  status                    String                       @default("pending") // pending, completed, failed
  paymentMethod             String? // "card", "bank_transfer", "paypal"
  stripePaymentIntentId     String? // Para rastrear en Stripe
  isRecurring               Boolean                      @default(false)
  description               String?
  processedAt               DateTime?
  metadata                  String?
  createdAt                 DateTime                     @default(now())
}

// ============================================
// MODELOS DE PUBLICACI脫N
// ============================================

model Post {
  id              String   @id @default(cuid())
  title           String?
  caption         String?
  hashtags        String?
  type            String
  status          String   @default("draft")
  contentId       String?
  content         Content? @relation(fields: [contentId], references: [id])
  platformId      String?
  platform        MonetizationPlatform? @relation(fields: [platformId], references: [id])
  scheduledAt     DateTime?
  publishedAt     DateTime?
  externalPostId  String?
  postUrl         String?
  engagementStats String?
  storyId         String?
  story           Story?   @relation(fields: [storyId], references: [id])
  metadata        String?
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

// ============================================
// MODELOS DE STORYTELLING
// ============================================

model Story {
  id              String      @id @default(cuid())
  title           String
  description     String?
  genre           String?
  targetAudience  String?
  tone            String?
  structure       String?
  characterIds    String?
  totalEpisodes   Int         @default(1)
  currentEpisode  Int         @default(1)
  status          String      @default("draft")
  monetizationStrategy String?
  posts           Post[]
  episodes        StoryEpisode[]
  analytics       StoryAnalytics?
  createdAt       DateTime    @default(now())
  updatedAt       DateTime    @updatedAt
}

model StoryEpisode {
  id          String   @id @default(cuid())
  storyId     String
  story       Story    @relation(fields: [storyId], references: [id])
  episodeNum  Int
  title       String
  synopsis    String?
  content     String
  hook        String?
  cliffhanger String?
  status      String   @default("draft")
  scheduledAt DateTime?
  publishedAt DateTime?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

model StoryAnalytics {
  id              String   @id @default(cuid())
  storyId         String   @unique
  story           Story    @relation(fields: [storyId], references: [id])
  totalViews      Int      @default(0)
  totalEngagement Float    @default(0)
  avgWatchTime    Float?
  completionRate  Float?
  revenue         Float    @default(0)
  subscriberGain  Int      @default(0)
  bestPerformingEpisode Int?
  metadata        String?
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

// ============================================
// MODELOS DE AUTOMATIZACI脫N
// ============================================

model Automation {
  id          String   @id @default(cuid())
  name        String
  description String?
  type        String
  trigger     String
  triggerConfig String?
  actions     String
  isActive    Boolean  @default(true)
  lastRunAt   DateTime?
  nextRunAt   DateTime?
  runCount    Int      @default(0)
  metadata    String?
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
}

model AutomationLog {
  id             String   @id @default(cuid())
  automationId   String?
  status         String
  input          String?
  output         String?
  error          String?
  duration       Int?
  createdAt      DateTime @default(now())
}

// ============================================
// MODELOS DE TENDENCIAS
// ============================================

model Trend {
  id           String   @id @default(cuid())
  platform     String
  type         String
  name         String
  description  String?
  volume       Int?
  growth       Float?
  startDate     DateTime?
  endDate       DateTime?
  relatedTags   String?
  contentIdeas  String?
  isActive      Boolean  @default(true)
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt
}

// ============================================
// MODELOS DE PLANTILLAS
// ============================================

model PromptTemplate {
  id        String   @id @default(cuid())
  name      String
  category  String
  template  String
  variables String
  platform  String   @default("general")
  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model ContentTemplate {
  id           String   @id @default(cuid())
  name         String
  type         String
  platform     String
  structure    String
  hooks        String?
  ctas         String?
  hashtags     String?
  bestTimes    String?
  isActive     Boolean  @default(true)
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
}

// ============================================
// MODELOS DE MASCOTAS/COMPA脩EROS
// ============================================

model Pet {
  id             String      @id @default(cuid())
  name           String
  type           String
  breed          String?
  description    String?
  referenceImage String?
  traits         String?
  personality    String?
  color          String?
  accessories    String?
  characterId    String?
  character      Character?  @relation(fields: [characterId], references: [id], onDelete: Cascade)
  contents       Content[]
  isActive       Boolean     @default(true)
  createdAt      DateTime    @default(now())
  updatedAt      DateTime    @updatedAt
}

// ============================================
// MODELOS DE INFLUENCERS IA DE REFERENCIA
// ============================================

model AIInfluencer {
  id                String   @id @default(cuid())
  name              String
  handle            String?
  platform          String
  followers         Int?
  engagement        Float?
  niche             String?
  style             String?
  contentTypes      String?
  postingSchedule   String?
  visualStyle       String?
  monetizationType  String?
  signatureElements String?
  petCompanion      Boolean     @default(false)
  petType           String?
  analysis          String?
  lessons           String?
  isActive          Boolean     @default(true)
  createdAt         DateTime   @default(now())
  updatedAt         DateTime   @updatedAt
  influencerSubscriptions InfluencerSubscription[]
}

// Suscripciones por influencer: cada cliente se suscribe por separado a cada influencer
model InfluencerSubscription {
  id                  String       @id @default(cuid())
  influencerId        String
  influencer          AIInfluencer @relation(fields: [influencerId], references: [id])
  userId              String?
  user                User?        @relation(fields: [userId], references: [id])
  tier                String       // tier contratado para esta suscripci贸n (basic, premium, etc.)
  status              String       @default("active") // active, paused, expired, cancelled
  joinedAt            DateTime     @default(now())
  expiresAt           DateTime?
  nextRenewalDate     DateTime?    // Pr贸xima fecha de renovaci贸n autom谩tica
  autoRenew           Boolean      @default(true) // Renovaci贸n autom谩tica activada
  price               Float?
  currency            String       @default("USD")
  // Integraci贸n con Stripe
  stripeSubscriptionId String?     // ID de suscripci贸n en Stripe
  stripeCustomerId    String?      // ID de cliente en Stripe
  paymentMethodId     String?      // ID del m茅todo de pago en Stripe
  metadata            String?
  earnings            Earning[]    // Relaci贸n con pagos registrados
  createdAt           DateTime     @default(now())
  updatedAt           DateTime     @updatedAt
}

// ============================================
// MODELOS DE ESTRATEGIAS VIRALES
// ============================================

model ViralStrategy {
  id              String   @id @default(cuid())
  name            String
  description     String?
  platform        String
  contentType     String
  hook            String?
  structure       String?
  elements        String?
  estimatedReach  Int?
  difficulty      String   @default("medium")
  timeframe       String?
  examples        String?
  tags            String?
  successRate     Float?
  isActive        Boolean  @default(true)
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}