import { Prisma, ListingStatus } from '@prisma/client'; import { prisma } from './prisma'; import { DEFAULT_LOCALE, SAMPLE_LISTING_SLUG } from './sampleListing'; export type ListingWithTranslations = Prisma.ListingTranslationGetPayload<{ include: { listing: { include: { images: { select: { id: true; url: true; altText: true; order: true; isCover: true; size: true; mimeType: true } }; owner: true; }; }; }; }>; type FetchOptions = { slug: string; locale?: string; }; function resolveImageUrl(img: { id: string; url: string | null; size: number | null }) { if (img.size && img.size > 0) { return `/api/images/${img.id}`; } return img.url; } /** * Fetch a listing translation by slug and locale. * Falls back to any locale if the requested locale is missing. */ export async function getListingBySlug({ slug, locale }: FetchOptions): Promise { const targetLocale = locale ?? DEFAULT_LOCALE; const translation = await prisma.listingTranslation.findFirst({ where: { slug, locale: targetLocale, listing: { status: ListingStatus.PUBLISHED, removedAt: null } }, include: { listing: { include: { images: { orderBy: { order: 'asc' }, select: { id: true, url: true, altText: true, order: true, isCover: true, size: true, mimeType: true } }, owner: true, }, }, }, }); if (translation) { return translation; } // Fallback: first translation for this slug return prisma.listingTranslation.findFirst({ where: { slug, listing: { status: ListingStatus.PUBLISHED, removedAt: null } }, include: { listing: { include: { images: { orderBy: { order: 'asc' }, select: { id: true, url: true, altText: true, order: true, isCover: true, size: true, mimeType: true } }, owner: true, }, }, }, orderBy: { createdAt: 'asc' }, }); } export function withResolvedListingImages(translation: ListingWithTranslations): ListingWithTranslations { const images = translation.listing.images .map((img) => { const url = resolveImageUrl(img); if (!url) return null; return { ...img, url }; }) .filter(Boolean) as ListingWithTranslations['listing']['images']; return { ...translation, listing: { ...translation.listing, images, }, }; } export { SAMPLE_LISTING_SLUG, DEFAULT_LOCALE };