Commit Graph
113 Commits
Author SHA1 Message Date
hikmettan f45afbfa3d fix: geçersiz/yer tutucu RESEND_API_KEY 'aktif' görünmesin
emailConfigured artık anahtarın 're_' ile başlamasını arıyor; böylece Coolify'da
boş/yer tutucu değer bırakıldığında arayüz yanlışlıkla 'E-posta aktif' demiyor.
2026-08-28 22:57:58 +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 5282543471 feat: zamanlayıcı teşhis ucu + geniş arşiv dolumu
- /api/health/scheduler: DT/sonuç taraması durumu, son DT turu, boş bellek,
  Chromium varlığı — uzaktan teşhis için
- Dolum eşiği 2.000 → 25.000, pencere 180 → 365 gün (arşiv 6 aylık havuzun
  %7'sinde erken duruyordu)
2026-08-28 22:37:11 +03:00
hikmettan 1838de95f5 feat: ihale dokümanları + OKAS kalem verisi + doğrudan temin (Playwright) + kalıcı arşiv
1) İhale evrakları (yeni)
   - server/documents.mjs: EKAP doküman URL üretimi (imzalı), ilan metni +
     OKAS kalem çıkarımı, Playwright ile doküman metni (varsa)
   - /api/documents/url · /ilan · /text · /config uçları
   - TenderDocuments paneli: 'EKAP Dokümanlarını Aç' + 'İlan Metnini AI ile
     Analiz Et' (11K+ karakter gerçek ilan metni doğrudan AI'ya gider)
   - NOT: eski EKAP host'u bot isteklerine bağlantı kesiyor; bağlantı
     kullanıcının tarayıcısında açılır, sunucu tarafı metin için Chromium gerekir

2) Kalem verisi gerçek oldu
   - ekap-scan: her ihale için IhaleDetay'dan OKAS ihtiyaç kalemleri çekilir
   - history-store: okas_kalemler kolonu + otomatik şema geçişi
   - --kalem-doldur modu: mevcut kayıtlara IKN'den çözerek kalem ekler
   - scheduler: tarama sonrası kalem doldurmayı zincirler
   - PriceAnalysis: yöntem şeffaflığı notu (birim fiyatlar kamuya açık değil;
     kategori bazlı yaklaşık değer olduğu açıkça yazıyor)

3) Doğrudan temin (Playwright)
   - Dockerfile: node:22-slim + nginx + Playwright/Chromium
   - scheduler: DT worker periyodik (DT_INTERVAL_SAAT, varsayılan 4 saat)
   - Bellek koruması: boş bellek DT_MIN_BOS_MB altındaysa tarama atlanır ve
     uyarı loglanır; DT_ENABLED=0 ile tamamen kapatılabilir

4) Kalıcı arşiv
   - Coolify'da /app/server/data volume bağlandı; arşiv artık deploy'lar
     arası korunuyor

Ayrıca: TenderDetailModal'daki sabit '3-5 Firma' tahmini kaldırıldı, yerine
gerçek geçerli teklif sayısı gösteriliyor.
2026-08-28 22:31:40 +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 daf5c2c117 fix: geçmiş arşiv kayıtları ana ekranı çökertiyordu
- SummaryCards/TenderList/DailyBulletin/ResultSearch/TenderCalendar:
  eklenmeZamani, baslik, kurum, ikn, tarih alanlarına güvenli erişim
  (arşiv kayıtlarında bu alanlar bulunmuyordu → TypeError, boş ekran)
- history-store: arşiv kayıtlarına arayüzün beklediği varsayılan alanlar
2026-08-28 10:46:54 +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 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 4f1ba88e94 deploy: canlı veri backend'ini container'a ekle (nginx /api → Node :3001)
- Dockerfile: nginx + Node tek container; backend arka planda, nginx ön planda
- nginx.conf: /api → 127.0.0.1:3001 proxy
- dt-store: node:sqlite guard (yoksa DT devre dışı, açık ihaleler yine canlı)
- Açık ihale canlı verisi sıfır npm bağımlılığıyla deploy'da çalışır
2026-08-26 21:28:25 +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