diff --git a/src/controllers/precedent.controller.ts b/src/controllers/precedent.controller.ts index b0d32e0..827dc66 100644 --- a/src/controllers/precedent.controller.ts +++ b/src/controllers/precedent.controller.ts @@ -67,35 +67,59 @@ SADECE anahtar kelimeleri aralarına boşluk koyarak yaz. Noktalama işareti, a if (Array.isArray(rawItems) && rawItems.length > 0) { const searchTerms = phrase.toLowerCase().split(/\s+/).filter(Boolean); - const outcomeTerms = ['beraat', 'mahkumiyet', 'bozma', 'onanma', 'tazminat', 'tahliye', 'kabul', 'red', 'ispat', 'zamanaşımı']; - const targetOutcomes = searchTerms.filter((t: string) => outcomeTerms.some(o => t.includes(o))); + const isBeraatSearch = searchTerms.some(t => t.includes('beraat')); + const isBozmaSearch = searchTerms.some(t => t.includes('bozma') || t.includes('bozulması')); const scoredItems = rawItems.map((item: any) => { - const text = (item.ozet || item.kararMetni || item.summary || item.content || item.title || item.konu || item.birimAdi || '').toLowerCase(); + const fullText = ( + item.ozet || item.kararMetni || item.summary || item.content || item.title || item.konu || item.birimAdi || '' + ); + const lowerText = fullText.toLowerCase(); let baseScore = 70; // 1. Arama terimlerinin metindeki kapsama oranı - const matchCount = searchTerms.filter((term: string) => text.includes(term)).length; + const matchCount = searchTerms.filter((term: string) => lowerText.includes(term)).length; const matchRatio = searchTerms.length > 0 ? matchCount / searchTerms.length : 1; baseScore += Math.round(matchRatio * 15); - // 2. Kullanıcının aradığı net netice/karar türü terimleri var mı? (Örn. beraat) - if (targetOutcomes.length > 0) { - const hasTargetOutcome = targetOutcomes.some((outcome: string) => text.includes(outcome)); - if (hasTargetOutcome) { - baseScore += 18; - } else { - baseScore -= 25; // Eğer beraat arayıp kararda beraat geçmiyorsa (örn sadece onanması varsa) sırayı düşür + // 2. Beraat araması için özel akıbet analizi ve filtreleme + if (isBeraatSearch) { + const hasExplicitBeraat = lowerText.includes('beraat') || lowerText.includes('beraatına') || lowerText.includes('beraatine') || lowerText.includes('beraat kararı'); + const isBeraatOnamasi = lowerText.includes('beraatına ilişkin') || lowerText.includes('beraatine ilişkin') || lowerText.includes('beraat hükmünün'); + const isPureMahkumiyetOnama = (lowerText.includes('mahkumiyetine') || lowerText.includes('mahkûmiyetine')) && (lowerText.includes('onanmasına') || lowerText.includes('itirazın reddine')); + + if (hasExplicitBeraat || isBeraatOnamasi) { + baseScore += 30; // Gerçek beraat içeren kararlar en üste + } + if (isPureMahkumiyetOnama && !hasExplicitBeraat) { + baseScore -= 45; // Mahkumiyet onaması olup beraat içermeyenleri dibe düşür } } - // Skor 45 - 98 arasında sınırlandırılır - const finalScore = Math.max(45, Math.min(98, baseScore)); + // 3. Bozma araması için özel analiz + if (isBozmaSearch) { + if (lowerText.includes('bozulmasına') || lowerText.includes('bozma')) { + baseScore += 25; + } else if (lowerText.includes('onanmasına')) { + baseScore -= 30; + } + } + + // 4. Pasaj (Özet) Cımbızlama: Aranan netice cümlesini tam ortalayarak özet yap + const keyTarget = isBeraatSearch ? 'beraat' : (isBozmaSearch ? 'bozulmasına' : searchTerms[0]); + if (keyTarget && lowerText.includes(keyTarget)) { + const idx = lowerText.indexOf(keyTarget); + const start = Math.max(0, idx - 90); + const end = Math.min(fullText.length, idx + 150); + item.ozet = '...' + fullText.slice(start, end).trim() + '...'; + } + + const finalScore = Math.max(30, Math.min(98, baseScore)); return { ...item, relevanceScore: finalScore, score: finalScore }; }); - // En yüksek alakaya göre yeniden sırala + // En yüksek beraat/netice eşleşmesine göre yeniden sırala scoredItems.sort((a: any, b: any) => b.relevanceScore - a.relevanceScore); if (data.results) data.results = scoredItems;