feat: havuz izleme — ölçüm geçmişi, ani düşüş/eksik yükleme uyarısı, /api/health/havuz

This commit is contained in:
2026-08-29 22:25:55 +03:00
parent 65997055fe
commit eb20a05478
3 changed files with 161 additions and 3 deletions
+25 -2
View File
@@ -1,6 +1,6 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useApp } from '../context/AppContext';
import { Database, PlusCircle, Eye, Layers, Trophy } from 'lucide-react';
import { Database, PlusCircle, Eye, Layers, Trophy, TrendingDown } from 'lucide-react';
export const LiveStatsBar = () => {
const { liveStats, tenders } = useApp();
@@ -9,6 +9,17 @@ export const LiveStatsBar = () => {
const takibimdeki = tenders.filter((t) => t.takipte).length;
const kalemSayisi = tenders.reduce((s, t) => s + (t.items?.length || 0), 0);
// Havuz sağlığı: kaynak (ilan.gov.tr) sayısı haftalık zirvenin çok altındaysa
// bunu açıkça söyleriz — kullanıcı "veri mi kayboldu?" diye düşünmesin.
const [havuz, setHavuz] = useState(null);
useEffect(() => {
fetch('/api/health/havuz?limit=40')
.then((r) => r.json())
.then((d) => setHavuz(d.success ? d : null))
.catch(() => {});
}, []);
const dusuk = havuz?.zirveyeOran != null && havuz.zirveyeOran < 0.6;
const stats = [
{ deger: liveStats.toplamIhale, etiket: 'Canlı İhale Havuzu', renk: 'text-white', dot: true },
{ deger: yukluIhale, etiket: 'Yüklü İhale', renk: 'text-white', icon: Database, iconRenk: 'text-blue-400' },
@@ -35,6 +46,18 @@ export const LiveStatsBar = () => {
</div>
);
})}
{dusuk && (
<div
className="flex items-center gap-1.5 text-amber-300"
title={`ilan.gov.tr'de şu an ${havuz.son?.kaynak_toplam?.toLocaleString('tr-TR')} açık ihale var; bu hafta en yüksek ${havuz.haftalikZirve?.toLocaleString('tr-TR')} idi. Havuzun tamamı yüklendi — eksik veri yok.`}
>
<TrendingDown className="w-3.5 h-3.5" />
<span className="font-bold">
Kaynakta ihale sayısı düşük (%{Math.round(havuz.zirveyeOran * 100)})
</span>
</div>
)}
</div>
</div>
);