import type { PipelineItem } from '../../domain/pipeline' export { matchScoreHex as scoreColor } from '../../lib/utils' export function detailPath(item: PipelineItem): string | null { // Both 'match-XXX' (static mock) and 'm__...' (deterministic dynamic) IDs are stable across sessions const isStableMatchId = item.matchId?.startsWith('match-') || item.matchId?.startsWith('m__') if (isStableMatchId) return `/demand/results/${item.matchId}` if (item.propertyId) return `/demand/property/${item.propertyId}` if (item.matchId) return `/demand/results/${item.matchId}` return null } export function getKiInsight(item: PipelineItem): { summary: string; positives: string[]; risks: string[] } { if (item.stage === 'SAVED') return { summary: `Merkliste-Eintrag mit ${item.matchScore}% Match. Prüfen Sie, ob dieses Objekt qualifiziert werden soll.`, positives: [`Match ${item.matchScore}%`], risks: ['Noch nicht qualifiziert'], } if (item.stage === 'CLOSED_WON') return { summary: `Abschluss erfolgreich. ${item.title} wurde zu ${item.matchScore}% Match abgeschlossen.`, positives: ['Vertraglich gesichert', `Match ${item.matchScore}%`, 'Alle Kriterien erfüllt'], risks: [], } if (item.stage === 'CLOSED_LOST') return { summary: item.notes ?? 'Objekt nicht realisiert.', positives: [], risks: ['Nicht verfügbar', 'Alternative Optionen prüfen'], } const s = item.matchScore return { summary: s >= 80 ? `Starkes Objekt (${s}%) — deckt die wesentlichen Suchkriterien ab. Prozess aktiv weitertreiben.` : s >= 65 ? `Solides Objekt (${s}%) mit Potenzial. Gezielte Klärung offener Punkte empfohlen.` : `Schwächerer Match (${s}%). Abweichungen kritisch prüfen bevor weitere Ressourcen investiert werden.`, positives: [ ...(s >= 80 ? [`Match ${s}% — hohe Übereinstimmung`] : []), ...(item.areaLabel ? [`Fläche: ${item.areaLabel}`] : []), ...(item.resultType === 'VERIFIED_PORTFOLIO' ? ['Geprüftes Portfolio-Objekt'] : []), ...(item.stage === 'NEGOTIATION' ? ['Verhandlung läuft — kurz vor Abschluss'] : []), ].slice(0, 3), risks: [ ...(s < 80 ? [`Match ${s}% — Abweichungen prüfen`] : []), ...(item.notes?.includes('Budget') ? ['Budget-Diskrepanz erwähnt'] : []), ...(item.resultType === 'FUTURE_AVAILABILITY' ? ['Verfügbarkeit noch nicht bestätigt'] : []), ].slice(0, 2), } }