/sonuc'taki otomatik üretim kaynağı sabit "giris_donusu" yazıyordu; oysa
?sihirbaz=1 üreten hiçbir yer giriş dönüşü değil — gerçek giriş dönüşü
/listem'e doğrudan iniyor, /sonuc'a uğramıyor. Hero, CTA formu, arama kartı,
+ kapısı, boş liste ekranı ve rapor-yok CTA'sı tek yanlış kovada
toplanıyordu, yani P2'nin ölçmek istediği soru ölçülmüyordu.
Etiket artık ?sihirbaz=1'i üreten tarafta kuruluyor ve /sonuc üzerinden
geçiriliyor; kapıdan gelenler tetikten türetiliyor. giris_donusu yalnız
gerçek callback yolunda kalıyor.
Güvenlik denetimi G3 · docs/ekip-raporlari/2026-09-22/07-guvenlik-denetimi.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bu iki kapı hedef=sihirbaz'a çevrildiği için akış artık ücretsiz risk
rozetiyle bitmiyor; girişli kullanıcıda 3 kredilik üretime kadar gidiyor.
Vaat kapının girişinde bedeli de söylüyor (son butonda '(3 kredi)' ikinci
kez görünüyor).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
better-auth 1.6.23 callback'i kendi göreli-yol kalkanından geçiriyor ve \w
ASCII olduğu için /rehber/ösym ya da /bolum/t%C4%B1p gibi yolları 403
INVALID_CALLBACK_URL ile reddediyordu: kullanıcı o sayfalardan hiç giriş
yapamıyordu. Callback artık yalnız auth'un da kabul edeceği yollarda
takılıyor, gerisinde sade /giris'e düşülüyor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bu kapı huninin en sonunda açılıyor (giriş yaptı, listesi yok, profili de
yok). "diger" ile sayılınca arama kartı gibi genel yüzeylerle aynı kovaya
düşüyordu; ayrı değer bu dilimi görünür kılar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Profil yokken CTA kullanıcıyı "/"'a gönderiyordu: /listem'e kadar gelmiş
adayı ana sayfaya geri atmak huninin ortasında bağlam kaybı. Artık kapı
aynı sayfada açılıyor (hedef "sihirbaz", tanıtım adımı atlanıyor);
tamamlanınca mevcut yol işliyor — /sonuc?sihirbaz=1 → /listem?uret=1.
Profilli dalda hedefe kaynak etiketi eklendi (uret=1 ilk parametre kalır).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Navbar'daki "Giriş yap" callback vermiyordu; giris-karti.tsx callback'siz
isteği "/"'a düşürdüğü için rehber ya da katalog okuyan ziyaretçi girişten
sonra ana sayfada uyanıyordu.
Yeni GirisLinki bileşeni usePathname ile bulunulan yolu callback yapıyor.
Callback bilerek sabit bir hedef (ör. /listem) değil: buton her sayfada
duruyor, sabit hedef bağlam kaybı olur; /listem?uret=1 yazılsaydı girişten
dönüşte üretim kendiliğinden başlar, kullanıcının ayrı onayı olmadan 3
kredi yanardı. Sorgu dizesi taşınmıyor — sorgu okuyan kanca tüm navbar'ı
Suspense zorunluluğuna sokardı.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Girişli kullanıcının /listem'e navbar'dan ulaşacak yolu yoktu: çekmece
butonu (Kendi Listem) manuel liste boşken tamamen gizleniyor, kredi pill'i
de /paket'e gidiyor. Girişli 14 oturumun 7'si /listem'i hiç görmedi.
Kredi pill'iyle birebir aynı sınıf setinde bir /listem girişi eklendi;
ikon ClipboardList (çekmecenin ListChecks'i ve kredinin Coins'i ile
karışmasın). Rapor var mı diye ek DB sorgusu yok — navbar'ın TTFB'si
bozulmasın, boş sayfada ListemBosCta karşılıyor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Tercih dönemi bitmeden yerini al." cümlesi her iki daldan da silindi:
üst bantta "tercih dönemi kapalı" yazarken aynı ekranda acele ettiren
bir çağrı duruyordu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Üretim denemesinin hangi yüzeyden başladığı ölçülebilsin diye dört yol
`&kaynak=` taşır: sihirbazın tamamlanması ve girişsiz callback'i
(sihirbaz), giriş dönüşündeki otomatik yönlendirme (giris_donusu), hazır
seçimler panelinin giriş CTA'sı (hazir_cta) ve paketi aktif kullanıcının
kartı (odeme_sonrasi).
Sabit href yerine listemUretHref(kaynak): `uret=1` her zaman ilk parametre
kalmalı, çünkü giris-karti.tsx:31 funnel metnini
callbackURL.startsWith("/listem?uret=1") ile seçiyor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bugüne kadar yalnız başarı (liste_olusturuldu) ölçülüyordu; kaç kişinin
üretimi denediği bilinmiyordu. /listem?uret=1 ile üretim gövdesi mount
olduğunda yeni bileşen `liste_uretim_basladi` atar.
Olay bilerek liste-uretici.tsx'e değil, listem-icerik.tsx'te ona kardeş
mount edilen yeni bir istemci bileşenine kondu (o dosya bu turda başka bir
işin altında). İkisi aynı `uret` dalında render edildiği için koşulları
birebir aynı.
`kaynak` URL'den, yani kullanıcı denetiminden geldiği için allowlist'ten
geçirilir; listede olmayan değer "bilinmiyor" raporlanır. Giriş
round-trip'inde değerin kaybolmaması için geriYol da kaynağı taşır —
`uret=1` her zaman ilk parametre kalır (giris-karti.tsx:31 sözleşmesi).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Profilsiz + eklemesinin toast aksiyonu ve çekmecedeki "Sıralamamı gir"
butonu kapıyı hedefsiz açıyordu: üç adımı dolduran kullanıcı
profilTamamlandi'den null alıp "Tercihlerin kaydedildi." toast'ıyla
yerinde kalıyordu. İki çağrı yerinde hedef "sihirbaz" oldu — akış
/sonuc'ta devam ediyor (girişliyse üretim, girişsizse ücretsiz tablo).
tetik "arti_toast" olarak korundu; kapi_acildi serisi kırılmıyor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
iPad raporu: liste üretildikten sonra ekran "Bad Gateway" gösterdi ve
tarayıcı `listem.txt` indirdi. Sıra şu: liste DB'ye yazıldı → `router.replace`
→ Next'in RSC isteği ters vekilden 502 aldı → Next tam-sayfa gezinmeye düştü
(WebKit düz metin cevabı dosya olarak kaydetti) → 6 sn'lik emniyet supabı
`window.location.replace` ile aynı 502'yi ekrana getirdi.
Üç değişiklik:
- Dockerfile runner katmanına `--max-old-space-size=768`. V8 cgroup sınırını
görmez, heap üst sınırını host RAM'ine göre seçer; `mem_limit: 1g` ile
birleşince V8 daha GC yapmadan konteyner OOM ile ölüyor ve açık istek 502'ye
düşüyor. Sınır builder katmanında vardı, runner'a miras kalmıyordu.
- `/api/saglik`: DB/oturum/AI'ya dokunmayan en ucuz uç. Dockerfile HEALTHCHECK
bunu yokluyor — süreç ölüp açılırken `docker ps` "unhealthy" gösterir, bir
sonraki 502'nin kaynağı tahmine kalmaz.
- Emniyet supabı tam-sayfa gezinmeden önce sunucuyu yokluyor. Sunucu yoksa
ekranda kalınıp "listen oluşturuldu ve kaydedildi, kredin yeniden harcanmaz"
ekranı + sunucuyu yeniden yoklayan buton gösteriliyor; `liste_uretim_hata
{kod:"SUNUCUYA_ULASILAMIYOR"}` olayı düşüyor. Sunucu yokken `router.refresh`
de aynı tuzağa düştüğü için o dalda atlanıyor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Katalog 464 oturum → 12 sıra girişi; kart tablonun altında kalıyordu. CtaSiraForm'a
varyant="kompakt" + konum prop'u; olay adları aynı, konum: ust|alt özelliği eklendi;
alan kimlikleri useId ile (aynı sayfada iki form).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Yayın sonrası denetim (2026-09-21):
- tadımlık havuzu snapshot'ı 2025 tabanını taşıyordu: örnek satır 'Tıp ~5.118,
az riskli' derken aynı sayfadaki tablo 4.481 gösteriyordu. Taban ve sıra
geçmişi artık okuma anında canlı DB'den; güncel kılavuzdan çıkmış program
örnek gösterilmez (sıradaki kategoriye düşülür)
- sunucuylaBirlestir riskleri her zaman yeniler: sunucu kaydı taze taban +
başka cihazın bayat riskini taşıyabiliyordu
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Denetim bulgusu (2026-09-21): ManuelTercih.efektifSira ekleme anının
snapshot'ıydı; 2026 verisi yüklenince /listem 2025 tabanıyla renk verirken
/sonuc tablosu 2026 gösteriyordu ve hiçbir yol yenilemiyordu.
- db.ts: efektifSiralarGetir(ids) — güncel COALESCE(sira2026, sira2025).
- liste-actions: listeTabanlariniTazele (oturumsuz, ≤24 id); sunucu kaydı
(listeSenkronla/listeyiKaydet) tazelenmiş yazılır.
- liste-store: tabanlariGuncelle — efektif sıra + profil varsa risk yenilenir,
arşivlenmiş program eski değerini korur, değişiklik yoksa yayın yok.
- liste-senkron: girişli/girişsiz herkes için sekme oturumu başına bir kez
(anahtar SON_YIL taşır).
- meraklisina-icerik: "son beş yılın" → VERI_YIL_SAYISI.
- rehber (4 yazı): katalog sayfalarını anlatan "2021–2025 / son 5 yıl"
ifadeleri 2021–2026 / son yıllar; yazıların kendi örnek tabloları
2021–2025 olarak etiketli kaldı.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Program artık siraGecmisi (YILLAR ile hizalı) + efektifSira + siraSon/puanSon/
kontenjanSon/yerlesenSon taşır. db.ts kolonları YILLAR'dan üretip takma adla
seçer, programSatiri eşleyicisi ham satırı Program'a çevirir; SELECT_COLS'un
üç tüketicisi de eşleyiciden geçer. EFEKTIF_SIRA veri-yillari'dan gelir.
- trend: ILK_YIL tek kaynaktan, opsiyonel ilkYil parametresi
- rapor snapshot'ına opsiyonel ilkYil yazılır (eski kayıtlar: okurken ILK_YIL)
- rapor promptu son 4 yılı göndermeye devam eder, anahtarlar dinamik
- tadımlık "son N yıl" filtresi genel: N != VERI_YIL_SAYISI ise servis edilmez
- veri-kapsami VERI_YIL_SAYISI'nı veri-yillari'dan türetir
Bileşenler bir sonraki commit'te yeni tipe geçer (ikisi birlikte derlenir).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Bilal kararı (21 Eylül 2026): kılavuzda artık olmayan eski program kayıtları
siteden kalkar; havuza yalnız son kılavuzda yer alan programlar girer.
Şema düğümü (H), aria-label, figcaption ve 4. bölüm paragrafı birlikte
güncellendi (AGENTS.md şema senkronu).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- derin /bolum ve /universite sayfalarında sıra aralığı hangi yıldan geldiğini
söyler (2025 / 2024 / 2024–2025); 2024 sırası '2025 verisi' diye sunulmaz
- <title> yuvarlanmış rakamlarla ve şablon eki olmadan ≤~86 karakter
- giriş formunda tek geri sayım interval'i (çift sayaç butonu erken açıyordu)
- RYBBIT_HOST sonundaki '/' atılır
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- tercihFarki eski 'İş garantisi' parametresini yeni ada eşleyerek kıyaslar;
ad değişikliği 3 kredilik güncelleme çağrısı üretmesin
- çekmece kartı yalnız profil yokken sıra ister, butonu sıra kapısını açar
(profilsiz ziyaretçi /listem giriş duvarına gönderilmiyordu → çıkmaz)
- sunucuylaBirlestir risksiz gelen kayıtların riskini doldurur
- /paket'teki fiyat kıyasına kaynak satırı
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sweet Cucumber Mocktail yalnız kişisel kullanım için ücretsizdi; site ticari.
Patrick Hand (SIL OFL) next/font/google ile gelir, Türkçe glifler latin-ext'te.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Site geneli ScrollFlow sarmalayıcısı (Lenis lerp'li kaydırma + hıza bağlı
skewY) tüm sayfa katmanını her karede transform'luyor, kaydırma performansını
düşürüyordu. Yerel tarayıcı kaydırmasına dönüldü; bölüm çapaları mevcut
scroll-mt değerleriyle çalışmaya devam eder. lenis bağımlılığı ve
data-lenis-prevent işaretleri temizlendi.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Sihirbaz öncelik çipi vaat diliyle çelişmesin; eski kayıtlı profillerdeki
seçim yeni ada eşlenir (doğrulamada düşmesin).
- Gizlilik metni: giriş yapan kullanıcının e-posta ve adının kendi
sunucumuzdaki analitik aracına kaydedildiği açıkça yazıldı (gönderim sürüyor).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
P6'nın bilinen eksiği: riskleriYenile yalnız kapı tamamlanınca çağrılıyordu;
profil hero/CTA formu, sihirbaz ya da giriş senkronuyla yazılınca önceden
eklenenlerin riski null kalıyor, /sonuc haritasında yanlış renkle pinleniyordu.
Liste deposu artık açılışta ve her PROFIL_DEGISTI_EVENT'te riskleri yeniler.
Çekmece alt kartı da riski hesaplanmamış listede analizi 'hazır' diye duyurmaz.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Footer "ÖSYM veya YÖK ile bağlantılı değildir" derken hero'daki kamu kurumu
logosu resmî onay iması taşıyordu. Aynı bilgi kutusu (sınıflar aynen) artık
logo + ayraç yerine metin satırı gösteriyor:
"Veri: YÖK Atlas · son güncelleme <time>9 Ağustos 2026</time>".
- veri-kaynagi.tsx: TARIH_METNI → export KATALOG_TARIH_METNI (tarih
biçiminin tek kaynağı; katalog altı satırıyla birebir aynı biçim)
- page.tsx: next/image import'u kalktı, KATALOG_VERI_TARIHI seo import'una
eklendi
- public/yok-logo.svg silinmedi (karar geri alınabilsin)
Yeni badge tasarlanmadı (mevcut kutu, pill değil). Bu commit diğer P3
commit'lerinden bağımsızdır (tek başına cherry-pick edilebilir).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
CtaSiraForm'a isteğe bağlı `aciklama` prop'u (yalnız profilsiz karttaki
paragrafın yerine geçer; varsayılan paragraflar aynen kaldı). "Sıralamanla
nereye yerleşirsin?" / "…programlarına yerleşir misin?" başlıkları kalktı:
varsayılan "Sıralamana yakın programlar hangileri?", katalogda
"Sıralaman {ad} tabanlarının neresinde?".
Üniversite ve bölüm sayfaları aynı köprü cümlesini tek sabitten
(KATALOG_CTA_ACIKLAMA) alır; kart /bolum/[slug] sayfasına üniversite
sayfasıyla aynı konumda (liste + sayfalama altı, mt-10) eklendi.
cta_form_goruntulendi ölçümü ve buton deseni değişmedi.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
/bolum/*/sayfa/N: title + description + H1 o sayfanın taban sırası aralığını
taşır (dilimdeki min–max efektif sıra; veri yoksa "taban verisi olmayan
programlar"). Görünür breadcrumb üniversite sayfasındaki desenle eşitlendi
(üst bölüm linki + "Sayfa N").
/universite/*/sayfa/N: description + giriş paragrafı o sayfadaki birim adlarını
sayar (ilk 2 + "ve N birim daha"); dilim tek birimden ibaretse birim içi taban
sırası aralığı eklenir. <title> uzunluk nedeniyle değişmedi.
Dilim hesabı tek yardımcıda (sayfaDilimi); metadata ve gövde aynı hesabı
kullanır. Canonical, robots, sitemap, rota dosyaları ve 1. sayfaların
başlık/açıklaması değişmedi.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Profil kapısının açılışı ve tamamlanmadan kapanışı doğrudan ölçülmüyordu;
"82 oturum kapıyı gördü" kod davranışından çıkarımdı (09-analitik-tur2).
İki yeni olay (adlar kalıcı sözleşme):
- kapi_acildi {tetik: arti|sonuc|sihirbaz|duzenle|diger}: depoda tek
açılış noktası (kapiyiAc). Her açıcı kendi tetik'ini yazar:
programEkleIste → arti, profilDuzenlemeyiAc → duzenle, profilToplamaAc →
isteğe bağlı 3. parametre, verilmezse hedeften (sonuc/sihirbaz), o da
yoksa diger. Depoya `tetik` alanı eklendi.
- kapi_kapatildi {adim: giris|sira|sihirbaz, tetik}: yalnız TAMAMLANMADAN
kapanışta; kapı bileşeninde tek noktadan (vazgec) — X, dışarı tıklama,
Esc ve "Vazgeç" butonları. Tamamlanan kapı profilTamamlandi ile depodan
kapanır, bu noktaya uğramaz.
Ham sıra/e-posta olaylara girmez. Davranış değişmez.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>