import { getQueue } from '@/lib/queue'; // ─── Types ──────────────────────────────────────────────────────────────────── export interface DraftRequest { interestId: string; clientId: string; portId: string; context: 'follow_up' | 'introduction' | 'stage_update' | 'general'; additionalInstructions?: string; } export interface DraftResult { subject: string; body: string; generatedAt: Date; } // ─── Request draft (enqueues job) ───────────────────────────────────────────── /** * Request an AI-generated email draft. * Enqueues a job on the 'ai' queue. Returns jobId for polling. * Job payload contains ONLY entity IDs (no PII). */ export async function requestEmailDraft( userId: string, request: DraftRequest, ): Promise<{ jobId: string }> { const aiQueue = getQueue('ai'); const job = await aiQueue.add('generate-email-draft', { // No PII — only IDs and context parameters interestId: request.interestId, clientId: request.clientId, portId: request.portId, context: request.context, additionalInstructions: request.additionalInstructions, requestedBy: userId, }); return { jobId: job.id! }; } // ─── Poll for result ────────────────────────────────────────────────────────── /** * Get the result of an email draft generation job. * Returns null if still processing. */ export async function getEmailDraftResult(jobId: string): Promise { const aiQueue = getQueue('ai'); const job = await aiQueue.getJob(jobId); if (!job) return null; const state = await job.getState(); if (state !== 'completed') return null; const returnValue = job.returnvalue as | { subject: string; body: string; generatedAt: string } | undefined | null; if (!returnValue) return null; return { subject: returnValue.subject, body: returnValue.body, generatedAt: new Date(returnValue.generatedAt), }; }