nextav/src/app/api/clusters/[id]/photos/route.ts

85 lines
2.4 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getDatabase } from '@/db';
/**
* GET /api/clusters/[id]/photos
* Get all photos from cluster libraries with pagination
*/
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const { searchParams } = new URL(request.url);
const db = getDatabase();
const clusterId = parseInt(id);
const limit = parseInt(searchParams.get('limit') || '50');
const offset = parseInt(searchParams.get('offset') || '0');
const search = searchParams.get('search');
if (isNaN(clusterId)) {
return NextResponse.json({ error: 'Invalid cluster ID' }, { status: 400 });
}
// Check cluster exists
const cluster = db.prepare('SELECT * FROM clusters WHERE id = ?').get(clusterId);
if (!cluster) {
return NextResponse.json({ error: 'Cluster not found' }, { status: 404 });
}
let query = `
SELECT m.*, l.path as library_path
FROM media m
INNER JOIN libraries l ON m.library_id = l.id
INNER JOIN library_cluster_mapping lcm ON l.id = lcm.library_id
WHERE lcm.cluster_id = ? AND m.type = 'photo'
`;
const params: any[] = [clusterId];
if (search) {
query += ' AND (m.title LIKE ? OR m.path LIKE ?)';
params.push(`%${search}%`, `%${search}%`);
}
query += ' ORDER BY m.created_at DESC LIMIT ? OFFSET ?';
params.push(limit, offset);
const photos = db.prepare(query).all(...params);
// Get total count
let countQuery = `
SELECT COUNT(*) as count
FROM media m
INNER JOIN libraries l ON m.library_id = l.id
INNER JOIN library_cluster_mapping lcm ON l.id = lcm.library_id
WHERE lcm.cluster_id = ? AND m.type = 'photo'
`;
const countParams: any[] = [clusterId];
if (search) {
countQuery += ' AND (m.title LIKE ? OR m.path LIKE ?)';
countParams.push(`%${search}%`, `%${search}%`);
}
const { count } = db.prepare(countQuery).get(...countParams) as { count: number };
return NextResponse.json({
photos,
total: count,
limit,
offset,
hasMore: offset + photos.length < count
});
} catch (error: any) {
console.error('Error fetching cluster photos:', error);
return NextResponse.json(
{ error: error.message },
{ status: 500 }
);
}
}