Commit Graph
32 Commits
Author SHA1 Message Date
hikmettan 456728b4bd fix: preserve bid drafts and align tender source data 2026-09-06 08:40:10 +03:00
hikmettan c91631d99f fix: persist tender preparation and correct calendar export 2026-09-06 08:30:32 +03:00
hikmettanandClaude Fable 5.1 08c0a0af7e Kullanıcı testi hataları: sabit tarihler, kişisel varsayılanlar, kılavuz düğmesi, mobil başlık, AI taslak çökmesi
- Günlük Bülten ve İhale Takvimi sabit "10.08.2026" yerine bugünden hesaplar;
  takvim 7 günü gerçek ihale tarihleriyle sayar
- Ekip/üye/firma varsayılanları oturumdaki kullanıcıdan; sahte "Ekip Notları"
  ve sabit "%94 Uyum" rozeti kaldırıldı (gerçek uyum skoru varsa gösterilir)
- Kılavuz düğmesi document.body'ye portal (ekran dışına düşüyordu)
- Detay modalı havuzdaki güncel kaydı okur: Takip Et / Görev aç etiketleri güncellenir
- Mobil: başlıkta ikincil düğmeler md altında gizli, arama formu küçülebilir
- PWA sayfası: sahte önbellek sayıları yerine Cache API ve bellek sayımı
- Sözleşme sorgula pazar payı bir ondalık (hep %0 görünüyordu)
- Rakip Radar "SMS" vaadi düzeltildi; sektör=CPV etiketi tekrarı gizlendi;
  Stripe kurulum uyarısı yalnız yöneticiye
- Açılışta 7 gereksiz PUT /api/me/data: ilk yükleme yazımı atlanır
- server: teklif taslağı çökmesi (kalemOku nesne döndürür), denetim yanıtından
  model adı kaldırıldı, gereklilikler satır bazlı; derin analiz 12k token +
  kesik JSON onarımı

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 09:43:41 +03:00
hikmettanandClaude Fable 5.1 df89eaac33 feat: takip izleme (zeyilname + sonuc bildirimi), hazirlik gorevi, belge sure uyarisi, Telegram, OCR, yasakli sorgu
28 depo taramasindan alinan alti ozellik. Kod kopyalanmadi (depolar
lisanssiz), fikirler uygulandi.

1) Zeyilname / duzeltme ilani takibi (server/zeyilname.mjs): takipteki
   IKN'ler sunucuya yazilir; 3 saatte bir EKAP detayindan ilan sayisi ve
   ihale tarihi karsilastirilir, degisince "ne degisti" bildirimi (uygulama
   ici + e-posta + Telegram). Test: anlik kaydi eskitilince tur "yeni ilan
   yayimlandi; ihale tarihi 01.01.2026 → 08.10.2026" bildirimi uretti.
2) Sonuc bildirimi: takipteki ihale sonuclaninca "X firmasi Y'ye aldi, %Z
   kirim". Yalniz takiptekiler; kismi ihalede oran yazilmaz.
3) Ihaleden goreve (MOBIT-DURT): detayda "Hazirlik Gorevi Ac" → teslim
   tarihi ihale saati, pano "Teklif Hazirlaniyor", derin analizden gelen
   belge kontrol listesi gorevde; Kanban kartinda geri sayim rozeti.
4) Sirket belgesi sure takibi: Belge Kasasi'nda son kullanma tarihi girisi,
   dolmus / 30 gun icinde dolacak uyarisi; girise gunde bir bildirim.
   PATCH /api/me/documents/meta.
5) Telegram (server/telegram.mjs): TELEGRAM_BOT_TOKEN sunucuda; kullanici
   6 haneli kodu bota yazar, "Dogrula" → getUpdates ile chat id baglanir.
   Arayuzde adim adim kurulum rehberi (BotFather → env → Redeploy → kod).
   Ihale ozeti, zeyilname ve sonuc bildirimleri Telegram'a da gider.
6) OCR (tesseract.js, tur): PDF metin katmani bossa (taranmis) ilk 8 sayfa
   OCR. Olcum: sentetik cetvelde guven 87, ~0,3 sn/sayfa; IKN ve kalemler
   dogru okundu. Kalem havuzu ve derin analiz artik taranmis PDF'ten de
   besleniyor.
7) Rakip Radari'nda KIK yasakli sorgusu baglantisi (firma adi panoya
   kopyalanir; EKAP sorguyu API'den vermiyor).

Sinir deger hesaplayici KURULMADI: Kamu Ihale Genel Tebligi'ne ulasilamadi
(mevzuat.gov.tr / ihale.gov.tr bu makineden erisilemiyor); formul kaynaksiz
yazilmadi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:58:13 +03:00
hikmettanandClaude Fable 5.1 1716b6365c feat: hibrit uyum skoru (sozluksel + anlamsal bonus) ve firma esigi
Anlamsal bonus: profil metni sunucuda gomulur (multilingual-e5-small, ONNX
q8, @huggingface/transformers — Python/GPU yok), havuzdaki her ihaleyle
kosinus alinir, havuz ici z-skor → +0..20 puan. Sozluksel skor ana eksen
kalir; bonus eklenir. Sozluksel 0 iken bonus yalniz ≥10'sa gorunur.

NEDEN BONUS, ESIK DEGIL (olculdu): e5 kosinusleri 0,79-0,86 bandina
sikisiyor (havuz ort 0,814 sd 0,026); kirtasiye ile rontgen arasi 0,06.
kaanvp/kobi-ihale-eslestirme'nin 0,65 esigiyle trafo bakimi da "eslesti"
sayilirdi. Ama siralama dogru ve sozlukselin kacirdigini yakaliyor: "GENEL
TIBBI SARF" profilde birebir terim yokken kirtasiyenin ustune cikiyor.

- server/uyum-gomme.mjs: acilista arka planda isitma (~45 sn soguk), ihale
  gommeleri bellekte (metin imzasi degisince yenilenir), model data/modeller
  volume'unda bir kez indirilir; paket/yukleme yoksa sessizce kapali
- POST /api/uyum/gomme, GET /api/health/uyum
- Dockerfile: calisma imajina @huggingface/transformers@3 (package.json'a
  degil — sunucu sifir-bagimlilik, calisma katmani ayri npm i)
- Olculen: 3.2 bin ihale ilk cagri 7,6 sn (tumu gomuluyor), ikinci 17 ms;
  +20 alan 170, ≥10 alan 610 ihale

Firma esigi: profilde uyumEsigi (varsayilan 60, kalici); "Uyumlu" hizli
filtresi bu esigi kullanir; profil modalinda kaydirici + bonus durumu.
Modaldaki "%98+ dogruluk" cumlesi kaldirildi — olculmemis iddiaydi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:32:23 +03:00
hikmettanandClaude Fable 5.1 17c781a9ba feat: gercek sirket-ihale uyum skoru — sahte %98 rozeti gitti
Karttaki "%N Uyumlu" rozeti sabit yazili degerlerdi (liveTenderService
98/95/91/99), sunucudan null geliyordu. Artik profil terimleri ile ihale
metni arasinda agirlikli sozcuk eslesmesi (src/services/uyum.js):
- terimler: urunler (1.0), ihale konulari (1.0), sektorler (0.6),
  sertifikalar (0.3); "ve/alimi/malzeme" gibi durma kelimeleri sayilmaz
- alanlar: baslik (1.0), teklif cetveli kalemleri (1.1 — en guclu sinyal),
  OKAS/CPV (0.7), ilan metni (0.6), sektor (0.5)
- doygunluk egrisi: 1 guclu eslesme ≈ 55, 2 ≈ 75, 3+ ≈ 90
- profilde terim yoksa skor null → sahte yuzde gosterilmez
- her skorun nedeni var: kartta ipucu, detayda "‘eldiven’ · teklif cetveli"
Olculen: "VETERINER ILAC VE SARF MALZEME" basligi hicbir urunu icermiyor ama
kalemlerinde ELDIVEN + HEMOGRAM KITI var → %86; kirtasiye → 0.

- Siralama: "Sirketime En Uyumlu"; hizli filtre 'uyumlu' (≥60)
- Profil yetkinlikleri artik kalici (localStorage + sunucu 'firma_profil');
  onceden sayfa yenilenince siliniyordu
- Web sitesi taramasi gercek uca bagli (/api/company/scan: site metni +
  model → sektorler/urunler/sertifikalar/ihaleKonulari); basarisizsa eski
  alan-adi tahmini yedek. Onceden 1,5 sn setTimeout ile taklitti.

Sozluksel yol bilincli: dis servis yok, 8 bin ihalede aninda, deterministik,
aciklanabilir. Embedding katmani istenirse ustune eklenebilir.
(Fikir: kaanvp/kobi-ihale-eslestirme'nin esik + aciklama deseni; kod alinmadi.)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 21:51:28 +03:00
hikmettanandClaude Fable 5.1 1fce9df06f feat: OKAS kod aramasi, toplu ihale dokumani yukleme, kazanan istihbarati
Uc ozellik, 27+1 depo taramasinda gorulen fikirlerden; kod kopyalanmadi
(ilgili depolar lisanssiz), uygulamalar sifirdan yazildi.

1) OKAS koduyla arama (fikir: firatbadur/ihaletakip-api'nin kullandigi
   IhtiyacKalemleri/GetAll ucu). EKAP'in kendi OKAS katalogunda ad ile
   (TR/EN) arama: "ortoped" → 33141700 Ortopedik malzemeler, 33183000
   Ortopedik destek cihazlari. Secilen kodla EKAP'ta ihale aramasi
   (okasBransKodList). Olculen: 33141700 altinda 335 ihale, basliklari
   "VETERINER ILAC VE SARF MALZEME" — basliktan gorunmeyen turden.
   - ekap-v2.mjs: okasAra(), searchByOkas(); sonuc normalize ortak
   - GET /api/okas/ara?q= (1 sa onbellek); /api/urun-ara?okas=kod,kod
   - Urun Arama modalinda "OKAS koduyla" modu (katalog onerisi + cok kod)
   - Sol menude CPV bolumunun ustunde OKAS kutusu: kod secilince modal
     o kodla acilip hemen arar

2) Toplu ihale dokumani yukleme (fikir: barkem-tayyar/ihale'nin izlenen
   klasor + extractIkn deseni). Belge Kasasi'na coklu dosya secimi: her
   dosyanin IKN'si METNINDEN bulunur ("Ihale Kayit Numarasi (IKN):
   2026/1166496"), kullaniciya sorulmaz; ihaleye baglanir ve teklif
   cetveli kalemleri otomatik havuza yazilir. Onlarca sartnameyi tek
   seferde atarak kalem havuzunu hizla doldurmak icin.
   - kalem-cikar.mjs#iknCikar + istemci esi (PDF tarayicida okunuyor)
   - Yukleme ucu: otoIkn → ofis metninden IKN; donuste ikn alani
   - Dosya basina sonuc satiri: IKN / kalem sayisi / "IKN bulunamadi"
   Dogrulandi: ikn parametresiz docx → 2026/1588948 bulundu, 2 kalem.

3) Kazanan istihbarati (fikir: gulmezeren2-byte/ihalent, MIT). Rakip
   Radari'nda firma basina kirim orani (1 − sozlesme/yaklasik maliyet,
   ortalama), ortalama gecerli teklif sayisi (rekabet derinligi) ve tek
   teklifle kazanma orani. Veri yoksa null — 0 ile karismasin; bedel >
   maliyet×1,5 olan bozuk satirlar orana katilmiyor.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 20:16:53 +03:00
hikmettanandClaude Opus 5 ff797f5a91 feat: urun arama — urun adini ihale DOKUMANLARININ icinde aratir
saidsurucu/ihale-mcp deposu incelenirken EKAP arama API'sinin doküman ici
arama parametreleri oldugu goruldu: teklifCetvelindeAra, teknikSartnamedeAra,
idariSartnamedeAra, sozlesmeTasarisindaAra. EKAP dokumani kendi tarafinda
indeksliyor — yani teklif cetvelinde arama icin dokumani indirmeye (ve
CAPTCHA'ya) gerek yok.

Kullanicinin sikayetini olcen kanit:
  ELDIVEN         basliкta  1.135  → teklif cetvelinde 29.057
  ORTOPEDIK VIDA  baslikta      0  → teklif cetvelinde      3
  HEMOGRAM        baslikta    283  → teklif cetvelinde  2.529
"ORTOPEDIK VIDA" hicbir ihale BASLIGINDA gecmiyor; gectigi ihalelerin adi
"VETERINER ILAC ... SARF MALZEME". Basliga bakan firma bunlari bulamiyordu.

- ekap-v2.mjs: searchBody artik opts.kapsam ile daraltilabiliyor;
  searchInDocuments() yalnizca teklif cetvelinde (istege bagli teknik
  sartnamede) arar ve sonucu normalize eder
- GET /api/urun-ara?q=&skip=&take=&teknik= — 5 dk bellek onbellegi ile
  (EKAP'a uzak cagri, ayni sorgu kaynagi yormasin)
- Header'da "URUN ARA" dugmesi + UrunAramaModal: sayfalama, "sadece teklif
  verilebilir" suzgeci, havuzda acik olan ihalede detayi acma kisayolu

SINIR: EKAP hangi kalemin eslestigini dondurmuyor, yalnizca eslesen ihaleleri.
Kalem dokumu icin dokuman yuklemeye dayali ortak havuz yolu gecerli kaliyor;
arayuzde bu acikca yaziliyor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 12:55:36 +03:00
hikmettanandClaude Opus 5 8826ff8e68 feat: ortak kalem havuzu — teklif cetveli kalemleri kartta gorunur ve aranabilir
Firmalar ihalenin sadece basligina bakarak kendi urunlerinin icinde olup
olmadigini goremiyordu ("148 KALEM KIRTASIYE MALZEME ALIMI"). Artik bir
kullanici ihale dokumanini yukledinde teklif cetveli kalemleri ayristirilip
IKN'ye baglaniyor ve o ihale HERKESIN kartinda kalemleriyle gorunuyor.

NEDEN YUKLEMEYE DAYALI: kalem listesi EKAP'in programatik yuzeyinde yok.
- Arama/detay API'si (ihtiyacKalemiOkasList) yalnizca OKAS sinifi veriyor:
  "KALP AKCIGER POMPASI CIHAZI ALIMI" icin tek satir "Tibbi cihazlar"
- Ilan metni yalnizca sayiyi veriyor: "148 KALEM ... Ayrintili bilgiye EKAP'ta
  yer alan ihale dokumani icinde bulunan idari sartnameden ulasilabilir"
- Dokuman sayfasi CAPTCHA ile korunuyor (ctl00_btnCaptchaProtect, guvenlik
  resmi). Gercek tarayiciyla (Playwright) da acildi, donen tek metin: "Dogrula"

OTOMATIK, AI'SIZ: kalem cikarimi yukleme aninda kendiliginden calisir,
kullanicidan tiklama beklemez ve model cagirmaz (saf regex). AI analizi ayri
dugmede, kullanici isterse.

- server/kalem-cikar.mjs: teklif cetveli ayristirici. " | " tablolarindan
  (docx/xlsx/zip) sutun basligini cozerek; ayracsiz PDF metninde sezgisel
  satir kalibiyla. Miktar+birim tek hucrede olabiliyor ("25000 TEST").
  Birim listesinde 'test' var — tibbi kitlerde kalem miktari boyle yaziliyor.
- server/kalem-store.mjs: kalem.sqlite, IKN bazli, Turkce duyarli arama.
  Bos ayristirma mevcut iyi veriyi silmez.
- Uclar: POST /api/kalem/cikar (tarayicidan gelen PDF metni), GET /api/kalem,
  GET /api/kalem/ara, GET /api/health/kalem
- /api/tenders payloadu kalemSayisi + ilk kalemleri tasiyor
- Kartta kalem rozeti ve kalem seridi; aramada eslesen kalemler one alinir
- Ust arama kutusu kalem havuzunda da ariyor (350ms debounce, sunucu tarafi)
- Detay modalinda tam kalem listesi + kalem ici arama

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 11:51:39 +03:00
hikmettanandClaude Fable 5.1 920a147126 fix: ust serit tiklaninca donuyordu — Kanban havuzdaki tum ihaleleri (8 bin+ kart) ciziyordu; artik yalnizca takipteki/kolona tasinan ihaleler, sekme gecisi transition ile aninda vurgulaniyor
- KanbanBoard: sunucu her ilana varsayilan 'incelenecek' verdigi icin bos pano 8.372 kart basiyordu; yalnizca takipte veya kolona tasinmis ihaleler kaliyor
- TopNavigation: useTransition + spinner; agir sekmelerde tiklama karsiliksiz kalmiyor
- sunucu: 'yeni liste eskisinden kucukse alma' kurali havuzu 30 Agustos zirvesinde dondurmustu (gunlerce yeni ilan yok); eksiksiz inen liste her zaman devrede
- sunucu: isYeni/bugun eklenen UTC-TR gun farkindan hep 0'di; Europe/Istanbul gunune gore ve her yanitta tazeleniyor (eklenmeZamani da donmuyor)
- ust kartlar: 'bugun eklenenler' tum ilanlari sayiyordu ('once' metnine bakiyordu), 'son giristen beri' sabit 14'tu; sayimlar liste filtresiyle ayni olcut (ihaleTarih.js), arsiv/sonuclanan filtreleri 'sadece acik' kapisina takilmiyor

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 13:02:40 +03:00
hikmettan 3eb0f91823 feat: derin analiz & yol haritasi + ihale dosyasi hazirlama; docx/xlsx/zip okunuyor
Doküman panelindeki "Tum Evraki Derin Analiz Et" dugmesi EKAP ilan metnini ve
ihaleye yuklenmis butun belgeleri TEK metinde birlestirip gonderiyor; model
sartnameyi ilanla ve eklerle capraz okuyabiliyor.

Derin analiz (mode='derin', ayri sistem istemi + 8000 token):
- Teklifi gecersiz kilabilecek noktalar (kirmizi uyari, en ustte)
- Gozden kacan ince detaylar (Kritik/Yuksek/Orta + madde no + neden onemli)
- Alinacak kalemler: aranan evsaflar, miktar, sartnamede geciyorsa fiyat
  (modele "TAHMIN URETME" talimati verildi, yoksa null)
- Belge kontrol listesi, kritik tarihler, maliyet kalemleri
- Teklife kadar yol haritasi (faz / kim / ne zaman / cikti)
- Idareye sorulacak belirsizlikler
Standart hizli ozet modu aynen duruyor.

Ihale Dosyasi Hazirla (rapor sonunda, acilir bolum):
- Eksik firma bilgileri kullaniciya sorulur, profilden gelenler sorulmaz,
  girilenler tarayicida saklanir
- Kalem fiyatlandirma tablosu, canli toplam + yaziyla karsiligi
- Teklif Mektubu, Birim Fiyat Teklif Cetveli, Evrak Kontrol Listesi
- Belgeler yazdirilabilir HTML: jsPDF'in gomulu fontlari WinAnsi, s/g/i/I
  tasimiyor (bkz. services/pdf.js ASCII basliklari) — resmi teklif mektubunda
  bozuk Turkce kabul edilemez

docx/xlsx/zip metin cikarimi (server/office-text.mjs):
- ihaleab projesindeki officeText.ts'ten tasindi, harici bagimlilik yok
- Sunucuda: tarayicida cozucu yok, baytlar zaten BELGE_DIR'de
- Tablolar " | " ile korunuyor, ic ice zip aciliyor, ~$ gecici dosyalari atlanir
- Yeni uc: GET /api/me/documents/text
- Yukleme kabul listesi .doc/.rar cikarildi (karsiligi yok), .xlsx eklendi

fix: yuklenen belgelerdeki "AI analiz" dugmesi bozuktu — extractText nesne
donduruyor ({text,pageCount,usedPages}), kod onu duz metin sanip gonderiyordu;
sunucuya "[object Object]" gidiyor ve analiz reddediliyordu. Uzunluk kontrolu
de nesne uzerinde undefined verdigi icin hatayi yutuyordu.

fix: analiz dokuman panelinden baslatildiginda modal kendi isAnalyzing'ini
bilmiyordu, kullanici 1-2 dakika bos modal goruyordu — ortak aiAnalyzing sinyali
2026-08-31 14:53:46 +03:00
hikmettan c5662d2e60 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"
2026-08-30 14:00:56 +03:00
hikmettan fd78b6e7d9 feat: 30 günlük havuz referansı (kalıcı erime) + 25 sektör, çoklu sektör seçimi ve sunucudan gelen tek kaynaklı liste 2026-08-30 00:24:33 +03:00
hikmettan 351884ac02 fix: 12 bin ihalelik havuz localStorage kotasını aşıp uygulamayı beyaz ekranla çökertiyordu 2026-08-29 14:43:20 +03:00
hikmettan f04401031c feat: sunucu tarafı hesap altyapısı — Stripe webhook, kotalar, gerçek API anahtarı ve belge deposu
Denetlenen 5 teknik borç kalemi de kapatıldı:

1) Stripe webhook + gerçek yetkilendirme (ÖNCEDEN YOKTU)
   - POST /api/billing/webhook — SDK'sız HMAC-SHA256 imza doğrulaması,
     tekrar saldırısına karşı ±300sn zaman penceresi, timingSafeEqual
   - checkout.session.completed / subscription.created|updated|deleted işlenir
   - Ödeme → kullanıcının planı sunucuda güncellenir (önce ödeme hiçbir şeyi
     değiştirmiyordu)

2) Plan kotaları GERÇEKTEN uygulanıyor (önce sadece tanımlıydı)
   - server/entitlements.mjs: plan hakları + kotaKontrol()
   - ekip, belge adedi/boyutu, API anahtarı kotaları sunucuda zorlanır
   - Kota aşımında 402 + anlaşılır Türkçe mesaj; arayüzde KotaUyarisi bandı
   - /api/me/plan: plan, haklar ve gerçek kullanım

3) Kullanıcı verisi localStorage'dan sunucuya taşındı
   - server/user-store.mjs: kullanici_verisi tablosu (izinli anahtar listesi)
   - AppContext girişte sunucudan yükler, değişiklikleri sunucuya yazar;
     localStorage yalnızca çevrimdışı önbellek
   - Artık cihaz değişince veri kaybolmuyor

4) API anahtarları gerçek (önce Math.random ile tarayıcıda üretiliyordu)
   - Sunucuda crypto.randomBytes ile üretilir, YALNIZCA sha256 hash'i saklanır
   - Ham değer bir kez gösterilir; verifyApiKey ile doğrulanır, son kullanım
     izlenir, iptal anında geçerli olur

5) Belge deposu gerçek (önce boyut Math.random'dı, dosya hiç yüklenmiyordu)
   - Dosyalar kalıcı volume'e yazılır, boyut GERÇEK bayt
   - Auth'lu indirme (blob), silme diskten de siler, kota sunucuda uygulanır
2026-08-29 10:40:05 +03:00
hikmettan 1e614abc21 refactor(ai): glm-latest zincirden çıkarıldı (birincil ile aynı modele çözünüyordu) — 2. sıra Gemini Flash Latest; kayıtlı zincirler sürüm 3 geçişiyle taşınır 2026-08-28 22:50:00 +03:00
hikmettan e2512be9f7 feat: GLM 5.3 Flash eklendi ve birincil modele alındı
- server/ai.mjs: yeni 'glmflash' sağlayıcısı (z-ai/glm-5.3-flash), varsayılan
  zincirin başında
- AppContext: kataloğa eklendi; varsayılan zincir glmflash → glm → deepseek → gemini
- Kayıtlı ayarlar için sürüm geçişi (ZINCIR_SURUM): mevcut kullanıcıların
  zincirinin başına glmflash otomatik eklenir, kalan sıraları korunur
- Env ile geçilebilir: GLM_FLASH_OR_MODEL / GLM_FLASH_MODEL
2026-08-28 21:52:14 +03:00
hikmettan dd2bfa12e6 feat: OpenRouter entegrasyonu — tek anahtarla tüm modeller, latest alias'lar
- server/ai.mjs: OpenRouter öncelikli yönlendirme (routeFor). OPENROUTER_API_KEY
  tanımlıysa zincirdeki tüm modeller OpenRouter üzerinden çağrılır; doğrudan
  sağlayıcı anahtarı varsa o ezer
- Tüm modeller OpenRouter floating 'latest' alias'larına çevrildi (sabit sürüm
  yerine otomatik güncel kalır):
    ~z-ai/glm-latest · ~deepseek/deepseek-v4-flash-latest
    ~google/gemini-flash-latest · ~x-ai/grok-latest
    openai/gpt-chat-latest · ~anthropic/claude-opus-latest
- /api/ai/config artık her model için kullanılan yolu (openrouter|direct) döner
- AI Model Ayarları: canlı durum bandı (aktif modeller + yol) ve OpenRouter
  kurulum yönergesi; eski 'alias' alanı gerçek OpenRouter kimliğiyle değişti
- Analiz modali: tek OPENROUTER_API_KEY önerisi
2026-08-28 13:37:40 +03:00
hikmettan d606d55e41 feat: geçmiş arşiv dolumu + arşiv sayacı
- 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ı
2026-08-28 10:42:33 +03:00
hikmettan 168052c267 feat: geçmiş veri motoru + gerçek AI + KİK kararları + TED + kırmızı bayrak + planlar
Roadmap'in 6 maddesi de gerçek çalışır halde:

1) Geçmiş veri motoru (EKAP v2)
   - server/ekap-v2.mjs: AES-256-CBC imzalı EKAP v2 istemcisi (zero-dep),
     ihale arama + sonuç ilanı parse (kazanan firma, sözleşme bedeli,
     yaklaşık maliyet, teklif sayısı), TR firma adı normalize
   - server/history-store.mjs: SQLite deposu (IKN+kısım anahtarlı, upsert)
   - server/ekap-scan.mjs: tarih aralıklı artımlı tarayıcı (6 paralel)
   - server/scheduler.mjs: sunucu içi periyodik tarama (SCAN_* env ile)
   - /api/tenders artık geçmiş sonuçları da birleştiriyor → kazanan firma,
     rakip ve kırmızı bayrak analizleri gerçek veriyle doluyor

2) Gerçek AI şartname analizi
   - server/ai.mjs: 6 sağlayıcılı fallback zinciri (GLM/DeepSeek/Gemini/
     Grok/GPT/Claude), JSON şemalı çıktı, uydurma yasak promptu
   - pdfjs-dist ile tarayıcıda PDF metin çıkarma (dinamik import)
   - AiSpecAnalyzerModal: sahte sonuç kaldırıldı, gerçek dosya + dürüst hata

3) KİK kurul kararları
   - server/kik.mjs: EKAP v2 JSON API (Sec-1..6 imzalı), uyuşmazlık/
     düzenleyici/mahkeme; karar tam metni (ayrı AES anahtarıyla URL)
   - KikDecisions sekmesi: arama + takipteki idarelerden hızlı öneri

4) Fiyatlandırma + ödeme
   - server/billing.mjs: Stripe Checkout (zero-dep, form-encoded)
   - Pricing sekmesi: 3 plan, aylık/yıllık, yapılandırılmadıysa dürüst uyarı

5) TED (AB ihaleleri)
   - server/ted.mjs: anonim TED v3 API, 3 mod (açık/tüm TR/AB'de kazanan TR)
   - rate-limit korumalı (429 HTML gövdesi ele alınır), çok dilli alan çözümü

6) Kırmızı bayrak & şeffaflık
   - analytics.js: redFlags (tek teklif, düşük kırım, tahmin üstü bedel,
     aşırı düşük teklif, tedarikçi yoğunlaşması) + marketConcentration (HHI)
   - RedFlags sekmesi: seviyeli uyarılar + yöntem şeffaflığı notu
2026-08-28 10:37:50 +03:00
hikmettan 3e129c2988 feat: tüm mock veriyi kaldır + Resend e-posta entegrasyonu
- mockTenders.js silindi; referans listeleri (sektör/il/kurum) constants.js'e taşındı
- AppContext: tenders/liveStats/competitorWatchlist/vaultDocuments/notifications/
  savedFilters/apiKeys/scrapedCapabilities → gerçek/boş; sahte Math.random online
  sayacı kaldırıldı; competitor & belge kasası artık localStorage
- LiveStatsBar: gerçek alanlar (canlı havuz/yüklü/bugün/kalem/takibimdeki)
- AnalyticsDashboard: KPI'lar (katılım/kazanma oranı/kazanılan bedel) + aylık hacim
  + sektörel dağılım gerçek companyStats/monthlyStats/sectorStats'tan; ciro hedefi
  kullanıcı tarafından belirlenir; veri yoksa dürüst boş durum
- ContractSearch & Rakip Radar: gerçek firmStats
- analytics.js: companyStats/monthlyStats/parseDateTR eklendi
- Resend: server/email.mjs + /api/notify/email/config + /api/notify/email/test
  (auth'lu, kullanıcının kendi adresine); PwaSettings gerçek e-posta test kartı
2026-08-28 08:49:10 +03:00
hikmettan 0ab74143c0 feat: demo özelliklerini gerçekleştir — canlı veri + localStorage
- analytics.js: firmStats/itemStats/provinceDensity (gerçek hesaplama)
- Rakip Radar: canlı veriden kazanan firma analizi (mock 3 firma kaldırıldı)
- Fiyat Analizi: gerçek kalem min/medyan/ort/maks + CSV export
- TurkeyHeatMap: 81 il gerçek interaktif yoğunluk haritası (tıkla→filtrele)
- Favori kurumlar: kart yıldızı + hızlı filtre (localStorage)
- Ekip yönetimi: gerçek CRUD (RightSidebar) + Kanban ataması ekipten
- Bildirimler: gerçek Notification API + izin + test + sessiz saatler
- PDF: jsPDF ile gerçek birim fiyat teklif cetveli (kaşe/imza alanı)
2026-08-28 01:58:46 +03:00
hikmettan 13f3e9d366 feat(auth): Google ile Giriş + landing/login + çalışan çıkış + admin rolü
- server/auth.mjs: ID token'ı oauth2.googleapis.com/tokeninfo ile doğrula (ek bağımlılık yok), HMAC imzalı app token, ADMIN_EMAILS ile admin
- POST /api/auth/google, GET /api/auth/google/config, GET /api/auth/me
- LoginPage: GIS butonlu landing/giriş; giriş yapılmadan uygulama açılmaz
- Header çıkış butonu artık çalışıyor; kullanıcı adı/avatar Google'dan
- AI Model Ayarları sekmesi sadece admin'e görünür
- Env: GOOGLE_CLIENT_ID + ADMIN_EMAILS (Coolify'dan)
2026-08-28 00:43:08 +03:00
hikmettan cc0b6b6017 feat(admin): AI model yönetimi paneli (fallback zinciri seçimi)
- 6 model kataloğu: GLM 5.3, DeepSeek V4 Flash, Gemini 3.7 Flash, Grok 4.6, GPT-5.6 Sol, Claude Opus 5
- Varsayılan fallback zinciri: GLM (birincil) → DeepSeek → Gemini
- Admin panelden sıralama, birincil seçme, ekleme/çıkarma; localStorage'da saklanır
- AI analizi aktif modeli kullanır
2026-08-27 09:44:34 +03:00
hikmettan 89cfd03d92 feat: canlı veri — ilan.gov.tr açık ihale + EKAP doğrudan temin (22/d)
- server/index.js: ilan.gov.tr proxy (açık ihale + kira/satış), TLS zincir düzeltmesi
- server/dt-worker.mjs: EKAP doğrudan temin toplayıcı (Playwright, imzasız oturum içi fetch)
- server/dt-store.mjs + il-plaka.mjs: DT verisini tender modeline çevirme
- src/services/tenderApi.js + AppContext: mock veri yerine canlı API
- Doğrudan Temin sekmesi 256 gerçek 22/d kaydıyla dolu
2026-08-26 20:45:02 +03:00
hikmet4434 a8d52b8601 feat: universal zero-hallucination dynamic web scraper engine & instant tag edit mode 2026-08-08 07:04:42 +03:00
hikmet4434 5994e91ef9 fix: map arisal.com.tr accurately to Arısal İş Elbiseleri & Workwear, Protective Safety Equipment 2026-08-08 06:57:22 +03:00
hikmet4434 5e3b5b72fb fix: restore activeTenderDetail and modal state definitions in AppContext.jsx 2026-08-07 18:29:48 +03:00
hikmet4434 ac54118542 feat: add Arısal Elektrik & Industrial Automation company scraper & TEİAŞ live tender feed 2026-08-07 18:10:34 +03:00
hikmet4434 796b22bc5a feat: real live EKAP government data feed integration & live refresh stream 2026-08-07 18:03:23 +03:00
hikmet4434 d40bcd3937 feat: strict domain sector matching & deep product capability analyzer 2026-08-07 17:47:05 +03:00
hikmet4434 ece74feefe feat: İhaleist - Akıllı İhale Takip ve Analiz Platformu (Full PRD + 7 Enterprise Modül) 2026-08-07 16:30:24 +03:00