From d606d55e417d6be23c3427d03d7f5fea50590d09 Mon Sep 17 00:00:00 2001 From: ht Date: Fri, 28 Aug 2026 10:42:33 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20ge=C3=A7mi=C5=9F=20ar=C5=9Fiv=20dolumu?= =?UTF-8?q?=20+=20ar=C5=9Fiv=20sayac=C4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scheduler: arşiv eşiğin altındaysa geniş geçmiş dolumu (180 gün/1500 kayıt), doluysa artımlı günlük tarama; ilk tur 90 sn sonra - LiveStatsBar: 'Sonuç Arşivi' sayacı (kazanan firma kayıt sayısı) - KİK: HTML entity çözümü tamamlandı --- server/scheduler.mjs | 29 ++++++++++++++++++++++++----- src/components/LiveStatsBar.jsx | 3 ++- src/context/AppContext.jsx | 3 ++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/server/scheduler.mjs b/server/scheduler.mjs index 4b37eca..e7c6613 100644 --- a/server/scheduler.mjs +++ b/server/scheduler.mjs @@ -12,20 +12,39 @@ import { spawn } from 'node:child_process'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { historyStats } from './history-store.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); let calisiyor = false; +// Arşiv boş/küçükse geniş geçmiş dolumu, doluysa artımlı günlük tarama. +function tarataParams() { + const s = historyStats(); + const mevcut = s.available ? (s.toplam || 0) : 0; + const esik = Number(process.env.SCAN_BACKFILL_ESIK || 2000); + if (mevcut < esik) { + return { + gun: process.env.SCAN_BACKFILL_GUN || '180', + limit: process.env.SCAN_BACKFILL_LIMIT || '1500', + tip: `geçmiş dolumu (arşivde ${mevcut} kayıt)`, + }; + } + return { + gun: process.env.SCAN_GUN || '3', + limit: process.env.SCAN_LIMIT || '300', + tip: `artımlı güncelleme (arşivde ${mevcut} kayıt)`, + }; +} + function tara() { if (calisiyor) { console.log('[scheduler] önceki tarama sürüyor, bu tur atlandı'); return; } calisiyor = true; - const gun = process.env.SCAN_GUN || '3'; - const limit = process.env.SCAN_LIMIT || '300'; - console.log(`[scheduler] EKAP sonuç taraması başlıyor (son ${gun} gün, limit ${limit})`); + const { gun, limit, tip } = tarataParams(); + console.log(`[scheduler] EKAP sonuç taraması — ${tip}: son ${gun} gün, limit ${limit}`); const p = spawn(process.execPath, [path.join(__dirname, 'ekap-scan.mjs'), '--gun', gun, '--limit', limit], { stdio: ['ignore', 'pipe', 'pipe'], @@ -50,7 +69,7 @@ export function startScheduler() { const saat = Number(process.env.SCAN_INTERVAL_SAAT || 6); const ms = Math.max(1, saat) * 3600 * 1000; console.log(`[scheduler] geçmiş sonuç taraması her ${saat} saatte bir çalışacak`); - // Açılıştan 2 dk sonra ilk tur (sunucu ısınsın), sonra periyodik - setTimeout(tara, 2 * 60 * 1000).unref?.(); + // Açılıştan 90 sn sonra ilk tur (sunucu ısınsın), sonra periyodik + setTimeout(tara, 90 * 1000).unref?.(); setInterval(tara, ms).unref?.(); } diff --git a/src/components/LiveStatsBar.jsx b/src/components/LiveStatsBar.jsx index 78ab980..13a50ea 100644 --- a/src/components/LiveStatsBar.jsx +++ b/src/components/LiveStatsBar.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { useApp } from '../context/AppContext'; -import { Database, PlusCircle, Eye, Layers } from 'lucide-react'; +import { Database, PlusCircle, Eye, Layers, Trophy } from 'lucide-react'; export const LiveStatsBar = () => { const { liveStats, tenders } = useApp(); @@ -14,6 +14,7 @@ export const LiveStatsBar = () => { { deger: yukluIhale, etiket: 'Yüklü İhale', renk: 'text-white', icon: Database, iconRenk: 'text-blue-400' }, { deger: liveStats.bugunEklenen, etiket: 'Bugün Eklenen', renk: 'text-emerald-400', icon: PlusCircle, iconRenk: 'text-emerald-400' }, { deger: kalemSayisi, etiket: 'Kalem', renk: 'text-white', icon: Layers, iconRenk: 'text-indigo-400' }, + { deger: liveStats.arsiv, etiket: 'Sonuç Arşivi', renk: 'text-white', icon: Trophy, iconRenk: 'text-emerald-400' }, { deger: takibimdeki, etiket: 'Takibimdeki', renk: 'text-white', icon: Eye, iconRenk: 'text-amber-400' }, ]; diff --git a/src/context/AppContext.jsx b/src/context/AppContext.jsx index 3132c69..f157b2e 100644 --- a/src/context/AppContext.jsx +++ b/src/context/AppContext.jsx @@ -12,7 +12,7 @@ export const AppProvider = ({ children }) => { return saved ? JSON.parse(saved) : []; }); - const [liveStats, setLiveStats] = useState({ toplamIhale: 0, bugunEklenen: 0 }); + const [liveStats, setLiveStats] = useState({ toplamIhale: 0, bugunEklenen: 0, arsiv: 0 }); const [searchQuery, setSearchQuery] = useState(''); const [selectedCity, setSelectedCity] = useState(''); const [selectedAlimTuru, setSelectedAlimTuru] = useState(''); @@ -60,6 +60,7 @@ export const AppProvider = ({ children }) => { setLiveStats({ toplamIhale: data.totalCount ?? 0, bugunEklenen: data.todayCount ?? 0, + arsiv: data.historyCount ?? 0, }); } catch (err) { setLiveDataError(err.message);