CPV/OKAS ham kod sınıflandırması: yayınlanmadan önce tamamlanan bir gate + sidebar filtresi

- server/cpv-classify.mjs (yeni): existing (kalem kodu) → keyword (66 kural, 45 OKAS_BOLUM kodunun tamamı kapsanıyor) → AI (analyzeSpec, sadece sözlükte gerçekten var olan kod kabul edilir) hibrit sınıflandırma
- server/index.js: cache.tenders'a eklenmeden ÖNCE her ihale için CPV sınıflandırması await'leniyor (mevcut "sektör" alanının aksine, sonradan zenginleştirilmiyor) — hem ilk yükleme hem arka plan tamamlama yolunda
- İKN bazlı kalıcı SQLite önbellek (history-store.mjs) — aynı ilan bir daha asla yeniden sınıflandırılmıyor
- /api/meta/filtreler artık cpvBolumler döndürüyor
- Frontend: Sektörler'in hemen altına CPV Kodu filtresi (arama + çoklu seçim), ihale kartında CPV rozeti, landing page'de yeni özellik: "AB uyumlu CPV sınıflandırması — Türkiye'de ilk"
This commit is contained in:
2026-08-30 14:00:56 +03:00
parent f98568da8e
commit c5662d2e60
10 changed files with 490 additions and 15 deletions
+5
View File
@@ -93,6 +93,11 @@ export const TenderCard = ({ tender }) => {
<span className="bg-slate-100 text-slate-700 font-medium text-[11px] px-2.5 py-1 rounded-md border border-slate-200">
{tender.sektor}
</span>
{tender.cpvLabel && tender.cpvLabel !== 'Genel' && (
<span className="bg-sky-50 text-sky-700 font-medium text-[11px] px-2.5 py-1 rounded-md border border-sky-200">
{tender.cpvLabel}
</span>
)}
{tender.aciliyetBadge && (
<span className="bg-red-500 text-white font-extrabold text-[11px] px-2 py-1 rounded-md flex items-center gap-1 shadow-2xs">
<AlertTriangle className="w-3 h-3" />