1+ import { createClient } from '@supabase/supabase-js'
2+ import { NextRequest , NextResponse } from 'next/server'
3+ import { z } from 'zod'
4+
5+ const supabaseUrl = process . env . NEXT_PUBLIC_SUPABASE_URL !
6+ const supabaseServiceRoleKey = process . env . SUPABASE_SERVICE_ROLE_KEY !
7+
8+ const supabase = createClient ( supabaseUrl , supabaseServiceRoleKey )
9+
10+ const updateProjectSchema = z . object ( {
11+ name : z . string ( ) . min ( 1 ) . max ( 50 ) . optional ( ) ,
12+ description : z . string ( ) . max ( 200 ) . optional ( ) ,
13+ visibility : z . enum ( [ 'private' , 'public' ] ) . optional ( ) ,
14+ template : z . string ( ) . optional ( ) ,
15+ } )
16+
17+ async function getUserFromAuth ( request : NextRequest ) {
18+ const authHeader = request . headers . get ( 'authorization' )
19+ if ( ! authHeader || ! authHeader . startsWith ( 'Bearer ' ) ) {
20+ return null
21+ }
22+
23+ const token = authHeader . substring ( 7 )
24+ const { data : { user } , error } = await supabase . auth . getUser ( token )
25+
26+ if ( error || ! user ) {
27+ return null
28+ }
29+
30+ return user
31+ }
32+
33+ // GET /api/projects/[id] - Get specific project
34+ export async function GET (
35+ request : NextRequest ,
36+ { params } : { params : { id : string } }
37+ ) {
38+ try {
39+ const user = await getUserFromAuth ( request )
40+ if ( ! user ) {
41+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
42+ }
43+
44+ const { data : project , error } = await supabase
45+ . from ( 'projects' )
46+ . select ( '*' )
47+ . eq ( 'id' , params . id )
48+ . eq ( 'user_id' , user . id )
49+ . single ( )
50+
51+ if ( error ) {
52+ if ( error . code === 'PGRST116' ) {
53+ return NextResponse . json ( { error : 'Project not found' } , { status : 404 } )
54+ }
55+ console . error ( 'Error fetching project:' , error )
56+ return NextResponse . json ( { error : 'Failed to fetch project' } , { status : 500 } )
57+ }
58+
59+ return NextResponse . json ( { project } )
60+ } catch ( error ) {
61+ console . error ( 'GET /api/projects/[id] error:' , error )
62+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
63+ }
64+ }
65+
66+ // PUT /api/projects/[id] - Update project
67+ export async function PUT (
68+ request : NextRequest ,
69+ { params } : { params : { id : string } }
70+ ) {
71+ try {
72+ const user = await getUserFromAuth ( request )
73+ if ( ! user ) {
74+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
75+ }
76+
77+ const body = await request . json ( )
78+ const validatedData = updateProjectSchema . parse ( body )
79+
80+ const { data : project , error } = await supabase
81+ . from ( 'projects' )
82+ . update ( {
83+ ...validatedData ,
84+ updated_at : new Date ( ) . toISOString ( ) ,
85+ } )
86+ . eq ( 'id' , params . id )
87+ . eq ( 'user_id' , user . id )
88+ . select ( )
89+ . single ( )
90+
91+ if ( error ) {
92+ if ( error . code === 'PGRST116' ) {
93+ return NextResponse . json ( { error : 'Project not found' } , { status : 404 } )
94+ }
95+ console . error ( 'Error updating project:' , error )
96+ return NextResponse . json ( { error : 'Failed to update project' } , { status : 500 } )
97+ }
98+
99+ return NextResponse . json ( { project } )
100+ } catch ( error ) {
101+ if ( error instanceof z . ZodError ) {
102+ return NextResponse . json ( { error : 'Invalid input' , details : error . errors } , { status : 400 } )
103+ }
104+
105+ console . error ( 'PUT /api/projects/[id] error:' , error )
106+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
107+ }
108+ }
109+
110+ // DELETE /api/projects/[id] - Delete project
111+ export async function DELETE (
112+ request : NextRequest ,
113+ { params } : { params : { id : string } }
114+ ) {
115+ try {
116+ const user = await getUserFromAuth ( request )
117+ if ( ! user ) {
118+ return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
119+ }
120+
121+ const { error } = await supabase
122+ . from ( 'projects' )
123+ . delete ( )
124+ . eq ( 'id' , params . id )
125+ . eq ( 'user_id' , user . id )
126+
127+ if ( error ) {
128+ console . error ( 'Error deleting project:' , error )
129+ return NextResponse . json ( { error : 'Failed to delete project' } , { status : 500 } )
130+ }
131+
132+ return NextResponse . json ( { success : true } )
133+ } catch ( error ) {
134+ console . error ( 'DELETE /api/projects/[id] error:' , error )
135+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
136+ }
137+ }
0 commit comments