forked from dubinc/dub
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.prisma
173 lines (146 loc) · 6.22 KB
/
schema.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
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
stripeId String? @unique // Stripe customer ID
usage Int @default(0)
usageLimit Int @default(1000)
billingCycleStart Int? // day of the month when the billing cycle starts
accounts Account[]
sessions Session[]
projects ProjectUsers[]
sentEmails SentEmail[]
links Link[]
createdAt DateTime @default(now())
usageUpdatedAt DateTime @default(now())
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model Project {
id String @id @default(cuid())
name String
slug String @unique
logo String?
domain String @unique
domainVerified Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users ProjectUsers[]
invites ProjectInvite[]
domainLastChecked DateTime @default(now())
usage Int @default(0)
ownerUsageLimit Int @default(1000)
ownerExceededUsage Boolean @default(false)
sentEmails SentEmail[]
links Link[]
}
model ProjectInvite {
email String
expires DateTime
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
projectId String
createdAt DateTime @default(now())
@@unique([email, projectId])
}
model ProjectUsers {
id String @id @default(cuid())
role String @default("member")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
projectId String
@@unique([userId, projectId])
}
enum EmailType {
firstDomainInvalidEmail
secondDomainInvalidEmail
firstUsageLimitEmail
secondUsageLimitEmail
}
model SentEmail {
id String @id @default(cuid())
type EmailType
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String?
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
projectId String?
}
model Link {
id String @id @default(cuid())
domain String // domain of the link (e.g. dub.sh) – also stored on Redis
key String // key of the link (e.g. /github) – also stored on Redis
url String @db.LongText // target url (e.g. https://github.com/steven-tey/dub) – also stored on Redis
archived Boolean @default(false) // whether the link is archived or not
expiresAt DateTime? // when the link expires – stored on Redis via ttl
password String? // password to access the link – also stored on Redis
proxy Boolean @default(false) // Proxy to use custom OG tags – if false, will use OG tags from target url
title String? // OG title for the link (e.g. Dub - Open-Source Bitly Alternative)
description String? @db.VarChar(280) // OG description for the link (e.g. An open-source link management tool for modern marketing teams to create, share, and track short links.)
image String? @db.LongText // OG image for the link (e.g. https://dub.sh/og-image.png)
// UTM parameters
utm_source String? // UTM source for the link (e.g. youtube.com)
utm_medium String? // UTM medium for the link (e.g. social)
utm_campaign String? // UTM campaign for the link (e.g. summer-sale)
utm_term String? // UTM term for the link (e.g. dub)
utm_content String? // UTM content for the link (e.g. description)
// Custom device targeting
ios String? @db.LongText // custom link for iOS devices
android String? @db.LongText // custom link for Android devices
clicks Int @default(0) // number of clicks
// User who created the link
user User? @relation(fields: [userId], references: [id])
userId String?
// Project that the link belongs to
project Project? @relation(fields: [domain], references: [domain], onUpdate: Cascade, onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([domain, key])
// indices for links per domain/project
@@index([domain, archived, expiresAt, createdAt(sort: Desc)])
@@index([domain, archived, expiresAt, clicks(sort: Desc)])
// indices for links per domain/project specific to a user
@@index([domain, archived, expiresAt, userId, createdAt(sort: Desc)])
@@index([domain, archived, expiresAt, userId, clicks(sort: Desc)])
// TODO: might wanna add indices for utm_source, utm_medium, utm_campaign
}