Commit Graph

170 Commits

Author SHA1 Message Date
bilalgursen
e9126650c3 fix(sonuc): harita tablonun altına alınır — hidrasyon kayması kapanır
Liste store'unun sunucu snapshot'ı her zaman boş liste döner
(liste-store.ts:86), kayıtlı manuel liste ancak hidrasyondan sonra
okunur. Harita sayfanın tepesindeyken kayıtlı listesi olan dönüş
ziyaretçisinde ~368 px yüksekliğinde sonradan beliriyor ve tadımlık ile
tabloyu aşağı itiyordu; main'in ilk çocuğu olduğu için impact fraction
~1, CLS eşiğinin çok üstü. Silinen placeholder bunu yeri sunucuda
rezerve ederek engelliyordu.

Harita tablonun altına alındı: sonradan belirdiğinde yalnızca sihirbaz
ile dipnotu iter, ikisi de katlanın altında. Bilgi mimarisi olarak da
doğru sıra — harita, tablodan kurulan listenin görselleştirmesi.

Yeni sıra: tadımlık → tablo → harita → sihirbaz → dipnot.
Sıraya bağlı stiller yeni sıraya göre doğrulandı: tadımlığın
first:mt-0'ı artık her durumda geçerli (üstünde kardeş kalmadı), harita
kendi mt-16'sını alıyor (tablo section'ı ve sihirbaz kartlarıyla aynı
ritim — eskiden üst boşluğu main'in py-12'sinden geliyordu).

Bulgu: 36-tasarimci-g1-ve-navbar.md B1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 23:20:34 +03:00
bilalgursen
d2e11908ba [Bilal] content(tadimlik): CTA'nın yeni vaadi
ÖNERİ — tek başına düşürülebilir (git reset --hard HEAD~1). Bir önceki
commit yalnız yanlış iddiayı kaldırdı ve kendi başına tutarlı; bu commit
CTA'ya yeni bir cümle öneriyor, karar Bilal'in.

Buton: "Giriş yap ve listeni oluştur" -> "Kendi listemi oluştur"
Alt satır: "· Giriş sonrası liste hemen üretilir" eklenir.

Sayı YOK ve bilerek: ACIK_SATIR (rapor-maske.ts, server-only) ve
DENEME_KREDISI (credits.ts, appdb import ediyor) bu "use client" dosyaya
import edilemez; elle "3"/"5" yazmak tek kaynak kuralını bozar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:21:15 +03:00
bilalgursen
2373a9a526 content(tadimlik): teslim edilmeyen "24 satırın tamamı" iddiası kalkar
Maske girişsiz kullanıcıya 24 satırın tamamını değil yalnız ilk birkaçının
analizini açıyor (rapor-maske.ts); "5 deneme kredin hazır" da butonun
götürdüğü yerin sözü değil. Buton metni yeni vaat eklemeden yanlış olanı
bırakıyor: "Giriş yap ve listeni oluştur". Kanonik sağ ok yerinde duruyor.

Üstteki "Bu, 24 satırlık Yapay Zeka listenden yalnızca bir örnek." cümlesi
doğru olduğu için değişmedi — üretilen liste gerçekten 24 satır.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:20:57 +03:00
bilalgursen
72ef3b8669 fix(tadimlik): CTA girişten dönüşte üretimi başlatır
Tadımlık CTA'sının giriş callback'i sonucHref() yerine
listemUretHref("tadimlik") — kullanıcı /sonuc'a geri bırakılmak yerine
üretimin koştuğu /listem'e iner, liste ek tık olmadan başlar.
"tadimlik" IZINLI_KAYNAKLAR'a eklendi, yoksa ölçüm "bilinmiyor"a düşerdi.

Ayrıca tadimlik_goruntulendi'nin üstüne seri kırılması notu: olay bugüne
kadar sayfanın ~2.200 px altında yaşıyordu, bundan sonra ilk ekranda —
iki dönem karşılaştırılamaz.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:18:45 +03:00
bilalgursen
5311459073 refactor(sihirbaz): listemUretHref tek kaynağa taşınır
Yerel fonksiyon sihirbaz-sabitler.ts'e (sonucHref'in yanına) taşındı ve
export edildi; `uret=1` parametre sırası sözleşmesinin yorumu da onunla
gitti. Davranış birebir aynı — tadımlık CTA'sı da aynı hedefi kullanacağı
için literal kopyanın dördüncü kez çoğalması engellendi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:18:22 +03:00
bilalgursen
552d5ce5f1 fix(sonuc): tadımlık tablonun üstüne alınır
Yeni sıra: ManuelHarita -> TadimlikBolumu -> SonucProgramTablosu. Tadımlık
ödeme öncesi gösterebildiğimiz tek gerçek önizleme; tablonun ~1.500 px
altında değil ilk ekranda durmalı. Props ve bileşen içleri değişmedi.

Tadımlık <section>'ına first:mt-0: harita boş durumda null döndüğü için bu
bölüm main'in ilk DOM çocuğu olabiliyor, main'in py-12'si yeterli.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:17:57 +03:00
bilalgursen
daa232c3c1 fix(sonuc): boş harita ilk ekranı işgal etmez
Manuel liste boşken ManuelHarita placeholder yerine null döner. Boş gri
alan /sonuc'un ilk ekranını kaplıyordu; ödeme öncesi ilk ekranda durması
gereken şey tadımlık. İlk "+" ile liste dolunca harita kendiliğinden
belirir, il geometrisi yine ancak o anda iner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 02:17:29 +03:00
bilalgursen
9bd448bd16 fix(kredi): kullanıcı başına üretim kilidi — çifte harcama kapanır
All checks were successful
Deploy / deploy (push) Successful in 10m52s
credit_ledger.ref_id benzersizliği yalnız AYNI denemenin tekrarını koruyordu
(ağda kaybolan cevap → aynı requestId ile retry). requestId istemcide her
mount'ta yeniden üretildiği için "aynı kullanıcı üretimi iki kez başlattı"
durumu hiç yakalanmıyordu: üretim sürerken (20-60 sn) ikinci sekmede açılan
/listem?uret=1 ya da geri→ileri ikinci bir ListeUretici monte edip 3 krediyi
ikinci kez yakıyordu. Karşılığında tek rapor çıkıyordu, çünkü reports.user_id
benzersiz ve ikinci üretim birincinin üstüne yazıyor. Bakiyesi yetmeyen
deneme kullanıcısı ise akışın ortasında "kredi yetersiz" ekranı görüyordu.

- report_locks (user_id birincil anahtar): ikinci INSERT benzersizlik
  ihlaliyle düşer, bu da "üretim sürüyor" demektir. Kilit kredi
  harcamasından ÖNCE alınır, finally'de bırakılır.
- Bayat kilit (süreç OOM'la öldü, deploy) 180 sn sonra devralınabilir;
  devir koşullu UPDATE olduğu için iki eşzamanlı devralmadan yalnız biri
  kazanır. Salım requestId koşullu: geç uyanan eski sahip devralanın
  kilidini silemez.
- Yeni SURUYOR kodu: istemci bunu "hata" sayıp taze requestId ile yeniden
  denerse çifte harcama kapısı yeniden açılırdı. Ekranda "Tekrar dene"
  bilerek yok; kullanıcı listeye yönlendiriliyor, kredi harcanmadı.
- DUPLICATE dalının "İstek tekrarlandı" HATA'sı da SURUYOR'a çevrildi
  (BACKLOG #1'deki ikinci çifte harcama yolu). Revizyon dalı değişmedi.

BACKLOG #1 · güvenlik denetimi G5

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:54:21 +03:00
bilalgursen
bca1849eee fix(olcum): otomatik üretimin kaynağı gerçek yüzeyden gelir (G3)
/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>
2026-09-22 01:45:31 +03:00
bilalgursen
84fc88e230 merge(icerik/sezon-celiskisi): [Bilal] content(bant): sezon-dışı bant metni — B alternatifi
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:38:36 +03:00
bilalgursen
d720e1888f merge(funnel/listem-girisi): fix(giris): callback yalnız better-auth'un kabul ettiği yollarda takılır
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:38:36 +03:00
bilalgursen
001440a8a2 merge(funnel/arti-olu-ucu): content(funnel): kapının girişindeki vaat akışın gerçek bedelini söyler
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:38:36 +03:00
bilalgursen
b922b466c9 content(funnel): kapının girişindeki vaat akışın gerçek bedelini söyler
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>
2026-09-22 01:37:55 +03:00
bilalgursen
248a01042f fix(giris): callback yalnız better-auth'un kabul ettiği yollarda takılır
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>
2026-09-22 01:36:59 +03:00
bilalgursen
1364f8cb43 feat(olcum): /listem boş ekranından açılan kapı ayrı tetikle sayılır
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>
2026-09-22 01:33:01 +03:00
bilalgursen
4034f03a8b [Bilal] content(bant): sezon-dışı bant metni — B alternatifi
Yalnız `BANT_METNI["takvim-belirsiz"]` değişir. İki seçenek yan yana:

A (dalda duran, ana commit'te):
  "2027 tercihine hazırlık · 2026 yerleştirme verisi yüklü"
  Kısa, bant şeridine tek satırda sığar; ne beklendiğini söylemez.

B (bu commit):
  "2026 yerleştirme verileri yüklendi — 2027 tercih takvimi açıklanınca
   geri sayım burada başlar"
  Sayacın neden boş olduğunu açıklar ve geri döneceğini vaat eder;
  ~95 karakter, 375 px'te saat ikonunun yanında alt satıra taşar.

Cherry-pick edilmezse dal A ile tutarlı çalışır.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:32:23 +03:00
bilalgursen
419b617cab fix(listem): boş durum CTA'sı ana sayfaya atmaz, tercih kapısını açar
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>
2026-09-22 01:21:46 +03:00
bilalgursen
7dc47ee1a9 fix(funnel): navbar giriş butonu kullanıcıyı bulunduğu sayfaya döndürür
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>
2026-09-22 01:21:32 +03:00
bilalgursen
cb22faf628 feat(funnel): navbar'da kalıcı Yapay Zeka listesi girişi
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>
2026-09-22 01:21:16 +03:00
bilalgursen
f734f489cc fix(ui): hero "Ücretsiz dene" butonuna kanonik sağ ok (AGENTS.md)
Kanonik CTA deseni: metin önce, sonunda `<ArrowRight className="size-4" />`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:21:02 +03:00
bilalgursen
3df74713d8 fix(icerik): kapanış CTA'sından sezon aciliyeti kalkar
"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>
2026-09-22 01:20:36 +03:00
bilalgursen
46efc7f86c fix(icerik): üst bant sezon dışında "sona erdi" demez, hazırlık çerçevesi kurar
2027 takvimi açıklanmadığı için bant artık "takvim-belirsiz" aşamasında:
geri sayım ve `role="timer"` hiç render edilmiyor (boş "--" sayaçları yok),
metin `BANT_METNI` üzerinden "2027 tercihine hazırlık · 2026 yerleştirme
verisi yüklü" oluyor. Yıl ve aralık `TERCIH_YILI`/`VERI_ARALIGI`'ndan
geliyor; takvim bilinmiyorsa `<time>` aralığı yerine veri penceresini
söyleyen düz satır duruyor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:19:43 +03:00
bilalgursen
e6fbc62fe9 feat(olcum): /listem?uret=1 yollarına kaynak parametresi
Ü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>
2026-09-22 01:18:24 +03:00
bilalgursen
54fb72d18c refactor(sezon): tercih takvimi tek kaynakta (lib/sezon.ts)
Üst banttaki elle gömülü 2026 başlangıç/bitiş damgaları `src/lib/sezon.ts`
içindeki `SEZON_TAKVIMI`ye taşındı. Aşama hesabı (`sezonAsamasi`) ve geri
sayım hedefi (`sezonHedefi`) artık oradan geliyor; `devam-ediyor` dalının
davranışı birebir aynı. 2027 takvimi ÖSYM tarafından açıklanmadığı için
`null` bırakıldı — tarih uydurulmadı.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:18:24 +03:00
bilalgursen
f60fbd135d feat(olcum): liste_uretim_basladi olayı — üretim denemesinin paydası
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>
2026-09-22 01:18:15 +03:00
bilalgursen
22c139ad22 fix(funnel): + kapısını tamamlayan kullanıcı listeye/sonuca çıkar
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>
2026-09-22 01:17:24 +03:00
bilalgursen
d41120c3ce fix(liste): üretim sonrası sunucu yanıt vermezse 502 sayfasına gidilmiyor
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>
2026-09-22 01:08:18 +03:00
bilalgursen
cc46244206 fix(ui): iPad'de progressive blur kaydırmada ortaya kaymıyor
Site geneli üst/alt blur katmanları `position: fixed` + `backdrop-filter`
taşıyordu. iOS/iPadOS WebKit (iPad'de Chrome da WebKit) bu birleşimde
bulanıklığı ayrı kompozit katmana alıp scroll sırasında bayat kaydırma
konumuyla çiziyor; katman ekranın ortasında şerit gibi görünüyordu.

Katmanların stili skiper-ui bileşeninin inline stilinden globals.css'teki
`.kt-sayfa-blur`a taşındı (inline stil `@supports` ile ezilemiyordu).
`@supports (-webkit-touch-callout: none)` yalnızca iOS/iPadOS'ta eşleşir —
masaüstü Safari dahil başka hiçbir tarayıcıda desteklenmez — ve orada
bulanıklık + maske düşer, degrade fade korunur. Geometri (112px, z-40,
print:hidden) ve diğer tarayıcılardaki görüntü değişmedi.

Katalogdaki ProgressiveBlur kullanımları `absolute` olduğu için bu hatadan
etkilenmiyor; bileşen onlar için olduğu gibi kaldı.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:08:01 +03:00
bilalgursen
507bf53a95 feat(seo): kapanan 28 bölüm + 2 üniversite sayfası benzer sayfaya kalıcı yönlendirilir
All checks were successful
Deploy / deploy (push) Successful in 6m50s
Arşivlenen slug'lar 200 + 'sayfa yok' dönüyordu (soft 404). Eşlemenin tek kaynağı
src/lib/kapanan-sluglar.ts; alt yollar (/sayfa/N) hedefin köküne gider; zincir ya da
çift kaynak build'i durdurur. Yıllık güncelleme kılavuzuna 5b adımı eklendi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 23:34:52 +03:00
bilalgursen
992a01abf1 feat(katalog): başlığın altında kompakt sıra giriş satırı (alttaki kart yerinde)
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>
2026-09-21 23:34:52 +03:00
bilalgursen
ea3310ac5b fix(liste): üretim sonrası ekran listeye kesin geçer
replaceState + router.refresh() ikilisinde Next yönlendirici kuyruğu refresh'i
hiç çalıştırmıyordu (ekran 'Listen hazırlanıyor'da kalıyor, yenileyince geliyordu).
Tek router.replace; 6 sn emniyet supabı (tam yükleme); 90 sn'de 'hâlâ hazırlanıyor'.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 23:34:52 +03:00
bilalgursen
c2ec6d3102 content(anasayfa): karşılaştırma tablosu rakipler hakkında genelleme yapmaz
Bazı ücretsiz robotlar artık yapay zekâ sohbeti/dengeli liste sunuyor; ✗ yerine
"Bazılarında" / "Danışmana göre". İki ayırt edici satır eklendi (resmî kayda
dayanma, yöntemin açık olması). Sorun kartı ve SSS cevabı aynı çizgiye çekildi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 23:34:52 +03:00
bilalgursen
95bc87e5f7 fix(paket): girişsiz ziyaretçide boş sayfa — kart gövdesi statik kabukta, yalnız CTA dinamik
Kök neden: React Flight ~3,2 KB'ı aşan dinamik parçayı ayrı satırlara bölüyor;
PPR resume bunlara verdiği segment kimliğini kabukta geç tamamlanan sınırın
(kök loading.tsx) kimliğiyle çakıştırıyor (S:3 iki kez) → HierarchyRequestError.
Lokal prod build'de yeniden üretildi, düzeltmeden sonra 5/5 temiz.
Girişsiz CTA metni: "ilk 3 tercihini ücretsiz gör" (sayılar sabitlerden).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 23:34:52 +03:00
bilalgursen
3cf8ec94a0 fix(veri): tadımlık örneği canlı tabanı gösterir; sunucudan gelen liste riskleri yeniden hesaplanır
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>
2026-09-21 20:06:35 +03:00
bilalgursen
49683fa113 fix(liste): kayıtlı manuel liste tabanları yeni veri yılına tazelenir; yıl metinleri 2021–2026
All checks were successful
Deploy / deploy (push) Successful in 7m24s
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>
2026-09-21 18:59:05 +03:00
bilalgursen
3e75a6fbbd fix(rapor): yazdırma dipnotundaki yıl aralığı raporun üretildiği veri penceresinden
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:05:14 +03:00
bilalgursen
2356e8aa38 merge: veri/2026-pc~1 — metinler ve meraklısına şeması ([Bilal] başlık-2027 commit'i hariç) 2026-09-21 17:04:25 +03:00
bilalgursen
1879ffa326 merge: veri/2026-pb — okuyan taraf yılsız Program tipine geçti 2026-09-21 17:04:25 +03:00
bilalgursen
54be4d14db merge: veri/2026 — P-0 yıl sözleşmesi + P-A veri betikleri 2026-09-21 17:04:12 +03:00
bilalgursen
ceeb70375d feat(veri): bileşenler yılsız Program'a ve veri-yillari sözlüğüne geçti (P-B b)
- SiraSerisi = { siraGecmisi, ilkYil? }; yardımcılar dizinin kendi son iki
  elemanıyla çalışır, yıl ilkYil + indeks. raporSiraSerisi diziyi doldurmaz:
  5 elemanlı eski raporlar 2024→2025 trendini göstermeye devam eder.
- Tablo başlıkları "Son ${VERI_YIL_SAYISI} yıl"; rapor listesi başlığı kaydın
  kendi pencere uzunluğunu söyler (eski rapor: 5).
- siraYiliEtiketi SON_YIL/ONCEKI_YIL'dan; bölüm/üniversite sayfa metinleri ve
  metadata SON_YIL, TERCIH_YILI, BASLIK_YILI sözlüğünden.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:00:39 +03:00
bilalgursen
ce40b7c5b3 feat(veri): Program tipi yılsız — db eşleyicisi, lib ve snapshot ilkYil (P-B a)
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>
2026-09-21 17:00:39 +03:00
bilalgursen
590fea749d docs(meraklisina): aday havuzu kuralı — yalnız en son tercih kılavuzundaki programlar
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>
2026-09-21 16:54:45 +03:00
bilalgursen
3fa5cab906 feat(veri): katalog/OG/rapor metinleri yılı veri-yillari.ts'ten okur — 2026 yüklemesi P-C
- "2025 yerleştirme" → SON_YIL, "2026 tercihleri" → TERCIH_YILI, başlık yılı → BASLIK_YILI
- yazdırılabilir rapor dipnotu: "2021–2025" → VERI_ARALIGI
- meraklısına 1. bölüm: efektif sıra açıklaması yılsız
- KATALOG_VERI_TARIHI: 2026-09-21 (2026 verisinin çekim tarihi)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:53:42 +03:00
bilalgursen
024a2a49c4 fix(odeme): önce kredi sonra paid damgası; çift pakette iade akışı; UNIQUE tespiti
All checks were successful
Deploy / deploy (push) Successful in 8m50s
- odemeyiSonuclandir krediyi yazıp sonra paid damgalar; araya kesinti girerse
  sipariş pending kalır ve yeniden denenir (eskiden: paid görünür, kredi yok).
  paid + deftersiz eski siparişler ilk ziyarette onarılır
- paket tek seferlik: grantCredits({ paketTekil }) zaten paketliye yazmaz
  (kontrol UPDATE'in WHERE'inde). Sipariş paid damgalanır, senkron log +
  destek@ e-postası, /odeme/sonuc 'Bu ödeme iade edilecek' kartı, /kosullar#iade
- drizzle DrizzleQueryError üst mesajında 'UNIQUE' yok → idempotent no-op yerine
  hata fırlıyordu (grant + iki spend yolu); cause zincirine bakılıyor
- callback geçici DB hatasında 500 yerine sonuç sayfasına yönlendirir
- krediKaydiVarMi (reason, ref_id) indeksini kullanır; haftalık mutabakat sorgusu

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:36:24 +03:00
bilalgursen
38e02e0ed9 feat(veri): yıl kapsamı tek kaynağı (veri-yillari.ts) — 2026 yüklemesi P-0
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:35:24 +03:00
bilalgursen
8f4669e31d fix(odeme): action redirect fırlatmaz, hedef döndürür + çift paket çekimine sunucu koruması
All checks were successful
Deploy / deploy (push) Successful in 8m46s
- baslatOdeme { error } | { yonlendir } döndürür; SatinAlForm client'ta
  router.push yapar (cacheComponents altında geri dönüşte buton tıklamaya
  sağır kalıyordu); tıklamada ok → dönen halka
- paketi olan yeniden 'paket', paketi olmayan 'topup' başlatamaz
- /odeme, paket alınmışken eski bekleyen paket siparişinin formunu göstermez

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:13:30 +03:00
bilalgursen
d7c29ac4a6 merge: entegrasyon/guvenli-etiket — görünen 'Garanti' dilim adı 'Güvenli'
# Conflicts:
#	src/features/sihirbaz/components/cta-sira-form.tsx
2026-09-21 16:13:04 +03:00
bilalgursen
bf6aee1fbe fix(giris): callback'te protokol-göreli adres reddi (açık yönlendirme)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:12:24 +03:00
bilalgursen
f05f3e0c69 fix: p7/p4 denetim bulguları — derin sayfa sıra yılı ve başlık uzunluğu, giriş sayacı, rybbit host
- 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>
2026-09-21 16:12:11 +03:00
bilalgursen
271e01e1dc merge: origin/gece/p7-katalog (gece vardiyası 2026-09-21) 2026-09-21 16:10:37 +03:00