export type OracleCanvasView = | 'pipeline' | 'team_performance' | 'account_timeline' | 'lead_map' | 'calendar_tasks'; export interface OracleQueryPayload { prompt: string; history: Array<{ role: 'user' | 'assistant'; content: string }>; mode: 'cot-rag'; preferredView?: OracleCanvasView; } export interface PipelineCardData { id: string; name: string; company: string; value: string; avatar: string; } export interface TeamMemberData { id: string; name: string; dealsClosed: number; revenueGenerated: string; avatar: string; } export interface TimelineEvent { id: string; type: 'email' | 'meeting' | 'call'; title: string; when: string; summary: string; } export interface CalendarEventData { id: string; day: string; time: string; title: string; suggested?: boolean; } export interface OracleQueryResult { view: OracleCanvasView; insight: string; summary: string; payload: { pipeline?: Record; revenueSeries?: Array<{ month: string; revenue: number; goal: number }>; quotaAttainment?: number; team?: TeamMemberData[]; account?: { name: string; totalDealValue: string; primaryContact: string; industry: string; contacts: Array<{ name: string; role: string; avatar: string }>; timeline: TimelineEvent[]; }; map?: { region: string; pins: Array<{ id: string; label: string; x: number; y: number; temperature: 'cold' | 'warm' | 'hot'; count?: number; }>; }; calendar?: { weekLabel: string; events: CalendarEventData[]; tasks: Array<{ id: string; title: string; subtitle: string; due: string }>; }; }; } export const DEFAULT_ORACLE_RESULT: OracleQueryResult = { view: 'pipeline', insight: 'Pipeline Velocity: Average deal cycle is 21 days, 10% faster than Q3.', summary: 'Pipeline view generated for Q4 by stage.', payload: { pipeline: { 'New Leads': [ { id: 'n1', name: 'Elena Rostova', company: 'Rostova Ventures', value: '$120k', avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=80&q=80', }, { id: 'n2', name: 'Mary Iluskimon', company: 'Nexloop', value: '$130k', avatar: 'https://images.unsplash.com/photo-1554151228-14d9def656e4?auto=format&fit=crop&w=80&q=80', }, ], Qualified: [ { id: 'q1', name: 'Etlena Roya', company: 'Mianaperson', value: '$120k', avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?auto=format&fit=crop&w=80&q=80', }, { id: 'q2', name: 'Silver Rostova', company: 'Silverline Co', value: '$130k', avatar: 'https://images.unsplash.com/photo-1542206395-9feb3edaa68d?auto=format&fit=crop&w=80&q=80', }, ], 'Proposal Sent': [ { id: 'p1', name: 'Magulanta Senneciton', company: 'Senneciton', value: '$140k', avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&w=80&q=80', }, { id: 'p2', name: 'Minatie Ganrison', company: 'Ganrison Group', value: '$130k', avatar: 'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?auto=format&fit=crop&w=80&q=80', }, ], Negotiation: [ { id: 'g1', name: 'Jomath Bilotmberg', company: 'Biotmberg', value: '$130k', avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=80&q=80', }, { id: 'g2', name: 'Josen Oateliars', company: 'Oateliars', value: '$100k', avatar: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&w=80&q=80', }, ], }, }, }; const VIEW_TO_PROMPT: Record = { pipeline: 'Show me a pipeline view by stage for Q4.', team_performance: "What's the performance of the sales team this month?", account_timeline: "Find all contacts at 'Apex Innovations' and their recent activity.", lead_map: 'Give me a map of all leads in California.', calendar_tasks: 'Schedule a follow-up with the top 3 high-value leads.', }; export function mockOracleResultForPrompt(prompt: string): OracleQueryResult { const text = prompt.toLowerCase(); if (text.includes('performance') || text.includes('team')) { return { view: 'team_performance', insight: 'Team is on track to exceed monthly quota by 15%.', summary: 'Performance dashboard for current month.', payload: { revenueSeries: [ { month: 'Jan', revenue: 10, goal: 20 }, { month: 'Feb', revenue: 30, goal: 35 }, { month: 'Mar', revenue: 28, goal: 40 }, { month: 'Sep', revenue: 52, goal: 55 }, { month: 'Oct', revenue: 56, goal: 60 }, { month: 'Nov', revenue: 74, goal: 70 }, { month: 'Dec', revenue: 88, goal: 80 }, ], quotaAttainment: 85, team: [ { id: 't1', name: 'Elena Rostova', dealsClosed: 12, revenueGenerated: '$1.2M', avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=80&q=80', }, { id: 't2', name: 'Etlena Roya', dealsClosed: 12, revenueGenerated: '$1.2M', avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?auto=format&fit=crop&w=80&q=80', }, { id: 't3', name: 'Minatie Ganrison', dealsClosed: 13, revenueGenerated: '$1.2M', avatar: 'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?auto=format&fit=crop&w=80&q=80', }, { id: 't4', name: 'Josen Oateliars', dealsClosed: 18, revenueGenerated: '$0.8M', avatar: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&w=80&q=80', }, ], }, }; } if (text.includes('apex') || text.includes('activity') || text.includes('contacts')) { return { view: 'account_timeline', insight: "Action: Schedule a check-in call with Apex's CEO regarding the proposal.", summary: 'Account history and associated contacts for Apex Innovations.', payload: { account: { name: 'Apex Innovations', totalDealValue: '$4.5M', primaryContact: 'Elena Rostova, CEO', industry: 'Technology', contacts: [ { name: 'Elena Rostova', role: 'CEO', avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?auto=format&fit=crop&w=80&q=80', }, { name: 'Mary Iluskimon', role: 'COO', avatar: 'https://images.unsplash.com/photo-1554151228-14d9def656e4?auto=format&fit=crop&w=80&q=80', }, { name: 'Entin Veenos', role: 'VP Finance', avatar: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&w=80&q=80', }, ], timeline: [ { id: 'a1', type: 'email', title: 'Email Sent', when: 'Today, 10:30 AM', summary: 'Proposal Follow-up', }, { id: 'a2', type: 'meeting', title: 'Meeting', when: 'Yesterday, 2:00 PM', summary: 'Q4 Strategy', }, { id: 'a3', type: 'call', title: 'Call Logged', when: 'Yesterday, 6:20 PM', summary: 'Discussed pricing', }, ], }, }, }; } if (text.includes('map') || text.includes('california') || text.includes('geographic')) { return { view: 'lead_map', insight: 'Insight: 60% of high-value leads are concentrated in the Bay Area.', summary: 'Geographic lead distribution in California.', payload: { map: { region: 'California', pins: [ { id: 'm1', label: 'SF', x: 26, y: 32, temperature: 'warm', count: 24 }, { id: 'm2', label: 'Oakland', x: 29, y: 35, temperature: 'cold', count: 19 }, { id: 'm3', label: 'San Jose', x: 32, y: 42, temperature: 'hot' }, { id: 'm4', label: 'LA', x: 44, y: 78, temperature: 'warm', count: 8 }, { id: 'm5', label: 'San Diego', x: 46, y: 88, temperature: 'cold' }, { id: 'm6', label: 'Sacramento', x: 36, y: 28, temperature: 'hot' }, ], }, }, }; } if (text.includes('schedule') || text.includes('calendar') || text.includes('follow-up')) { return { view: 'calendar_tasks', insight: "Scheduling: Proposed times minimize conflicts and align with contact's preferred hours.", summary: 'Weekly calendar and follow-up actions generated.', payload: { calendar: { weekLabel: 'Week 21', events: [ { id: 'c1', day: 'Mon', time: '10:00', title: 'Elena Rostova' }, { id: 'c2', day: 'Tue', time: '12:00', title: 'Appointments' }, { id: 'c3', day: 'Wed', time: '13:00', title: 'Follow-up', suggested: true }, { id: 'c4', day: 'Thu', time: '14:00', title: 'Meeting' }, { id: 'c5', day: 'Fri', time: '12:00', title: 'Follow-up', suggested: true }, ], tasks: [ { id: 'k1', title: 'Follow-up', subtitle: 'Elena Rostova', due: 'Due Today' }, { id: 'k2', title: 'Prepare Proposal', subtitle: 'Apex Innovations', due: 'Due Tomorrow' }, { id: 'k3', title: 'Confirm Slot', subtitle: 'Mr. Kapoor', due: 'Due Today' }, ], }, }, }; } return DEFAULT_ORACLE_RESULT; } export async function queryOracle(payload: OracleQueryPayload): Promise { const endpoint = import.meta.env.VITE_ORACLE_QUERY_URL; if (!endpoint) { if (payload.preferredView) { return mockOracleResultForPrompt(VIEW_TO_PROMPT[payload.preferredView]); } return mockOracleResultForPrompt(payload.prompt); } const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); if (!response.ok) { throw new Error(`Oracle query failed with ${response.status}`); } return (await response.json()) as OracleQueryResult; }