import { prisma } from './db'; export interface SearchFilters { people?: number[]; tags?: number[]; dateFrom?: Date; dateTo?: Date; mediaType?: 'all' | 'photos' | 'videos'; page?: number; pageSize?: number; } export async function searchPhotos(filters: SearchFilters) { const { people = [], tags = [], dateFrom, dateTo, mediaType = 'all', page = 1, pageSize = 30, } = filters; const skip = (page - 1) * pageSize; // Build where clause const where: any = { processed: true, }; // Media type filter if (mediaType !== 'all') { if (mediaType === 'photos') { where.media_type = 'image'; } else if (mediaType === 'videos') { where.media_type = 'video'; } } // Date filter if (dateFrom || dateTo) { where.date_taken = {}; if (dateFrom) { where.date_taken.gte = dateFrom; } if (dateTo) { where.date_taken.lte = dateTo; } } // People filter (photo has face with person_id in list) if (people.length > 0) { where.faces = { some: { personId: { in: people }, }, }; } // Tags filter if (tags.length > 0) { where.PhotoTagLinkage = { some: { tagId: { in: tags }, }, }; } // Execute query const [photos, total] = await Promise.all([ prisma.photo.findMany({ where, include: { Face: { include: { Person: true, }, }, PhotoTagLinkage: { include: { Tag: true, }, }, }, orderBy: { date_taken: 'desc' }, skip, take: pageSize, }), prisma.photo.count({ where }), ]); return { photos, total, page, pageSize, totalPages: Math.ceil(total / pageSize), }; } export async function getAllPeople() { return prisma.person.findMany({ orderBy: [ { first_name: 'asc' }, { last_name: 'asc' }, ], }); } export async function getAllTags() { return prisma.tag.findMany({ orderBy: { tag_name: 'asc' }, }); }