@danielcok17/prisma-db 1.19.2 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/prisma/app.prisma CHANGED
@@ -30,118 +30,113 @@ model Account {
30
30
  }
31
31
 
32
32
  model User {
33
- id String @id @default(cuid())
34
- brand String @default("smartlex") // Multi-brand: "smartlex" | "justi"
35
- name String?
36
- email String?
37
- emailVerified DateTime?
38
- image String?
33
+ id String @id @default(cuid())
34
+ brand String @default("smartlex") // Multi-brand: "smartlex" | "justi"
35
+ name String?
36
+ email String?
37
+ emailVerified DateTime?
38
+ image String?
39
39
  // Credentials authentication fields
40
- password String? // Hashed password pre credentials login
41
- createdAt DateTime @default(now())
42
- agreedToTerms Boolean @default(false)
43
- practiceArea String[]
44
- lawFirm String?
45
- yearsOfExperience Int?
40
+ password String? // Hashed password pre credentials login
41
+ createdAt DateTime @default(now())
42
+ agreedToTerms Boolean @default(false)
43
+ practiceArea String[]
44
+ lawFirm String?
45
+ yearsOfExperience Int?
46
46
  // Nové polia pre schvalovanie používateľov
47
- isApproved Boolean @default(false) // Či je používateľ schválený
48
- isRejected Boolean @default(false) // Či je používateľ zamietnutý
49
- approvedAt DateTime? // Kedy bol schválený
50
- rejectedAt DateTime? // Kedy bol zamietnutý
51
- approvedBy String? // ID admina, ktorý schválil
52
- rejectedBy String? // ID admina, ktorý zamietol
53
- rejectionReason String? // Dôvod zamietnutia
47
+ isApproved Boolean @default(false) // Či je používateľ schválený
48
+ isRejected Boolean @default(false) // Či je používateľ zamietnutý
49
+ approvedAt DateTime? // Kedy bol schválený
50
+ rejectedAt DateTime? // Kedy bol zamietnutý
51
+ approvedBy String? // ID admina, ktorý schválil
52
+ rejectedBy String? // ID admina, ktorý zamietol
53
+ rejectionReason String? // Dôvod zamietnutia
54
54
  // Nové polia pre tracking a žiadosť
55
- referralSource String? // Odkiaľ sa o nás dozvedel (Google, Facebook, LinkedIn, etc.)
56
- applicationText String? // Text žiadosti o prihlásenie
55
+ referralSource String? // Odkiaľ sa o nás dozvedel (Google, Facebook, LinkedIn, etc.)
56
+ applicationText String? // Text žiadosti o prihlásenie
57
57
  // ✨ STRIPE FIELDS (B2C - len pre individuálnych používateľov)
58
- subscriptionTier SubscriptionTier @default(FREE) // Aktuálny subscription tier (cache)
59
- messageCount Int @default(4) // Free tier default
60
- messageCountResetAt DateTime? // Kedy sa má resetovať message count
61
- adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
58
+ subscriptionTier SubscriptionTier @default(FREE) // Aktuálny subscription tier (cache)
59
+ messageCount Int @default(4) // Free tier default
60
+ messageCountResetAt DateTime? // Kedy sa má resetovať message count
61
+ adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
62
62
  // ✨ COMPANY FIELDS (pre SZČO - samostatne zárobkovo činná osoba)
63
- customerType CustomerType @default(INDIVIDUAL) // Typ zákazníka: fyzická osoba alebo SZČO
64
- companyName String? // Obchodné meno (pre SZČO)
65
- companyNumber String? // IČO (povinné pre SZČO, 8 číslic)
66
- vatNumber String? // IČ DPH (SK + 10 číslic, nepovinné)
67
- taxNumber String? // DIČ (10 číslic, nepovinné)
68
- companyStreet String? // Ulica a číslo (pre SZČO)
69
- companyCity String? // Mesto (pre SZČO)
70
- companyPostalCode String? // PSČ (pre SZČO, formát: XXX XX)
71
- companyCountry String? @default("SK") // Krajina (ISO kód, default SK)
63
+ customerType CustomerType @default(INDIVIDUAL) // Typ zákazníka: fyzická osoba alebo SZČO
64
+ companyName String? // Obchodné meno (pre SZČO)
65
+ companyNumber String? // IČO (povinné pre SZČO, 8 číslic)
66
+ vatNumber String? // IČ DPH (SK + 10 číslic, nepovinné)
67
+ taxNumber String? // DIČ (10 číslic, nepovinné)
68
+ companyStreet String? // Ulica a číslo (pre SZČO)
69
+ companyCity String? // Mesto (pre SZČO)
70
+ companyPostalCode String? // PSČ (pre SZČO, formát: XXX XX)
71
+ companyCountry String? @default("SK") // Krajina (ISO kód, default SK)
72
72
  // ✨ UTM TRACKING & ATTRIBUTION FIELDS
73
73
  // First-visit attribution (celý lifecycle)
74
- firstUtmSource String? // Prvý UTM source
75
- firstUtmMedium String? // Prvý UTM medium
76
- firstUtmCampaign String? // Prvá kampaň
77
- firstUtmContent String? // Prvý content/variant
78
- firstUtmTerm String? // Prvé keywords
79
- firstVisitAt DateTime? // Kedy prvýkrát navštívil web
74
+ firstUtmSource String? // Prvý UTM source
75
+ firstUtmMedium String? // Prvý UTM medium
76
+ firstUtmCampaign String? // Prvá kampaň
77
+ firstUtmContent String? // Prvý content/variant
78
+ firstUtmTerm String? // Prvé keywords
79
+ firstVisitAt DateTime? // Kedy prvýkrát navštívil web
80
80
  // Registration attribution
81
- registrationUtmSource String? // UTM source pri registrácii
82
- registrationUtmMedium String? // UTM medium pri registrácii
83
- registrationUtmCampaign String? // Kampaň pri registrácii
84
- registrationUtmContent String? // Content/variant pri registrácii
85
- registrationUtmTerm String? // Keywords pri registrácii
81
+ registrationUtmSource String? // UTM source pri registrácii
82
+ registrationUtmMedium String? // UTM medium pri registrácii
83
+ registrationUtmCampaign String? // Kampaň pri registrácii
84
+ registrationUtmContent String? // Content/variant pri registrácii
85
+ registrationUtmTerm String? // Keywords pri registrácii
86
86
  // Profile fields
87
- phone String? // Mobilný telefón
88
- phoneVerified DateTime? // Kedy bol telefón overený cez OTP
89
- occupation String? // Povolanie (Právnik, Účtovník, etc.)
90
- preferredLanguage String? @default("sk") // Jazyk odpovedi (sk, cs, en)
87
+ phone String? // Mobilný telefón
88
+ phoneVerified DateTime? // Kedy bol telefón overený cez OTP
89
+ occupation String? // Povolanie (Právnik, Účtovník, etc.)
90
+ preferredLanguage String? @default("sk") // Jazyk odpovedi (sk, cs, en)
91
91
  // Email Lifecycle — 360° user view
92
92
  lastActiveAt DateTime?
93
93
  lastLoginAt DateTime?
94
94
  activatedAt DateTime?
95
- lifecycleStage LifecycleStage @default(REGISTERED)
96
- lifetimeValue Int @default(0)
95
+ lifecycleStage LifecycleStage @default(REGISTERED)
96
+ lifetimeValue Int @default(0)
97
97
  lastEmailSentAt DateTime?
98
98
  lastMarketingEmailSentAt DateTime?
99
- isEmailSuppressed Boolean @default(false)
100
- referralCode String? @unique
101
- churnRiskScore Int @default(0)
99
+ isEmailSuppressed Boolean @default(false)
100
+ referralCode String? @unique
101
+ churnRiskScore Int @default(0)
102
102
  churnRiskUpdatedAt DateTime?
103
103
  // Relations
104
- approvalRequest UserApprovalRequest?
105
- stripeCustomer StripeCustomer? // ✨ B2C Stripe customer
106
- ownedOrganizations Organization[] @relation("OrganizationOwner")
107
- organizationMembers OrganizationMember[]
108
- createdInvites OrganizationInvite[] @relation("InviteCreator")
109
- accounts Account[]
110
- answers Answer[]
111
- conversations Conversation[]
112
- feedbacks Feedback[]
113
- pageViews PageView[]
114
- sessions Session[]
115
- workflowLogs WorkflowLog[]
116
- verificationTokens VerificationToken[]
117
- passwordResetTokens PasswordResetToken[]
118
- phoneOtps PhoneOtp[]
119
- canvasDocuments CanvasDocument[]
120
- canvasDocumentVersions CanvasDocumentVersion[]
104
+ approvalRequest UserApprovalRequest?
105
+ stripeCustomer StripeCustomer? // ✨ B2C Stripe customer
106
+ ownedOrganizations Organization[] @relation("OrganizationOwner")
107
+ organizationMembers OrganizationMember[]
108
+ createdInvites OrganizationInvite[] @relation("InviteCreator")
109
+ accounts Account[]
110
+ answers Answer[]
111
+ conversations Conversation[]
112
+ feedbacks Feedback[]
113
+ pageViews PageView[]
114
+ sessions Session[]
115
+ workflowLogs WorkflowLog[]
116
+ verificationTokens VerificationToken[]
117
+ passwordResetTokens PasswordResetToken[]
118
+ phoneOtps PhoneOtp[]
119
+ canvasDocuments CanvasDocument[]
120
+ canvasDocumentVersions CanvasDocumentVersion[]
121
121
  // Folder system relations
122
- ownedFolders Folder[] @relation("FolderOwner")
123
- addedFolderItems FolderItem[] @relation("FolderItemAdder")
124
- folderActivities FolderActivity[] @relation("FolderActivityUser")
125
- folderSharesReceived FolderShare[] @relation("FolderShareUser")
126
- createdFolderShares FolderShare[] @relation("FolderShareCreator")
122
+ ownedFolders Folder[] @relation("FolderOwner")
123
+ addedFolderItems FolderItem[] @relation("FolderItemAdder")
124
+ folderActivities FolderActivity[] @relation("FolderActivityUser")
125
+ folderSharesReceived FolderShare[] @relation("FolderShareUser")
126
+ createdFolderShares FolderShare[] @relation("FolderShareCreator")
127
127
  // UTM tracking relations
128
- touchPoints TouchPoint[]
129
- conversions Conversion[]
128
+ touchPoints TouchPoint[]
129
+ conversions Conversion[]
130
130
  // Ingestion pipeline
131
- ingestedDocuments IngestedDocument[]
132
- adminGrants AdminGrant[]
133
- invoiceGrants InvoiceGrant[]
134
- emailSends EmailSend[]
135
- emailConsent EmailConsent?
136
- userScore UserScore?
137
- sequenceEnrollments EmailSequenceEnrollment[]
138
- referralsSent Referral[] @relation("ReferralsSent")
139
- referralsReceived Referral[] @relation("ReferralsReceived")
140
- // Files & folders system
141
- userFiles UserFile[] @relation("UserFiles")
142
- reviewTables FileReviewTable[] @relation("UserReviewTables")
143
- filesTotalBytes BigInt @default(0)
144
- filesCount Int @default(0)
131
+ ingestedDocuments IngestedDocument[]
132
+ adminGrants AdminGrant[]
133
+ invoiceGrants InvoiceGrant[]
134
+ emailSends EmailSend[]
135
+ emailConsent EmailConsent?
136
+ userScore UserScore?
137
+ sequenceEnrollments EmailSequenceEnrollment[]
138
+ referralsSent Referral[] @relation("ReferralsSent")
139
+ referralsReceived Referral[] @relation("ReferralsReceived")
145
140
 
146
141
  // Multi-brand: compound unique allows same email across brands
147
142
  @@unique([email, brand])
@@ -202,10 +197,10 @@ model Organization {
202
197
 
203
198
  // Subscription (B2B)
204
199
  subscriptionTier SubscriptionTier @default(FREE) // Tier organizácie (cache)
205
- messageCount Int @default(0) // Spoločný pool správ pre všetkých členov
206
- messageLimit Int @default(4) // Free tier default
207
- messageCountResetAt DateTime? // Kedy sa má resetovať pool
208
- adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
200
+ messageCount Int @default(0) // Spoločný pool správ pre všetkých členov
201
+ messageLimit Int @default(4) // Free tier default
202
+ messageCountResetAt DateTime? // Kedy sa má resetovať pool
203
+ adminGrantExpiresAt DateTime? // Kedy admin grant expiruje
209
204
 
210
205
  // Settings
211
206
  isActive Boolean @default(true)
@@ -292,13 +287,12 @@ model Conversation {
292
287
  updatedAt DateTime @updatedAt
293
288
  summary String?
294
289
  messagesSinceLastSummary Int? @default(0)
295
- integrityHash String? // HMAC-SHA256 hash chain - posledný chainHash pre verifikáciu integrity
290
+ integrityHash String? // HMAC-SHA256 hash chain - posledný chainHash pre verifikáciu integrity
296
291
  // Relácie
297
292
  answers Answer[]
298
293
  user User @relation(fields: [userId], references: [id])
299
294
  workflowLogs WorkflowLog[]
300
295
  canvasDocuments CanvasDocument[]
301
- fileUsages UserFileConversation[]
302
296
 
303
297
  @@index([userId])
304
298
  @@index([createdAt])
@@ -318,8 +312,8 @@ model Answer {
318
312
  processingTime Int?
319
313
  model String?
320
314
  userId String?
321
- contentHash String? // HMAC-SHA256 hash obsahu správy (content + role + messageId)
322
- chainHash String? // Hash chain - zahŕňa predchádzajúci chainHash pre integritu sekvencie
315
+ contentHash String? // HMAC-SHA256 hash obsahu správy (content + role + messageId)
316
+ chainHash String? // Hash chain - zahŕňa predchádzajúci chainHash pre integritu sekvencie
323
317
  createdAt DateTime @default(now())
324
318
  updatedAt DateTime @updatedAt
325
319
  // Relácie
@@ -331,6 +325,7 @@ model Answer {
331
325
  WorkflowLog WorkflowLog[]
332
326
  files MessageFile[]
333
327
  canvasDocumentId String? // No FK constraint - flexible document management
328
+
334
329
  @@index([conversationId])
335
330
  @@index([messageId])
336
331
  @@index([role])
@@ -339,13 +334,13 @@ model Answer {
339
334
  }
340
335
 
341
336
  model MessageFile {
342
- id String @id @default(cuid())
343
- answerId String?
344
- fileName String
345
- fileType String
346
- base64Data String
347
- uploadedAt DateTime @default(now())
348
- answer Answer? @relation(fields: [answerId], references: [id], onDelete: Cascade)
337
+ id String @id @default(cuid())
338
+ answerId String?
339
+ fileName String
340
+ fileType String
341
+ base64Data String
342
+ uploadedAt DateTime @default(now())
343
+ answer Answer? @relation(fields: [answerId], references: [id], onDelete: Cascade)
349
344
 
350
345
  @@index([answerId])
351
346
  @@index([fileType])
@@ -852,11 +847,11 @@ enum CustomerType {
852
847
 
853
848
  // Stripe: Tier predplatného
854
849
  enum SubscriptionTier {
855
- FREE // Free tier (4 messages/month)
856
- LAWYER // Lawyer tier (1000 messages/month, €29/month, 1 user)
857
- LAWYER_PRO // Lawyer Pro tier (3000 messages/month, €49/month, 1 user) - RECOMMENDED
858
- LAW_FIRM // Law Firm tier (10000 messages/month, €129/month, up to 5 users)
859
- ENTERPRISE // Enterprise tier (unlimited messages, unlimited users, custom pricing)
850
+ FREE // Free tier (4 messages/month)
851
+ LAWYER // Lawyer tier (1000 messages/month, €29/month, 1 user)
852
+ LAWYER_PRO // Lawyer Pro tier (3000 messages/month, €49/month, 1 user) - RECOMMENDED
853
+ LAW_FIRM // Law Firm tier (10000 messages/month, €129/month, up to 5 users)
854
+ ENTERPRISE // Enterprise tier (unlimited messages, unlimited users, custom pricing)
860
855
  }
861
856
 
862
857
  // Stripe: Billing interval
@@ -895,8 +890,7 @@ enum FolderItemType {
895
890
  CONVERSATION
896
891
  CANVAS_DOCUMENT
897
892
  REFERENCE
898
- ATTACHMENT // deprecated — kept for migration of old data
899
- USER_FILE
893
+ ATTACHMENT
900
894
  }
901
895
 
902
896
  // Folder activity types (for timeline)
@@ -908,42 +902,10 @@ enum FolderActivityType {
908
902
  ITEM_ADDED
909
903
  ITEM_REMOVED
910
904
  ITEM_UPDATED
911
- ITEM_MOVED
912
905
  SHARE_ADDED
913
906
  SHARE_REMOVED
914
907
  USER_MESSAGE
915
908
  USER_NOTE
916
- FILE_INDEXED
917
- FILE_INDEX_ERROR
918
- }
919
-
920
- enum UserFileStatus {
921
- STORED
922
- QUEUED
923
- INDEXING
924
- INDEXED
925
- ERROR
926
- DELETED
927
- }
928
-
929
- enum UserFileUploadSource {
930
- FOLDER // nahraté cez UI priečinka / prípadu
931
- CHAT // nahraté z chatovej konverzácie
932
- STORAGE // nahraté priamo do "Môj archív"
933
- CANVAS // AI-vygenerovaný dokument uložený z canvas editora
934
- }
935
-
936
- enum IndexingJobStatus {
937
- QUEUED
938
- RUNNING
939
- COMPLETED
940
- FAILED
941
- }
942
-
943
- enum FolderType {
944
- PERSONAL
945
- MATTER
946
- KNOWLEDGE_BASE
947
909
  }
948
910
 
949
911
  // Folder permission levels
@@ -1071,19 +1033,81 @@ model PasswordResetToken {
1071
1033
 
1072
1034
  // Phone OTP verification (BulkGate)
1073
1035
  model PhoneOtp {
1074
- id String @id @default(cuid())
1075
- userId String
1076
- phone String
1077
- bulkgateId String @unique // OTP ID from BulkGate API response
1078
- expiresAt DateTime
1079
- createdAt DateTime @default(now())
1080
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1036
+ id String @id @default(cuid())
1037
+ userId String
1038
+ phone String
1039
+ bulkgateId String @unique // OTP ID from BulkGate API response
1040
+ expiresAt DateTime
1041
+ createdAt DateTime @default(now())
1042
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1081
1043
 
1082
1044
  @@index([userId])
1083
1045
  @@index([bulkgateId])
1084
1046
  @@index([expiresAt])
1085
1047
  }
1086
1048
 
1049
+ model MeetingSlot {
1050
+ id String @id @default(cuid())
1051
+ startsAt DateTime
1052
+ durationMinutes Int @default(30)
1053
+ status MeetingSlotStatus @default(AVAILABLE)
1054
+ holdExpiresAt DateTime?
1055
+ note String?
1056
+ createdByAdminEmail String?
1057
+ createdAt DateTime @default(now())
1058
+ updatedAt DateTime @updatedAt
1059
+
1060
+ bookings MeetingBooking[]
1061
+
1062
+ @@index([status, startsAt])
1063
+ @@index([startsAt])
1064
+ }
1065
+
1066
+ model MeetingBooking {
1067
+ id String @id @default(cuid())
1068
+ slotId String
1069
+ status MeetingBookingStatus @default(OTP_PENDING)
1070
+ name String?
1071
+ email String
1072
+ phone String
1073
+ visitorNote String?
1074
+ publicToken String @unique
1075
+ bulkgateId String? @unique
1076
+ otpExpiresAt DateTime?
1077
+ holdExpiresAt DateTime?
1078
+ phoneVerifiedAt DateTime?
1079
+ slotStartAt DateTime
1080
+ slotEndAt DateTime
1081
+ adminNote String?
1082
+ adminActionBy String?
1083
+ acceptedAt DateTime?
1084
+ declinedAt DateTime?
1085
+ canceledAt DateTime?
1086
+ completedAt DateTime?
1087
+ noShowAt DateTime?
1088
+ createdAt DateTime @default(now())
1089
+ updatedAt DateTime @updatedAt
1090
+
1091
+ slot MeetingSlot @relation(fields: [slotId], references: [id], onDelete: Cascade)
1092
+
1093
+ @@index([slotId])
1094
+ @@index([status, createdAt])
1095
+ @@index([email])
1096
+ @@index([phone])
1097
+ @@index([slotStartAt])
1098
+ }
1099
+
1100
+ model MeetingBookingSettings {
1101
+ id String @id @default("default")
1102
+ bookingEnabled Boolean @default(true)
1103
+ timezone String @default("Europe/Bratislava")
1104
+ bookingHorizonDays Int @default(30)
1105
+ minLeadHours Int @default(12)
1106
+ adminNotificationEmail String @default("info@smartlex.sk")
1107
+ createdAt DateTime @default(now())
1108
+ updatedAt DateTime @updatedAt
1109
+ }
1110
+
1087
1111
  // ============================================
1088
1112
  // INGESTION PIPELINE MODELS
1089
1113
  // ============================================
@@ -1103,7 +1127,7 @@ model IngestedDocument {
1103
1127
  references String[] // Legal references from classification
1104
1128
  chunkCount Int?
1105
1129
  embeddingCost Float? // EUR
1106
- qdrantDocId String? @unique // doc_id used in Qdrant vector payloads
1130
+ qdrantDocId String? @unique // doc_id used in Qdrant vector payloads
1107
1131
  folderId String? // Optional folder association
1108
1132
  storagePath String? // Local filesystem path (dev/staging)
1109
1133
  storageUrl String? // Cloud storage URL (prod — S3/DigitalOcean Spaces)
@@ -1127,138 +1151,6 @@ enum IngestionStatus {
1127
1151
  ERROR
1128
1152
  }
1129
1153
 
1130
- model UserFile {
1131
- id String @id @default(cuid())
1132
- userId String
1133
-
1134
- storageKey String @unique
1135
- storageUrl String?
1136
- checksumSha256 String
1137
-
1138
- fileName String
1139
- fileType String
1140
- fileSize Int
1141
- pageCount Int?
1142
- language String? @default("sk")
1143
-
1144
- status UserFileStatus @default(STORED)
1145
-
1146
- docType String?
1147
- legalArea String?
1148
- summary String?
1149
- extractedData Json?
1150
- references String[] @default([])
1151
- chunkCount Int?
1152
- qdrantDocId String? @unique
1153
- indexingCost Float?
1154
- indexedAt DateTime?
1155
- indexError String?
1156
-
1157
- tags String[] @default([])
1158
-
1159
- parentFileId String?
1160
- versionNumber Int @default(1)
1161
-
1162
- uploadSource UserFileUploadSource @default(STORAGE)
1163
- uploadContextId String? // polymorphic: folderId | conversationId | documentId | null
1164
- isAiGenerated Boolean @default(false) // true = AI vygeneroval obsah (canvas export)
1165
-
1166
- createdAt DateTime @default(now())
1167
- updatedAt DateTime @updatedAt
1168
- deletedAt DateTime?
1169
-
1170
- user User @relation("UserFiles", fields: [userId], references: [id], onDelete: Cascade)
1171
- indexingJobs FileIndexingJob[]
1172
- deadlines FileDeadline[]
1173
- parentFile UserFile? @relation("FileVersions", fields: [parentFileId], references: [id], onDelete: SetNull)
1174
- childVersions UserFile[] @relation("FileVersions")
1175
- conversationUsages UserFileConversation[]
1176
-
1177
- @@index([userId])
1178
- @@index([status])
1179
- @@index([userId, status])
1180
- @@index([userId, deletedAt])
1181
- @@index([qdrantDocId])
1182
- @@index([uploadSource])
1183
- @@index([uploadContextId])
1184
- @@index([checksumSha256])
1185
- }
1186
-
1187
- model UserFileConversation {
1188
- id String @id @default(cuid())
1189
- fileId String
1190
- conversationId String
1191
- createdAt DateTime @default(now())
1192
-
1193
- file UserFile @relation(fields: [fileId], references: [id], onDelete: Cascade)
1194
- conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
1195
-
1196
- @@unique([fileId, conversationId])
1197
- @@index([fileId])
1198
- @@index([conversationId])
1199
- }
1200
-
1201
- model FileIndexingJob {
1202
- id String @id @default(cuid())
1203
- fileId String
1204
- userId String
1205
- status IndexingJobStatus @default(QUEUED)
1206
- attempts Int @default(0)
1207
- maxAttempts Int @default(3)
1208
- errorMsg String?
1209
- startedAt DateTime?
1210
- finishedAt DateTime?
1211
- createdAt DateTime @default(now())
1212
-
1213
- file UserFile @relation(fields: [fileId], references: [id], onDelete: Cascade)
1214
-
1215
- @@index([fileId])
1216
- @@index([userId])
1217
- @@index([status])
1218
- @@index([createdAt])
1219
- }
1220
-
1221
- model FileDeadline {
1222
- id String @id @default(cuid())
1223
- fileId String
1224
- userId String
1225
- label String
1226
- deadlineAt DateTime
1227
- notifyAt DateTime?
1228
- isNotified Boolean @default(false)
1229
- isDismissed Boolean @default(false)
1230
- sourceSection String?
1231
- sourcePage Int?
1232
- createdAt DateTime @default(now())
1233
-
1234
- file UserFile @relation(fields: [fileId], references: [id], onDelete: Cascade)
1235
-
1236
- @@index([fileId])
1237
- @@index([userId])
1238
- @@index([deadlineAt])
1239
- @@index([notifyAt, isNotified])
1240
- @@index([userId, isDismissed])
1241
- }
1242
-
1243
- model FileReviewTable {
1244
- id String @id @default(cuid())
1245
- userId String
1246
- folderId String?
1247
- name String
1248
- columns Json
1249
- fileIds String[] @default([])
1250
- results Json?
1251
- status String @default("draft")
1252
- createdAt DateTime @default(now())
1253
- updatedAt DateTime @updatedAt
1254
-
1255
- user User @relation("UserReviewTables", fields: [userId], references: [id], onDelete: Cascade)
1256
-
1257
- @@index([userId])
1258
- @@index([folderId])
1259
- @@index([status])
1260
- }
1261
-
1262
1154
  enum LifecycleStage {
1263
1155
  REGISTERED
1264
1156
  ACTIVATED
@@ -1324,14 +1216,33 @@ enum ReferralStatus {
1324
1216
  }
1325
1217
 
1326
1218
  enum InvoiceGrantStatus {
1327
- PENDING // Faktúra odoslaná, čaká na platbu
1328
- PAID // Zaplatené, grant aktívny
1329
- VOID // Stornovaná (admin alebo Stripe)
1219
+ PENDING // Faktúra odoslaná, čaká na platbu
1220
+ PAID // Zaplatené, grant aktívny
1221
+ VOID // Stornovaná (admin alebo Stripe)
1330
1222
  }
1331
1223
 
1332
1224
  enum CollectionMethod {
1333
1225
  CHARGE_AUTOMATICALLY // Automatické strhnutie kartou
1334
- SEND_INVOICE // Faktúra na email (bank transfer)
1226
+ SEND_INVOICE // Faktúra na email (bank transfer)
1227
+ }
1228
+
1229
+ enum MeetingSlotStatus {
1230
+ AVAILABLE
1231
+ HELD
1232
+ BOOKED
1233
+ BLOCKED
1234
+ ARCHIVED
1235
+ }
1236
+
1237
+ enum MeetingBookingStatus {
1238
+ OTP_PENDING
1239
+ PENDING_ADMIN_REVIEW
1240
+ ACCEPTED
1241
+ DECLINED
1242
+ CANCELED
1243
+ COMPLETED
1244
+ NO_SHOW
1245
+ EXPIRED
1335
1246
  }
1336
1247
 
1337
1248
  // ============================================
@@ -1407,9 +1318,6 @@ model Folder {
1407
1318
  path String @default("/") // Materialized path: "/parentId/grandparentId/..."
1408
1319
  depth Int @default(0)
1409
1320
 
1410
- // Folder type
1411
- folderType FolderType @default(PERSONAL)
1412
-
1413
1321
  // Metadata
1414
1322
  sortOrder Int @default(0)
1415
1323
  isArchived Boolean @default(false)
@@ -1547,6 +1455,7 @@ model AdminGrant {
1547
1455
  isActive Boolean @default(true)
1548
1456
  revokedAt DateTime?
1549
1457
  revokedBy String?
1458
+ invoiceNumber String?
1550
1459
  createdAt DateTime @default(now())
1551
1460
  updatedAt DateTime @updatedAt
1552
1461
 
@@ -1562,20 +1471,20 @@ model AdminGrant {
1562
1471
  // One-off admin invoice — standalone faktúra pre špeciálne prípady (demo, trial, custom deal)
1563
1472
  // Pre recurring fakturáciu použiť StripeSubscription s collectionMethod=SEND_INVOICE
1564
1473
  model InvoiceGrant {
1565
- id String @id @default(cuid())
1566
- userId String?
1567
- organizationId String?
1568
- stripeInvoiceId String @unique
1569
- tier SubscriptionTier
1570
- durationDays Int // Na koľko dní sa aktivuje grant po platbe
1571
- amount Int // Suma v centoch (EUR)
1572
- status InvoiceGrantStatus @default(PENDING)
1573
- grantId String? // ID AdminGrantu vytvoreného po platbe
1574
- createdBy String // Admin email
1575
- notes String?
1576
- paidAt DateTime?
1577
- createdAt DateTime @default(now())
1578
- updatedAt DateTime @updatedAt
1474
+ id String @id @default(cuid())
1475
+ userId String?
1476
+ organizationId String?
1477
+ stripeInvoiceId String @unique
1478
+ tier SubscriptionTier
1479
+ durationDays Int // Na koľko dní sa aktivuje grant po platbe
1480
+ amount Int // Suma v centoch (EUR)
1481
+ status InvoiceGrantStatus @default(PENDING)
1482
+ grantId String? // ID AdminGrantu vytvoreného po platbe
1483
+ createdBy String // Admin email
1484
+ notes String?
1485
+ paidAt DateTime?
1486
+ createdAt DateTime @default(now())
1487
+ updatedAt DateTime @updatedAt
1579
1488
 
1580
1489
  user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
1581
1490
  organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@ -1613,39 +1522,39 @@ model AppInvite {
1613
1522
  // ============================================
1614
1523
 
1615
1524
  model EmailSend {
1616
- id String @id @default(cuid())
1617
- userId String?
1618
- templateSlug String
1619
- campaignId String?
1620
-
1621
- status EmailStatus @default(QUEUED)
1622
- sentAt DateTime?
1623
- deliveredAt DateTime?
1624
- toEmail String
1625
- fromEmail String @default("info@mail.smartlex.sk")
1626
-
1627
- openedAt DateTime?
1628
- openCount Int @default(0)
1629
- clickedAt DateTime?
1630
- clickCount Int @default(0)
1631
-
1632
- bouncedAt DateTime?
1633
- bounceType BounceType?
1634
- complainedAt DateTime?
1635
- unsubscribedAt DateTime?
1636
-
1637
- errorMessage String?
1638
- errorCode String?
1525
+ id String @id @default(cuid())
1526
+ userId String?
1527
+ templateSlug String
1528
+ campaignId String?
1529
+
1530
+ status EmailStatus @default(QUEUED)
1531
+ sentAt DateTime?
1532
+ deliveredAt DateTime?
1533
+ toEmail String
1534
+ fromEmail String @default("info@mail.smartlex.sk")
1535
+
1536
+ openedAt DateTime?
1537
+ openCount Int @default(0)
1538
+ clickedAt DateTime?
1539
+ clickCount Int @default(0)
1540
+
1541
+ bouncedAt DateTime?
1542
+ bounceType BounceType?
1543
+ complainedAt DateTime?
1544
+ unsubscribedAt DateTime?
1545
+
1546
+ errorMessage String?
1547
+ errorCode String?
1548
+
1549
+ subjectLine String?
1550
+ espMessageId String? @unique
1551
+ idempotencyKey String? @unique
1552
+ isTransactional Boolean @default(false)
1553
+ metadata Json?
1639
1554
 
1640
- subjectLine String?
1641
- espMessageId String? @unique
1642
- idempotencyKey String? @unique
1643
- isTransactional Boolean @default(false)
1644
- metadata Json?
1645
-
1646
- createdAt DateTime @default(now())
1555
+ createdAt DateTime @default(now())
1647
1556
 
1648
- user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
1557
+ user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
1649
1558
 
1650
1559
  @@index([userId])
1651
1560
  @@index([templateSlug])
@@ -1659,43 +1568,43 @@ model EmailSend {
1659
1568
  }
1660
1569
 
1661
1570
  model EmailSequence {
1662
- id String @id @default(cuid())
1663
- slug String @unique
1664
- name String
1665
- description String?
1666
- triggerEvent String
1667
- isActive Boolean @default(true)
1571
+ id String @id @default(cuid())
1572
+ slug String @unique
1573
+ name String
1574
+ description String?
1575
+ triggerEvent String
1576
+ isActive Boolean @default(true)
1668
1577
 
1669
- steps EmailSequenceStep[]
1670
- enrollments EmailSequenceEnrollment[]
1578
+ steps EmailSequenceStep[]
1579
+ enrollments EmailSequenceEnrollment[]
1671
1580
 
1672
- createdAt DateTime @default(now())
1673
- updatedAt DateTime @updatedAt
1581
+ createdAt DateTime @default(now())
1582
+ updatedAt DateTime @updatedAt
1674
1583
  }
1675
1584
 
1676
1585
  model EmailSequenceStep {
1677
- id String @id @default(cuid())
1586
+ id String @id @default(cuid())
1678
1587
  sequenceId String
1679
1588
  templateSlug String
1680
1589
  stepOrder Int
1681
- delayMinutes Int @default(0)
1590
+ delayMinutes Int @default(0)
1682
1591
  sendCondition Json?
1683
1592
  skipCondition Json?
1684
- isActive Boolean @default(true)
1593
+ isActive Boolean @default(true)
1685
1594
 
1686
- sequence EmailSequence @relation(fields: [sequenceId], references: [id], onDelete: Cascade)
1595
+ sequence EmailSequence @relation(fields: [sequenceId], references: [id], onDelete: Cascade)
1687
1596
 
1688
- createdAt DateTime @default(now())
1597
+ createdAt DateTime @default(now())
1689
1598
 
1690
1599
  @@unique([sequenceId, stepOrder])
1691
1600
  }
1692
1601
 
1693
1602
  model EmailSequenceEnrollment {
1694
- id String @id @default(cuid())
1695
- userId String
1696
- sequenceId String
1697
- currentStep Int @default(0)
1698
- status EnrollmentStatus @default(ACTIVE)
1603
+ id String @id @default(cuid())
1604
+ userId String
1605
+ sequenceId String
1606
+ currentStep Int @default(0)
1607
+ status EnrollmentStatus @default(ACTIVE)
1699
1608
 
1700
1609
  enrolledAt DateTime @default(now())
1701
1610
  completedAt DateTime?
@@ -1704,51 +1613,51 @@ model EmailSequenceEnrollment {
1704
1613
  nextSendAt DateTime?
1705
1614
  processingLockedAt DateTime?
1706
1615
 
1707
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1708
- sequence EmailSequence @relation(fields: [sequenceId], references: [id])
1616
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1617
+ sequence EmailSequence @relation(fields: [sequenceId], references: [id])
1709
1618
 
1710
1619
  @@index([status, nextSendAt])
1711
1620
  @@index([userId, sequenceId, status])
1712
1621
  }
1713
1622
 
1714
1623
  model EmailConsent {
1715
- id String @id @default(cuid())
1716
- userId String @unique
1624
+ id String @id @default(cuid())
1625
+ userId String @unique
1717
1626
 
1718
- marketingConsent Boolean @default(false)
1719
- productUpdatesConsent Boolean @default(false)
1720
- legalNewsConsent Boolean @default(false)
1627
+ marketingConsent Boolean @default(false)
1628
+ productUpdatesConsent Boolean @default(false)
1629
+ legalNewsConsent Boolean @default(false)
1721
1630
 
1722
- doubleOptinSentAt DateTime?
1723
- doubleOptinConfirmedAt DateTime?
1724
- doubleOptinToken String? @unique
1631
+ doubleOptinSentAt DateTime?
1632
+ doubleOptinConfirmedAt DateTime?
1633
+ doubleOptinToken String? @unique
1725
1634
 
1726
- user User @relation(fields: [userId], references: [id], onDelete: Restrict)
1727
- history EmailConsentHistory[]
1635
+ user User @relation(fields: [userId], references: [id], onDelete: Restrict)
1636
+ history EmailConsentHistory[]
1728
1637
 
1729
- createdAt DateTime @default(now())
1730
- updatedAt DateTime @updatedAt
1638
+ createdAt DateTime @default(now())
1639
+ updatedAt DateTime @updatedAt
1731
1640
  }
1732
1641
 
1733
1642
  model EmailConsentHistory {
1734
- id String @id @default(cuid())
1735
- consentId String
1736
- userId String
1643
+ id String @id @default(cuid())
1644
+ consentId String
1645
+ userId String
1737
1646
 
1738
- action ConsentAction
1739
- channel String
1740
- oldValue Boolean?
1741
- newValue Boolean
1647
+ action ConsentAction
1648
+ channel String
1649
+ oldValue Boolean?
1650
+ newValue Boolean
1742
1651
 
1743
- consentText String
1744
- consentVersion String
1745
- consentMethod String
1746
- ipAddress String?
1747
- userAgent String?
1652
+ consentText String
1653
+ consentVersion String
1654
+ consentMethod String
1655
+ ipAddress String?
1656
+ userAgent String?
1748
1657
 
1749
- consent EmailConsent @relation(fields: [consentId], references: [id], onDelete: Restrict)
1658
+ consent EmailConsent @relation(fields: [consentId], references: [id], onDelete: Restrict)
1750
1659
 
1751
- createdAt DateTime @default(now())
1660
+ createdAt DateTime @default(now())
1752
1661
 
1753
1662
  @@index([userId, createdAt])
1754
1663
  @@index([consentId])
@@ -1756,25 +1665,25 @@ model EmailConsentHistory {
1756
1665
  }
1757
1666
 
1758
1667
  model UserScore {
1759
- id String @id @default(cuid())
1760
- userId String @unique
1761
- score Int @default(0)
1762
- leadSegment LeadSegment @default(COLD)
1763
- churnRisk ChurnRisk @default(NONE)
1668
+ id String @id @default(cuid())
1669
+ userId String @unique
1670
+ score Int @default(0)
1671
+ leadSegment LeadSegment @default(COLD)
1672
+ churnRisk ChurnRisk @default(NONE)
1764
1673
 
1765
- signupScore Int @default(0)
1766
- engagementScore Int @default(0)
1767
- usageScore Int @default(0)
1768
- intentScore Int @default(0)
1769
- decayScore Int @default(0)
1674
+ signupScore Int @default(0)
1675
+ engagementScore Int @default(0)
1676
+ usageScore Int @default(0)
1677
+ intentScore Int @default(0)
1678
+ decayScore Int @default(0)
1770
1679
 
1771
- lastActivityAt DateTime?
1772
- scoreUpdatedAt DateTime @default(now())
1680
+ lastActivityAt DateTime?
1681
+ scoreUpdatedAt DateTime @default(now())
1773
1682
 
1774
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1775
- events UserScoreEvent[]
1683
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1684
+ events UserScoreEvent[]
1776
1685
 
1777
- createdAt DateTime @default(now())
1686
+ createdAt DateTime @default(now())
1778
1687
 
1779
1688
  @@index([score])
1780
1689
  @@index([leadSegment])
@@ -1782,18 +1691,18 @@ model UserScore {
1782
1691
  }
1783
1692
 
1784
1693
  model UserScoreEvent {
1785
- id String @id @default(cuid())
1786
- userScoreId String
1787
- userId String
1788
- eventType String
1789
- pointsDelta Int
1790
- scoreBefore Int
1791
- scoreAfter Int
1792
- metadata Json?
1694
+ id String @id @default(cuid())
1695
+ userScoreId String
1696
+ userId String
1697
+ eventType String
1698
+ pointsDelta Int
1699
+ scoreBefore Int
1700
+ scoreAfter Int
1701
+ metadata Json?
1793
1702
 
1794
- userScore UserScore @relation(fields: [userScoreId], references: [id], onDelete: Cascade)
1703
+ userScore UserScore @relation(fields: [userScoreId], references: [id], onDelete: Cascade)
1795
1704
 
1796
- createdAt DateTime @default(now())
1705
+ createdAt DateTime @default(now())
1797
1706
 
1798
1707
  @@index([userId, createdAt])
1799
1708
  @@index([userScoreId])
@@ -1802,35 +1711,35 @@ model UserScoreEvent {
1802
1711
  }
1803
1712
 
1804
1713
  model EmailSuppression {
1805
- id String @id @default(cuid())
1806
- email String
1807
- reason SuppressionReason
1808
- source String?
1714
+ id String @id @default(cuid())
1715
+ email String
1716
+ reason SuppressionReason
1717
+ source String?
1809
1718
 
1810
- suppressedAt DateTime @default(now())
1719
+ suppressedAt DateTime @default(now())
1811
1720
 
1812
1721
  @@unique([email, reason])
1813
1722
  @@index([email])
1814
1723
  }
1815
1724
 
1816
1725
  model Referral {
1817
- id String @id @default(cuid())
1818
- referrerId String?
1819
- referredUserId String?
1820
- referredEmail String?
1821
- status ReferralStatus @default(PENDING)
1822
- referralCode String @unique
1823
-
1824
- rewardType String?
1825
- rewardedAt DateTime?
1826
- clickCount Int @default(0)
1827
- registeredAt DateTime?
1828
- convertedAt DateTime?
1829
-
1830
- createdAt DateTime @default(now())
1831
-
1832
- referrer User? @relation("ReferralsSent", fields: [referrerId], references: [id], onDelete: SetNull)
1833
- referredUser User? @relation("ReferralsReceived", fields: [referredUserId], references: [id], onDelete: SetNull)
1726
+ id String @id @default(cuid())
1727
+ referrerId String?
1728
+ referredUserId String?
1729
+ referredEmail String?
1730
+ status ReferralStatus @default(PENDING)
1731
+ referralCode String @unique
1732
+
1733
+ rewardType String?
1734
+ rewardedAt DateTime?
1735
+ clickCount Int @default(0)
1736
+ registeredAt DateTime?
1737
+ convertedAt DateTime?
1738
+
1739
+ createdAt DateTime @default(now())
1740
+
1741
+ referrer User? @relation("ReferralsSent", fields: [referrerId], references: [id], onDelete: SetNull)
1742
+ referredUser User? @relation("ReferralsReceived", fields: [referredUserId], references: [id], onDelete: SetNull)
1834
1743
 
1835
1744
  @@index([referrerId])
1836
1745
  @@index([referredUserId])