/**
* API Route: /api/notifications
*
* GET: Fetch user's notifications with pagination
*/
import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@/auth';
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
export async function GET(request: NextRequest) {
try {
const session = await auth();
if (!session?.user?.id) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
const searchParams = request.nextUrl.searchParams;
const limit = parseInt(searchParams.get('limit') || '20');
const offset = parseInt(searchParams.get('offset') || '0');
const unreadOnly = searchParams.get('unread_only') === 'true';
// Build query
let query = supabase
.from('notifications')
.select(`
id,
type,
title,
message,
related_entity_type,
related_entity_id,
read_at,
created_at,
actor:actor_id (
id,
username,
display_name,
avatar_url
)
`, { count: 'exact' })
.eq('user_id', session.user.id)
.order('created_at', { ascending: false })
.range(offset, offset + limit - 1);
// Filter by read status if requested
if (unreadOnly) {
query = query.is('read_at', null);
}
const { data: notifications, error, count } = await query;
if (error) {
console.error('Error fetching notifications:', error);
return NextResponse.json(
{ error: 'Failed to fetch notifications' },
{ status: 500 }
);
}
return NextResponse.json({
notifications: notifications || [],
count: count || 0,
hasMore: (count || 0) > offset + limit,
});
} catch (error) {
console.error('Error in GET /api/notifications:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}