import type { DashboardPath } from '@/lib/dashboard/path-types' function excerpt(text: string, max = 120): string { const plain = text.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim() if (plain.length <= max) return plain return `${plain.slice(0, max)}…` } export interface BriefingPathsInput { recentNotes: Array<{ id: string title: string | null content: string notebookId: string | null }> inboxCount: number dueFlashcards: number insights: Array<{ id: string insight: string score: number viewed: boolean note1: { id: string; title: string | null } note2: { id: string; title: string | null } note1Excerpt?: string note2Excerpt?: string }> bridgeSuggestions: Array<{ clusterAId: number clusterBId: number clusterAName: string clusterBName: string suggestedTitle: string suggestedContent: string justification: string }> agentSuggestions: Array<{ id: string topic: string reason: string clusterId: number | null }> } /** Pistes instantanées à partir du briefing déjà chargé — sans requête lourde. */ export function buildFastPathsFromBriefing(input: BriefingPathsInput): DashboardPath[] { const paths: DashboardPath[] = [] const focus = input.recentNotes[0] if (focus) { paths.push({ id: `continue-${focus.id}`, type: 'continue', priority: 100, title: focus.title || 'Untitled', description: excerpt(focus.content, 140), actionKey: 'continue', noteId: focus.id, notebookId: focus.notebookId ?? undefined, }) for (const ins of input.insights .filter(i => i.note1.id === focus.id || i.note2.id === focus.id) .slice(0, 2)) { const other = ins.note1.id === focus.id ? ins.note2 : ins.note1 paths.push({ id: `connect-${focus.id}-${other.id}`, type: 'connect', priority: 88, title: other.title || 'Untitled', description: ins.insight, actionKey: 'compare', noteId: focus.id, note2Id: other.id, notebookId: focus.notebookId ?? undefined, score: Math.round(ins.score * 100), }) } } const freshInsight = input.insights.find(i => !i.viewed) if (freshInsight) { paths.push({ id: `resurface-${freshInsight.id}`, type: 'resurface', priority: 85, title: `${freshInsight.note1.title || '…'} ↔ ${freshInsight.note2.title || '…'}`, description: freshInsight.insight, actionKey: 'openInsight', insightId: freshInsight.id, noteId: freshInsight.note1.id, note2Id: freshInsight.note2.id, score: Math.round(freshInsight.score * 100), }) } for (const bridge of input.bridgeSuggestions.slice(0, 2)) { paths.push({ id: `bridge-${bridge.clusterAId}-${bridge.clusterBId}`, type: 'bridge', priority: 70, title: bridge.suggestedTitle, description: bridge.justification || bridge.suggestedContent.slice(0, 140), actionKey: 'createBridge', clusterAId: bridge.clusterAId, clusterBId: bridge.clusterBId, notebookId: focus?.notebookId ?? undefined, }) } for (const agent of input.agentSuggestions.slice(0, 2)) { paths.push({ id: `research-${agent.id}`, type: 'research', priority: 65, title: agent.topic, description: agent.reason, actionKey: 'createAgent', agentSuggestionId: agent.id, notebookId: focus?.notebookId ?? undefined, }) } if (input.inboxCount > 0) { paths.push({ id: 'organize-inbox', type: 'organize', priority: 60, title: `${input.inboxCount} notes`, description: 'inbox', actionKey: 'organizeInbox', }) } if (input.dueFlashcards > 0) { paths.push({ id: 'review-flashcards', type: 'review', priority: 55, title: `${input.dueFlashcards}`, description: 'flashcards', actionKey: 'reviewCards', }) } paths.push({ id: 'daily-journal', type: 'daily', priority: 40, title: new Date().toISOString().slice(0, 10), description: 'daily', actionKey: 'openDaily', }) return paths.sort((a, b) => b.priority - a.priority).slice(0, 8) }