Files
ihaleist/docs/DEVIR.md
T

7.7 KiB
Raw Blame History

ihaleist — Devir Notu

Tarih: 30 Ağustos 2026 Canlı: https://ihaleist.seymata.com · Coolify: seymata.com · Kaynak: gitea (hikmettan/ihaleist)


🚨 ÖNCE BU — canlıda aktif sorun

canlı ilan havuzu: 120 / 3.080   ← kullanıcılar bunu görüyor

Sebep: c5662d2 ile eklenen CPV kapısı, ilanlariBirlestir() içinde her ilan için AI çağırıyor ve "CPV bitmeden yayınlama" diye bekletiyordu. 3.000 ilan × AI = saatler. Log kanıtı: [ihaleist-api] ilk yükleme: 120 ilan (havuz 3080) bir kez yazılmış, havuz hazır hiç yazılmamış; her yenilemede yenileme başladı (mevcut 120 ilan…).

Düzeltme yazıldı, gitea'ya gitti, canlıya ALINAMADI.

Gitea'da olup canlıda olmayan commitler

commit ne yapıyor
14f24e0 CPV kapısı havuzu bloklamıyor — yayın anında yalnızca önbellek + anahtar kelime (senkron), kalanı cpvZenginlestir() ile arka planda AI
ac77146 İlan/ihale tarihi etiketli gösterim + "sadece açık ihaleler" filtresi

Yapılacak

Coolify → ihaleist → Actions → Redeploy. Tek işlem ikisini de indirir, havuz 120 → 3.080 olur.

Uyarı: Coolify'ın Redeploy'u ajan otomasyonundan güvenilir tetiklenmiyor. Bu seansta ~10 denemenin çoğu deploy kaydı oluşturmadı (bazen çalıştı). En hızlı yol: kullanıcıdan tek tık istemek. Çalışan yöntem (bazen): find ile Actions ref'ini bul → tıkla → find ile Redeploy ref'ini bul → tıkla. Koordinatla tıklama ölçek kayması yüzünden yanlış yere gidiyor.


Bu seansta tamamlananlar

Stripe — canlı ve doğrulandı

  • Yıllık abonelik: Pro 8.954 ₺, Kurumsal 24.800 ₺ (%17 indirim), yıllık varsayılan
  • configured: true, webhookHazir: true
  • Uçtan uca test edildi: TEST100 kuponuyla 100 ₺ gerçek ödeme → checkout.session.completed → webhook Delivered → sunucu logu [stripe-webhook] hikmet044@gmail.com → pro planına geçti
  • Abonelik dönem sonunda iptal edildi (sub_1U9qpPCr82j1cLP0x71Cnsfx, 29.08.2027, yenileme yok)
  • Yönetici geçersizleştirmesi satın alınan planı eziyordu → /api/me/plan artık plan (etkin erişim) + abonelik (satın alınan) + yonetici ayrı döndürüyor

İptal ekranı

src/components/CancelSubscriptionModal.jsx — 8 seçenekli ayrılma nedeni + 500 karakter açıklama ("Diğer" seçilirse zorunlu). Neden hem Stripe'a (cancellation_details.feedback) hem kendi DB'mize yazılıyor. Dönem sonunda iptal.

Sektör sınıflandırması: %51 → %2

Dört ayrı hata bulundu ve düzeltildi:

  1. Türkçe büyük harf — JS'in i bayrağı İ/I çiftini katlamaz; /inşaat/i "İNŞAAT" ile eşleşmiyordu. Başlıkların yarısı TAMAMEN BÜYÜK HARF. → normalizeTr() (Türkçe küçültme + ASCII katlama), kurallar ASCII alfabede yazıldı.
  2. Kelime ortası eşleşme — /asi / "binası onarımı" ile eşleşip Sağlık üretiyordu. → tüm kalıplara \b.
  3. Kurum adı başlığı eziyordu — "Gıda ürünleri" + "X DEVLET HASTANESİ" birleştirilince Sağlık kuralı (1. sıra) Gıda'dan (4. sıra) önce eşleşiyordu. → sektorBul() parçaları öncelik sırasıyla tek tek tarıyor.
  4. Doküman metni zehirliyordu — her e-ihale ilanındaki "e-imza ile imzalanarak", "numune sunulması istenmektedir" gibi standart metin yanlış sınıf üretiyordu ("Kedi ve köpek maması" → Bilişim). → ilanKonusu() yalnızca işin konusunu ayıklıyor.

Ayrıca: 8 → 28 sektör, OKAS/CPV kod eşlemesi (44 bölüm + 17 alt grup), doküman zenginleştirme (kalıcı önbellekli, dokuman-v3).

kaynak önce sonra
canlı ilan %51 ~%7
arşiv (OKAS) %51 %4
doğrudan temin %29 %0

DT'de kilit bulgu: BransKodList zaten OKAS/CPV kodu — idarenin kendi sınıflandırması.

DT hızı: 0,36 → 3,2 kayıt/sn (9×)

İki hata vardı:

  • Detay kuyruğu rowid (en eski) sırayla gidiyordu; arayüz en yeni 5.000'i gösteriyor → gösterilen hiçbir kayda detay ulaşmıyordu. → ORDER BY rowid DESC
  • Bütçe 4 saatte 30 detay → 10 bin kayıt 55 gün. → DT_DETAILS=4000

Hız: 10 paralel + adaptif fren (hata → gecikme ×2, max 2,5 sn; temiz → ×0,9, min 250 ms). Üretimde ölçüldü: dakikada ~170 kayıt.

Havuz izleme

/api/health/havuz — havuz_olcum tablosu, 7 ve 30 günlük ortalamaya kıyas, kaynak_dusus / kalici_dusus / eksik_yukleme ayrımı, ADMIN_EMAILS'e e-posta (6 saatte bir en fazla), üst şeritte kullanıcıya görünür uyarı.

Sonsuz kaydırma

Sayfalama kalktı. 20'şer yükleniyor (IntersectionObserver, 600 px önden). Yan fayda: 10.335 kayıtta 1.034 sayfa düğmesi DOM'a basılıyordu, o da gitti. Sıfırlama yalnızca filtre/sıralama değişiminde (havuz yenilemesinde değil).

Doküman yükleme

EKAP dosyası sunucudan alınamıyor (6 yöntem denendi, hepsi BIG-IP'e takıldı). Kullanıcı indirip yüklüyor → belgeler.ikn ile ihaleye bağlanıyor → "AI analiz" düğmesiyle metni çıkarılıp şartname analizine gidiyor. DT kayıtlarında da çalışıyor.

Tarih gösterimi + açık ihale filtresi (ac77146, deploy bekliyor)

  • Üç kaynağa da ham ilanTarihi eklendi (canlı publishStartDate, DT yayim_tarihi, arşiv ilan_tarihi)
  • Kartta: sol blokta İHALE etiketi, yeşil rozet İlan: gg.aa.yyyy, mavi rozet İhale: gg.aa.yyyy ss:dd
  • onlyValidOnly context'te vardı ama filtrede hiç kullanılmıyordu → artık gerçekten süzüyor, varsayılan açık, araç çubuğunda "Sadece açık ihaleler" kutusu. Tarihi okunamayan kayıt gizlenmiyor.

Bilinen açıklar

konu durum
GitHub uzağı hikmet4434/ihaleist → Repository not found. Gitea çalışıyor, Coolify oradan deploy ediyor. GitHub yedeği ~10 commit geride.
DT_INTERVAL_SAAT Hiç oluşmadı (form alanına yazma düşmemiş). DT_DETAILS=4000 var ve çalışıyor. Aralık hâlâ 4 saat.
EKAP ilan dosyası Sunucudan indirilemiyor. EncIlanId'ler kayıtlı. İlerlemek için EKAP arayüzünde ağ trafiğini yakalamak gerek.
database is locked DT worker yazarken API okuyor, turda ~6 kayıt kaybı. WAL modu çözer.
Görsel doğrulama Sonsuz kaydırma ve tarih değişiklikleri build + statik kontrol geçti, tarayıcıda görülmedi (bu Chrome profilinde uygulamaya giriş yapılmamış).
Canlı ilan %7 Genel Başlığında hiç sinyal olmayan kayıtlar ("MALZEME ALIMI"). "Genel" filtre listesinde seçilebilir.

Ortam

  • Volume: /app/server/data → history.sqlite, dt.sqlite, users.sqlite
  • Girilmiş sırlar: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, RESEND_API_KEY, OPENROUTER_API_KEY, GOOGLE_CLIENT_ID
  • E-posta: bildirim@ihaleist.com (Resend, eu-west-1, doğrulanmış)
  • Zamanlayıcı: geçmiş tarama 6 sa · DT 4 sa · bildirim 6 sa

Sağlık uçları

/api/stats                havuz sayıları
/api/health/scheduler     zamanlayıcı + DT son tur
/api/health/havuz         7/30 günlük havuz ölçümü
/api/health/sektor        doküman zenginleştirme ilerlemesi
/api/meta/filtreler       sektör + kurum listesi (tek kaynak)
/api/billing/plans        configured, webhookHazir, fiyat kimliği tanılaması

Sınıflandırma mimarisi

server/siniflandir.mjs tek kaynak — üç veri kaynağı da buradan geçer. Öncelik: OKAS kodu → başlık → kalem adları → ilan konusu → kurum adı. İlk eşleşen kazanır. Kural yazarken: desenler normalleştirilmiş (ASCII, küçük harf) metne uygulanır, \b ile sınırlanır, ı/ş/ç/ğ/ö/ü kullanılmaz.