File size: 6,208 Bytes
cc442ef
 
 
 
 
 
 
 
 
 
d9186b1
 
 
 
 
 
 
 
 
 
 
 
65aabf4
d9186b1
 
 
 
 
65aabf4
 
 
d9186b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc442ef
 
 
d9186b1
 
 
 
 
 
 
 
 
 
 
 
 
 
cc442ef
 
 
5746532
 
6c294cb
5746532
 
f0f0df4
19d10a4
 
5746532
 
 
 
 
ca816a7
d9186b1
5746532
 
 
 
 
cc442ef
5746532
d9186b1
 
 
 
 
 
 
 
 
41fe9a9
 
 
d9186b1
 
 
 
 
 
5746532
 
cc442ef
 
 
d9186b1
 
 
 
 
 
 
 
 
 
 
cc442ef
 
 
d9186b1
cc442ef
 
 
d9186b1
 
 
 
81f2ec0
cc442ef
 
 
 
d9186b1
cc442ef
d9186b1
 
abc4e24
 
d9186b1
 
 
538f814
 
cc442ef
 
d9186b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc442ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b5f6b08
 
 
 
 
 
5746532
 
 
 
 
 
 
 
 
4967196
41fe9a9
5746532
d9186b1
83c2a9a
 
 
 
 
 
 
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
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
}