14 yeni rehber yazısı (hepsi editör denetiminden geçti, 46 yazıda 829 iç link tarandı, 0 kırık hedef; 180+ DB rakamı yazıların kendi filtreleriyle yeniden koşuldu): taban-siralamalari-alti-yilda-nasil-degisti · kac-net-ile-hangi-bolum · siralama-bandlari-hangi-kapilar-acilir · ayni-bolum-farkli-universite-siralama-farki · hangi-bolumlerin-kontenjani-azaldi · yeni-acilan-bolumler-nasil-degerlendirilir · bilgisayar-mi-yazilim-muhendisligi-mi · kktc-universiteleri-okunur-mu · yapay-zekaya-tercih-sordum-guvenilir-mi · ek-madde-1-puanim-yetiyor-mu · universitede-ilk-hafta-ders-kaydi-muafiyet-kayit-dondurma · yks-2027-takvimi · rehber-ogretmenler-icin-veri-kaynaklari · bolumumu-sevmedim-hangi-kapilar-var İki canlı yazı düzeltildi: - veliler-icin-tercih-rehberi: veli diliyle kapanış; altındaki "sıralamanı gir" kutusu artık veliye ölü uç değil - bos-kontenjanlar-ne-anlatiyor: "birkaç yüz kişilik fark" aslında ~9 bin (ÖSYM 265.356 ↔ bizim 256.532); payda açıklaması tersti — ek kontenjan paydaya girseydi oran düşerdi. guncelleme alanı eklendi (sitemap lastmod). Kurallar (AGENTS.md): - Yayın sonrası arama motoru bildirimi: URL denetimi yalnız canlıda 200 dönen adrese; kota sayacı; mülk/hesap notu; sitemap grep kuralı - Yıkıcı git komutları yasak: reset/checkout --/restore/clean/stash - Tarayıcı açma: tasarımcı ve UX gerekli gördüğünde açabilir (yetenek için .claude/agents/tasarimci.md'ye tarayıcı araçları eklendi) docs/gece-vardiyasi/2026-09-22/ — 34 rapor: CEO kararları ve kapanış turu, marka/ödeme analizi, sıfır ödeme teşhisi, SEO konu planı, veri kalitesi, editör denetimi, CTO şartnamesi, yazılımcı ve güvenlik raporları, SABAH-OZETI. docs/ekip/YAYIN-KUYRUGU.md — Search Console bildirim kuyruğu. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
19 KiB
Markdown
74 lines
19 KiB
Markdown
# 07 — Güvenlik ve uyum denetimi: üç merge adayı dal + çalışma ağacı
|
||
|
||
Denetleyen: `guvenlik-uyum` · 22 Eyl 2026 · `main` = `e21cda4`
|
||
Kapsam: `funnel/arti-olu-ucu` (22c139a), `funnel/listem-girisi` (cb22faf, 7dc47ee, 419b617), `olcum/liste-uretim-basladi` (f60fbd1, e6fbc62) ve commit'lenmemiş `src/features/rapor/components/liste-uretici.tsx`.
|
||
Kod değiştirilmedi, commit atılmadı, canlıya dokunulmadı.
|
||
|
||
## Özet (5 madde)
|
||
|
||
1. **Kritik bulgu yok.** Üç dalın hiçbiri yetkilendirme, ödeme bütünlüğü ya da açık yönlendirme açığı açmıyor. Üçü de — aşağıdaki düzeltmelerle — merge edilebilir.
|
||
2. **P4 açık yönlendirme iddiası doğrulandı: açık yok.** `giris-karti.tsx:18-19` kalkanı `//evil.com`, `/\evil.com`, mutlak URL ve `javascript:`'i düşürüyor; better-auth 1.6.23 ayrıca hem POST hem magic-link GET yolunda kendi göreli-yol kalkanını koşuyor. **Ama** aynı kalkan `/rehber/ösym` gibi ASCII dışı ya da yüzde-kodlu her yolu better-auth'a 403 olarak gönderiyor → `GirisLinki` bu yolda girişi tamamen kırıyor (yeni regresyon, orta).
|
||
3. **P3 rıza iddiası doğrulandı ama yarım.** Ödeme anındaki buton gerçekten "Yapay Zeka listemi kur (3 kredi)" diyor (`tercih-profili-kapisi.tsx:462`) ve `raporVar`/`bekleyen.eslesir` korumaları tutuyor; çift üretim yolu açılmıyor. Kırık olan **girişteki vaat**: + toast'ı ve çekmece paneli hâlâ yalnız "sıralamanı gir → riskini gösterelim" diyor, oysa akış artık 3 kredilik bir satın almayla bitiyor (orta).
|
||
4. **P2'de allowlist iki yerde delik.** (a) `kaynak` ham hâliyle URL'de kaldığı için Rybbit'in `trackUrlParams` açık pageview'ına allowlist'ten bağımsız giriyor (`/listem` maskesiz); (b) otomatik üretim yolu **her zaman** `giris_donusu` etiketi atıyor, oysa o yol tam olarak giriş dönüşü *olmayan* yol — hero/arama/+/ödeme-sonrası hepsi bu tek yanlış etikete düşüyor, yani P2'nin ölçmek istediği şey ölçülmüyor (orta, ölçüm doğruluğu).
|
||
5. **Çalışma ağacındaki "kredin yeniden harcanmaz" iddiası DOĞRU.** `SunucuYokEkrani` yalnızca `listeOlustur` `ok:true` döndükten sonra görünür; o noktada `reports` satırı yazılmış ve kredi `spendCredits` ile bir kez düşmüştür, "Listemi aç" `?uret=1` taşımadığı için ikinci üretim başlatmaz. `/api/saglik` sabit gövdeli, DB'ye/oturuma dokunmuyor — bilgi sızdırmıyor, rate limit gerektirmiyor (zaten `main`'de, d41120c).
|
||
|
||
---
|
||
|
||
## Bulgu tablosu
|
||
|
||
| # | Dosya:satır | Sorun | Somut istismar / ihlal senaryosu | Önem | Düzeltme | Kesinlik |
|
||
|---|---|---|---|---|---|---|
|
||
| G1 | `src/features/kullanici/components/giris-linki.tsx:25-30` (+ `giris-karti.tsx:18-19`) | Callback'e konan `usePathname()` değeri ASCII dışı ya da `%` içerebiliyor; better-auth'un göreli-yol regex'i `[\w\-.+/@]` dışına çıkan her şeyi 403 `INVALID_CALLBACK_URL` ile reddediyor. Site içi kalkan geçiyor, auth katmanı geçmiyor. | Ziyaretçi `/{herhangi}/ösym-nedir` ya da `/bolum/t%C4%B1p` gibi bir adrese geliyor (yanlış/dış link, soft-404 sayfası da navbar'ı render ediyor — bkz. BACKLOG #5). Navbar'daki "Giriş yap" `/giris?callback=%2Fbolum%2Ft%25C4%25B1p` üretiyor; kullanıcı e-posta ya da Google'a basıyor, better-auth 403 dönüyor, `giris-form.tsx:99-103` "Bağlantı gönderilemedi" diyor. Kullanıcı o sayfadan **hiç giriş yapamıyor**, tekrar denemek de çözmüyor. `main`'de callback hep `/` olduğu için bu yol yoktu. | **orta** | `giris-linki.tsx`'te href kurmadan önce yolu süz: `/^\/[\w\-./+@]*$/.test(pathname)` değilse sade `/giris`. (Alternatif: `giris-karti.tsx` kalkanını aynı beyaz listeye daraltmak — iki yer yerine tek yer.) | DOĞRULANDI (better-auth 1.6.23 `auth/trusted-origins.mjs` regex'i lokalde payload setiyle koşturuldu; `/rehber/ösym`, `/rehber/%C3%B6sym` → `false`) |
|
||
| G2 | `src/features/liste/components/program-ekle-butonu.tsx:73,77,84` · `liste-cekmecesi.tsx:279,283,296` | Kapının **girişindeki** vaat ile **çıkışındaki** bedel uyuşmuyor. Toast: "Sıralamanı girersen bu programın risk seviyesini de gösteririz" + buton "Sıralamamı gir". Çekmece: "Sıralamanı girince her seçimin riskini gösteririz" + "Sıralamamı gir". Dal bu iki kapıyı `hedef="sihirbaz"`e çevirdiği için akışın sonu artık ücretsiz risk rozeti değil, 3 kredilik LLM üretimi. | 17 yaşındaki kullanıcı katalogda + ile program ekliyor, "Sıralamamı gir"e basıyor (beklenti: rozet). Sıra + 3 sihirbaz adımını dolduruyor, son butonda "(3 kredi)" ilk kez görünüyor; basınca `/sonuc?sihirbaz=1` → otomatik `/listem?uret=1` → 5 deneme kredisinin 3'ü yanıyor, kullanıcı baktığı katalog sayfasından koparılıyor. "Vazgeç" derse profil hiç kaydedilmediği için **istediği risk rozetini de alamıyor**. | **orta** | İki seçenek: (a) toast/çekmece metnini akışın gerçek sonucuna eşitle ("…sıralamanı girip birkaç seçim yaparsan 24'lük listeni de 3 krediyle kurarız") — metin `[BİLAL]`; ya da (b) bu iki yüzeyi `hedef=null` bırakıp AI'yı ayrı, adı konmuş bir CTA'ya taşı. Kod tarafı `[KARAR]`, cümle `[BİLAL]`. | DOĞRULANDI (koddan; buton etiketi zinciri `tercih-profili-kapisi.tsx:456-466` ile eşleştirildi) |
|
||
| G3 | `src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx:225` (olcum dalı) | Otomatik üretim `kaynak="giris_donusu"` atıyor. Oysa `?sihirbaz=1` üreten **hiçbir** yer giriş dönüşü değil: `hero-form.tsx:104`, `cta-sira-form.tsx:172`, `use-tercih-profili.ts:331` (+ kapısı ve boş durum), `rapor-yok-cta.tsx:24`, `arama-funnel-karti.tsx:94`. Gerçek giriş dönüşü `/giris?callback=/listem?uret=1&kaynak=hazir_cta\|sihirbaz` ile **doğrudan** `/listem`'e iner, `/sonuc`'a uğramaz. | Saldırı değil, ölçüm ihlali: P2'nin tek amacı "üretimi hangi yüzey başlattı" sorusu. Merge edilirse hero (ana huni), katalog araması, + kapısı ve ödeme-sonrası CTA'sının hepsi tek bir `giris_donusu` kovasında toplanıyor; `sihirbaz` ve `hazir_cta` değerleri ise yalnız giriş dönüşünde düşüyor. Etiketler fiilen ters. | **orta** | `?sihirbaz=1`'i üreten taraf kaynağını URL'de taşısın (`sonucHref({sihirbaz:"1", kaynak:"hero"\|"arama"\|"arti"\|"bos_durum"\|"odeme_sonrasi"})`), `otomatikGonder` onu geçirsin; `IZINLI_KAYNAKLAR`'a `hero`, `arama`, `arti` eklensin. `giris_donusu` yalnız `/giris` callback'inden gelen yolda kalsın. | DOĞRULANDI (koddan; `?sihirbaz=1` üreticilerinin tamamı grep'lendi) |
|
||
| G4 | `src/features/rapor/components/uretim-basladi-olayi.tsx:25-32,54` · `src/app/layout.tsx:118` | Allowlist yalnız **özel olay özelliğini** koruyor. `kaynak` ham hâliyle adres çubuğunda kalıyor ve Rybbit `trackUrlParams: true` ile çalışıyor (`docs/gece-vardiyasi/2026-09-21/01-analitik-bulgular.md:181`); `data-mask-patterns` yalnız `/sonuc` ve `/odeme/sonuc`'u kapsıyor, `/listem` kapsam dışı. | Ücretsiz hesap açan biri `/listem?uret=1&kaynak=<istediği 200 karakter>` ile geziniyor. `liste_uretim_basladi.kaynak` doğru şekilde `bilinmiyor`a düşüyor **ama** aynı isteğin pageview'ı querystring'i olduğu gibi Rybbit'e yazıyor: panelde keyfi metin + `/listem` için kardinalite şişmesi. Giriş round-trip'i üzerinden de taşınabiliyor (`listem-icerik.tsx:51-53` → better-auth query karakter seti `%` ve `&`'a izin veriyor, yani `%3Cscript%3E` geçiyor; `<`/`>` ham hâli 403'e takılıyor). | **düşük** | `/listem`'i `data-mask-patterns`'a ekle **ya da** `listem/page.tsx`'te `kaynak`ı `ListemIcerik`'e vermeden önce allowlist'ten geçir (tek doğrulama noktası, hem URL hem olay için). İkincisi G3 düzeltmesiyle aynı yere düşüyor. | OLASI (`trackUrlParams: true` ekip raporundan alındı; canlı Rybbit'e sorgu atılmadı) |
|
||
| G5 | `src/features/rapor/rapor-actions.ts:118-124` + `liste-uretici.tsx:104,120-126` | Eşzamanlı ikinci üretim kilidi yok: iki paralel `ListeUretici` mount'u iki ayrı `requestId` üretir, `spendCredits` ikisini de geçirir → 6 kredi, 2 LLM çağrısı, tek rapor. | Üretim sürerken (20–60 sn) kullanıcı geri→ileri basıyor ya da `/listem?uret=1`'i ikinci sekmede açıyor: `raporVar` hâlâ `false` olduğu için `listem-icerik.tsx:73` ikinci kez `ListeUretici` render ediyor. **Not:** bu `main`'de de var; `funnel/arti-olu-ucu` yalnızca bu URL'e varan yolu bir tık kısaltarak maruziyeti artırıyor. | **yüksek** (mevcut, dalların doğurduğu değil) | BACKLOG #1 ("dalda") ile aynı iş: `SURUYOR` kodu + kullanıcı başına üretim kilidi. P3/P4'ün merge'i bunu beklemek zorunda değil, ama **aynı yayında** çıkmalı. | DOĞRULANDI (koddan; BACKLOG #1 ile örtüşüyor) |
|
||
| G6 | `src/features/rapor/components/listem-bos-cta.tsx:35-36` (listem-girisi) · `src/features/odeme/components/paket-satinal.tsx:157` (olcum) · `rapor-yok-cta.tsx:24-27` · `sihirbaz-cagri-karti.tsx:199-201,333` | Bedeli **hiç** yazmayan tek tık → 3 kredi yolları. "Yapay Zeka listeni kur", "listeni oluştur", "24'lük listeni oluştur", `/sonuc`'un büyük "Yapay Zeka listemi kur" butonu (kayıtlı eşleşen seçim varsa modal hiç açılmaz, `ilerle()` doğrudan koşar). | `rapor-yok-cta.tsx:31` ayrıca yanlış söylüyor: "sonuç sayfasındaki sihirbazla listeni kur" — oysa sihirbaz açılmıyor, `otomatikGonder` üretimi anında başlatıyor. Ödemesini yeni yapmış kullanıcı için zarar düşük (60 kredi), ama deneme kredisiyle gezen öğrenci `/listem` boş durumundan tek tıkla 3 kredisini yakıyor. | **düşük** | Bu dört yüzeyin etiketine "(3 kredi)" ekle — kanonik metin zaten `tercih-profili-kapisi.tsx:462`'de var. `rapor-yok-cta.tsx:31`'in yanlış cümlesi düzeltilsin. Metin `[BİLAL]`. | DOĞRULANDI (koddan) |
|
||
| G7 | `src/features/rapor/components/liste-uretici.tsx:56-72,159` (çalışma ağacı) | Sağlık yoklaması artık **mutlu yolda** ve fail-closed: `fetch("/api/saglik")` herhangi bir nedenle başarısız olursa (kurumsal proxy, 5 sn'yi aşan yavaş mobil bağlantı, geçici 503) liste gerçekten hazırken kullanıcıya "sunucuya ulaşamıyoruz" ekranı gösteriliyor. | Zarar sınırlı: liste DB'de, kredi tek düşmüş, "Listemi aç" ikinci yoklamada geçince listeye götürüyor. Yani **para riski yok**, yanlış alarm riski var. `SAGLIK_YOKLAMA_MS = 5000` yavaş 3G'de gerçek bir eşik. | **düşük** | Bulunduğu hâliyle kabul edilebilir. İstenirse: yoklama bir kez başarısız olunca 1 kez daha denensin (toplam ~2 sn ek), ya da eşik 8 sn'ye çıksın. | DOĞRULANDI (koddan; ağ koşulu simüle edilmedi) |
|
||
| G8 | `package.json` → `next@16.2.10` | `pnpm audit --prod`: 2 kritik + 12 yüksek. Ulaşılabilirlik denetlendi — **2 kritik ulaşılamıyor**: AVIF RCE için `images.remotePatterns` gerekiyor, `next.config.ts`'te tanımlı değil (optimizer yalnız yerel dosya); Windows RCE'nin karşılığı yok (Linux/Docker). Ulaşılabilir olan: "DoS in App Router using Server Actions" — bu uygulama server action ağırlıklı (`listeOlustur`, `odeme-actions`). | Kimliksiz saldırgan server action uçlarına biçimsiz yük göndererek süreci tüketebiliyor (advisory GHSA detayına bakılmalı). Dallarla ilgisi yok, mevcut durum. | **orta** | `next` 16.2.10 → **16.2.11** (yama sürümü, 9 advisory kapanıyor; 2 kritik için 16.3.3 gerekiyor ama minor atlama ayrı bir iş). | DOĞRULANDI (`pnpm audit --prod`, salt okuma) |
|
||
|
||
### Bulunamadı (arandı, yok)
|
||
|
||
- **Açık yönlendirme:** `//evil.com`, `/\evil.com`, `/%2fevil.com`, `/%5cevil.com`, `%2f%2f…`, `https://evil.com`, `javascript:` payload'larının hiçbiri `giris-karti.tsx:18-19` kalkanından geçip dış hedefe çıkmıyor; `/%2f…` kalkanı geçiyor ama tarayıcı `%2f`'i yolda çözmediği için aynı köken içinde 404 oluyor ve better-auth zaten reddediyor. `dogrula-karti.tsx:9-11`'in kalkanı zayıf (`/\evil.com`'u geçiriyor) **ama** better-auth `magic-link/verify` ucunda `originCheck` ile `(?!\/|\\|%2f|%5c)` uyguluyor → sömürülebilir değil. Yine de iki kalkanın farklı olması ileride kırılgan; birleştirilmesi önerilir (düşük, mevcut).
|
||
- **Çift üretim / çifte kredi (dalların açtığı):** yok. Otoritatif koruma sunucuda: `listem-icerik.tsx:52,54` raporu her istekte taze okuyor, rapor varsa `ListeUretici` hiç render edilmiyor. `/sonuc`'taki `raporVar` bayatlasa bile sonucu değiştirmiyor. Geri tuşu yolu kapalı (`otomatikGonder` `router.replace` kullanıyor, `ListeUretici` başarıda `router.replace("/listem")`).
|
||
- **Kredi iadesi gereken yeni dal:** yok. Üretim hatasında iade `rapor-actions.ts:163-170`'te duruyor; dallar bu yolu değiştirmiyor. `SunucuYokEkrani` iade gerektirmiyor (rapor yazılmış).
|
||
- **`/api/saglik` bilgi sızıntısı:** yok. Gövde sabit `{ok:true}`, sürüm/uptime/DB durumu yok, `Cache-Control: no-store`. Kimliksiz erişim sorun değil (Docker HEALTHCHECK zaten kullanıyor); rate limit gerektirmiyor — istek başına DB/AI maliyeti sıfır.
|
||
- **`?kaynak=` üzerinden LLM prompt enjeksiyonu / SQL:** yok. `kaynak` yalnız analitik etiketi ve URL olarak dolaşıyor; `raporUret(params)`'a giren tek şey `sihirbazDogrula`'dan geçmiş seçimler ve `siraTurGecerli`'den geçmiş sayı (`rapor-actions.ts:99-110`).
|
||
- **Yeni yetkilendirme açığı:** yok. Üç dal da yeni route/action eklemiyor; `kullanicininRaporu(session.user.id)` ve `spendCredits({userId: user.id})` sahiplik kapsamını koruyor. Id tahminiyle başkasının raporuna erişilen yeni yüzey yok.
|
||
- **İstemci paketine sızan sır:** yok. Dalların dokunduğu dosyalarda `process.env` okuması yok; `RYBBIT_API_KEY` yalnız `analitik-sunucu.ts`'te ve dosya `server-only`.
|
||
|
||
---
|
||
|
||
## Metin × kod uyumsuzlukları
|
||
|
||
1. **`gizlilik/page.tsx:97-98` — "Yalnızca oturumunu açık tutmak için zorunlu çerezler kullanılır."** Kod ayrıca `PROFIL_CEREZ_ADI` çerezini yazıyor: `max-age=31536000` (1 yıl), içeriği öğrencinin **başarı sıralaması + puan türü + ilgi alanları + iller** (`sihirbaz-profil.ts:51-57`). Reklam/izleme çerezi değil, işlevsel — ama "yalnızca oturum" ifadesi yanlış ve süresi bir yıl. KVKK aydınlatma yükümlülüğü açısından metin genişletilmeli: hangi çerez, ne tutuyor, ne kadar duruyor. **Taslak cümle önerisi ([BİLAL], avukat teyidi gerekir):** "Oturum çerezinin yanında, girdiğin başarı sıralamasını ve tercih seçimlerini cihazında saklayan işlevsel bir çerez kullanılır (1 yıl); bunu tarayıcı ayarlarından silebilirsin." — Mevcut, dalların doğurduğu değil.
|
||
2. **`rapor-yok-cta.tsx:31` — "sonuç sayfasındaki sihirbazla listeni kur."** Kod sihirbazı açmıyor; `/sonuc?sihirbaz=1` `otomatikGonder`'i tetikleyip üretimi doğrudan başlatıyor (`sihirbaz-cagri-karti.tsx:218-228`). Yanlış vaat + bedel bildirilmeden harcama. Bkz. G6.
|
||
3. **`program-ekle-butonu.tsx:73` / `liste-cekmecesi.tsx:283`** — bkz. G2: "riskini gösteririz" vaadi 3 kredilik üretimle bitiyor.
|
||
4. **Uyum — 18 yaş altı:** bu üç dal yeni bir veri toplama noktası açmıyor, ama P3 ile ücretli aksiyona ulaşan tık sayısı azalıyor. Mesafeli satış/cayma hakkı metinlerinde değişiklik gerekmiyor (kredi harcaması satın alma değil, satın alınmış kredinin kullanımı) — yine de G2'nin çözümü bedel şeffaflığının tek gerçek koruması.
|
||
|
||
## KVKK — yeni kişisel veri akışı
|
||
|
||
- **Üç dalın doğurduğu yeni akış: yok.** `kaynak` kişisel veri değil; `liste_uretim_basladi` özellikleri (`kaynak`, `paketli`, `profil: var|yok`) kişisel veri taşımıyor ve `src/lib/analitik.ts:10-11` ham sıralama kuralına uyuyor — sıralama hiçbir yeni yerde gönderilmiyor. `GirisLinki` bilinçli olarak yalnız pathname taşıyor, query taşımıyor (doğru tercih).
|
||
- **Mevcut, dikkat çekmek istediğim iki akış (dalların dışı):**
|
||
- `liste-giris-url.ts:15-17` pathname **+ query**'yi callback'e koyuyor. Eski tip `/sonuc?sira=123456&tur=say` adresinde bu, öğrencinin **ham başarı sıralamasını** `/giris?callback=…` üzerinden better-auth'a, oradan magic-link doğrulama URL'ine ve **Resend ile gönderilen e-postanın gövdesine** taşıyor (`auth.ts:19-24` `hedef.search = kaynak.search`). Gizlilik metninin "ham sıralama analitiğe gönderilmez" sözü analitik için doğru, ama e-posta sağlayıcısı için böyle bir söz yok ve akış var. **orta**, mevcut.
|
||
- `rybbit-identify.tsx:29-30` e-posta adresini ve adı Rybbit trait'i olarak gönderiyor. Gizlilik metni bunu **açıkça yazıyor** (`gizlilik/page.tsx:102-105`) ve Rybbit kendi sunucumuzda → uyumlu, aksiyon gerekmiyor.
|
||
|
||
---
|
||
|
||
## Dal dal merge hükmü
|
||
|
||
| Dal | Hüküm | Koşul |
|
||
|---|---|---|
|
||
| `olcum/liste-uretim-basladi` (P2) | **Şu düzeltmeden sonra merge edilebilir** | **G3 zorunlu** (`giris_donusu` etiketi yanlış — düzeltilmezse dalın tek amacı olan ölçüm yanlış veri üretir, üstelik seri kırılması yaratır). **G4 önerilir** (aynı düzeltmeyle tek noktada çözülüyor: `kaynak`ı `listem/page.tsx`'te allowlist'ten geçirip `ListemIcerik`'e temiz ver). Güvenlik açısından merge engeli yok. |
|
||
| `funnel/arti-olu-ucu` (P3) | **Şu düzeltmeden sonra merge edilebilir** | **G2**: + toast'ı ve çekmece panelinin metni akışın gerçek sonucuna eşitlenmeli (cümle `[BİLAL]`). Kod olduğu gibi kalabilir — rıza anı (`(3 kredi)` butonu) ve `raporVar`/`eslesir` korumaları sağlam, çifte harcama yolu açmıyor. Metin düzeltilmeden merge edilirse 17–19 yaş kullanıcıya yanlış vaatle kredi harcatmış oluruz. |
|
||
| `funnel/listem-girisi` (P4) | **Şu düzeltmeden sonra merge edilebilir** | **G1 zorunlu**: `giris-linki.tsx`'e yol beyaz listesi eklenmeli, yoksa ASCII dışı/yüzde-kodlu adreslerde giriş tamamen kırılıyor (açık yönlendirme değil ama daha kötü: kullanıcı kaybı). Navbar `/listem` linki ve boş durum CTA'sı güvenlik açısından temiz. Sıra notu: `listem-bos-cta.tsx:35` `kaynak=bos_durum` kullanıyor, bu değer `olcum` dalında tanımlı — CEO'nun "P2 önce merge edilir" kararı korunmalı (aksi hâlde zararsız ama ölçülmeyen bir parametre kalır). |
|
||
| Çalışma ağacı — `liste-uretici.tsx` | **Merge edilebilir (düzeltme koşulu yok)** | "Listen oluşturuldu ve hesabına kaydedildi — kredin yeniden harcanmaz" iddiası doğrulandı. G7 (fail-closed yanlış alarm) isteğe bağlı iyileştirme. |
|
||
|
||
---
|
||
|
||
## Bilal'den istenen
|
||
|
||
1. **G2'nin cümlesi** — + toast'ı ve çekmece panelindeki "sıralamanı gir → riskini gösterelim" metni, akış 3 kredilik listeyle bittiği için değişmeli; yeni cümleyi sen yazmalısın (**~10 dk**).
|
||
2. **`next` 16.2.10 → 16.2.11 yama yükseltmesi onayı** — 9 advisory kapanıyor, biri gerçekten ulaşılabilir (server action DoS); yama sürümü olduğu için build riski düşük (**~20 dk, build dahil**).
|
||
3. **Gizlilik metnindeki çerez cümlesi** — "yalnızca oturum çerezi" ifadesi 1 yıllık tercih profili çerezini kapsamıyor; önerdiğim taslak cümle için avukat teyidi gerekir (**~5 dk karar, teyit ayrı**).
|