# Güvenlik ve uyum geri bildirimi — 7 Ekim 2026 merge paketi Kapsam: dal `v2`, HEAD `e4c06f5`; `e3d79f5` (revizyon sınırı kaldırıldı), `15f4c4f` (rehber bağlantı düzeltme logu) ve pazarlama/yasal metin tutarlılığı. Kod değiştirilmedi; denetim koddan (statik okuma). Canlıya dokunulmadı. ## Özet (5 madde) 1. **Kritik yok.** Kredi düşme/iade yolu ve paket kapısı doğru: paketsiz-kredili aday revizyon yapamaz (üç bağımsız kapı: prompt, araç, çekirdek). Sınırsız revizyon maliyet riski **düşük** — her revizyon 1 sohbet kredisi ister, kullanıcı başına üretim kilidi var, cevap başına tek revizyon; ölçülü maliyet revizyon başına ~2,4 kuruş (60 kredilik paketin tamamı revizyona gitse ≈1,5 TL). 2. **Metin × kod (orta, avukat teyidi):** "Sınırsız liste revizyonu" vaadi gerçekte **kredili** bir sınırsızlık — her revizyon isteği 1 sohbet kredisi yakar, kredi bitince revizyon da biter. Ana sayfa ve paket kartındaki madde bu şartı söylemiyor; "sınırsız" iddiasının önemli kısıtı aynı yerde açıklanmalı (Ticari Reklam Yönetmeliği m.7 / 6502 m.6 tüketiciyi yanıltıcı beyan riski). 3. **Kullanıcıya giden iki yanıltıcı cümle (düşük):** `liste-revizyon.ts:39,42` "kredin/paketin etkilenmedi" diyor ama o turun 1 sohbet kredisi harcanmış kalıyor; `rapor.ts:712` hâlâ "Revizyon hakkın kullanılmadı" diyor (hak kavramı kalktı). 4. **Bağlantı logu (düşük, OLASI):** `sohbet-akisi.ts:281` yalnız slug logluyor; e-posta/ad/puan taşımıyor. Ancak slug **modelin yazdığı serbest metinden** geliyor; kullanıcı mesajına yazılmış `/rehber/ahmet-yilmaz-plani` gibi bir adres modelce tekrarlanırsa log'a geçer. Sayaç + yalnız `yeniSlug` (kayıtlı slug) loglanması yeterli. 5. **Rate limit yok ama sorun değil:** `/api/soru` üzerinde hız sınırı yok; maliyet kapısı kredi (deneme 5, paket 60). Magic link better-auth varsayılanı 5/60 sn ile sınırlı (`node_modules/better-auth/dist/plugins/magic-link/index.mjs:157-162`). Revizyon paketsize kapalı olduğu için "başkasının parasıyla LLM" saldırısı bu değişiklikle açılmadı. ## Bulgu tablosu | # | Dosya:satır | Sorun | Senaryo | Önem | Düzeltme | Kesinlik | |---|---|---|---|---|---|---| | 1 | `src/app/page.tsx:247`, `src/features/odeme/components/paket-satinal.tsx:37` | "Sınırsız liste revizyonu (danışmanla sohbetten)" — gerçekte her revizyon `spendCreditForMessage` ile 1 kredi düşer (`src/app/api/soru/route.ts:150-156`); 60 kredi bitince revizyon imkânsız, top-up (129 TL) gerekir | Veli 299 TL öder, öğrenci 60 mesajı sorularla bitirir; "sınırsız revizyon" için ikinci ödeme istenir → "sınırsız dediniz" şikâyeti / tüketici hakem heyeti | **Orta** | Maddeyi "Liste revizyonu sayı sınırı yok; her istek 1 sohbet kredisi" biçimine getir ya da revizyonu bedelsiz mesaj yap (`bedelsiz` yoluna `liste_revize` eklemek teknik olarak kolay; o zaman cevap başına tek revizyon + üretim kilidi kötüye kullanımı yine sınırlar). Metin değişikliği `[BİLAL]`, avukat teyidi gerekir | DOĞRULANDI (koddan) | | 2 | `src/features/rapor/liste-revizyon.ts:39,42` | Hata mesajı "kredin/paketin etkilenmedi" — revizyonu tetikleyen mesajın 1 kredisi iade edilmiyor (route yalnız akış yarım kalırsa iade eder, `route.ts:317-327`) | Aday "havuz yetersiz" hatası alır, 1 kredi gitti ama ekranda "etkilenmedi" yazar; destek talebi/güven kaybı | Düşük | "revizyon bedeli alınmadı; bu mesajın sohbet kredisi düştü" ya da revizyon hatasında chat kredisini de iade et (refId=mesajId zaten var, `grantCredits reason:"refund"` ile idempotent) | DOĞRULANDI | | 3 | `src/lib/ai/rapor.ts:712` | `RaporUretimHatasi` metni "Revizyon hakkın kullanılmadı." — hak kavramı `e3d79f5` ile kalktı; `hataMesaji` bu metni olduğu gibi araca ve kullanıcıya geçirir (`liste-revizyon.ts:34`) | Çifte doğrulama başarısızlığında aday "hak" diye bir şey olduğunu sanır; pazarlama "sınırsız" diyor | Düşük | Metni "Tekrar dener misin?" ile sınırla | DOĞRULANDI | | 4 | `src/lib/ai/sohbet-akisi.ts:125,221,281` | `duzeltilenSluglar` modelin cevabındaki ham slug'ı (`[a-z0-9-]+`, üst sınır yok: `baglanti-denetimi.ts:48,58`) stdout'a yazar. Slug kaynağı model çıktısı; model kullanıcının yazdığı adresi tekrar edebilir | Aday sohbete "/rehber/ahmet-yilmaz-icin-liste var mı" yazar, model adresi anıp cevaplar → log'a `ahmet-yilmaz-icin-liste→(düz)` düşer. Docker log'u `docker-compose.yml`'de boyut/süre sınırsız (logging ayarı yok) | Düşük | Yalnız sayı + `yeniSlug` (kayıtlı slug) logla; ham slug'ı atma veya ilk 40 karaktere kırp. Compose'a `logging: max-size/max-file` ekle | OLASI (senaryo kurgu; gerçek log örneği görülmedi) | | 5 | `src/app/api/soru/route.ts` (tüm POST) | Kullanıcı başına hız sınırı yok; sınır yalnız kredi (`spendCreditForMessage`) | Deneme hesabı başına 5 mesaj × cevap başına ≤8 araç + 1024 token; magic link ile sınırsız hesap → hesap başına ~5–8 kuruş; para kaybı değil, kapasite (1 GB RAM, tek konteyner) | Düşük | Değişiklik gerektirmiyor; ileride e-posta alan adı/IP başına günlük hesap sınırı (önceki raporlarda var) | DOĞRULANDI (ön-mevcut, bu merge'le değişmedi) | | 6 | `src/lib/ai/sohbet-akisi.ts:111-139`, `liste-revizyon.ts:124` | Sohbet zaman aşımında (`kesici.abort`) araç içindeki `raporUret` iptal sinyali almaz, devam eder ve listeyi yazar; route `onYarim` ile sohbet kredisini iade eder | Sağlayıcı 270 sn'de bitirmezse aday hem iadeyi hem revizyonu alır; kasıtlı tetiklenemez (süre sunucuda), para kaybı 1 kredi | Düşük | Bilgi notu; kabul edilebilir | DOĞRULANDI (koddan çıkarım) | ### Doğrulanan ve sorun bulunmayan noktalar - **Paket kapısı üç katmanlı:** prompt (`danisman-prompt.ts:77-79` "paketi YOK: liste_revize çağırma"), araç (`araclar.ts:1745-1747` `hasPaket` yoksa hata), çekirdek (`liste-revizyon.ts:69-75` `user.hasPaket` DB'den okunur, `kod:"PAKET"`). Paketsiz-kredili aday revizyon **yapamaz**; `hasPaket` istemciden değil `session.user.id` ile DB'den gelir (`route.ts:116-120`). - **Kredi/iade yolu:** paketliye `maliyet=0`; `spendCredits` yine `UNIQUE(reason, ref_id)` (`appdb/schema.ts:134`) ile 0-deltalı satır yazar → aynı `mesajId` ikinci kez revizyon tetikleyemez (`liste-revizyon.ts:99-119`). Üretim hatasında `grantCredits(refund, refId=mesajId)` idempotent. `revision_count` yalnız sayaç. - **Eşzamanlılık:** `uretimKilidiAl` kullanıcı başına tek üretim (`uretim-kilidi.ts:31-59`, bayat eşik 180 sn, koşullu UPDATE). Aynı cevapta ikinci `liste_revize` kotayla reddedilir (`sohbet-akisi.ts:148-151`), cevap başına ≤8, adım başına ≤4 araç. - **Girdi:** `liste_revize` argümanı `revizyonKuraliKur` ile şema doğrulamasından geçer; `not` ≤1000 karakter ve `kullaniciMetni` ile `<>` temizlenip `` etiketinde LLM'e gider (`rapor.ts:459,594`). Sohbet mesajı ≤2000 karakter, `clientMessageId` UNIQUE. - **Bağlantı düzeltme verisi kalıcı depolanmıyor:** `duzeltmeler` yalnız log + `onDenetim` (eval) — `chat_messages.meta`'ya yazılmıyor. `getRehberAramaKayitlari` yalnız slug/başlık/açıklama döner (`rehber.ts:259-265`). Kullanıcı mesajı tampondan geçmez (yalnız model çıktısı), prompt enjeksiyon yüzeyi artmadı. - **Analitik:** revizyonla ilgili Rybbit olayı yok (`src/lib/analitik*.ts` ve `rybbit-identify.tsx`'te "revizyon" geçmiyor); bu merge'le üçüncü tarafa yeni veri akışı eklenmedi. ## Metin × kod uyumsuzlukları | Yer | Metin | Kod | Not | |---|---|---|---| | `page.tsx:247`, `paket-satinal.tsx:37` | "Sınırsız liste revizyonu (danışmanla sohbetten)" | Her revizyon isteği 1 sohbet kredisi (`route.ts:150-156`); kredi bitince 402 | Bulgu 1 — `[BİLAL]`, avukat teyidi | | `src/app/paket/page.tsx:13` (meta description) | "liste revizyonları ve soru hakkı" | Uyumlu (sayı vermiyor) | — | | `src/app/kosullar/page.tsx:50-58` | Paket içeriği için `/paket`'e yönlendiriyor; revizyon/kredi tüketimi hakkında hüküm yok | Krediyle sınırlı revizyon | Koşullarda "revizyon dâhil; her sohbet mesajı 1 kredi" cümlesi eklenirse Bulgu 1'in hukuki tarafı kapanır (taslak, avukat teyidi) | | `src/app/gizlilik/page.tsx:165-172` | OpenRouter'a "mesajlar, program bilgileri, kaydettiğin tercihler" gider | Revizyonda ek olarak `not` özeti + önceki liste özeti + profil gider (`liste-revizyon.ts:123-129`) — hepsi zaten sayılan kategorilerde | Uyumlu | | `src/app/gizlilik/page.tsx` (tamamı) | Sunucu günlükleri hiç anılmıyor | `console.info/warn` ile araç adı, slug, denetim sayıları loglanıyor; kişisel veri yok (Bulgu 4 hariç olası) | Bilgi; "teknik günlükler" cümlesi eklenebilir (isteğe bağlı) | | `docs/urun/vizyon.md:41` | "2 liste revizyonu hakkı" | Sınır kalktı | Eski belge, `[KARAR]` düzeyinde güncellenebilir | | `src/lib/ai/rapor.ts:712` | "Revizyon hakkın kullanılmadı" | Hak kavramı yok | Bulgu 3 | ## Bilal'den istenen 1. "Sınırsız liste revizyonu" maddesinin yanına kredi şartını ekleyip eklemeyeceğine (ya da revizyonu bedelsiz mesaj yapıp yapmayacağına) karar ver — Bulgu 1; ~5 dk karar, metin değişikliği avukat teyidiyle. 2. Bulgu 2–3'teki iki hata metninin düzeltilmesi için yazılımcıya küçük bir iş aç (~10 dk). 3. Bulgu 4 için log satırını sayaç + kayıtlı slug'a indirmeyi onayla (~5 dk; yazılımcı tek satır).