13 KiB
13 KiB
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)
- QA'nın 9 maddesinden 8'i düzeltildi (H1, H2, H3, M1–M5, L1–L3, L5, L6 +
cagri.tsimportu); her biri ayrı commit. H4'e (model araç çağırmadan "Kaydettim" diyor) görev gereği dokunulmadı. sistemPromptuartı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 farkexport).- 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. <gerçek soru>" artık bedelsiz geçmiyor (H3).
- İ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.
- 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ızexportkelimesi;tsx --conditions=react-serverile 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:
profilAlanYazoku → değiştir → yaz yerine tek SQL ifadesi (json_set/json_remove, upsert). - Önce: iki araç
Promise.allile → 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_setdesteği koddan çıkarım; lokaldefile: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_guncelleaçık + kısa cevap sınırı" seçeneğidanismanAkisi'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
spendCreditForMessageyoluna 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:
sohbetGecmisiGetiryeniden eskiye +rowidsıralayıp 100 alır, çevirir;GET /api/soruaynı 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_atsaniye çö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 sorgusunarowidsı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.aracCalistiriciargü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ı".0da aynı hata (önce sessizce yok sayılıyordu).tur: "__proto__"→ önceTypeError· sonra açık hata.
- QA'nın 118 vakalık
arac-test.ts'i yeniden koşuldu:FIRLATTIsayı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
LIKEyerine 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.tskullanı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
- Araç tanımı (modele giden şema) dört yerde değişti — sistem prompt metni değişmedi, ama eval mühendisi bilmeli:
program_idveprogram_idleröğeleristring | integer;profil_guncelle.degerstring | number | null;ucret_ustminimum: 1;dilseçeneklerine Almanca, Fransızca, Arapça, Rusça eklendi. Sebep: gövdeler bunları zaten kabul ediyordu (gerçek modeldeger: 300sayısı gönderdi; "Almanca" süzgeci 17 sonuç veriyordu); şema sıkı doğrulanınca çalışan çağrılar kırılırdı. dilgenişletmesi 8 numaranın parçası amab26df27(9) commit'ine girdi (aynı dosya, etkileşimsiz kısmi ekleme yapılamadı).danismanAkisi'ne isteğe bağlızamanAsimiMseklendi (H2'yi 120 sn beklemeden test etmek için).- 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/soruhı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_guncelleile iki alan kaydı —json_setyolu. - 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.dbcommit edilmedi. Test için eklenen 120 dolgu mesajı veqa-arac-kullaniciprofil satırı silindi; QA'nın kayıtlarındanqa-arac-kullanici'nın sohbet mesajları da silindi (dolgu eklerken temizlendi).src/lib/db.tsvesrc/lib/rapor-havuzu.tsbaş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 olarakb26df27commit'ini değil o anki ağacı doğruladı.- Para ve kişisel veriye (kredi, profil) dokunuldu:
guvenlik-uyumdenetimi önerilir.
Bilal'den istenen
- [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).
- [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).
/api/soru'ya hız sınırı eklensin mi (1 dk).