import { NextResponse } from 'next/server'; import { ListingStatus, UserStatus } from '@prisma/client'; import { prisma } from '../../../../../lib/prisma'; import { loadN8nBillingApiKey } from '../../../../../lib/apiKeys'; import { resolveBillingDetails } from '../../../../../lib/billing'; function pickTranslation(translations: { slug: string; locale: string }[]) { return translations.find((t) => t.locale === 'en') || translations.find((t) => t.locale === 'fi') || translations[0] || null; } function extractApiKey(req: Request) { const headerKey = req.headers.get('x-api-key'); if (headerKey) return headerKey.trim(); const auth = req.headers.get('authorization'); if (auth && auth.toLowerCase().startsWith('bearer ')) { return auth.slice(7).trim(); } return null; } export async function POST(req: Request) { const expectedKey = loadN8nBillingApiKey(); if (!expectedKey) { return NextResponse.json({ error: 'Billing API key missing' }, { status: 500 }); } const providedKey = extractApiKey(req); if (!providedKey || providedKey !== expectedKey) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } let body: any; try { body = await req.json(); } catch { return NextResponse.json({ error: 'Invalid payload' }, { status: 400 }); } const listingId = typeof body.listingId === 'string' ? body.listingId : undefined; const listingSlug = typeof body.listingSlug === 'string' ? body.listingSlug.trim() : undefined; const ownerEmailRaw = typeof body.ownerEmail === 'string' ? body.ownerEmail.trim() : undefined; const ownerEmail = ownerEmailRaw ? ownerEmailRaw.toLowerCase() : undefined; if (!listingId && !listingSlug && !ownerEmail) { return NextResponse.json({ error: 'Provide listingId, listingSlug, or ownerEmail' }, { status: 400 }); } let listing: any = null; if (listingId || listingSlug) { const listings = await prisma.listing.findMany({ where: { removedAt: null, status: { not: ListingStatus.REMOVED }, id: listingId ?? undefined, translations: listingSlug ? { some: { slug: listingSlug } } : undefined, }, include: { owner: { select: { id: true, email: true, status: true, approvedAt: true, emailVerifiedAt: true, billingEmailsEnabled: true, billingAccountName: true, billingIban: true, billingIncludeVatLine: true, }, }, translations: { select: { slug: true, locale: true } }, }, take: listingSlug ? 2 : 1, }); if (listingSlug && listings.length > 1) { return NextResponse.json({ error: 'Listing slug is ambiguous; provide listingId' }, { status: 400 }); } listing = listings[0] ?? null; if (!listing && listingId) { return NextResponse.json({ error: 'Listing not found' }, { status: 404 }); } if (!listing && listingSlug) { return NextResponse.json({ error: 'Listing not found' }, { status: 404 }); } } let owner = listing?.owner ?? null; if (!owner && ownerEmail) { owner = await prisma.user.findFirst({ where: { email: { equals: ownerEmail, mode: 'insensitive' } }, select: { id: true, email: true, status: true, approvedAt: true, emailVerifiedAt: true, billingEmailsEnabled: true, billingAccountName: true, billingIban: true, billingIncludeVatLine: true, }, }); } if (!owner) { return NextResponse.json({ enabled: false }); } const ownerReady = owner.status === UserStatus.ACTIVE && owner.approvedAt && owner.emailVerifiedAt; if (!ownerReady || !owner.billingEmailsEnabled) { return NextResponse.json({ enabled: false, owner: { id: owner.id, email: owner.email } }); } const billing = resolveBillingDetails(owner, listing ?? undefined); const enabled = Boolean(billing.accountName && billing.iban); const listingHasOverride = listing && (listing.billingAccountName !== null && listing.billingAccountName !== undefined || listing.billingIban !== null && listing.billingIban !== undefined || listing.billingIncludeVatLine !== null && listing.billingIncludeVatLine !== undefined); const source = listingHasOverride ? 'listing' : 'user'; return NextResponse.json({ enabled, owner: { id: owner.id, email: owner.email }, listing: listing ? { id: listing.id, slug: pickTranslation(listing.translations)?.slug ?? listing.translations[0]?.slug ?? null, status: listing.status, } : null, billing: enabled ? { ...billing, source } : null, }); } export const dynamic = 'force-dynamic';