@@ -3,145 +3,68 @@ import { dub } from "@/lib/dub";
3
3
import { prisma } from "@/lib/prisma" ;
4
4
import { storage } from "@/lib/storage" ;
5
5
import { cancelSubscription } from "@/lib/stripe" ;
6
- import { recordLink } from "@/lib/tinybird" ;
7
6
import { WorkspaceProps } from "@/lib/types" ;
8
7
import { formatRedisLink , redis } from "@/lib/upstash" ;
9
8
import {
9
+ APP_DOMAIN_WITH_NGROK ,
10
10
DUB_DOMAINS_ARRAY ,
11
11
LEGAL_USER_ID ,
12
12
LEGAL_WORKSPACE_ID ,
13
13
R2_URL ,
14
14
} from "@dub/utils" ;
15
- import { waitUntil } from "@vercel/functions " ;
15
+ import { qstash } from "../cron " ;
16
16
17
17
export async function deleteWorkspace (
18
18
workspace : Pick <
19
19
WorkspaceProps ,
20
20
"id" | "slug" | "logo" | "stripeId" | "referralLinkId"
21
21
> ,
22
22
) {
23
- const [ customDomains , defaultDomainLinks ] = await Promise . all ( [
24
- prisma . domain . findMany ( {
23
+ await Promise . all ( [
24
+ // Remove the users
25
+ prisma . projectUsers . deleteMany ( {
25
26
where : {
26
27
projectId : workspace . id ,
27
28
} ,
28
- select : {
29
- slug : true ,
30
- } ,
31
29
} ) ,
32
- prisma . link . findMany ( {
30
+
31
+ // Remove the default workspace
32
+ prisma . user . updateMany ( {
33
33
where : {
34
- projectId : workspace . id ,
35
- domain : {
36
- in : DUB_DOMAINS_ARRAY ,
37
- } ,
34
+ defaultWorkspace : workspace . slug ,
38
35
} ,
39
- select : {
40
- id : true ,
41
- domain : true ,
42
- key : true ,
43
- url : true ,
44
- tags : {
45
- select : {
46
- tagId : true ,
47
- } ,
48
- } ,
49
- proxy : true ,
50
- image : true ,
51
- projectId : true ,
52
- createdAt : true ,
36
+ data : {
37
+ defaultWorkspace : null ,
53
38
} ,
54
39
} ) ,
55
- ] ) ;
56
-
57
- const response = await prisma . projectUsers . deleteMany ( {
58
- where : {
59
- projectId : workspace . id ,
60
- } ,
61
- } ) ;
62
-
63
- waitUntil (
64
- ( async ( ) => {
65
- const linksByDomain : Record < string , string [ ] > = { } ;
66
- defaultDomainLinks . forEach ( async ( link ) => {
67
- const { domain, key } = link ;
68
-
69
- if ( ! linksByDomain [ domain ] ) {
70
- linksByDomain [ domain ] = [ ] ;
71
- }
72
- linksByDomain [ domain ] . push ( key . toLowerCase ( ) ) ;
73
- } ) ;
74
40
75
- const pipeline = redis . pipeline ( ) ;
41
+ // Remove the API keys
42
+ prisma . restrictedToken . deleteMany ( {
43
+ where : {
44
+ projectId : workspace . id ,
45
+ } ,
46
+ } ) ,
76
47
77
- Object . entries ( linksByDomain ) . forEach ( ( [ domain , links ] ) => {
78
- pipeline . hdel ( domain . toLowerCase ( ) , ...links ) ;
79
- } ) ;
48
+ // Cancel the workspace's Stripe subscription
49
+ workspace . stripeId && cancelSubscription ( workspace . stripeId ) ,
80
50
81
- // delete all domains, links, and uploaded images associated with the workspace
82
- await Promise . allSettled ( [
83
- ...customDomains . map ( ( { slug } ) =>
84
- markDomainAsDeleted ( {
85
- domain : slug ,
86
- workspaceId : workspace . id ,
87
- } ) ,
88
- ) ,
89
- // delete all default domain links from redis
90
- pipeline . exec ( ) ,
91
- // record deletes in Tinybird for default domain links
92
- recordLink (
93
- defaultDomainLinks . map ( ( link ) => ( {
94
- link_id : link . id ,
95
- domain : link . domain ,
96
- key : link . key ,
97
- url : link . url ,
98
- tag_ids : link . tags . map ( ( tag ) => tag . tagId ) ,
99
- workspace_id : link . projectId ,
100
- created_at : link . createdAt ,
101
- deleted : true ,
102
- } ) ) ,
103
- ) ,
104
- // remove all images from R2
105
- ...defaultDomainLinks . map ( ( { id, image } ) =>
106
- image && image . startsWith ( `${ R2_URL } /images/${ id } ` )
107
- ? storage . delete ( image . replace ( `${ R2_URL } /` , "" ) )
108
- : Promise . resolve ( ) ,
109
- ) ,
110
- ] ) ;
51
+ // Delete workspace logo if it's a custom logo stored in R2
52
+ workspace . logo &&
53
+ workspace . logo . startsWith ( `${ R2_URL } /logos/${ workspace . id } ` ) &&
54
+ storage . delete ( workspace . logo . replace ( `${ R2_URL } /` , "" ) ) ,
111
55
112
- await Promise . allSettled ( [
113
- // delete workspace logo if it's a custom logo stored in R2
114
- workspace . logo &&
115
- workspace . logo . startsWith ( `${ R2_URL } /logos/${ workspace . id } ` ) &&
116
- storage . delete ( workspace . logo . replace ( `${ R2_URL } /` , "" ) ) ,
117
- // if they have a Stripe subscription, cancel it
118
- workspace . stripeId && cancelSubscription ( workspace . stripeId ) ,
119
- // set the referral link to `/deleted/[slug]`
120
- workspace . referralLinkId &&
121
- dub . links . update ( workspace . referralLinkId , {
122
- key : `/deleted/${ workspace . slug } -${ workspace . id } ` ,
123
- archived : true ,
124
- identifier : `/deleted/${ workspace . slug } -${ workspace . id } ` ,
125
- } ) ,
126
- // delete the workspace
127
- prisma . project . delete ( {
128
- where : {
129
- slug : workspace . slug ,
130
- } ,
131
- } ) ,
132
- prisma . user . updateMany ( {
133
- where : {
134
- defaultWorkspace : workspace . slug ,
135
- } ,
136
- data : {
137
- defaultWorkspace : null ,
138
- } ,
139
- } ) ,
140
- ] ) ;
141
- } ) ( ) ,
142
- ) ;
56
+ // Set the referral link to `/deleted/[slug]`
57
+ workspace . referralLinkId &&
58
+ dub . links . update ( workspace . referralLinkId , {
59
+ key : `/deleted/${ workspace . slug } -${ workspace . id } ` ,
60
+ archived : true ,
61
+ identifier : `/deleted/${ workspace . slug } -${ workspace . id } ` ,
62
+ } ) ,
63
+ ] ) ;
143
64
144
- return response ;
65
+ await queueWorkspaceDeletion ( {
66
+ workspaceId : workspace . id ,
67
+ } ) ;
145
68
}
146
69
147
70
export async function deleteWorkspaceAdmin (
@@ -235,3 +158,19 @@ export async function deleteWorkspaceAdmin(
235
158
deleteWorkspaceResponse,
236
159
} ;
237
160
}
161
+
162
+ export async function queueWorkspaceDeletion ( {
163
+ workspaceId,
164
+ delay,
165
+ } : {
166
+ workspaceId : string ;
167
+ delay ?: number ;
168
+ } ) {
169
+ return await qstash . publishJSON ( {
170
+ url : `${ APP_DOMAIN_WITH_NGROK } /api/cron/workspaces/delete` ,
171
+ ...( delay && { delay } ) ,
172
+ body : {
173
+ workspaceId,
174
+ } ,
175
+ } ) ;
176
+ }
0 commit comments