@@ -2,6 +2,16 @@ import { NextResponse } from "next/server";
22import { getServerSession } from "next-auth" ;
33import { authOptions } from "@/lib/auth" ;
44import prisma from "@/lib/prisma" ;
5+
6+ const getMembership = async ( userId : string , workspaceId : string ) => {
7+ return await prisma . workspaceMember . findFirst ( {
8+ where : { userId, workspaceId } ,
9+ } ) ;
10+ } ;
11+
12+
13+
14+
515import { Prisma } from "@prisma/client" ;
616
717import { validatePlatformUrl , detectPlatform , slugifyPlatform , isKnownPlatform , type Platform } from "@/lib/platforms" ;
@@ -53,12 +63,25 @@ export async function PUT(
5363 ? rawExplicitPlatform as Platform
5464 : null ;
5565
66+ const user = await prisma . user . findUnique ( {
67+ where : { email : session . user . email } ,
68+ select : { id : true } ,
69+ } ) ;
70+
71+ if ( ! user ) {
72+ return NextResponse . json ( { error : "Unauthorized" } , { status : 401 } ) ;
73+ }
74+
5675 const link = await prisma . link . findUnique ( {
5776 where : { id } ,
58- include : { user : true } ,
5977 } ) ;
6078
61- if ( ! link || link . user . email !== session . user . email ) {
79+ if ( ! link ) {
80+ return NextResponse . json ( { error : "Not Found" } , { status : 404 } ) ;
81+ }
82+
83+ const membership = await getMembership ( user . id , link . workspaceId ) ;
84+ if ( ! membership ) {
6285 return NextResponse . json ( { error : "Forbidden" } , { status : 403 } ) ;
6386 }
6487
@@ -76,7 +99,7 @@ export async function PUT(
7699 data . parentId = null ;
77100 } else {
78101 const parentGroup = await prisma . link . findFirst ( {
79- where : { id : parentId , userId : link . userId , isGroup : true } ,
102+ where : { id : parentId , workspaceId : link . workspaceId , isGroup : true } ,
80103 } ) ;
81104 if ( ! parentGroup ) {
82105 return NextResponse . json (
@@ -197,7 +220,7 @@ export async function PUT(
197220 const proposedRoute = link . alias || data . platform ;
198221 const existingLink = await tx . link . findFirst ( {
199222 where : {
200- userId : link . userId ,
223+ workspaceId : link . workspaceId ,
201224 id : { not : link . id } ,
202225 isGroup : false ,
203226 OR : [
@@ -277,12 +300,25 @@ export async function DELETE(
277300 // No body is fine for regular link deletion
278301 }
279302
303+ const user = await prisma . user . findUnique ( {
304+ where : { email : session . user . email } ,
305+ select : { id : true } ,
306+ } ) ;
307+
308+ if ( ! user ) {
309+ return NextResponse . json ( { error : "Unauthorized" } , { status : 401 } ) ;
310+ }
311+
280312 const link = await prisma . link . findUnique ( {
281313 where : { id } ,
282- include : { user : true } ,
283314 } ) ;
284315
285- if ( ! link || link . user . email !== session . user . email ) {
316+ if ( ! link ) {
317+ return NextResponse . json ( { error : "Not Found" } , { status : 404 } ) ;
318+ }
319+
320+ const membership = await getMembership ( user . id , link . workspaceId ) ;
321+ if ( ! membership ) {
286322 return NextResponse . json ( { error : "Forbidden" } , { status : 403 } ) ;
287323 }
288324
@@ -292,17 +328,17 @@ export async function DELETE(
292328 if ( deleteChildren ) {
293329 // Delete all children first, then the group
294330 await tx . link . deleteMany ( {
295- where : { parentId : id , userId : link . userId } ,
331+ where : { parentId : id , workspaceId : link . workspaceId } ,
296332 } ) ;
297333 } else {
298334 // Ungroup: set children's parentId to null and reassign positions
299335 const children = await tx . link . findMany ( {
300- where : { parentId : id , userId : link . userId } ,
336+ where : { parentId : id , workspaceId : link . workspaceId } ,
301337 orderBy : { position : 'asc' } ,
302338 } ) ;
303339
304340 const maxOrder = await tx . link . aggregate ( {
305- where : { userId : link . userId , parentId : null } ,
341+ where : { workspaceId : link . workspaceId , parentId : null } ,
306342 _max : { position : true } ,
307343 } ) ;
308344
@@ -321,13 +357,47 @@ export async function DELETE(
321357 return NextResponse . json ( { success : true } ) ;
322358 }
323359
360+ // A/B test variant reversion logic
361+ if ( link . abTestParentId ) {
362+ const parentId = link . abTestParentId ;
363+ await prisma . $transaction ( async ( tx ) => {
364+ // Find the sibling variant
365+ const sibling = await tx . link . findFirst ( {
366+ where : {
367+ abTestParentId : parentId ,
368+ id : { not : id } ,
369+ } ,
370+ } ) ;
371+
372+ if ( sibling ) {
373+ // Revert sibling to a standard link
374+ let cleanPlatform = sibling . platform ;
375+ if ( cleanPlatform . endsWith ( "__ab_b" ) ) {
376+ cleanPlatform = cleanPlatform . replace ( / _ _ a b _ b $ / , "" ) ;
377+ }
378+ await tx . link . update ( {
379+ where : { id : sibling . id } ,
380+ data : {
381+ abTestVariant : null ,
382+ abTestParentId : null ,
383+ platform : cleanPlatform ,
384+ } ,
385+ } ) ;
386+ }
387+
388+ // Delete the requested link
389+ await tx . link . delete ( {
390+ where : { id } ,
391+ } ) ;
392+ } ) ;
393+
394+ return NextResponse . json ( { success : true } ) ;
395+ }
396+
324397 // Regular link deletion
325398 await prisma . link . delete ( {
326399 where : { id } ,
327400 } ) ;
328401
329402 return NextResponse . json ( { success : true } ) ;
330403}
331-
332-
333-
0 commit comments