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:
@@ -60,15 +60,23 @@ export const AppProvider = ({ children }) => {
|
||||
const toggleSektor = (sek) =>
|
||||
setSelectedSektorler((prev) => (prev.includes(sek) ? prev.filter((s) => s !== sek) : [...prev, sek]));
|
||||
|
||||
// CPV filtresi (bölüm kodu bazlı, çoklu seçim) — sektör deseniyle birebir aynı.
|
||||
const [selectedCpvler, setSelectedCpvler] = useState([]);
|
||||
const toggleCpv = (kod) =>
|
||||
setSelectedCpvler((prev) => (prev.includes(kod) ? prev.filter((k) => k !== kod) : [...prev, kod]));
|
||||
|
||||
// Sektör/kurum listeleri sunucudan gelir; sabit liste yalnızca yedektir.
|
||||
const [sektorListesi, setSektorListesi] = useState(SECTORS_LIST);
|
||||
const [kurumTipiListesi, setKurumTipiListesi] = useState(INSTITUTION_TYPES_LIST);
|
||||
// CPV bölüm listesi için statik bir yedek yok — yalnızca sunucudan gelir.
|
||||
const [cpvBolumListesi, setCpvBolumListesi] = useState([]);
|
||||
useEffect(() => {
|
||||
fetch('/api/meta/filtreler')
|
||||
.then((r) => r.json())
|
||||
.then((d) => {
|
||||
if (d?.sektorler?.length) setSektorListesi(d.sektorler);
|
||||
if (d?.kurumTipleri?.length) setKurumTipiListesi(d.kurumTipleri);
|
||||
if (d?.cpvBolumler?.length) setCpvBolumListesi(d.cpvBolumler);
|
||||
})
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
@@ -468,6 +476,7 @@ export const AppProvider = ({ children }) => {
|
||||
setSelectedAlimTuru('');
|
||||
setSelectedKurumTipi('');
|
||||
setSelectedSektorler([]);
|
||||
setSelectedCpvler([]);
|
||||
setQuickFilter('all');
|
||||
};
|
||||
|
||||
@@ -505,6 +514,10 @@ export const AppProvider = ({ children }) => {
|
||||
toggleSektor,
|
||||
sektorListesi,
|
||||
kurumTipiListesi,
|
||||
selectedCpvler,
|
||||
setSelectedCpvler,
|
||||
toggleCpv,
|
||||
cpvBolumListesi,
|
||||
onlyValidOnly,
|
||||
setOnlyValidOnly,
|
||||
quickFilter,
|
||||
|
||||
Reference in New Issue
Block a user