Files
hikmettanandClaude Fable 5.1 7fa71f1a4e
Quality gates / test-build (push) Canceled after 0s
Quality gates / container (push) Canceled after 0s
feat(ai): Z.ai GLM birincil sağlayıcı; OpenRouter yalnız yedek
OpenRouter anahtarı iptal olup bakiye eksiye düşünce şartname analizi,
TED çevirisi ve site taraması durmuştu. Artık ZAI_API_KEY ile GLM 5.3 ve
GLM 5.3 Flash doğrudan Z.ai Coding Plan üzerinden çağrılır; kalan modeller
OpenRouter anahtarı varsa yedek olarak denenir.

- server/zai.mjs: doğrudan istemci; glm-5.x için reasoning_effort:low,
  glm-4.x için thinking kapalı; süreç genelinde en fazla 2 eşzamanlı istek
  (kullanıcı istekleri arka plan çevirisinden öncelikli); geçici 429'da
  aynı modelle yeniden deneme, 1113 bakiye hatasında hemen sıradaki model.
- ai.mjs: 'zai' (GLM 5.3) sağlayıcısı eklendi, Z.ai yolu yeni istemciyi
  kullanıyor; varsayılan sıra zai → glmflash → gemini → …
- ted-ceviri.mjs: önce ZAI_TRANSLATE_MODELS (glm-5.3-flash, glm-5.3),
  sonra OpenRouter; 2'li eşzamanlı parça işleme.
- Admin model kataloğuna GLM 5.3 eklendi, kayıtlı zincirler sürüm 4'e taşınır.
- tests/zai.test.mjs: düşünme ayarı, 429/1113 davranışı, eşzamanlılık,
  analyzeSpec ve TED çevirisinin Z.ai'ye gittiği.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 23:11:41 +03:00

161 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 /` "bin**ası** 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`,
`ZAI_API_KEY`, `OPENROUTER_API_KEY` (yalnız yedek), `GOOGLE_CLIENT_ID`
- **Yapay zekâ (2026-09-10):** birincil sağlayıcı Z.ai Coding Plan. `ZAI_BASE_URL`
= `https://api.z.ai/api/coding/paas/v4/chat/completions`; aynı anda en fazla 2 istek
(`ZAI_MAX_CONCURRENCY`), GLM 5.x'te `reasoning_effort: low`. Şartname analizi
GLM 5.3 → GLM 5.3 Flash, TED çevirisi GLM 5.3 Flash → GLM 5.3; ikisi de bitince
OpenRouter zincirine düşer. Ayrıntı: `server/zai.mjs`.
- **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**.