/
datamodel.prisma
executable file
·599 lines (543 loc) · 14.5 KB
/
datamodel.prisma
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
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
type Address {
id: ID! @unique
street: String
city: String
postalCode: String
country: String
}
enum Title {
MONSIEUR
MADAME
MADEMOISELLE
MONDAMOISEAU
}
enum CollabRequestStatus {
PENDING
REJECTED
ACCEPTED
CANCELED
}
# Represents a company or an individual that is going to receive an invoice
type Customer {
id: ID! @unique
token: String @unique
name: String
title: Title
firstName: String
lastName: String
email: String!
address: Address
phone: String
occupation: String
userNotes: Json @default(value: "{}")
siret: String
rcs: String
rm: String
serviceCompany: Company! @relation(name: "CompanyCustomers")
projects: [Project!]! @relation(name: "CustomerProjects")
linkedTasks: [Item!]! @relation(name: "LinkedCustomerTasks")
comments: [Comment!]! @relation(name: "CommentAuthorCustomer")
commentViews: [CommentView!]!
@relation(name: "CommentViewCustomer", onDelete: CASCADE)
files: [File!]! @relation(name: "CustomerFiles")
customerEvents: [CustomerEvent!]!
@relation(name: "CustomerCustomerEvents", onDelete: CASCADE)
}
enum ProjectStatus {
ONGOING
ARCHIVED
REMOVED
}
enum ProjectTemplate {
BLANK
WEBSITE
IDENTITY
PROSPECTION
MOTION
LANDING
CARD
FLYER_A5
FACEBOOK_AD
TRANSLATION
}
enum ItemStatus {
PENDING
FINISHED
# deprecated statuses
SNOOZED
UPDATED
UPDATED_SENT
ADDED
ADDED_SENT
}
enum ReminderType {
QUOTE_AFTER_10_DAYS
QUOTE_AFTER_15_DAYS
QUOTE_AFTER_20_DAYS
QUOTE_5_DAYS_LEFT
QUOTE_2_DAYS_LEFT
AMENDMENT_AFTER_5_DAYS
AMENDMENT_AFTER_10_DAYS
# Delay sending
DELAY
# 2 day reminder
FIRST
# FIRST + days reminder
SECOND
# SECOND + 1 days reminder
LAST
INVOICE_DELAY
INVOICE_FIRST
INVOICE_SECOND
INVOICE_THIRD
INVOICE_FOURTH
INVOICE_LAST
CONTENT_ACQUISITION_DELAY
CONTENT_ACQUISITION_FIRST
CONTENT_ACQUISITION_SECOND
# customer has not replied, user warning at LAST + 2 days
USER_WARNING
# Morning email with tasks the user can complete
MORNING_TASKS
# Evening email with what happened during the day
EVENING_RECAP
# Reset focused tasks time
RESET_FOCUSED_TASKS
# End of a snooze period
SNOOZE_END
# Slipping away users notification
SLIPPING_AWAY
# Deadline Approaching
DEADLINE_APPROACHING
}
enum ReminderStatus {
PENDING
SENT
ERROR
CANCELED
}
enum JobType {
TEAM
FULLTIME_INDIVIDUAL
PARTTIME_INDIVIDUAL
NOT_FREELANCER
}
enum Reviewer {
USER
CUSTOMER
}
enum DAY {
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
}
enum CustomerEventType {
VIEWED_PROJECT
POSTED_COMMENT
UPLOADED_ATTACHMENT
FINISHED_TASK
VIEWED_QUOTE
ACCEPTED_QUOTE
}
enum UserEventType {
ME_CALL
FOCUSED_TASK
UNFOCUSED_TASK
SENT_REMINDER
CANCELED_REMINDER
ADDED_TASK
UPDATED_TASK
FINISHED_TASK
UNFINISHED_TASK
REMOVED_TASK
CREATED_PROJECT
UPDATED_PROJECT
ARCHIVED_PROJECT
UNARCHIVED_PROJECT
REMOVED_PROJECT
CREATED_CUSTOMER
UPDATED_CUSTOMER
REMOVED_CUSTOMER
POSTED_COMMENT
ADDED_SECTION
UPDATED_SECTION
REMOVED_SECTION
UPLOADED_ATTACHMENT
REMOVED_ATTACHMENT
COLLAB_ASKED
COLLAB_REQUESTED
COLLAB_ACCEPTED
COLLAB_REJECTED
LINKED_CUSTOMER_TO_TASK
UNLINKED_CUSTOMER_TO_TASK
LINKED_CUSTOMER_TO_PROJECT
UNLINKED_CUSTOMER_TO_PROJECT
LINKED_COLLABORATOR_TO_PROJECT
UNLINKED_COLLABORATOR_TO_PROJECT
LINKED_TO_PROJECT
ASSIGNED_TO_TASK
REMOVE_ASSIGNMENT_TO_TASK
}
enum Skill {
PRINT_DESIGN
WEB_DESIGN
UX_DESIGN
UI_DESIGN
COPYWRITING
VIDEO
ACCOUNTING
PHOTOGRAPHY
MARKETING
FRONT_END_DEVELOPMENT
BACK_END_DEVELOPMENT
}
enum EmailCategory {
CUSTOMER
CUSTOMER_REPORT
CONTENT_ACQUISITION
INVOICE
COMMENT_ADDED
}
type CommentView {
id: ID! @unique
user: User @relation(name: "CommentViewUser")
customer: Customer @relation(name: "CommentViewCustomer")
comment: Comment @relation(name: "CommentViews")
createdAt: DateTime!
}
type Comment {
id: ID! @unique
text: String!
authorUser: User @relation(name: "CommentAuthorUser")
authorCustomer: Customer @relation(name: "CommentAuthorCustomer")
viewedByUser: Boolean! @default(value: false)
viewedByCustomer: Boolean! @default(value: false)
views: [CommentView!]! @relation(name: "CommentViews", onDelete: CASCADE)
item: Item! @relation(name: "ItemComments")
createdAt: DateTime!
}
enum ItemType {
DEFAULT
CUSTOMER
CONTENT_ACQUISITION
CUSTOMER_REMINDER
VALIDATION
USER_REMINDER
INVOICE
PERSONAL
}
type TimeRange {
id: ID! @unique
task: Item! @relation(name: "TaskTimeRanges")
start: DateTime!
end: DateTime
}
type ScheduleSpot {
id: ID! @unique
task: Item! @relation(name: "TaskScheduleSpots")
date: DateTime!
position: Int!
status: ItemStatus! @default(value: PENDING)
}
type Item {
id: ID! @unique
owner: User! @relation(name: "UserTasks")
scheduledFor: DateTime
schedulePosition: Int
scheduledForDays: [ScheduleSpot!]!
@relation(name: "TaskScheduleSpots", onDelete: CASCADE)
focusedBy: User @relation(name: "UserFocusedTasks")
linkedCustomer: Customer @relation(name: "LinkedCustomerTasks")
assignee: User @relation(name: "UserAssignedTasks")
name: String!
type: ItemType! @default(value: DEFAULT)
description: String @default(value: "")
unit: Float! @default(value: 0)
comments: [Comment!]! @relation(name: "ItemComments", onDelete: CASCADE)
status: ItemStatus! @default(value: PENDING)
section: Section @relation(name: "SectionItems")
reviewer: Reviewer! @default(value: USER)
reminders: [Reminder!]! @relation(name: "ItemReminders", onDelete: CASCADE)
attachments: [File!]! @relation(name: "TaskAttachments", onDelete: CASCADE)
finishedAt: DateTime
position: Int!
dailyRate: Float
dueDate: DateTime
createdAt: DateTime!
updatedAt: DateTime!
timeItTook: Float
currentlyTimedBy: User @relation(name: "UserCurrentTask")
workedTimes: [TimeRange!]!
@relation(name: "TaskTimeRanges", onDelete: CASCADE)
tags: [Tag!]! @relation(name: "ItemTags")
# deprecated
snoozedUntil: Reminder @relation(name: "SnoozeReminders", onDelete: CASCADE)
}
type Section {
id: ID! @unique
name: String!
items: [Item!]! @relation(name: "SectionItems", onDelete: CASCADE)
project: Project! @relation(name: "ProjectSections")
position: Int!
price: Float
}
type QuoteItem {
id: ID! @unique
section: QuoteSection! @relation(name: "QuoteItemSection")
name: String!
}
type QuoteSection {
id: ID! @unique
quote: Quote! @relation(name: "QuoteSections")
items: [QuoteItem!]! @relation(name: "QuoteItemSection")
name: String!
price: Float!
}
type Quote {
id: ID! @unique
issueNumber: Int! @default(value: 0)
header: Json
footer: Json
sections: [QuoteSection!]! @relation(name: "QuoteSections", onDelete: CASCADE)
project: Project! @relation(name: "ProjectQuotes")
hasTaxes: Boolean! @default(value: false)
taxRate: Float @default(value: 20)
acceptedAt: DateTime
createdAt: DateTime!
updatedAt: DateTime!
invalid: Boolean! @default(value: true)
validQuote: Quote @relation(name: "ValidQuote")
}
type Project {
id: ID! @unique
name: String!
sharedNotes: Json! @default(value: "{}")
personalNotes: Json! @default(value: "{}")
template: ProjectTemplate @default(value: BLANK)
customer: Customer @relation(name: "CustomerProjects")
owner: User! @relation(name: "UserProjects")
# this token is a way to restrict access to anyone else than the customer
token: String! @unique
status: ProjectStatus! @default(value: ONGOING)
sections: [Section!]! @relation(name: "ProjectSections", onDelete: CASCADE)
viewedByCustomer: Boolean! @default(value: false)
issuedAt: DateTime
deadline: DateTime
budget: Float
notifyActivityToCustomer: Boolean! @default(value: true)
attachments: [File!]! @relation(name: "ProjectAttachments")
linkedCollaborators: [User!]! @relation(name: "CollaboratorsProject")
quoteHeader: Json
quoteFooter: Json
quotes: [Quote!]! @relation(name: "ProjectQuotes")
createdAt: DateTime!
updatedAt: DateTime!
}
type Company {
id: ID! @unique
name: String
owner: User! @relation(name: "CompanyOwner")
email: String
address: Address
phone: String
type: String
siret: String
rcs: String
rcsCity: String
rm: String
vat: String
vatRate: Float
logo: File @relation(name: "CompanyLogo", onDelete: CASCADE)
banner: File @relation(name: "CompanyBanner", onDelete: CASCADE)
bannerUnsplashId: String
customers: [Customer!]! @relation(name: "CompanyCustomers", onDelete: CASCADE)
documents: [File!]! @relation(name: "CompanyDocuments", onDelete: CASCADE)
}
type Settings {
user: User! @relation(name: "UserSettings")
assistantName: String! @default(value: "Edwige")
language: String @default(value: "fr")
hasFullWeekSchedule: Boolean! @default(value: false)
# deprecated
askItemFinishConfirmation: Boolean! @default(value: true)
askStartProjectConfirmation: Boolean! @default(value: true)
}
type User {
id: ID! @unique
email: String! @unique
hmacIntercomId: String
password: String!
firstName: String!
lastName: String!
referrer: User @relation(name: "UserReferrees")
referrees: [User!]! @relation(name: "UserReferrees")
company: Company! @relation(name: "CompanyOwner", onDelete: CASCADE)
startWorkAt: DateTime
endWorkAt: DateTime
startBreakAt: DateTime
endBreakAt: DateTime
workingDays: [DAY!]!
timeZone: String
userEvents: [UserEvent!]! @relation(name: "UserUserEvents", onDelete: CASCADE)
reminders: [Reminder!]! @relation(name: "UserReminders", onDelete: CASCADE)
morningReminders: [Reminder!]!
@relation(name: "UserMorningReminders", onDelete: CASCADE)
eveningReminders: [Reminder!]!
@relation(name: "UserEveningReminders", onDelete: CASCADE)
resetFocusReminders: [Reminder!]!
@relation(name: "UserResetFocusReminders", onDelete: CASCADE)
defaultDailyPrice: Int @default(value: 350)
defaultVatRate: Int @default(value: 20)
commentViews: [CommentView!]!
@relation(name: "CommentViewUser", onDelete: CASCADE)
workingFields: [String!]!
otherSkill: String
skills: [Skill!]!
otherPain: String
painsExpressed: [String!]!
canBeContacted: Boolean
jobType: JobType
interestedFeatures: [String!]!
hasUpcomingProject: Boolean
settings: Settings! @relation(name: "UserSettings", onDelete: CASCADE)
tasks: [Item!]! @relation(name: "UserTasks", onDelete: CASCADE)
focusedTasks: [Item!]! @relation(name: "UserFocusedTasks", onDelete: CASCADE)
currentTask: Item @relation(name: "UserCurrentTask")
projects: [Project!]! @relation(name: "UserProjects", onDelete: CASCADE)
collaborationProjects: [Project!]! @relation(name: "CollaboratorsProject")
files: [File!]! @relation(name: "UserFiles", onDelete: CASCADE)
comments: [Comment!]! @relation(name: "CommentAuthorUser")
notifications: [Notification!]! @relation(name: "UserNotifications")
createdAt: DateTime!
updatedAt: DateTime!
tags: [Tag!]! @relation(name: "UserTags", onDelete: CASCADE)
lifetimePayment: Boolean @default(value: false)
quoteNumber: Int! @default(value: 0)
collaborators: [User!]! @relation(name: "Collaborators")
collaboratorRequests: [CollabRequest!]! @relation(name: "CollabRequester")
collaborationRequests: [CollabRequest!]! @relation(name: "CollabRequestee")
assignedTasks: [Item!]! @relation(name: "UserAssignedTasks")
emailTemplates: [EmailTemplate!]!
@relation(name: "UserEmailTemplates", onDelete: CASCADE)
}
type CollabRequest {
id: ID! @unique
requester: User! @relation(name: "CollabRequester")
requestee: User @relation(name: "CollabRequestee")
requesteeEmail: String # if the user is not registered yet
status: CollabRequestStatus!
acceptedAt: DateTime
rejectedAt: DateTime
createdAt: DateTime!
updatedAt: DateTime!
}
type Reminder {
id: ID! @unique
item: Item @relation(name: "ItemReminders")
user: User @relation(name: "UserReminder")
morningRemindersUser: User @relation(name: "UserMorningReminders")
eveningRemindersUser: User @relation(name: "UserEveningReminders")
postHookId: String!
type: ReminderType!
sendingDate: DateTime!
status: ReminderStatus @default(value: PENDING)
metadata: Json @default(value: "{}")
# deprecated
resetFocusRemindersUser: User @relation(name: "UserResetFocusReminders")
snoozedItem: Item @relation(name: "SnoozeReminders")
}
enum DocumentType {
DEFAULT
ADMIN
DELIVERABLE
}
type File {
id: ID! @unique
ownerUser: User @relation(name: "UserFiles")
ownerCustomer: Customer @relation(name: "CustomerFiles")
filename: String!
mimetype: String!
encoding: String!
url: String!
documentType: DocumentType! @default(value: DEFAULT)
linkedTask: Item @relation(name: "TaskAttachments")
linkedProject: Project @relation(name: "ProjectAttachments")
createdAt: DateTime!
}
type UserEvent {
id: ID! @unique
type: UserEventType!
createdAt: DateTime!
user: User @relation(name: "UserUserEvents")
metadata: Json @default(value: "{}")
notifications: [Notification!]!
@relation(name: "UserEventNotifications", onDelete: CASCADE)
project: Project @relation(name: "UserEventOnProject")
section: Section @relation(name: "UserEventOnSection")
task: Item @relation(name: "UserEventOnTask")
comment: Comment @relation(name: "UserEventOnComment")
file: File @relation(name: "UserEventOnFile")
reminder: Reminder @relation(name: "UserEventOnReminder")
collaborator: User @relation(name: "UserEventOnCollaborator")
customer: Customer @relation(name: "UserEventOnCustomer")
}
type CustomerEvent {
id: ID! @unique
type: CustomerEventType!
createdAt: DateTime!
customer: Customer! @relation(name: "CustomerCustomerEvents")
metadata: Json @default(value: "{}")
notifications: [Notification!]!
@relation(name: "CustomerEventNotifications", onDelete: CASCADE)
project: Project @relation(name: "CustomerEventOnProject")
task: Item @relation(name: "CustomerEventOnTask")
comment: Comment @relation(name: "CustomerEventOnComment")
file: File @relation(name: "CustomerEventOnFile")
quote: Quote @relation(name: "CustomerEventOnQuote")
}
type Notification {
id: ID! @unique
unread: Boolean! @default(value: true)
customerEvent: CustomerEvent @relation(name: "CustomerEventNotifications")
userEvent: UserEvent @relation(name: "UserEventNotifications")
user: User! @relation(name: "UserNotifications")
createdAt: DateTime!
updatedAt: DateTime!
}
type Tag {
id: ID! @unique
items: [Item!]! @relation(name: "ItemTags")
name: String!
colorBg: String!
colorText: String!
owner: User @relation(name: "UserTags")
}
type EmailType {
id: ID! @unique
name: String
position: Int
category: EmailCategory!
availableParams: [EmailParamForType!]! @relation(name: "EmailTypeParams")
}
type EmailParamForType {
id: ID! @unique
param: EmailParam @relation(name: "EmailParamForTypeEmailParam")
required: Boolean!
}
type EmailParam {
id: ID! @unique
paramId: String! @unique
name: String!
}
type EmailTemplate {
id: ID! @unique
type: EmailType! @relation(name: "EmailTemplateEmailType")
timing: Json
subject: Json!
content: Json!
owner: User! @relation(name: "UserEmailTemplates")
}