create-crm-tmp 1.0.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.
Files changed (187) hide show
  1. package/bin/create-crm-tmp.js +93 -0
  2. package/package.json +25 -0
  3. package/template/.prettierignore +33 -0
  4. package/template/.prettierrc.json +25 -0
  5. package/template/README.md +173 -0
  6. package/template/eslint.config.mjs +18 -0
  7. package/template/exemple-contacts.csv +11 -0
  8. package/template/next.config.ts +8 -0
  9. package/template/package.json +64 -0
  10. package/template/postcss.config.mjs +7 -0
  11. package/template/prisma/migrations/20251126144728_init/migration.sql +78 -0
  12. package/template/prisma/migrations/20251126155204_add_user_roles/migration.sql +5 -0
  13. package/template/prisma/migrations/20251128095126_add_company_info/migration.sql +19 -0
  14. package/template/prisma/migrations/20251128123321_add_smtp_config/migration.sql +22 -0
  15. package/template/prisma/migrations/20251128132303_add_status/migration.sql +23 -0
  16. package/template/prisma/migrations/20251201102207_add_user_active/migration.sql +75 -0
  17. package/template/prisma/migrations/20251201105507_add_email_signature/migration.sql +2 -0
  18. package/template/prisma/migrations/20251201151122_add_tasks/migration.sql +45 -0
  19. package/template/prisma/migrations/20251202111854_add_task_reminder/migration.sql +2 -0
  20. package/template/prisma/migrations/20251202135859_add_google_meet_integration/migration.sql +27 -0
  21. package/template/prisma/migrations/20251203103317_add_meta_lead_integration/migration.sql +20 -0
  22. package/template/prisma/migrations/20251203104002_add_google_ads_integration/migration.sql +18 -0
  23. package/template/prisma/migrations/20251203112122_add_google_sheet_integration/migration.sql +32 -0
  24. package/template/prisma/migrations/20251203153853_allow_multiple_integration_configs/migration.sql +20 -0
  25. package/template/prisma/migrations/20251205141705_update_user_roles/migration.sql +12 -0
  26. package/template/prisma/migrations/20251205150000_add_commercial_and_telepro_assignment/migration.sql +21 -0
  27. package/template/prisma/migrations/20251205160000_add_interaction_logging/migration.sql +11 -0
  28. package/template/prisma/migrations/20251208090314_add_automatic_interaction_types/migration.sql +12 -0
  29. package/template/prisma/migrations/20251208094843_mg/migration.sql +14 -0
  30. package/template/prisma/migrations/20251208100000_add_company_support/migration.sql +14 -0
  31. package/template/prisma/migrations/20251208110000_add_templates/migration.sql +26 -0
  32. package/template/prisma/migrations/20251208141304_add_video_conference_task_type/migration.sql +2 -0
  33. package/template/prisma/migrations/20251209104759_add_internal_note_to_task/migration.sql +2 -0
  34. package/template/prisma/migrations/20251209134803_add_company_field/migration.sql +2 -0
  35. package/template/prisma/migrations/20251209150000_rename_company_to_company_name/migration.sql +3 -0
  36. package/template/prisma/migrations/20251209150016_add_email_tracking/migration.sql +21 -0
  37. package/template/prisma/migrations/20251209155908_add_notify_contact_to_task/migration.sql +2 -0
  38. package/template/prisma/migrations/20251210110019_add_appointment_types/migration.sql +10 -0
  39. package/template/prisma/migrations/20251210113928_add_contact_files/migration.sql +26 -0
  40. package/template/prisma/migrations/20251212132339_add_custom_roles/migration.sql +24 -0
  41. package/template/prisma/migrations/20251215104448_add_file_interaction_types/migration.sql +11 -0
  42. package/template/prisma/migrations/20251215145616_add_closing_reasons/migration.sql +12 -0
  43. package/template/prisma/migrations/20251216140850_add_log_users/migration.sql +25 -0
  44. package/template/prisma/migrations/20251216151000_rename_perdu_to_ferme/migration.sql +8 -0
  45. package/template/prisma/migrations/20251216162318_add_column_mappings_to_google_sheet/migration.sql +2 -0
  46. package/template/prisma/migrations/20251216185127_add_workflows/migration.sql +80 -0
  47. package/template/prisma/migrations/20251216192237_add_scheduled_workflow_actions/migration.sql +32 -0
  48. package/template/prisma/migrations/migration_lock.toml +3 -0
  49. package/template/prisma/schema.prisma +582 -0
  50. package/template/prisma.config.ts +14 -0
  51. package/template/src/app/(auth)/invite/[token]/page.tsx +200 -0
  52. package/template/src/app/(auth)/layout.tsx +3 -0
  53. package/template/src/app/(auth)/reset-password/complete/page.tsx +213 -0
  54. package/template/src/app/(auth)/reset-password/page.tsx +146 -0
  55. package/template/src/app/(auth)/reset-password/verify/page.tsx +183 -0
  56. package/template/src/app/(auth)/signin/page.tsx +166 -0
  57. package/template/src/app/(dashboard)/agenda/page.tsx +3051 -0
  58. package/template/src/app/(dashboard)/automatisation/[id]/page.tsx +24 -0
  59. package/template/src/app/(dashboard)/automatisation/_components/workflow-editor.tsx +905 -0
  60. package/template/src/app/(dashboard)/automatisation/new/page.tsx +20 -0
  61. package/template/src/app/(dashboard)/automatisation/page.tsx +337 -0
  62. package/template/src/app/(dashboard)/closing/page.tsx +1052 -0
  63. package/template/src/app/(dashboard)/contacts/[id]/page.tsx +6028 -0
  64. package/template/src/app/(dashboard)/contacts/page.tsx +3713 -0
  65. package/template/src/app/(dashboard)/dashboard/page.tsx +186 -0
  66. package/template/src/app/(dashboard)/layout.tsx +30 -0
  67. package/template/src/app/(dashboard)/settings/page.tsx +4070 -0
  68. package/template/src/app/(dashboard)/templates/page.tsx +567 -0
  69. package/template/src/app/(dashboard)/users/list/page.tsx +507 -0
  70. package/template/src/app/(dashboard)/users/page.tsx +457 -0
  71. package/template/src/app/(dashboard)/users/permissions/page.tsx +181 -0
  72. package/template/src/app/(dashboard)/users/roles/page.tsx +434 -0
  73. package/template/src/app/api/audit-logs/route.ts +57 -0
  74. package/template/src/app/api/auth/[...all]/route.ts +4 -0
  75. package/template/src/app/api/auth/check-active/route.ts +31 -0
  76. package/template/src/app/api/auth/google/callback/route.ts +94 -0
  77. package/template/src/app/api/auth/google/disconnect/route.ts +32 -0
  78. package/template/src/app/api/auth/google/route.ts +34 -0
  79. package/template/src/app/api/auth/google/status/route.ts +32 -0
  80. package/template/src/app/api/closing-reasons/route.ts +27 -0
  81. package/template/src/app/api/contacts/[id]/files/[fileId]/route.ts +94 -0
  82. package/template/src/app/api/contacts/[id]/files/route.ts +269 -0
  83. package/template/src/app/api/contacts/[id]/interactions/[interactionId]/route.ts +91 -0
  84. package/template/src/app/api/contacts/[id]/interactions/route.ts +103 -0
  85. package/template/src/app/api/contacts/[id]/meet/route.ts +296 -0
  86. package/template/src/app/api/contacts/[id]/route.ts +322 -0
  87. package/template/src/app/api/contacts/[id]/send-email/route.ts +254 -0
  88. package/template/src/app/api/contacts/export/route.ts +270 -0
  89. package/template/src/app/api/contacts/import/route.ts +381 -0
  90. package/template/src/app/api/contacts/route.ts +283 -0
  91. package/template/src/app/api/dashboard/stats/route.ts +299 -0
  92. package/template/src/app/api/email/track/[id]/route.ts +68 -0
  93. package/template/src/app/api/integrations/google-sheet/sync/route.ts +526 -0
  94. package/template/src/app/api/invite/complete/route.ts +88 -0
  95. package/template/src/app/api/invite/validate/route.ts +55 -0
  96. package/template/src/app/api/reminders/route.ts +95 -0
  97. package/template/src/app/api/reset-password/complete/route.ts +73 -0
  98. package/template/src/app/api/reset-password/request/route.ts +84 -0
  99. package/template/src/app/api/reset-password/validate/route.ts +49 -0
  100. package/template/src/app/api/reset-password/verify/route.ts +74 -0
  101. package/template/src/app/api/roles/[id]/route.ts +183 -0
  102. package/template/src/app/api/roles/route.ts +140 -0
  103. package/template/src/app/api/send/route.ts +282 -0
  104. package/template/src/app/api/settings/change-password/route.ts +95 -0
  105. package/template/src/app/api/settings/closing-reasons/[id]/route.ts +84 -0
  106. package/template/src/app/api/settings/closing-reasons/route.ts +74 -0
  107. package/template/src/app/api/settings/company/route.ts +121 -0
  108. package/template/src/app/api/settings/google-ads/[id]/route.ts +117 -0
  109. package/template/src/app/api/settings/google-ads/route.ts +122 -0
  110. package/template/src/app/api/settings/google-sheet/[id]/route.ts +230 -0
  111. package/template/src/app/api/settings/google-sheet/auto-map/route.ts +196 -0
  112. package/template/src/app/api/settings/google-sheet/route.ts +254 -0
  113. package/template/src/app/api/settings/meta-leads/[id]/route.ts +123 -0
  114. package/template/src/app/api/settings/meta-leads/route.ts +132 -0
  115. package/template/src/app/api/settings/profile/route.ts +42 -0
  116. package/template/src/app/api/settings/smtp/route.ts +130 -0
  117. package/template/src/app/api/settings/smtp/test/route.ts +121 -0
  118. package/template/src/app/api/settings/statuses/[id]/route.ts +101 -0
  119. package/template/src/app/api/settings/statuses/route.ts +83 -0
  120. package/template/src/app/api/statuses/route.ts +25 -0
  121. package/template/src/app/api/tasks/[id]/attendees/route.ts +76 -0
  122. package/template/src/app/api/tasks/[id]/route.ts +728 -0
  123. package/template/src/app/api/tasks/meet/route.ts +240 -0
  124. package/template/src/app/api/tasks/route.ts +417 -0
  125. package/template/src/app/api/templates/[id]/route.ts +140 -0
  126. package/template/src/app/api/templates/route.ts +91 -0
  127. package/template/src/app/api/users/[id]/route.ts +168 -0
  128. package/template/src/app/api/users/list/route.ts +45 -0
  129. package/template/src/app/api/users/me/route.ts +48 -0
  130. package/template/src/app/api/users/route.ts +250 -0
  131. package/template/src/app/api/webhooks/google-ads/route.ts +208 -0
  132. package/template/src/app/api/webhooks/meta-leads/route.ts +258 -0
  133. package/template/src/app/api/workflows/[id]/route.ts +192 -0
  134. package/template/src/app/api/workflows/process/route.ts +293 -0
  135. package/template/src/app/api/workflows/route.ts +124 -0
  136. package/template/src/app/favicon.ico +0 -0
  137. package/template/src/app/globals.css +1416 -0
  138. package/template/src/app/layout.tsx +31 -0
  139. package/template/src/app/page.tsx +32 -0
  140. package/template/src/components/dashboard/activity-chart.tsx +67 -0
  141. package/template/src/components/dashboard/contacts-chart.tsx +63 -0
  142. package/template/src/components/dashboard/recent-activity.tsx +164 -0
  143. package/template/src/components/dashboard/sales-analytics-chart.tsx +81 -0
  144. package/template/src/components/dashboard/stat-card.tsx +61 -0
  145. package/template/src/components/dashboard/status-distribution-chart.tsx +45 -0
  146. package/template/src/components/dashboard/tasks-pie-chart.tsx +88 -0
  147. package/template/src/components/dashboard/top-contacts-list.tsx +129 -0
  148. package/template/src/components/dashboard/upcoming-tasks-list.tsx +126 -0
  149. package/template/src/components/editor.tsx +856 -0
  150. package/template/src/components/email-template.tsx +35 -0
  151. package/template/src/components/header.tsx +320 -0
  152. package/template/src/components/invitation-email-template.tsx +79 -0
  153. package/template/src/components/meet-cancellation-email-template.tsx +120 -0
  154. package/template/src/components/meet-confirmation-email-template.tsx +156 -0
  155. package/template/src/components/meet-update-email-template.tsx +209 -0
  156. package/template/src/components/page-header.tsx +61 -0
  157. package/template/src/components/reset-password-email-template.tsx +79 -0
  158. package/template/src/components/sidebar.tsx +294 -0
  159. package/template/src/components/skeleton.tsx +380 -0
  160. package/template/src/components/ui/commands.tsx +396 -0
  161. package/template/src/components/ui/components.tsx +150 -0
  162. package/template/src/components/ui/theme.tsx +5 -0
  163. package/template/src/components/view-as-banner.tsx +45 -0
  164. package/template/src/components/view-as-modal.tsx +186 -0
  165. package/template/src/contexts/mobile-menu-context.tsx +31 -0
  166. package/template/src/contexts/sidebar-context.tsx +107 -0
  167. package/template/src/contexts/task-reminder-context.tsx +239 -0
  168. package/template/src/contexts/view-as-context.tsx +84 -0
  169. package/template/src/hooks/use-user-role.ts +82 -0
  170. package/template/src/lib/audit-log.ts +45 -0
  171. package/template/src/lib/auth-client.ts +16 -0
  172. package/template/src/lib/auth.ts +35 -0
  173. package/template/src/lib/check-permission.ts +193 -0
  174. package/template/src/lib/contact-duplicate.ts +112 -0
  175. package/template/src/lib/contact-interactions.ts +371 -0
  176. package/template/src/lib/encryption.ts +99 -0
  177. package/template/src/lib/google-calendar.ts +300 -0
  178. package/template/src/lib/google-drive.ts +372 -0
  179. package/template/src/lib/permissions.ts +412 -0
  180. package/template/src/lib/prisma.ts +32 -0
  181. package/template/src/lib/roles.ts +120 -0
  182. package/template/src/lib/template-variables.ts +76 -0
  183. package/template/src/lib/utils.ts +46 -0
  184. package/template/src/lib/workflow-executor.ts +482 -0
  185. package/template/src/proxy.ts +91 -0
  186. package/template/tsconfig.json +34 -0
  187. package/template/vercel.json +8 -0
@@ -0,0 +1,32 @@
1
+ -- CreateTable
2
+ CREATE TABLE "scheduled_workflow_action" (
3
+ "id" TEXT NOT NULL,
4
+ "workflowId" TEXT NOT NULL,
5
+ "actionId" TEXT,
6
+ "contactId" TEXT NOT NULL,
7
+ "actionType" TEXT NOT NULL,
8
+ "actionData" JSONB NOT NULL,
9
+ "executeAt" TIMESTAMP(3) NOT NULL,
10
+ "executed" BOOLEAN NOT NULL DEFAULT false,
11
+ "executedAt" TIMESTAMP(3),
12
+ "error" TEXT,
13
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
14
+ "updatedAt" TIMESTAMP(3) NOT NULL,
15
+
16
+ CONSTRAINT "scheduled_workflow_action_pkey" PRIMARY KEY ("id")
17
+ );
18
+
19
+ -- CreateIndex
20
+ CREATE INDEX "scheduled_workflow_action_executeAt_executed_idx" ON "scheduled_workflow_action"("executeAt", "executed");
21
+
22
+ -- CreateIndex
23
+ CREATE INDEX "scheduled_workflow_action_contactId_idx" ON "scheduled_workflow_action"("contactId");
24
+
25
+ -- CreateIndex
26
+ CREATE INDEX "scheduled_workflow_action_workflowId_idx" ON "scheduled_workflow_action"("workflowId");
27
+
28
+ -- AddForeignKey
29
+ ALTER TABLE "scheduled_workflow_action" ADD CONSTRAINT "scheduled_workflow_action_workflowId_fkey" FOREIGN KEY ("workflowId") REFERENCES "workflow"("id") ON DELETE CASCADE ON UPDATE CASCADE;
30
+
31
+ -- AddForeignKey
32
+ ALTER TABLE "scheduled_workflow_action" ADD CONSTRAINT "scheduled_workflow_action_contactId_fkey" FOREIGN KEY ("contactId") REFERENCES "contact"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"
@@ -0,0 +1,582 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
5
+ // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
6
+
7
+ generator client {
8
+ provider = "prisma-client"
9
+ output = "../generated/prisma"
10
+ }
11
+
12
+ datasource db {
13
+ provider = "postgresql"
14
+ }
15
+
16
+ enum Role {
17
+ USER
18
+ ADMIN
19
+ MANAGER
20
+ COMMERCIAL
21
+ TELEPRO
22
+ COMPTABLE
23
+ }
24
+
25
+ model CustomRole {
26
+ id String @id @default(cuid())
27
+ name String @unique
28
+ description String?
29
+ permissions Json // Tableau de codes de permissions
30
+ isSystem Boolean @default(false) // Profils système non modifiables
31
+ createdAt DateTime @default(now())
32
+ updatedAt DateTime @updatedAt
33
+ users User[]
34
+
35
+ @@map("custom_role")
36
+ }
37
+
38
+ model User {
39
+ id String @id
40
+ name String
41
+ email String
42
+ emailVerified Boolean @default(false)
43
+ active Boolean @default(true)
44
+ image String?
45
+ role Role @default(USER)
46
+ customRoleId String? // Profil personnalisé optionnel
47
+ customRole CustomRole? @relation(fields: [customRoleId], references: [id], onDelete: SetNull)
48
+ createdAt DateTime @default(now())
49
+ updatedAt DateTime @updatedAt
50
+ sessions Session[]
51
+ accounts Account[]
52
+ smtpConfig SmtpConfig?
53
+ contactsCreated Contact[] @relation("ContactCreatedBy")
54
+ contactsAssignedAsCommercial Contact[] @relation("ContactAssignedCommercial")
55
+ contactsAssignedAsTelepro Contact[] @relation("ContactAssignedTelepro")
56
+ interactions Interaction[]
57
+ tasksAssigned Task[] @relation("TaskAssignedTo")
58
+ tasksCreated Task[] @relation("TaskCreatedBy")
59
+ googleAccount UserGoogleAccount?
60
+ metaLeadConfigs MetaLeadConfig[]
61
+ googleAdsLeadConfigs GoogleAdsLeadConfig[]
62
+ googleSheetSyncConfigsOwned GoogleSheetSyncConfig[] @relation("GoogleSheetOwner")
63
+ googleSheetSyncConfigsAssigned GoogleSheetSyncConfig[] @relation("GoogleSheetAssignedUser")
64
+ templates Template[] @relation("TemplateCreatedBy")
65
+ filesUploaded ContactFile[] @relation("ContactFileUploadedBy")
66
+ auditLogsAsActor AuditLog[] @relation("AuditActor")
67
+ auditLogsAsTargetUser AuditLog[] @relation("AuditTargetUser")
68
+ workflows Workflow[] @relation("WorkflowOwner")
69
+
70
+ @@unique([email])
71
+ @@index([customRoleId])
72
+ @@map("user")
73
+ }
74
+
75
+ model AuditLog {
76
+ id String @id @default(cuid())
77
+ actorId String?
78
+ actor User? @relation("AuditActor", fields: [actorId], references: [id], onDelete: SetNull)
79
+ targetUserId String?
80
+ targetUser User? @relation("AuditTargetUser", fields: [targetUserId], references: [id], onDelete: SetNull)
81
+ action String
82
+ entityType String
83
+ entityId String?
84
+ metadata Json?
85
+ createdAt DateTime @default(now())
86
+
87
+ @@index([entityType, entityId])
88
+ @@index([createdAt])
89
+ @@map("audit_log")
90
+ }
91
+
92
+ model Session {
93
+ id String @id
94
+ expiresAt DateTime
95
+ token String
96
+ createdAt DateTime @default(now())
97
+ updatedAt DateTime @updatedAt
98
+ ipAddress String?
99
+ userAgent String?
100
+ userId String
101
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
102
+
103
+ @@unique([token])
104
+ @@index([userId])
105
+ @@map("session")
106
+ }
107
+
108
+ model Account {
109
+ id String @id
110
+ accountId String
111
+ providerId String
112
+ userId String
113
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
114
+ accessToken String?
115
+ refreshToken String?
116
+ idToken String?
117
+ accessTokenExpiresAt DateTime?
118
+ refreshTokenExpiresAt DateTime?
119
+ scope String?
120
+ password String?
121
+ createdAt DateTime @default(now())
122
+ updatedAt DateTime @updatedAt
123
+
124
+ @@index([userId])
125
+ @@map("account")
126
+ }
127
+
128
+ model Verification {
129
+ id String @id
130
+ identifier String
131
+ value String
132
+ expiresAt DateTime
133
+ createdAt DateTime @default(now())
134
+ updatedAt DateTime @updatedAt
135
+
136
+ @@index([identifier])
137
+ @@map("verification")
138
+ }
139
+
140
+ model Company {
141
+ id String @id @default("company")
142
+ name String?
143
+ address String?
144
+ city String?
145
+ postalCode String?
146
+ country String?
147
+ phone String?
148
+ email String?
149
+ website String?
150
+ siret String?
151
+ vatNumber String?
152
+ logo String?
153
+ createdAt DateTime @default(now())
154
+ updatedAt DateTime @updatedAt
155
+
156
+ @@map("company")
157
+ }
158
+
159
+ model SmtpConfig {
160
+ id String @id @default(cuid())
161
+ userId String @unique
162
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
163
+ host String
164
+ port Int
165
+ secure Boolean @default(false)
166
+ username String
167
+ password String
168
+ fromEmail String
169
+ fromName String?
170
+ signature String?
171
+ createdAt DateTime @default(now())
172
+ updatedAt DateTime @updatedAt
173
+
174
+ @@map("smtp_config")
175
+ }
176
+
177
+ model Status {
178
+ id String @id @default(cuid())
179
+ name String
180
+ color String // Couleur au format hexadécimal (ex: #3B82F6)
181
+ order Int @default(0) // Ordre d'affichage
182
+ createdAt DateTime @default(now())
183
+ updatedAt DateTime @updatedAt
184
+ contacts Contact[]
185
+ metaLeadConfigs MetaLeadConfig[]
186
+ googleAdsLeadConfigs GoogleAdsLeadConfig[]
187
+ googleSheetSyncConfigs GoogleSheetSyncConfig[]
188
+ workflowTriggerFromStatus Workflow[] @relation("WorkflowTriggerFromStatus")
189
+ workflowTriggerToStatus Workflow[] @relation("WorkflowTriggerToStatus")
190
+ workflowActionNewStatus WorkflowAction[] @relation("WorkflowActionNewStatus")
191
+ workflowActionConditionStatus WorkflowAction[] @relation("WorkflowActionConditionStatus")
192
+
193
+ @@unique([name])
194
+ @@map("status")
195
+ }
196
+
197
+ enum Civility {
198
+ M
199
+ MME
200
+ MLLE
201
+ }
202
+
203
+ enum InteractionType {
204
+ CALL
205
+ SMS
206
+ EMAIL
207
+ MEETING
208
+ NOTE
209
+ STATUS_CHANGE
210
+ CONTACT_UPDATE
211
+ APPOINTMENT_CREATED
212
+ APPOINTMENT_DELETED
213
+ APPOINTMENT_CHANGED
214
+ ASSIGNMENT_CHANGE
215
+ FILE_UPLOADED
216
+ FILE_REPLACED
217
+ FILE_DELETED
218
+ }
219
+
220
+ enum TaskType {
221
+ CALL
222
+ MEETING
223
+ EMAIL
224
+ VIDEO_CONFERENCE
225
+ OTHER
226
+ }
227
+
228
+ enum TaskPriority {
229
+ LOW
230
+ MEDIUM
231
+ HIGH
232
+ URGENT
233
+ }
234
+
235
+ model Contact {
236
+ id String @id @default(cuid())
237
+ civility Civility?
238
+ firstName String?
239
+ lastName String?
240
+ phone String // Obligatoire
241
+ secondaryPhone String?
242
+ email String?
243
+ address String?
244
+ city String?
245
+ postalCode String?
246
+ origin String? // Origine du contact
247
+ companyName String? // Nom de l'entreprise (texte brut)
248
+ isCompany Boolean @default(false) // Indique si le contact est une entreprise
249
+ companyId String? // ID de l'entreprise à laquelle ce contact est lié
250
+ companyRelation Contact? @relation("ContactCompany", fields: [companyId], references: [id], onDelete: SetNull)
251
+ contacts Contact[] @relation("ContactCompany") // Contacts liés à cette entreprise (via companyId)
252
+ statusId String?
253
+ status Status? @relation(fields: [statusId], references: [id], onDelete: SetNull)
254
+ closingReason String? // Motif de fermeture (si statut Fermé)
255
+ assignedCommercialId String? // Commercial assigné
256
+ assignedCommercial User? @relation("ContactAssignedCommercial", fields: [assignedCommercialId], references: [id], onDelete: SetNull)
257
+ assignedTeleproId String? // Télépro assigné
258
+ assignedTelepro User? @relation("ContactAssignedTelepro", fields: [assignedTeleproId], references: [id], onDelete: SetNull)
259
+ createdById String // Utilisateur qui a créé le contact
260
+ createdBy User @relation("ContactCreatedBy", fields: [createdById], references: [id], onDelete: Cascade)
261
+ createdAt DateTime @default(now())
262
+ updatedAt DateTime @updatedAt
263
+ interactions Interaction[]
264
+ tasks Task[]
265
+ files ContactFile[]
266
+ scheduledWorkflowActions ScheduledWorkflowAction[]
267
+
268
+ @@index([statusId])
269
+ @@index([assignedCommercialId])
270
+ @@index([assignedTeleproId])
271
+ @@index([createdById])
272
+ @@index([companyId])
273
+ @@index([isCompany])
274
+ @@map("contact")
275
+ }
276
+
277
+ model Interaction {
278
+ id String @id @default(cuid())
279
+ contactId String
280
+ contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
281
+ type InteractionType
282
+ title String?
283
+ content String // Contenu de l'interaction
284
+ metadata Json? // Métadonnées pour stocker les détails des changements (ancienne valeur, nouvelle valeur, etc.)
285
+ userId String // Utilisateur qui a créé l'interaction
286
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
287
+ date DateTime? // Date de l'interaction (pour RDV, appels, etc.)
288
+ createdAt DateTime @default(now())
289
+ updatedAt DateTime @updatedAt
290
+ emailTracking EmailTracking?
291
+
292
+ @@index([contactId])
293
+ @@index([userId])
294
+ @@map("interaction")
295
+ }
296
+
297
+ model EmailTracking {
298
+ id String @id @default(cuid())
299
+ interactionId String @unique
300
+ interaction Interaction @relation(fields: [interactionId], references: [id], onDelete: Cascade)
301
+ openCount Int @default(0) // Nombre d'ouvertures
302
+ firstOpenedAt DateTime? // Date de la première ouverture
303
+ lastOpenedAt DateTime? // Date de la dernière ouverture
304
+ createdAt DateTime @default(now())
305
+ updatedAt DateTime @updatedAt
306
+
307
+ @@index([interactionId])
308
+ @@map("email_tracking")
309
+ }
310
+
311
+ model Task {
312
+ id String @id @default(cuid())
313
+ contactId String? // Optionnel : peut être créée depuis un contact
314
+ contact Contact? @relation(fields: [contactId], references: [id], onDelete: SetNull)
315
+ type TaskType
316
+ title String?
317
+ description String // Description HTML (avec Editor)
318
+ priority TaskPriority @default(MEDIUM)
319
+ scheduledAt DateTime // Date et heure de la tâche
320
+ reminderMinutesBefore Int? // Rappel en minutes avant l'heure prévue (ex: 15, 30, 60)
321
+ assignedUserId String // Utilisateur assigné
322
+ assignedUser User @relation("TaskAssignedTo", fields: [assignedUserId], references: [id], onDelete: Cascade)
323
+ createdById String // Utilisateur qui a créé la tâche
324
+ createdBy User @relation("TaskCreatedBy", fields: [createdById], references: [id], onDelete: Cascade)
325
+ completed Boolean @default(false) // Tâche terminée ou non
326
+ completedAt DateTime? // Date de complétion
327
+ googleEventId String? // ID de l'évènement Google Calendar
328
+ googleMeetLink String? // URL du Google Meet
329
+ durationMinutes Int? // Durée de la réunion en minutes (pour Google Meet)
330
+ internalNote String? // Note personnelle (non partagée dans les emails)
331
+ notifyContact Boolean? // Si le contact a été prévenu lors de la création
332
+ createdAt DateTime @default(now())
333
+ updatedAt DateTime @updatedAt
334
+
335
+ @@index([contactId])
336
+ @@index([assignedUserId])
337
+ @@index([createdById])
338
+ @@index([scheduledAt])
339
+ @@index([googleEventId])
340
+ @@map("task")
341
+ }
342
+
343
+ model UserGoogleAccount {
344
+ id String @id @default(cuid())
345
+ userId String @unique
346
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
347
+ accessToken String
348
+ refreshToken String
349
+ tokenExpiresAt DateTime
350
+ email String? // Email du compte Google connecté
351
+ createdAt DateTime @default(now())
352
+ updatedAt DateTime @updatedAt
353
+
354
+ @@map("user_google_account")
355
+ }
356
+
357
+ model ContactFile {
358
+ id String @id @default(cuid())
359
+ contactId String
360
+ contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
361
+ fileName String // Nom original du fichier
362
+ fileSize Int // Taille en octets
363
+ mimeType String // Type MIME du fichier
364
+ googleDriveFileId String // ID du fichier dans Google Drive
365
+ uploadedById String // Utilisateur qui a uploadé le fichier
366
+ uploadedBy User @relation("ContactFileUploadedBy", fields: [uploadedById], references: [id], onDelete: Cascade)
367
+ createdAt DateTime @default(now())
368
+ updatedAt DateTime @updatedAt
369
+
370
+ @@index([contactId])
371
+ @@index([uploadedById])
372
+ @@map("contact_file")
373
+ }
374
+
375
+ model MetaLeadConfig {
376
+ id String @id @default(cuid())
377
+ name String // Nom de la configuration (ex: "Campagne Facebook Q4")
378
+ pageId String
379
+ accessToken String // Jeton d'accès de la page ou du système (chiffré)
380
+ verifyToken String // Token de vérification pour le webhook
381
+ active Boolean @default(true)
382
+ defaultStatusId String?
383
+ defaultStatus Status? @relation(fields: [defaultStatusId], references: [id], onDelete: SetNull)
384
+ defaultAssignedUserId String?
385
+ defaultAssignedUser User? @relation(fields: [defaultAssignedUserId], references: [id], onDelete: SetNull)
386
+ createdAt DateTime @default(now())
387
+ updatedAt DateTime @updatedAt
388
+
389
+ @@map("meta_lead_config")
390
+ }
391
+
392
+ model GoogleAdsLeadConfig {
393
+ id String @id @default(cuid())
394
+ name String // Nom de la configuration (ex: "Campagne Google Ads Produits")
395
+ webhookKey String // Clé secrète partagée pour sécuriser le webhook
396
+ active Boolean @default(true)
397
+ defaultStatusId String?
398
+ defaultStatus Status? @relation(fields: [defaultStatusId], references: [id], onDelete: SetNull)
399
+ defaultAssignedUserId String?
400
+ defaultAssignedUser User? @relation(fields: [defaultAssignedUserId], references: [id], onDelete: SetNull)
401
+ createdAt DateTime @default(now())
402
+ updatedAt DateTime @updatedAt
403
+
404
+ @@map("google_ads_lead_config")
405
+ }
406
+
407
+ model GoogleSheetSyncConfig {
408
+ id String @id @default(cuid())
409
+ name String // Nom de la configuration (ex: "Contacts Ventes")
410
+ ownerUserId String
411
+ ownerUser User @relation("GoogleSheetOwner", fields: [ownerUserId], references: [id], onDelete: Cascade)
412
+ spreadsheetId String
413
+ sheetName String
414
+ headerRow Int
415
+ phoneColumn String // Conservé pour compatibilité
416
+ firstNameColumn String? // Conservé pour compatibilité
417
+ lastNameColumn String? // Conservé pour compatibilité
418
+ emailColumn String? // Conservé pour compatibilité
419
+ cityColumn String? // Conservé pour compatibilité
420
+ postalCodeColumn String? // Conservé pour compatibilité
421
+ originColumn String? // Conservé pour compatibilité
422
+ columnMappings Json? // Nouveau format de mapping dynamique
423
+ active Boolean @default(true)
424
+ lastSyncedRow Int?
425
+ defaultStatusId String?
426
+ defaultStatus Status? @relation(fields: [defaultStatusId], references: [id], onDelete: SetNull)
427
+ defaultAssignedUserId String?
428
+ defaultAssignedUser User? @relation("GoogleSheetAssignedUser", fields: [defaultAssignedUserId], references: [id], onDelete: SetNull)
429
+ createdAt DateTime @default(now())
430
+ updatedAt DateTime @updatedAt
431
+
432
+ @@map("google_sheet_sync_config")
433
+ }
434
+
435
+ model ClosingReason {
436
+ id String @id @default(cuid())
437
+ name String // Libellé du motif de fermeture (ex: Faux numéro, Pas intéressé, etc.)
438
+ createdAt DateTime @default(now())
439
+ updatedAt DateTime @updatedAt
440
+
441
+ @@map("closing_reason")
442
+ }
443
+
444
+ enum TemplateType {
445
+ EMAIL
446
+ SMS
447
+ NOTE
448
+ }
449
+
450
+ model Template {
451
+ id String @id @default(cuid())
452
+ name String // Nom du template
453
+ type TemplateType // Type de template (EMAIL, SMS, NOTE)
454
+ subject String? // Sujet (pour EMAIL uniquement)
455
+ content String // Contenu du template (HTML pour EMAIL, texte pour SMS et NOTE)
456
+ userId String // Utilisateur qui a créé le template
457
+ user User @relation("TemplateCreatedBy", fields: [userId], references: [id], onDelete: Cascade)
458
+ workflowActions WorkflowAction[] @relation("WorkflowActionEmailTemplate")
459
+ createdAt DateTime @default(now())
460
+ updatedAt DateTime @updatedAt
461
+
462
+ @@index([userId])
463
+ @@index([type])
464
+ @@map("template")
465
+ }
466
+
467
+ enum WorkflowTriggerType {
468
+ CONTACT_CREATED // Nouveau contact créé
469
+ STATUS_CHANGED // Changement de statut
470
+ TIME_BASED // Basé sur le temps
471
+ MANUAL // Déclencheur manuel
472
+ }
473
+
474
+ enum WorkflowActionType {
475
+ SEND_EMAIL // Envoyer un email
476
+ SEND_SMS // Envoyer un SMS
477
+ CHANGE_STATUS // Changer le statut
478
+ CREATE_TASK // Créer une tâche
479
+ WAIT // Attendre
480
+ }
481
+
482
+ enum WorkflowConditionOperator {
483
+ EQUALS // Est égal à
484
+ NOT_EQUALS // N'est pas égal à
485
+ }
486
+
487
+ model Workflow {
488
+ id String @id @default(cuid())
489
+ name String
490
+ description String?
491
+ active Boolean @default(true)
492
+ userId String // Utilisateur propriétaire du workflow
493
+ user User @relation("WorkflowOwner", fields: [userId], references: [id], onDelete: Cascade)
494
+
495
+ // Configuration du déclencheur
496
+ triggerType WorkflowTriggerType
497
+
498
+ // Pour STATUS_CHANGED
499
+ triggerFromStatusId String? // Statut source (optionnel, null = tous)
500
+ triggerToStatusId String? // Statut cible (optionnel, null = tous)
501
+ triggerStatus Status? @relation("WorkflowTriggerFromStatus", fields: [triggerFromStatusId], references: [id], onDelete: SetNull)
502
+ triggerToStatus Status? @relation("WorkflowTriggerToStatus", fields: [triggerToStatusId], references: [id], onDelete: SetNull)
503
+
504
+ // Pour TIME_BASED
505
+ triggerTimeDays Int? // Nombre de jours après un événement
506
+ triggerTimeHours Int? // Nombre d'heures après un événement
507
+
508
+ actions WorkflowAction[]
509
+ scheduledActions ScheduledWorkflowAction[]
510
+ createdAt DateTime @default(now())
511
+ updatedAt DateTime @updatedAt
512
+
513
+ @@index([userId])
514
+ @@index([active])
515
+ @@map("workflow")
516
+ }
517
+
518
+ model WorkflowAction {
519
+ id String @id @default(cuid())
520
+ workflowId String
521
+ workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
522
+
523
+ // Type d'action
524
+ actionType WorkflowActionType
525
+
526
+ // Ordre d'exécution
527
+ order Int @default(0)
528
+
529
+ // Délai avant l'action (en jours et heures)
530
+ delayDays Int @default(0)
531
+ delayHours Int @default(0)
532
+
533
+ // Configuration spécifique selon le type d'action
534
+ // Pour SEND_EMAIL
535
+ emailTemplateId String? // Template email à utiliser
536
+ emailTemplate Template? @relation("WorkflowActionEmailTemplate", fields: [emailTemplateId], references: [id], onDelete: SetNull)
537
+
538
+ // Pour SEND_SMS
539
+ smsMessage String? // Message SMS
540
+
541
+ // Pour CHANGE_STATUS
542
+ newStatusId String? // Nouveau statut
543
+ newStatus Status? @relation("WorkflowActionNewStatus", fields: [newStatusId], references: [id], onDelete: SetNull)
544
+
545
+ // Pour CREATE_TASK
546
+ taskTitle String? // Titre de la tâche
547
+ taskDescription String? // Description de la tâche
548
+
549
+ // Condition (optionnelle)
550
+ conditionOperator WorkflowConditionOperator? // Opérateur de condition
551
+ conditionStatusId String? // Statut pour la condition
552
+ conditionStatus Status? @relation("WorkflowActionConditionStatus", fields: [conditionStatusId], references: [id], onDelete: SetNull)
553
+
554
+ createdAt DateTime @default(now())
555
+ updatedAt DateTime @updatedAt
556
+
557
+ @@index([workflowId])
558
+ @@index([order])
559
+ @@map("workflow_action")
560
+ }
561
+
562
+ model ScheduledWorkflowAction {
563
+ id String @id @default(cuid())
564
+ workflowId String
565
+ workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
566
+ actionId String? // ID de l'action dans le workflow (optionnel, pour référence)
567
+ contactId String
568
+ contact Contact @relation(fields: [contactId], references: [id], onDelete: Cascade)
569
+ actionType String // SEND_EMAIL, SEND_SMS, CHANGE_STATUS, CREATE_TASK, WAIT
570
+ actionData Json // Données de l'action (template, message, status, etc.)
571
+ executeAt DateTime // Date d'exécution
572
+ executed Boolean @default(false)
573
+ executedAt DateTime? // Date d'exécution réelle
574
+ error String? // Message d'erreur si l'exécution a échoué
575
+ createdAt DateTime @default(now())
576
+ updatedAt DateTime @updatedAt
577
+
578
+ @@index([executeAt, executed])
579
+ @@index([contactId])
580
+ @@index([workflowId])
581
+ @@map("scheduled_workflow_action")
582
+ }
@@ -0,0 +1,14 @@
1
+ // This file was generated by Prisma and assumes you have installed the following:
2
+ // npm install --save-dev prisma dotenv
3
+ import 'dotenv/config';
4
+ import { defineConfig, env } from 'prisma/config';
5
+
6
+ export default defineConfig({
7
+ schema: 'prisma/schema.prisma',
8
+ migrations: {
9
+ path: 'prisma/migrations',
10
+ },
11
+ datasource: {
12
+ url: env('DIRECT_URL'),
13
+ },
14
+ });