From fd464e9cc221e84eaccaa45e0716d9cbc2d9a019 Mon Sep 17 00:00:00 2001 From: bilalgursen Date: Mon, 5 Oct 2026 01:14:08 +0300 Subject: [PATCH] =?UTF-8?q?docs(gece):=20yaz=C4=B1l=C4=B1mc=C4=B1=20QA=20d?= =?UTF-8?q?=C3=BCzeltmeleri=20raporu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- .../05-yazilimci-qa-duzeltmeleri.md | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 docs/gece-vardiyasi/2026-10-05/05-yazilimci-qa-duzeltmeleri.md diff --git a/docs/gece-vardiyasi/2026-10-05/05-yazilimci-qa-duzeltmeleri.md b/docs/gece-vardiyasi/2026-10-05/05-yazilimci-qa-duzeltmeleri.md new file mode 100644 index 0000000..bccd8f3 --- /dev/null +++ b/docs/gece-vardiyasi/2026-10-05/05-yazilimci-qa-duzeltmeleri.md @@ -0,0 +1,133 @@ +# 05 — Yazılımcı: QA düzeltmeleri (danışman sohbeti) + +Dal `gece/eval-jev` · kaynak rapor `03-qa-dal-ve-kod-denetimi.md` · 5 Ekim 2026 gecesi · yazılımcı + +## Özet (5 madde) + +1. **QA'nın 9 maddesinden 8'i düzeltildi** (H1, H2, H3, M1–M5, L1–L3, L5, L6 + `cagri.ts` importu); her biri ayrı commit. H4'e (model araç çağırmadan "Kaydettim" diyor) görev gereği dokunulmadı. +2. **`sistemPromptu` artık içe aktarılabilir:** `src/lib/ai/danisman-prompt.ts` (`sistemPromptu`, `PROFIL_ONAY_SOR`). Metin birebir aynı (eski/yeni satır karşılaştırması: tek fark `export`). +3. **Kredi tarafındaki iki delik kapandı:** zaman aşımında yarım cevap artık "tamam" sayılmıyor ve kredi iade ediliyor (H2); "evet. " artık bedelsiz geçmiyor (H3). +4. **İki bilinçli karar verildi:** H3'te sıkı kalıp eşleşmesi seçildi; M1'de sunucu davranışı korunup istemci metni düzeltildi (kopmada iade, bedava cevap kapısı olurdu). Gerekçeler aşağıda. +5. **Doğrulama:** typegen + tsc + lint (eslint 0 uyarı, tasarım denetimi 0 hata / 12 eski uyarı) + tek `pnpm build` (1935 sayfa) geçti. Gerçek model çağrısı: 4 adım (sınır 15). Tarayıcı ve sunucu açılmadı; route düzeyi davranışlar (402 vb.) fonksiyon testine dayanır, aşağıda "koddan çıkarım" diye işaretli. + +## Commit listesi + +| Sha | Hata | Mesaj | +|---|---|---| +| `3e4886e` | Ek | refactor(danisman): sistemPromptu saf modüle taşındı | +| `4e2470e` | H1 (1) | fix(danisman): aynı adımda iki profil_guncelle birbirini ezmesin | +| `1191f16` | M2 (6) | fix(danisman): 100 mesajı aşan geçmişte en yeni 100 dönsün | +| `08f4ec2` | M3 (7) | fix(danisman): modele giden pencere tutarlı olsun | +| `3f1e770` | H3 (3) | fix(danisman): bedelsiz onay yolu yalnız gerçek onayda açılsın [KARAR] | +| `90a9994` | H2 (2) | fix(danisman): zaman aşımında yarım cevap tamam sayılmasın, kredi iade edilsin | +| `3c3183b` | M1 (5) | fix(danisman): bağlantı kopunca istemci "iade edildi" demesin | +| `72b673b` | M4+M5 (8) | fix(danisman): araç argümanları şemayla doğrulansın, "300 km" 300 okunsun | +| `b26df27` | L1–L3, L5, L6 (9) | fix(danisman): Türkçe-duyarsız il/bölüm/üniversite eşleşmesi, kısa girdi hatası | + +Değişen dosyalar: `src/app/api/soru/route.ts`, `src/lib/ai/{danisman-prompt,sohbet-gecmisi}.ts` (yeni), `src/lib/ai/{araclar,sohbet-akisi,cagri}.ts`, `src/lib/danisman-profil-db.ts`, `src/lib/mesafe.ts`, `src/features/rapor/rapor-queries.ts`, `src/features/rapor/components/sohbet-client.tsx` (yalnız toast metni + yorum). + +## Düzeltmeler ve kanıt + +Hepsi çalıştırılarak doğrulandı (aksi yazılmadıkça). Betikler scratchpad `yz/` altında, commit edilmedi. + +### Ek — `sistemPromptu` taşındı +- Yeni yol: `import { sistemPromptu } from "@/lib/ai/danisman-prompt"`. Girdi: `{ params, listeOzeti, kilitli?, profil? }`. +- Kanıt: HEAD'deki fonksiyon gövdesiyle yeni dosyadaki gövdenin `diff`'i yalnız `export` kelimesi; `tsx --conditions=react-server` ile Next dışından çağrıldı (4.621 karakter döndü). +- Next kılavuzu (`route.md`) route dosyasından ek dışa aktarımı anlatmıyor; ayrı dosya görev tanımındaki yönlendirmeyle seçildi. + +### H1 — iki `profil_guncelle` birbirini eziyordu +- Değişen: `profilAlanYaz` oku → değiştir → yaz yerine tek SQL ifadesi (`json_set` / `json_remove`, upsert). +- Önce: iki araç `Promise.all` ile → DB `{"maxKm":300}`; her araç yalnız kendi alanını görüyor. +- Sonra: DB `{"evIl":"ANKARA","maxKm":300}`; iki araç çıktısında da iki satır. Silme ve geçersiz değer (`maxKm: 5` → hata) çalışıyor. +- Gerçek modelle: "evet" → model iki `profil_guncelle`'yi aynı adımda çağırdı → DB'de ikisi de var. +- Not: üretim libsql (uzak) kullanıyorsa `json_set` desteği koddan çıkarım; lokalde `file:` ile doğrulandı. + +### H2 — zaman aşımında yarım cevap "tamam" sayılıyordu +- Değişen: `sohbet-akisi.ts` — "abort" parçası istemciye geçirilmiyor; döngüden sonra zaman aşımı sinyaline bakılıp hata fırlatılıyor → `onYarim` (iade + yarım kayıt) + hata parçası. İsteğe bağlı `zamanAsimiMs` (varsayılan 120 sn; test için). +- Önce (sahte sağlayıcı "takıl", 120,0 sn): `[onTamam] "Bu cevap takılacak ve "`, parçalar `… abort finish`. +- Sonra (`zamanAsimiMs: 4000`): `[onYarim] "Bu cevap takılacak ve " → iade`, parçalar `… error(Danışman şu anda yanıt veremiyor.)`. Normal cevap ve "yarıda kes" modu eskisi gibi (onTamam / hata). +- Varsayılan 120 sn ile düzeltme sonrası yeniden koşulmadı (aynı kod yolu; koddan çıkarım). + +### H3 — bedelsiz onay yolu kredi atlatıyordu [KARAR] +- Seçim: **sıkı kalıp**. Mesaj noktalama atıldıktan sonra baştan sona onay sözlerinden oluşmalı (evet / olur / tamam / kaydet / hayır / gerek yok… + "lütfen", "bunu", "teşekkürler" dolgusu). Uymayan mesaj normal kredili soru. +- Gerekçe: en sade çözüm ve deliği kökten kapatıyor — bedelsiz turda soru metni hiç taşınamıyor. "Yalnız `profil_guncelle` açık + kısa cevap sınırı" seçeneği `danismanAkisi`'ne iki yeni parametre ister ve "evet, peki hukuk?" yine bedelsiz model turu harcar; eklenmedi. 26 Eyl kararı ("profil onayı kredi harcamaz") gerçek onay için aynen duruyor. +- Önce/sonra (eski fonksiyon betiğe birebir kopyalandı, 16 vaka): "evet. Ege hukuk taban sırası kaç?", "evet ama izmir hukuk kaç", "tamam, peki ODTÜ?", "evet hukuk" → önce bedelsiz, sonra kredili. "evet", "Evet.", "EVET!", "evet, kaydet lütfen", "hayır", "Hayır, gerek yok." vb. 12 gerçek onay → bedelsiz kaldı. +- 0 kredide 402 dönmesi: route'ta kalıba uymayan mesaj `spendCreditForMessage` yoluna düşer (koddan çıkarım; sunucu açılmadı). +- Yan etki: kalıpta olmayan onay ("aynen", "ok") 1 kredi harcar; 0 kredide 402 alır. + +### M1 (5) — istemci kopunca "iade edildi" diyordu +- Seçim: **sunucu doğru, istemci metni yanlış.** Sunucu kopmada üretip kaydetmeye devam eder, kredi harcanmış kalır. Kopmada iade seçilmedi: cevabı okuyup son anda bağlantıyı kesen kullanıcı her soruda iade alırdı. +- Değişen: yalnız toast metni — "Bağlantı koptu. Cevap tamamlanırsa sohbetine kaydedilir, tamamlanamazsa kredin iade edilir — yeniden göndermeden önce sayfayı yenile." + iki yorum. Görsel değişiklik yok. +- Kanıt: metin değişikliği; tarayıcıda denenmedi (koddan çıkarım). Sunucu davranışını QA çalıştırarak doğrulamıştı. +- Kalan: soru hâlâ giriş kutusuna geri konuyor; kullanıcı uyarıya rağmen yeniden gönderirse iki kredi öder. İstemci "sunucu hatası" ile "bağlantı koptu"yu ayırt edemiyor; ayırmak davranış değişikliği ister (tasarımcı/ürün kararı). + +### M2 (6) — 100 mesajı aşınca en eski 100 dönüyordu +- Değişen: `sohbetGecmisiGetir` yeniden eskiye + `rowid` sıralayıp 100 alır, çevirir; `GET /api/soru` aynı fonksiyonu kullanır (kopya sorgu kalktı). +- Önce (120 dolgu mesajı): dönen 100, ilk "dolgu 1", son "dolgu 100". +- Sonra: ilk "dolgu 21", son "dolgu 120", sıra birebir doğru (aynı saniyeye düşen soru-cevap çiftleri dahil — `created_at` saniye çözünürlüklü). + +### M3 (7) — modele bozuk rol sırası gidiyordu +- Değişen: `modelPenceresi` (`src/lib/ai/sohbet-gecmisi.ts`) — baştaki danışman mesajları atılır, art arda aynı rol tek mesajda birleşir (yinelenen metin bir kez). 12'lik pencere sorgusuna `rowid` sıralaması eklendi. +- Önce → sonra (roller): `uauauauauuua`+yeni → `uauauauauuuau` → `uauauauauau`; `auauauauauau`+yeni → `auauauauauauu` → `uauauauauau`; aynı soru üç kez → tek mesaj. +- Birleştirme seçildi (atma değil): cevapsız kalan mesajdaki bilgi ("Ankara'da yaşıyorum") kaybolmasın. + +### M4 + M5 (8) — `sayiParse` ve argüman doğrulama +- `sayiParse`: birim eki sayıdan ayrıldı. "300 km" önce "Değer kabul edilmedi" (300.000 okunuyordu), sonra "Evden en fazla 300 km". "400 bin TL", "300k" eskisi gibi. +- `aracCalistirici` argümanı `ARACLAR` şemasına göre denetliyor: bilinmeyen alan, yanlış tip, geçersiz seçenek, alt sınır, eksik zorunlu alan. Örnek sonuçlar: + - `arama: 12345` → önce "Araç çalışmadı; veriye ulaşılamadı" · sonra "arama: metin olmalı (gelen: 12345)". + - `dilim: "orta"` → önce süzgeç `dilim = undefined`, 2.234 sonuç · sonra "dilim: geçersiz seçenek …; şunlardan biri olmalı: hayal, dengeli, guvenli". + - `ucret_ust: -5` → önce "yıllık ücret ≤ -5 TL", 757 sonuç · sonra "ucret_ust: en az 1 olmalı". `0` da aynı hata (önce sessizce yok sayılıyordu). + - `tur: "__proto__"` → önce `TypeError` · sonra açık hata. +- QA'nın 118 vakalık `arac-test.ts`'i yeniden koşuldu: `FIRLATTI` sayısı 5 → 0; geçerli vakaların sonuç sayıları değişmedi. +- İsteğe bağlı alanda `null` "verilmedi" sayılır (modeller boş alanı böyle yollayabiliyor). + +### L1–L3, L5, L6 (9) +| Girdi | Önce | Sonra | +|---|---|---| +| `program_ara il:"IZMIR"` | İl tanınmadı | 129 sonuç | +| `program_ara arama:"isletme"` / `"ISLETME"` | 0 | 513 (İşletme ile aynı) | +| `program_ara universite:"bogazici"` / `"ODTÜ"` | 0 / 0 | 12 / 22 | +| `il_ozeti "Afyon"` | İl bulunamadı | Afyonkarahisar | +| `profil_guncelle evIl "IZMIR"` | İl tanınmadı | Yaşadığı il: İzmir | +| `bolum_ozeti "a"`, `"---"` | Abaza Dili ve Edebiyatı | "en az 3 harf yaz" | +| `bolum_istihdam ["a"]` | Acil Yardım | "en az 3 harf yaz" | +| `universite_profili "a"` | Abdullah Gül | "en az 3 harf yaz" | +| `universite_profili "DEÜ"` | bulunamadı | Dokuz Eylül Üniversitesi | +| `program_ara arama:"%"` | 3.247 sonuç | "en az 3 harf yaz" | + +- Bölüm/üniversite araması SQL `LIKE` yerine katlanmış adla JS'te eşleniyor (ayrık 1.744 bölüm adı, 322 üniversite adı bir kez okunur). İşletme 513, iKTiSAT 171, hukuk 140: önce/sonra aynı. +- Hata logu artık yalnız mesajı basıyor; `cagri.ts` kullanılmayan import kalktı (eslint uyarısı 1 → 0). +- Gerçek modelle: "IZMIR'de isletme okumak istiyorum…" → `program_ara {"arama":"İşletme","il":"İzmir"}`, 19 eşleşme, cevap geldi. + +## Şartnameden sapmalar + +1. **Araç tanımı (modele giden şema) dört yerde değişti** — sistem prompt metni değişmedi, ama eval mühendisi bilmeli: `program_id` ve `program_idler` öğeleri `string | integer`; `profil_guncelle.deger` `string | number | null`; `ucret_ust` `minimum: 1`; `dil` seçeneklerine Almanca, Fransızca, Arapça, Rusça eklendi. Sebep: gövdeler bunları zaten kabul ediyordu (gerçek model `deger: 300` sayısı gönderdi; "Almanca" süzgeci 17 sonuç veriyordu); şema sıkı doğrulanınca çalışan çağrılar kırılırdı. +2. `dil` genişletmesi 8 numaranın parçası ama `b26df27` (9) commit'ine girdi (aynı dosya, etkileşimsiz kısmi ekleme yapılamadı). +3. `danismanAkisi`'ne isteğe bağlı `zamanAsimiMs` eklendi (H2'yi 120 sn beklemeden test etmek için). +4. L4 (uzun girdi araç sonucuna yansıyor), L7 (baştaki boş satır), L8 (Jev eşiği), L9 (depodaki `app.db` şeması) görev listesinde yoktu; dokunulmadı. + +## Düzeltilemeyen / açık kalan + +- **H4** — görev gereği dokunulmadı (yapay zekâ mühendisi). +- **M1'in istemci yarısı** tam kapanmadı: metin doğru ama soru kutuya geri konuyor (yukarıda). +- **`/api/soru` hız sınırı yok** (QA H3 notu): bedelsiz "evet" turu sınırsız tekrarlanabilir. Her tur yalnız onay taşıyor, soru soramıyor; yine de model çağrısı maliyeti var. +- **Route düzeyinde uçtan uca test yapılmadı** (sunucu açılmadı): 402, başlıklar, GET cevabı koddan çıkarım. + +## Merge sonrası doğrulanması gerekenler + +- Üretim veritabanında (libsql) `profil_guncelle` ile iki alan kaydı — `json_set` yolu. +- 0 kredili hesapla "evet. " → 402; yalnız "evet" → bedelsiz. +- Tarayıcıda bağlantı kopması: yeni toast metni ve sayfa yenilenince cevabın görünmesi. +- Eval turunda araç şeması değişikliklerinin (sapma 1) model davranışına etkisi. + +## Çalışma ağacı notu + +- `data/app.db` commit edilmedi. Test için eklenen 120 dolgu mesajı ve `qa-arac-kullanici` profil satırı silindi; QA'nın kayıtlarından `qa-arac-kullanici`'nın sohbet mesajları da silindi (dolgu eklerken temizlendi). +- `src/lib/db.ts` ve `src/lib/rapor-havuzu.ts` başka bir ajanın commit'lenmemiş değişikliği; dokunulmadı. tsc/lint/build bu değişiklikler çalışma ağacındayken koşuldu, yani build tam olarak `b26df27` commit'ini değil o anki ağacı doğruladı. +- Para ve kişisel veriye (kredi, profil) dokunuldu: **`guvenlik-uyum` denetimi önerilir.** + +## Bilal'den istenen + +1. [BİLAL] H3 kararını onayla ya da değiştir: yalnız baştan sona evet/hayır olan mesaj bedelsiz; "evet + soru" 1 kredi (1 dk). +2. [BİLAL] M1: bağlantı kopunca soru giriş kutusuna geri konmaya devam etsin mi (yeniden gönderen iki kredi öder) — kaldırılsın mı (2 dk). +3. `/api/soru`'ya hız sınırı eklensin mi (1 dk).