Commit Graph

184 Commits

Author SHA1 Message Date
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
d275e4d29c merge: veri/2026-entegrasyon — sitedeki taban sıraları 2026 yerleştirme verisine geçti
Some checks failed
Deploy / deploy (push) Has been cancelled
Yıl sözleşmesi (veri-yillari.ts, EFEKTIF_SIRA_SQL), P-A veri betikleri ve
yıllık güncelleme runbook'u, yokatlas.db 2026 verisi (arşivli), okuyan taraf
yılsız Program tipi, metinler + meraklısına şeması, yazdırma dipnotu.

Denetim: kod-denetcisi 2026-09-21 — koşullu merge; yayın sonrası prod'da
pnpm tadimlik --force, kayıtlı liste tabanı yenileme takip işi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 18:51:57 +03:00
bilalgursen
a97c65f5f8 fix(odeme): kredi ve paid damgaları akışını düzelt; çift paket iade akışını güncelle
All checks were successful
Deploy / deploy (push) Successful in 8m56s
- odemeyiSonuclandir fonksiyonu, kredi ve paid damgalarını doğru sırayla işleyerek sipariş durumunu günceller.
- iade akışında, paket tek seferlik kontrolü ve eski siparişlerin onarımı sağlandı.
- UNIQUE hatası için DrizzleQueryError mesajı güncellendi; callback geçici DB hatalarında yönlendirme yapıldı.
- krediKaydiVarMi indeksi ile haftalık mutabakat sorgusu optimize edildi.
2026-09-21 17:18:33 +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
cd26b1fd56 data: yokatlas.db 2026 yerleştirme verisi (arşivli)
YÖK Atlas tercih-kilavuz API'si, çekim 2026-09-21: 21.493 program (18.251'inde
2026 sırası). Son kılavuzda olmayan 3.706 satır programs_arsiv'e taşındı.
2025 ve önceki dolu değerler değişmedi (veri-kalite: 0 fark).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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
a773ac7beb feat(veri): 2026 yükleme hattı — yıl kilitli refresh, geçmiş doldurma, arşiv, kalite kapısı (P-A)
- yokatlas-goc: idempotent şema göçü (yıl kolonları, son_kilavuz_yili, eski_kod,
  programs_arsiv, veri_meta) + betiklerin ortak yardımcıları
- refresh: --yil/--db zorunlu, YIL KİLİDİ (…1 = DB sira<yil-1> ≥%95 ve eksiz ≠),
  yıl asla r.yil'den türetilmez; ham veri data/ham/*.jsonl.gz, --ham ile API'siz
  tekrar; benzersiz kod = totalElements; tek transaction + önceki yıl sağlaması;
  yeni programda …1/2/3 → üç önceki yıl; efektif indeks EFEKTIF_SIRA_SQL ile
- gecmis-doldur: yalnız NULL alan; API …1/2/3 → eski_kod → kanıtlı 1:1 ad eşleşmesi
- eski-arsivle: güncel kılavuzda olmayanlar → programs_arsiv, netler yeni koda; --kuru
- detay: netler bağımsız + yıl sağlaması; kırılım yalnız --kirilim, alan yoksa durur,
  mevcut değerin üstüne NULL yazılmaz; `yil - 1` varsayımı kalktı
- veri-kalite: salt okunur kalite kapısı, zorunlu kontrol kalırsa çıkış kodu 1
- docs/veri/yillik-guncelleme.md: adım adım runbook + geri alma

DB commit'lenmedi (arşivleme kararı [Bilal]).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:03:01 +03:00
bilalgursen
85ed972c68 feat(tadimlik): batch üretimi yılsız alanlarla; snapshot'a ilkYil (P-B c)
Prompt ve mock metni "son ${VERI_YIL_SAYISI} yıl" der; program seçimi
yerlesenSon'a göre; snapshot rapor.ts programBilgisi ile aynı şekilde
siraGecmisi + ilkYil yazar.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:00:39 +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
bilalgursen
977db40099 merge: origin/gece/p4-eposta (gece vardiyası 2026-09-21) 2026-09-21 16:10:37 +03:00
bilalgursen
f7ed8f2f0b fix: denetim bulguları — çip adı sahte 'tercihlerin değişmiş', çekmece kartı, senkron riski
- 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>
2026-09-21 16:06:15 +03:00
bilalgursen
1e9598ac93 content(rehber): dilim adı "garanti" → "güvenli" (17 yazı)
Dilim anlamındaki "garanti" metinde, şema düğümlerinde, %% aria ve
%% altyazi satırlarında "güvenli" oldu; düzyazıda ilk geçişte bir kez
"halk arasında 'garanti tercih'" köprüsü kuruldu (arama terimi kaybolmasın;
siralama-sartlari-2026'da terim yalnız şema düğümünde geçtiği için köprü yok).
Başlık/slug/URL değişmedi; `classDef garanti` iç renk sınıfı olarak kaldı.
"Garanti değildir / garanti etmez / 'garanti olsun' diye" gibi vaat reddi
ve halk dili eleştirisi cümlelerine dokunulmadı.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:03:32 +03:00
bilalgursen
5853b7d091 feat(etiket): görünen "Garanti" dilim adı site genelinde "Güvenli"
Yalnız kullanıcıya görünen etiket değişir; iç anahtar, tip, DB değeri, API
parametresi, mermaid classDef ve analitik değeri `garanti` olarak kalır
(veri göçü yok).

- risk.ts: tek kaynak DILIM_ETIKET + dilimdenFarkliRiskEtiketi; rapor
  listesi, yazdır tablosu, /sonuc sekmeleri, seçimlerim paneli ve
  meraklısına şeridi buradan okur
- "Güvenli · Güvenli" / "Güvenli (Güvenli)": satır detayında risk etiketi
  yalnız dilimin varsayılanından farklıysa, yazdır ve seçimlerimde yalnız
  kelime farklıysa yazılır
- LLM prompt'ları: `garanti` teknik anahtar, adaya "güvenli" denir sözlüğü
  (rapor, soru, tadımlık); liste özeti modele görünen dilim adıyla gider
- meraklısına şeması (SEMA düğümü, aria-label), 2. bölüm anlatımı ve
  AGENTS.md şema kuralı görünen adla eşitlendi
- "yerleşme garantisi vermez" türü vaat reddi cümleleri aynen kaldı

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:03:22 +03:00
bilalgursen
0400aa5d77 chore(rehber): şema fontu lisanslı Sweet Cucumber yerine OFL Patrick Hand
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>
2026-09-21 16:00:17 +03:00
bilalgursen
d79758adc0 perf: Lenis smooth scroll ve scroll skew efektini kaldır
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>
2026-09-21 15:31:11 +03:00
bilalgursen
294fb2cf6a chore(metin): 'İş garantisi' çipi → 'İş bulma kolaylığı'; gizlilikte Rybbit kimlik verisi
- 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>
2026-09-21 15:29:43 +03:00
bilalgursen
f17ee48a88 fix(liste): profilsiz + sonrası riskler her profil yolunda dolsun
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>
2026-09-21 15:29:04 +03:00
bilalgursen
97952f6e06 chore(metin): danışman fiyat kıyası Armut ortalamasına göre (1.000–3.000 TL)
52520ac temel alındı; rakam Armut'un 'YKS Tercih Danışmanı Fiyatları'
sayfasındaki ortalama fiyatla (1.000–3.000 TL, 21.09.2026'da açılıp
okundu) eşitlendi, kaynak satırı tarihlendi. 'Onda bir' söylemi kalktı.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:27:51 +03:00
bilalgursen
899d29af04 chore(guven): hero'da YÖK logosu yerine tarihli veri satırı [Bilal onayı gerekir]
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>
2026-09-21 15:27:27 +03:00
bilalgursen
9a446df572 merge: origin/gece/p3b-tadimlik-dili~1 (gece vardiyası 2026-09-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:27:27 +03:00
bilalgursen
343fcf610a merge: origin/gece/p6-arti-aninda-ekle (gece vardiyası 2026-09-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:27:27 +03:00
bilalgursen
a834f5ff01 merge: origin/gece/p5-kapi-olcum (gece vardiyası 2026-09-21)
All checks were successful
Deploy / deploy (push) Successful in 8m3s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:07:25 +03:00
bilalgursen
dedf3561b3 merge: origin/gece/p2-olcum~1 (gece vardiyası 2026-09-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:07:25 +03:00
bilalgursen
f87af6e2c6 merge: origin/gece/p1-rehber-altyapi (gece vardiyası 2026-09-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:07:24 +03:00
bilalgursen
f5911c5ef4 merge: origin/gece/rehber-yazilari (gece vardiyası 2026-09-21)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 15:07:24 +03:00
bilalgursen
2602b6f407 feat(rehber): universite-okurken-tekrar-yks yazısı
Hâlihazırda okuyan öğrencinin yeniden YKS süreci: kayıtlı olmak sınava/tercihe
engel değil, ilişik kesme yalnız yeni kayıt için (2026-YKS Kılavuzu b.10),
önce bakılacak iki sınavsız kapı (Ek Madde-1, not ortalamasıyla yatay geçiş),
devam / kayıt dondurma / kayıt sildirme tablosu, SSS ve Kaynaklar.
1 flowchart TD (%% aria + %% altyazi).

Yeni yazıya 3 iç link aynı commit'te (dynamicParams=false; yazı alınmazsa
~1 ile linkler de gider): mezuna-kalmak-mi-kayit-olmak-mi,
yatay-gecis-cap-yandal (teyitsiz "eski kaydın silinir" cümlesi kılavuz
ifadesine çekildi), yerlesemedim-ne-yapmaliyim.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 09:26:22 +03:00
bilalgursen
1a87d89b5a feat(liste): ilk + profilsiz ziyaretçide anında eklesin [Bilal onayı gerekir]
PROTOTİP — Bilal telefonda bakıp karar verecek (CEO tur 2, karar #12).
Katalogdan +'ya basan 82 profilsiz oturumun 77'si 5 ekranlık kapıdan
dönüyordu (09-analitik-tur2, S6). Sıra tersine çevrildi: önce ver, sonra
iste.

- programEkleIste: profil yokken programı hemen ekler (sıra bilinmiyorsa
  risk null), kapıyı açmaz; dönüşe `profilsiz` eklendi.
- Buton: program_eklendi {kaynak, yol: "dogrudan", profilli: evet|hayir}.
  Profilsiz eklemede sonner toast (sabit id, 8 sn): "Seçtiklerine eklendi"
  + "Sıralamamı gir →" aksiyonu → profilToplamaAc(null, true,
  "arti_toast") (tanıtım ekranı atlanır). KapiTetik'e "arti_toast".
- Profil kapıdan girilince mevcut profilTamamlandi → riskleriYenile null
  riskleri doldurur (yeni kod yok).

Kapı bileşeni, sihirbaz adımları, SEMA ve meraklisina-icerik değişmedi
(+ kapısı şemada yok → senkron kuralı tetiklenmez). Geri almak için bu
commit'i revert etmek yeterli; K1 ölçümü (gece/p5-kapi-olcum) bağımsız.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 09:24:51 +03:00
bilalgursen
f1abedccee feat(katalog): CTA kartında vaatsiz başlık + köprü cümlesi, /bolum sayfasına CTA
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>
2026-09-21 09:24:32 +03:00
bilalgursen
4dfb24bb13 feat(seo): derin katalog sayfalarında başlık/açıklama/H1'i sayfanın içeriğiyle ayrıştır
/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>
2026-09-21 09:22:59 +03:00
bilalgursen
79bc7fa8be fix(ai): tadımlık trendi deterministik + gerekçe dil filtresi
cae2aaa yalnız riskNotu'yu deterministik yapmıştı; aynı satırın gerekce ve
trendOzeti alanları DB'deki eski LLM metni olarak servis ediliyordu (lokal
havuzda 89 satır "Son 4 yıl…", 13+ satır "yerleşme olasılığı/ihtimali").
Oradaki "olasılık dili sızamaz" yorumu yanlıştı; düzeltildi.
- yeni src/lib/trend.ts: trendOzetiMetni() saf fonksiyonu — rapor.ts'teki
  trendOzetiUret gövdesi buraya taşındı, rapor ve tadımlık aynı kaynaktan
  okur. Yıl aralığı serideki dolu yıllardan gelir ("2021-2025 arasında…")
- trend cümlesinden tahmin yargısı çıktı: "bölüm zorlaşıyor" → "taban
  sıkılaştı", "yerleşmek görece kolaylaşıyor" → "taban gevşedi". ±%10
  eşiği, ilk–son yıl mantığı, 5/13/6 ve LLM şeması/prompt'u aynı
- tadimlikSec(): DB'deki trendOzeti servis edilmez; program.siraGecmisi'nden
  okuma anında üretilir (alan yoksa "yeterli geçmiş yıl verisi yok")
- tadimlikSec(): gerekce olasılık/ihtimal/şans/garanti/kesin/yüzde/
  "yerleşirsin"/"son 4 yıl" içeriyorsa satır yok sayılır → "genel"
  kategoriye düşer, o da takılırsa null (tadımlık gizlenir). Eşleşme
  Türkçe küçük harfle yapılır (İ/ı)
DB satırları, şema ve script'ler değişmedi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 09:22:40 +03:00
bilalgursen
643e41cc98 fix(analitik): kullaniciTanit script'ten önce sessiz no-op olmasın
Erken olay kuyruğu yalnız olay() içindi; sert yüklemede (OAuth / e-posta
linki dönüşü) RybbitIdentify effect'i de script'ten önce koşuyor, identify
kayboluyor ve kuyruktan boşalan olaylar anonim profile yazılıyordu
(08-kod-denetimi #6).

- Tek "son değer" slotu (bekleyenKimlik): kuyruk değil, yalnız en son
  kimlik anlamlı. Yoklama zamanlayıcısı olay kuyruğuyla ortak
  (zamanlayiciyiBaslat); script 10 sn'de gelmezse slot da atılır.
- kuyruguBosalt kimliği olaylardan ÖNCE uygular.
- kullaniciTemizle slotu siler.

rybbit-identify.tsx'e dokunulmadı.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 09:22:10 +03:00
bilalgursen
67be93c394 feat(analitik): kapi_acildi + kapi_kapatildi olayları
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>
2026-09-21 05:25:23 +03:00
bilalgursen
9c7ea13590 fix(rehber): taban yazısında ürün verisi 5 yıl (2021–2025), hedef yazısında dilim adı atfı silindi
- taban-siralamalar-nasil-degisir: şema, %% aria ve gövdede "dört yıl / son 4 yıl" -> 5 yıl
  (yokatlas.db programs tablosunda sira2021..sira2025 kolonları dolu; ürün satırı "Son 5 yıl" gösteriyor).
  Genel okuma tavsiyesi olan "en az 3-4 yıla bak" altyazısı yerinde.
- hedef-siralama-nasil-belirlenir: "üründe dilimin adı da böyle geçer" yan cümlesi silindi
  (dilim etiketi kararı bekliyor).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 05:24:27 +03:00
bilalgursen
4b87a3e71e fix(analitik): program_eklendi yalnız gerçek eklemede atılsın
Olay, profilsiz ziyaretçide program listeye girmeyip profil kapısı
açıldığında da atılıyordu (kapiAcildi dalı else'e düşüyordu); seri
"ekleme"yi değil "+ tıklaması"nı ölçüyordu (09-analitik-tur2, S6).

- Buton: yalnız sonuc.eklendi iken {kaynak, yol: "dogrudan"}.
- profilTamamlandi: bekleyen program listeye girdiyse (ekle() true)
  {kaynak, yol: "kapi"}.
- OlayAdi yorumuna seri kırılması notu.

Davranış değişmez: profilsiz + hâlâ kapıyı açar.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 05:23:40 +03:00
bilalgursen
ea3ba5f335 chore(ci): .env.production'a RYBBIT_* ve EMAIL_REPLY_TO [Bilal onayı gerekir]
Sunucu tarafı Rybbit olayları (odeme_tamamlandi, giris_basarili) üç env
ister: RYBBIT_HOST, RYBBIT_SITE_ID, RYBBIT_API_KEY. CI'ın yazdığı
.env.production'da bunlar yoktu → prod'da sunucuOlayi hep no-op.
EMAIL_REPLY_TO isteğe bağlı (yoksa destek@kolaytercih.com).

Yalnızca secret ADI referansı eklenir; değerler Gitea secret'larına Bilal
tarafından girilmeli. Secret tanımlı değilse satır boş gelir: Rybbit
gönderimi no-op kalır, Reply-To varsayılana düşer — zararsız.

Deploy hattına dokunur: Bilal onaylamadan merge edilmez. Reddedilirse bu
commit tek başına atılabilir (önceki dört commit'e bağımlılığı yok).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 04:55:10 +03:00
bilalgursen
17046c830f feat(analitik): giris_basarili sunucu olayı
Oturum oluşturulduğunda (databaseHooks.session.create.after) Rybbit'e
sunucudan giris_basarili düşer; yontem = eposta | google | diger
(better-auth uç yolundan türetilir). Huninin "link istendi → giriş yapıldı"
adımı bugüne dek ölçülemiyordu.

- await yok: Rybbit'in 3 sn'lik timeout'u girişi geciktirmez; sunucuOlayi
  hata fırlatmaz. E-posta adresi olaya girmez, yalnızca kullanıcı ID.
- RYBBIT_HOST/SITE_ID/API_KEY yoksa no-op — prod .env.production'da bu
  üçü bugün yok (bkz. ayrı ci.yaml commit'i), eklenene dek olay düşmez.

Giriş akışının davranışını değiştirmez (yalnızca yan etki ekler).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 04:55:10 +03:00
bilalgursen
2af4a9f781 feat(giris): adres başına 60 sn soğuma
Aynı e-posta adresine 60 sn içinde ikinci giriş linki gönderilmez: istek
yine 200 döner (form "gönderildi" gösterir), mail çıkmaz. Üçüncü kişiye
mail bombardımanını ve Resend kotasının yakılmasını engeller; bugüne dek
tek sınır better-auth'un IP limitiydi (5 istek/60 sn).

- Kaynak süreç içi Map (globalThis.__girisEpostaSon), anahtar
  trim+lowercase adres. verification tablosundan türetilmez: orada
  identifier token'dır ve satır sendMagicLink'ten önce yazılır.
- Pencere kaymaz (düşen istek süreyi uzatmaz); her çağrıda eski kayıtlar
  budanır. Gönderim hata verirse kayıt silinir, kullanıcı hemen yeniden
  deneyebilir.
- Yalnızca NODE_ENV=production: dev paneli "anında giriş" art arda istek
  atıyor. Konsol modunda da işler (lokal docker testi).

Canlı giriş yolunu değiştirir; merge öncesi lokal docker testi şart.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 04:55:10 +03:00