Generate route file — Create src/app/api/<path>/route.ts with handlers for each method. Use this template per method:
GET (list):
export async function GET() {
try {
const { userId } = await requireAuth()
const supabase = await createClient()
const { data, error } = await supabase
.from('TABLE_NAME')
.select('*')
.eq('user_id', userId)
if (error) throw error
return Response.json({ items: data })
} catch (error) {
if ((error as Error).message === 'Unauthorized') {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
return Response.json({ error: 'Internal server error' }, { status: 500 })
}
}
POST (create):
export async function POST(request: Request) {
try {
const { userId } = await requireAuth()
const supabase = await createClient()
const body = await request.json()
const { data, error } = await supabase
.from('TABLE_NAME')
.insert({ ...body, user_id: userId })
.select()
.single()
if (error) throw error
return Response.json({ item: data }, { status: 201 })
} catch (error) {
if ((error as Error).message === 'Unauthorized') {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
return Response.json({ error: 'Internal server error' }, { status: 500 })
}
}
PUT (update):
export async function PUT(request: Request) {
try {
const { userId } = await requireAuth()
const supabase = await createClient()
const body = await request.json()
const { id, ...updates } = body
const { data, error } = await supabase
.from('TABLE_NAME')
.update(updates)
.eq('id', id)
.eq('user_id', userId)
.select()
.single()
if (error) throw error
return Response.json({ item: data })
} catch (error) {
if ((error as Error).message === 'Unauthorized') {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
return Response.json({ error: 'Internal server error' }, { status: 500 })
}
}
DELETE:
export async function DELETE(request: Request) {
try {
const { userId } = await requireAuth()
const supabase = await createClient()
const { searchParams } = new URL(request.url)
const id = searchParams.get('id')
if (!id) {
return Response.json({ error: 'Missing id' }, { status: 400 })
}
const { error } = await supabase
.from('TABLE_NAME')
.delete()
.eq('id', id)
.eq('user_id', userId)
if (error) throw error
return Response.json({ success: true })
} catch (error) {
if ((error as Error).message === 'Unauthorized') {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
return Response.json({ error: 'Internal server error' }, { status: 500 })
}
}