import { NextResponse } from 'next/server'; import { and, desc, eq } from 'drizzle-orm'; import { withAuth, withPermission } from '@/lib/api/helpers'; import { db } from '@/lib/db'; import { interests } from '@/lib/db/schema/interests'; import { clientAddresses, clientContacts } from '@/lib/db/schema/clients'; import { errorResponse, NotFoundError } from '@/lib/errors'; import { buildEoiContext } from '@/lib/services/eoi-context'; /** * Returns the resolved `EoiContext` for the given interest. Drives the * EOI generate dialog's pre-flight preview so a sales rep can see (and * correct) every value before sending the document for signing. * * Augments the core context with `available.emails` / `available.phones` * — every non-deleted client_contacts row for the linked client. The * dialog renders these as combobox options so the rep can pick a * secondary contact for this EOI (Phase 3b). * * No mutation; pure read. */ export const GET = withAuth( withPermission('interests', 'view', async (_req, ctx, params) => { try { const context = await buildEoiContext(params.id!, ctx.portId); // Resolve the linked client to fetch every contact row. The core // context only carries the single "primary" value; the dialog needs // the full set to render the combobox. const interest = await db.query.interests.findFirst({ where: and(eq(interests.id, params.id!), eq(interests.portId, ctx.portId)), }); if (!interest) throw new NotFoundError('Interest'); const contactRows = await db .select({ id: clientContacts.id, channel: clientContacts.channel, value: clientContacts.value, isPrimary: clientContacts.isPrimary, source: clientContacts.source, }) .from(clientContacts) .where(eq(clientContacts.clientId, interest.clientId)) .orderBy(desc(clientContacts.isPrimary), desc(clientContacts.updatedAt)); const addressRows = await db .select({ id: clientAddresses.id, streetAddress: clientAddresses.streetAddress, city: clientAddresses.city, subdivisionIso: clientAddresses.subdivisionIso, postalCode: clientAddresses.postalCode, countryIso: clientAddresses.countryIso, isPrimary: clientAddresses.isPrimary, source: clientAddresses.source, }) .from(clientAddresses) .where(eq(clientAddresses.clientId, interest.clientId)) .orderBy(desc(clientAddresses.isPrimary), desc(clientAddresses.updatedAt)); const available = { emails: contactRows .filter((c) => c.channel === 'email') .map((c) => ({ id: c.id, value: c.value, isPrimary: c.isPrimary, source: c.source })), phones: contactRows .filter((c) => c.channel === 'phone' || c.channel === 'whatsapp') .map((c) => ({ id: c.id, value: c.value, isPrimary: c.isPrimary, channel: c.channel, source: c.source, })), addresses: addressRows, }; return NextResponse.json({ data: { ...context, available } }); } catch (error) { return errorResponse(error); } }), );