11import { and , eq } from 'drizzle-orm'
2- import { NextResponse } from 'next/server'
2+ import { type NextRequest , NextResponse } from 'next/server'
33import { getSession } from '@/lib/auth'
44import { createLogger } from '@/lib/logs/console-logger'
55import { db } from '@/db'
66import { workflow , workspaceMember } from '@/db/schema'
77
8- const logger = createLogger ( 'WorkflowDetailAPI ' )
8+ const logger = createLogger ( 'WorkflowByIdAPI ' )
99
10- export async function GET ( request : Request , { params } : { params : Promise < { id : string } > } ) {
10+ /**
11+ * GET /api/workflows/[id]
12+ * Fetch a single workflow by ID
13+ */
14+ export async function GET ( request : NextRequest , { params } : { params : Promise < { id : string } > } ) {
1115 const requestId = crypto . randomUUID ( ) . slice ( 0 , 8 )
1216 const startTime = Date . now ( )
17+ const { id : workflowId } = await params
1318
1419 try {
1520 // Get the session
1621 const session = await getSession ( )
1722 if ( ! session ?. user ?. id ) {
18- logger . warn ( `[${ requestId } ] Unauthorized workflow access attempt` )
23+ logger . warn ( `[${ requestId } ] Unauthorized access attempt for workflow ${ workflowId } ` )
1924 return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
2025 }
2126
22- const { id : workflowId } = await params
27+ const userId = session . user . id
2328
24- if ( ! workflowId ) {
25- return NextResponse . json ( { error : 'Workflow ID is required' } , { status : 400 } )
26- }
27-
28- // Fetch the workflow from database
29+ // Fetch the workflow
2930 const workflowData = await db
3031 . select ( )
3132 . from ( workflow )
@@ -38,42 +39,124 @@ export async function GET(request: Request, { params }: { params: Promise<{ id:
3839 }
3940
4041 // Check if user has access to this workflow
41- // User can access if they own it OR if it's in a workspace they're part of
42- const canAccess = workflowData . userId === session . user . id
42+ let hasAccess = false
43+
44+ // Case 1: User owns the workflow
45+ if ( workflowData . userId === userId ) {
46+ hasAccess = true
47+ }
4348
44- if ( ! canAccess && workflowData . workspaceId ) {
45- // Check workspace membership
49+ // Case 2: Workflow belongs to a workspace the user is a member of
50+ if ( ! hasAccess && workflowData . workspaceId ) {
4651 const membership = await db
47- . select ( )
52+ . select ( { id : workspaceMember . id } )
4853 . from ( workspaceMember )
4954 . where (
5055 and (
5156 eq ( workspaceMember . workspaceId , workflowData . workspaceId ) ,
52- eq ( workspaceMember . userId , session . user . id )
57+ eq ( workspaceMember . userId , userId )
5358 )
5459 )
5560 . then ( ( rows ) => rows [ 0 ] )
5661
5762 if ( membership ) {
58- // User is a member of the workspace, allow access
59- const elapsed = Date . now ( ) - startTime
60- logger . info ( `[${ requestId } ] Workflow ${ workflowId } fetched in ${ elapsed } ms` )
61- return NextResponse . json ( { data : workflowData } , { status : 200 } )
63+ hasAccess = true
64+ }
65+ }
66+
67+ if ( ! hasAccess ) {
68+ logger . warn ( `[${ requestId } ] User ${ userId } denied access to workflow ${ workflowId } ` )
69+ return NextResponse . json ( { error : 'Access denied' } , { status : 403 } )
70+ }
71+
72+ const elapsed = Date . now ( ) - startTime
73+ logger . info ( `[${ requestId } ] Successfully fetched workflow ${ workflowId } in ${ elapsed } ms` )
74+
75+ return NextResponse . json ( { data : workflowData } , { status : 200 } )
76+ } catch ( error : any ) {
77+ const elapsed = Date . now ( ) - startTime
78+ logger . error ( `[${ requestId } ] Error fetching workflow ${ workflowId } after ${ elapsed } ms` , error )
79+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
80+ }
81+ }
82+
83+ /**
84+ * DELETE /api/workflows/[id]
85+ * Delete a workflow by ID
86+ */
87+ export async function DELETE (
88+ request : NextRequest ,
89+ { params } : { params : Promise < { id : string } > }
90+ ) {
91+ const requestId = crypto . randomUUID ( ) . slice ( 0 , 8 )
92+ const startTime = Date . now ( )
93+ const { id : workflowId } = await params
94+
95+ try {
96+ // Get the session
97+ const session = await getSession ( )
98+ if ( ! session ?. user ?. id ) {
99+ logger . warn ( `[${ requestId } ] Unauthorized deletion attempt for workflow ${ workflowId } ` )
100+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
101+ }
102+
103+ const userId = session . user . id
104+
105+ // Fetch the workflow to check ownership/access
106+ const workflowData = await db
107+ . select ( )
108+ . from ( workflow )
109+ . where ( eq ( workflow . id , workflowId ) )
110+ . then ( ( rows ) => rows [ 0 ] )
111+
112+ if ( ! workflowData ) {
113+ logger . warn ( `[${ requestId } ] Workflow ${ workflowId } not found for deletion` )
114+ return NextResponse . json ( { error : 'Workflow not found' } , { status : 404 } )
115+ }
116+
117+ // Check if user has permission to delete this workflow
118+ let canDelete = false
119+
120+ // Case 1: User owns the workflow
121+ if ( workflowData . userId === userId ) {
122+ canDelete = true
123+ }
124+
125+ // Case 2: Workflow belongs to a workspace and user has admin/owner role
126+ if ( ! canDelete && workflowData . workspaceId ) {
127+ const membership = await db
128+ . select ( { role : workspaceMember . role } )
129+ . from ( workspaceMember )
130+ . where (
131+ and (
132+ eq ( workspaceMember . workspaceId , workflowData . workspaceId ) ,
133+ eq ( workspaceMember . userId , userId )
134+ )
135+ )
136+ . then ( ( rows ) => rows [ 0 ] )
137+
138+ if ( membership && ( membership . role === 'owner' || membership . role === 'admin' ) ) {
139+ canDelete = true
62140 }
63- } else if ( canAccess ) {
64- // User owns the workflow, allow access
65- const elapsed = Date . now ( ) - startTime
66- logger . info ( `[${ requestId } ] Workflow ${ workflowId } fetched in ${ elapsed } ms` )
67- return NextResponse . json ( { data : workflowData } , { status : 200 } )
68141 }
69142
70- logger . warn (
71- `[${ requestId } ] User ${ session . user . id } attempted to access workflow ${ workflowId } without permission`
72- )
73- return NextResponse . json ( { error : 'Access denied' } , { status : 403 } )
143+ if ( ! canDelete ) {
144+ logger . warn (
145+ `[${ requestId } ] User ${ userId } denied permission to delete workflow ${ workflowId } `
146+ )
147+ return NextResponse . json ( { error : 'Access denied' } , { status : 403 } )
148+ }
149+
150+ // Delete the workflow
151+ await db . delete ( workflow ) . where ( eq ( workflow . id , workflowId ) )
152+
153+ const elapsed = Date . now ( ) - startTime
154+ logger . info ( `[${ requestId } ] Successfully deleted workflow ${ workflowId } in ${ elapsed } ms` )
155+
156+ return NextResponse . json ( { success : true } , { status : 200 } )
74157 } catch ( error : any ) {
75158 const elapsed = Date . now ( ) - startTime
76- logger . error ( `[${ requestId } ] Error fetching workflow after ${ elapsed } ms: ` , error )
77- return NextResponse . json ( { error : 'Failed to fetch workflow ' } , { status : 500 } )
159+ logger . error ( `[${ requestId } ] Error deleting workflow ${ workflowId } after ${ elapsed } ms` , error )
160+ return NextResponse . json ( { error : 'Internal server error ' } , { status : 500 } )
78161 }
79162}
0 commit comments