| generator client { |
| provider = "prisma-client-js" |
| } |
|
|
| datasource db { |
| provider = "postgresql" |
| url = env("DATABASE_URL") |
| } |
|
|
| model User { |
| id String @id @default(uuid()) |
| phone String @unique |
| name String? |
| role Role @default(STUDENT) |
| language Language @default(FR) |
| city String? |
| activity String? |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| currentStreak Int @default(0) |
| longestStreak Int @default(0) |
| lastActivityAt DateTime? |
| businessProfile BusinessProfile? |
| enrollments Enrollment[] |
| messages Message[] |
| payments Payment[] |
| responses Response[] |
| progress UserProgress[] |
| } |
|
|
| model BusinessProfile { |
| id String @id @default(uuid()) |
| userId String @unique |
| activityLabel String? |
| activityPhrase String? |
| activityType String? |
| locationCity String? |
| mainCustomer String? |
| mainProblem String? |
| offerSimple String? |
| promise String? |
| marketData Json? |
| competitorList Json? |
| financialProjections Json? |
| fundingAsk String? |
| lastUpdatedFromDay Int @default(0) |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| teamMembers Json? |
| user User @relation(fields: [userId], references: [id]) |
| } |
|
|
| model Track { |
| id String @id @default(uuid()) |
| title String |
| description String? |
| duration Int |
| language Language @default(FR) |
| isPremium Boolean @default(false) |
| priceAmount Int? |
| stripePriceId String? |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| enrollments Enrollment[] |
| payments Payment[] |
| days TrackDay[] |
| progress UserProgress[] |
| } |
|
|
| model TrackDay { |
| id String @id @default(uuid()) |
| trackId String |
| dayNumber Float |
| title String? |
| audioUrl String? |
| imageUrl String? |
| videoUrl String? |
| videoCaption String? |
| lessonText String? |
| exerciseType ExerciseType @default(TEXT) |
| exercisePrompt String? |
| validationKeyword String? |
| buttonsJson Json? |
| exerciseCriteria Json? |
| badges Json? |
| unlockCondition String? |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| track Track @relation(fields: [trackId], references: [id]) |
| } |
|
|
| model UserProgress { |
| id String @id @default(uuid()) |
| userId String |
| trackId String |
| score Int @default(0) |
| lastInteraction DateTime @default(now()) |
| exerciseStatus ExerciseStatus @default(PENDING) |
| badges Json? |
| behavioralScoring Json? |
| confidenceScore Float? |
| adminTranscription String? |
| overrideAudioUrl String? |
| reviewedBy String? |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| iterationCount Int @default(0) |
| aiSource String? |
| track Track @relation(fields: [trackId], references: [id]) |
| user User @relation(fields: [userId], references: [id]) |
|
|
| @@unique([userId, trackId]) |
| } |
|
|
| model Enrollment { |
| id String @id @default(uuid()) |
| userId String |
| trackId String |
| status EnrollmentStatus @default(ACTIVE) |
| currentDay Float @default(1) |
| startedAt DateTime @default(now()) |
| completedAt DateTime? |
| lastActivityAt DateTime @default(now()) |
| track Track @relation(fields: [trackId], references: [id]) |
| user User @relation(fields: [userId], references: [id]) |
| responses Response[] |
| } |
|
|
| model Response { |
| id String @id @default(uuid()) |
| enrollmentId String |
| userId String |
| dayNumber Int |
| content String? |
| mediaUrl String? |
| createdAt DateTime @default(now()) |
| aiSource String? |
| enrollment Enrollment @relation(fields: [enrollmentId], references: [id], onDelete: Cascade) |
| user User @relation(fields: [userId], references: [id]) |
| } |
|
|
| model Message { |
| id String @id @default(uuid()) |
| userId String |
| direction Direction |
| channel String @default("WHATSAPP") |
| content String? |
| mediaUrl String? |
| payload Json? |
| createdAt DateTime @default(now()) |
| user User @relation(fields: [userId], references: [id]) |
|
|
| @@index([userId, createdAt]) |
| } |
|
|
| model Payment { |
| id String @id @default(uuid()) |
| userId String |
| trackId String |
| amount Int |
| currency String @default("XOF") |
| status PaymentStatus @default(PENDING) |
| stripeSessionId String? @unique |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| track Track @relation(fields: [trackId], references: [id]) |
| user User @relation(fields: [userId], references: [id]) |
| } |
|
|
| model TrainingData { |
| id String @id @default(uuid()) |
| audioUrl String |
| transcription String |
| manualCorrection String? |
| rawWER Float? |
| normalizedWER Float? |
| status TrainingStatus @default(PENDING) |
| createdAt DateTime @default(now()) |
| updatedAt DateTime @updatedAt |
| } |
|
|
| enum Role { |
| STUDENT |
| ADMIN |
| } |
|
|
| enum EnrollmentStatus { |
| ACTIVE |
| COMPLETED |
| DROPPED |
| } |
|
|
| enum Language { |
| FR |
| WOLOF |
| } |
|
|
| enum ContentType { |
| TEXT |
| AUDIO |
| IMAGE |
| VIDEO |
| } |
|
|
| enum Direction { |
| INBOUND |
| OUTBOUND |
| } |
|
|
| enum PaymentStatus { |
| PENDING |
| COMPLETED |
| FAILED |
| REFUNDED |
| } |
|
|
| enum ExerciseType { |
| TEXT |
| AUDIO |
| BUTTON |
| } |
|
|
| enum ExerciseStatus { |
| PENDING |
| PENDING_REMEDIATION |
| PENDING_REVIEW |
| COMPLETED |
| PENDING_DEEPDIVE |
| } |
|
|
| enum TrainingStatus { |
| PENDING |
| REVIEWED |
| IGNORED |
| } |
|
|