Files
kolaytercih/docs/gece-vardiyasi/2026-09-21/05-ceo-kararlari.md
bilalgursen d10eff31b3 docs: gece vardiyası 2026-09-21 raporları
Çok ajanlı gece vardiyasının çıktıları: analitik (Rybbit) bulguları, SEO/GEO
konu planı, marka stratejisi, canlı mail testi, CEO kararları (2 tur), CTO
şartnamesi, yazar/yazılımcı raporları, bağımsız kod denetimi ve sabah özeti
(yazılı + sesli). Kod değişiklikleri gece/* dallarında.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 13:08:24 +03:00

198 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 05 — CEO kararları — 2026-09-21 gece vardiyası (Tur 2)
Hazırlayan: CEO ajanı · Girdi: `01`–`04` raporları + kod doğrulaması · Kod/içerik değiştirilmedi, yalnızca bu dosya yazıldı.
İşaretler: **[KARAR]** ajan yetkisinde, bu gece uygulanır (yalnız `gece/*` dalında, push/merge yok) · **[BİLAL]** Bilal onayı bekliyor; ben yalnızca tavsiye veriyorum.
## 1. Özet — bu gecenin ve bu haftanın odağı (5 madde)
1. **Sezon dışındayız ve veri yok denecek kadar az** (son 7g 86 oturum; gerçek kullanıcıdan `odeme_baslatildi` = 0; huni adımlarında n < 40). Bu yüzden fiyat, paket, /sonuc→/giris dönüşümü ve katalog köprüsü üzerinde **deney/yeniden tasarım yapmıyoruz**. Bu dönemin işi: ölçümü onarmak, içerik altyapısını düzeltmek, kendi vaadimizi delen metinleri temizlemek.
2. **Bu gece 4 teknik paket + 3 yazı.** Marka raporunun 8 "hemen" işinden yalnızca tartışmasız olanı (olmayan özelliği satan "yerleşme olasılığı" dili + 4/5 yıl tutarsızlığı) yapılıyor; SEO'nun 15 yazısından 3'ü yazılıyor. Geri kalan her şey ya Bilal kararına ya veriye bağlı.
3. **Çelişki çözümü — SEO "15 yeni yazı" diyor, analitik "24 yazının 16'sı ≤7 oturum, 4'ü sıfır; önce nedenini anla" diyor.** Karar: ikisi de haklı. Takvimi kaçmayacak 1 yazı + 2027 adayına (gelecek sezonun müşterisi) dönük 2 yazı yazılır; kalan 12 yazı, Search Console indekslenme verisi gelmeden onaylanmaz. Yeni yazıdan önce altyapı: şema metni botlara görünmüyor ve güncelleme tarihi alanı yok (ikisi de koddan doğrulandı).
4. **Bilal'in bu haftası (~7–10 saat) şu sırayla harcanmalı:** (a) `ek-yerlestirme-sonuclari-ve-kayit` yazısını + rehber altyapı dalını gözden geçirip yayına almak — sonuçlar açıklanmadan, tercihen Çarşamba'ya kadar; (b) 1 saatlik elle işler: DMARC/SPF, magic link tıklama testi, Rybbit ayarları; (c) §4'teki kararlar (30 dk); (d) **ÖSYM 2026 yerleştirme tablolarını indirip repoya koymak** — karne, veri raporu, en değerli rehber yazısının güncellenmesi ve 2027 sezonunun tamamı buna bağlı; ajanlar dosya indiremiyor.
5. **Geri dönüşü zor marka kararlarını (Garanti→Güvenli, YÖK logosu, kurucu kimliği, fiyat kıyası) ben vermiyorum;** ucuz olanları ayrı commit olarak dalda hazırlatıyorum ki Bilal "evet" derse cherry-pick etsin, "hayır" derse atsın. Pahalı olanı (Garanti→Güvenli, ~10 dosya + şema) karar gelmeden hazırlatmıyorum.
### Raporlardaki iddiaların kod doğrulaması
| İddia | Sonuç |
|---|---|
| `use-gorunum-olayi.ts:28-31` ref null iken effect bir daha çalışmıyor; `kaydet-banner.tsx` ve `tadimlik-satiri.tsx` koşullu `return null` yapıyor (01) | **Doğru.** Effect deps `[ad, anahtarEki]`; iki bileşen de ilk render'da null dönüyor. |
| `el-cizimi-sema.tsx` mermaid zincirinde `catch` yok; `aria-label` yalnız `svg` dolunca render ediliyor, SSR'da yalnız `aria-hidden` iskelet var (01, 02-T1) | **Doğru** (satır 55-74 ve 85-97). |
| `rehber.ts` tırnak regex'i baş/son tırnağı bağımsız siliyor; 2 yazının açıklaması bozuk (02-T2) | **Doğru.** `merkezi-yerlestirme-nasil-calisir.md:3` ve `taban-siralamalar-nasil-degisir.md:3` tırnakla başlayıp tırnakla bitmiyor. |
| `guncelleme` alanı / `dateModified` yok; sitemap `lastModified: y.tarih`; "diğer yazılar" = son 4 (02-T3, T4) | **Doğru** (`sitemap.ts`, `seo.tsx` `articleJsonLd`, `rehber-makale.tsx:40-42`). |
| "yerleşme olasılığı" vaadi `page.tsx:180`, `paket-satinal.tsx:31`; "yüksek ihtimalle yerleşirsin" `rapor.ts:166` (03) | **Doğru.** Ek: `rapor.ts:168` "orta ihtimalle yerleşilebilir" de aynı sorun. |
| "2.000–10.000 TL" ve "onda bir" kıyası (03-G4) | **Doğru ama eksik sayılmış:** `src/app/layout.tsx:55` (site geneli meta description) ve `page.tsx:228` de "onda bir fiyatına" diyor; marka raporunun dosya listesinde yok. |
| "Garanti" üç sözlük (03-G1) | **Doğru, aslında dört:** `rapor-yazdir.tsx:13` "Garanti (Güvenli)" ve `meraklisina-demo.tsx:149,207` de var; marka raporunun İŞ-7 dosya listesinde eksik. |
| "4 yıl" ↔ "5 yıl" (03-G7) | **Doğru.** DB'de `sira2021…sira2025` = 5 yıl; ana sayfa ve `/paket` "4 yıl" diyor. Doğrusu 5. |
| `eposta-gonder.ts` / `auth.ts` prod'da anahtar yoksa konsola yazıp başarı dönüyor; `EMAIL_FROM` sessiz fallback; `Reply-To` yok (04) | **Doğru.** |
| `rybbit-identify.tsx:28-31` e-posta+isim trait gönderiyor (01) | **Doğru.** Gizlilik metni yalnızca "ziyaretin hesabınla eşleştirilir" diyor; e-posta/isim/IP'den söz etmiyor. |
| `error.tsx`'te ChunkLoadError toparlanması var mı? (01) | **Yok** (dosyada chunk/reload geçmiyor). Tek olay; bu gece kapsam dışı. |
| "`content/rehber/` altında 25 yazı" (02-T13) | **Yanlış.** `ls content/rehber \| wc -l` = **24**. Analitik raporundaki 24 doğru. İşlevsel etkisi yok. |
| "Katalog köprüsünü değiştirmeden önce CTA tıklama olayı eklenmeli" (01) | **Kısmen gereksiz.** `sira_girildi` zaten `kaynak: hero \| cta \| …` taşıyor (`hero-form.tsx:82`, `cta-sira-form.tsx:105`, `tercih-profili-kapisi.tsx:160`) ve Rybbit pathname'i kaydediyor. Eksik olan payda: CTA formunun *görüntülenmesi*. |
| **Yeni bulgu (raporlarda yok):** `el-cizimi-sema.tsx:14-15` yorumu: şema fontu (Sweet Cucumber Mocktail) "kişisel kullanım için ücretsiz — canlıya çıkmadan ticari lisans alınmalı". | Site canlı ve 24 yazıda bu font kullanılıyor. Lisansın alınıp alınmadığı koddan anlaşılamıyor → §5. |
---
## 2. Bu gece yazılacak blog yazıları (3 yazı; 4. slot bilinçli boş)
Ortak yazar kuralları **[KARAR]**:
- Dal: tek ortak dal `gece/rehber-yazilari`; yalnızca `content/rehber/*.md` değişir, `src/` değişmez (P1 ile çakışmasın).
- Frontmatter `tarih: 2026-09-22` (Bilal yayın gününe göre düzeltir). Güncellenen eski yazılara `guncelleme: 2026-09-22` satırı eklenir — P1 bu alanı okuyacak; eski parser'da zararsız (fazla anahtar yok sayılıyor).
- 1 `flowchart TD` şema (`%% aria:` zorunlu, `%% altyazi:` önerilir; `hayal`/`uyari`/`garanti` classDef'leri yalnızca iç anahtar, renk her zaman metin etiketiyle) + en az 1 tablo + ilk paragraf tek başına cevap + soru biçimli H2'ler + sonda **"Kaynaklar"** bölümü (resmî URL + erişim tarihi).
- **Doğrulama kuralı:** resmî sayfa/PDF bu gece açılıp okunamadıysa o cümle yumuşatılmaz, **yazıdan çıkarılır**; yazar raporuna "doğrulanamadı" diye düşülür. Haber sitesinden tarih/tutar alınmaz. 2027'ye dair hiçbir tarih yazılmaz.
- Dil: `03-marka-stratejisi.md` Ek A. "Garanti/kesin/yerleşirsin/olasılık" yok. Dilim adı ilk geçişte **"güvenli tercih (halk arasında 'garanti tercih')"**, sonrasında "güvenli" — H2 kararı ne çıkarsa çıksın uyumlu kalır.
- CTA: yazı sonundaki `CtaSiraForm` zaten otomatik. Metin içi ürün linki `/tercih-robotu` olarak kalır (mevcut 24 yazıyla tutarlı; 301 tek sıçrama, GEO T13 landing'i yapılırsa kendiliğinden düzelir — bkz. §6).
### 2.1 `ek-yerlestirme-sonuclari-ve-kayit` — takvim aciliyeti
- **Neden:** Ek tercih bu gece 23.59'da bitti; sorgu 7–10 gün içinde zirve yapar ve bir daha gelmez. Sitenin en çok gösterim alan kümesine (`yerlesemedim-ne-yapmaliyim`, 23 oturum / 171 AI gösterimi) eklemleniyor. Ürün bağı zayıf (okuyucu 2026'da tercihi bitirmiş kişi) — değeri tazelik + marka anılması; bu yüzden tek "takvim" yazısı bu.
- **Doğrulanacak (resmî):** ÖSYM ek yerleştirme duyurusu `https://www.osym.gov.tr/2026-yks-ek-yerlestirme-icin-tercih-islemleri` (tercih tarihleri 17–21 Eylül, ücret son günü); 2026 Ek Yerleştirme Kılavuzu PDF'i (kayıt süreci, ek yerleşenin sonraki yıl OBP durumu). **Sonuç tarihi açıklanmadı** → "21 Eylül 2026 itibarıyla ÖSYM tarih açıklamadı; sonuç `sonuc.osym.gov.tr`'de yayımlanır" yazılır, tahmin yazılmaz. KYK ek yurt bölümü yalnız `gsb.gov.tr`/`kygm.gsb.gov.tr` sayfası açılabildiyse; yoksa bölüm çıkarılır.
- **İç link/CTA:** `/rehber/ek-yerlestirme-2026`, `/rehber/universite-kayit-rehberi-2026`, `/rehber/obp-nedir-nasil-hesaplanir`, `/rehber/yerlesemedim-ne-yapmaliyim`, §2.2 yazısı. Kapanış: "seneye listeyi baştan doğru kur" → `/tercih-robotu`.
- **Bu yazarın sahip olduğu ek dosya:** `ek-yerlestirme-2026.md` — "ne zaman?" bölümü geçmiş zamana çevrilir (gerçekleşen tarih yalnız ÖSYM duyurusundan), yeni yazıya link, `guncelleme` satırı. Boş kontenjan rakamı **yazılmaz** (114.808 / 110.053 çelişkisi çözülmedi).
### 2.2 `mezuna-kalmak-mi-kayit-olmak-mi` — 2027 müşterisinin ilk kararı
- **Neden:** Mezuna kalan aday = 2027 sezonunun en olası ödeyen kullanıcısı. Karar ağacı formatı rakipte yok; forum ağırlıklı SERP. Dayandığı tek kural (OBP çarpanı 0,12 → 0,06) mevcut yazımızla tutarlı (`obp-nedir-nasil-hesaplanir.md:34`) ve "15–30 puan" rakamı formülden deterministik (not × 5 × 0,06).
- **Doğrulanacak (resmî):** 2026-YKS Kılavuzu OBP maddesi — (i) "yerleştirilen" mi "kayıt yaptıran" mı, (ii) kontenjansız açıköğretim istisnası, (iii) kuralın yalnızca izleyen yılda mı uygulandığı. Ek Madde-1 cümlesi: YÖK yatay geçiş yönetmeliği (`mevzuat.gov.tr`) ve mevcut `yerlesemedim-ne-yapmaliyim.md` "Yol 2" ile birebir tutarlı olmalı. Doğrulanamayan alt madde çıkarılır.
- **Yazılmayacak:** askerlik/tecil; "psikolojik yük" gibi kaynaksız tablo satırı; "X bin sıra farkı küçüktür/büyüktür" türü uydurma eşik.
- **İç link/CTA:** `/rehber/yerlesemedim-ne-yapmaliyim`, `/rehber/yatay-gecis-cap-yandal`, `/rehber/obp-nedir-nasil-hesaplanir`, §2.1 ve §2.3; "hedef bölümünün son 5 yıl tabanına bak" → `/bolumler`.
- **Bu yazarın sahip olduğu ek dosyalar:** `yerlesemedim-ne-yapmaliyim.md` ve `obp-nedir-nasil-hesaplanir.md` — yalnızca yeni yazıya birer link + `guncelleme`. (OBP kırılması SSS'si ayrı yazı olmayacak — §6.)
### 2.3 `hedef-siralama-nasil-belirlenir` — ürünle en güçlü bağ, tamamen kendi verimiz
- **Neden:** 12. sınıf ve mezunlar Eylül–Kasım'da hedef koyar; AI gösteriminde 1 numaramız olan `kac-siralama-ile-hangi-bolume-girebilirim`'in 2027 ikizi. **Doğrulanabilirliği en yüksek yazı:** tablo `data/yokatlas.db`'den (`programs` + `netler`), salt-okunur `sqlite3` sorgusuyla. Ayrıca iki ölü yazıya (`taban-siralamalar-nasil-degisir`, `taban-puan-mi-siralama-mi`) doğal iç link verir.
- **Doğrulanacak:** önce `netler` tablosunun şeması ve anlamı okunur (`src/features/katalog/components/program-netleri.tsx` nasıl sunuyorsa yazı da öyle adlandırır). Tablodaki her rakam sorgu çıktısından; veri yılı açıkça yazılır ("2025 yerleştirmesi; 2026 verisi yüklenince güncellenecek"), kaynak satırı YÖK Atlas. `data/app.db`'ye dokunulmaz; `yokatlas.db`'ye yazılmaz.
- **Yazılmayacak:** SEO planındaki "hedef sıra = en sıkı yılın %10–15 üstü" tamponu — üründe böyle bir kural yok, uydurma yöntem olur. Yerine ürünün gerçek kuralı: taban > 1,4 × sıra = güvenli, [sıra, 1,4 × sıra] = dengeli (`src/lib/risk.ts:36-37`, `/meraklisina`). "Bu netle girersin" dili yasak → "2025'te yerleşen son kişinin netleri".
- **İç link/CTA:** örnek bölümün `/bolum/<slug>` sayfası, `/rehber/kac-siralama-ile-hangi-bolume-girebilirim`, iki ölü yazı, `/meraklisina`; kapanış "deneme sıralamanı gir, hangi dilimde olduğunu gör" → `/tercih-robotu`.
- **Bu yazarın sahip olduğu ek dosyalar:** `kac-siralama-ile-hangi-bolume-girebilirim.md`, `taban-siralamalar-nasil-degisir.md`, `taban-puan-mi-siralama-mi.md` — yalnızca yeni yazıya link + `guncelleme`.
**Bilal onayı:** üç yazı da dalda kalır. §2.1 ve §2.2 YMYL'ye yakın (resmî kural anlatıyor) → Bilal "Kaynaklar" bölümündeki linkleri açıp kural cümlelerini gözle teyit etmeden yayımlamasın.
---
## 3. Bu gece CTO'ya verilen teknik işler (4 paket, öncelik sıralı)
Ortak: her paket kendi worktree + `gece/<konu>` dalı; AGENTS.md geçerli (kod yazmadan önce `node_modules/next/dist/docs/`; tarayıcı/dev sunucusu yok); `data/app.db`, `docker-compose.yml`, `docs/geo/geo-raporu.md` dokunulmaz; **şema/DB migrasyonu gerektiren hiçbir iş yok**. Her paket sonunda kendi dalında `pnpm build` (en az `tsc` + lint) geçmeli. Paketlerin dosya kümeleri ayrık tasarlandı; aşağıdaki "sahip olduğu dosyalar" dışına çıkılmaz. Hiçbiri Bilal görmeden merge edilmez; ayrıca işaretlenenler **karar** gerektirir.
### P1 · Rehber altyapısı: şema metni SSR'da, hata toparlama, `guncelleme` alanı
- **Dayanak:** 02-T1 (P0), 02-T2, 02-T3, 02-T5, 02-T9; 01-CTO-3 (`getBBox` → sonsuz iskelet).
- **Sahip olduğu dosyalar:** `src/features/rehber/components/el-cizimi-sema.tsx`, `src/features/rehber/components/rehber-makale.tsx`, `src/lib/rehber.ts`, `src/app/sitemap.ts`, `src/lib/seo.tsx` (yalnız `articleJsonLd`).
- **Kabul kriterleri:**
1. `ariaLabel` metni sunucu HTML'inde **görünür** biçimde var (figcaption altında `<details><summary>Şemayı metin olarak oku</summary>…`); gizli metin yok. Doğrulama: build çıktısındaki bir rehber sayfasının HTML'inde aria cümlesi `grep` ile bulunur. `role="img" aria-label` korunur.
2. `mermaid.render` hata verirse iskelet kalkar, metin alternatifi açık gösterilir; yakalanmamış promise kalmaz.
3. Frontmatter: tırnak yalnızca baş **ve** son aynıysa soyulur; iki etkilenen yazının `aciklama`'sı `"` ile başlar (node ile doğrula).
4. İsteğe bağlı `guncelleme` alanı: sitemap `lastModified = guncelleme ?? tarih`; JSON-LD `dateModified`; OG `modifiedTime`; gövdede görünür `<time>` ("Yayın: … · Güncelleme: …"). Tarih biçimi **deterministik** (elle TR ay adı; `toLocaleString`/saat dilimi yok — hydration #418 şüphesi). `/rehber` sitemap girdisine `lastModified = max(...)`.
5. Tablolar `overflow-x-auto` sarmalayıcıda (marked renderer ya da sarmalayıcı sınıf); sayfa yatay taşmıyor.
- **Kapsam dışı:** `kume`/`ilgili` alanı ve `/rehber` küme başlıkları (T4), FAQPage (T8), llms.txt, IndexNow, flowchart dışı mermaid türleri, font değişimi, yazar/E-E-A-T alanı.
- **Risk:** `ElCizimiSema` `/meraklisina` hunisiyle ortak → `<details>` orada da görünecek; AGENTS.md şema senkron kuralı bozulmaz (metin kaynağı yine tek `aria-label`), ama Bilal görsel olarak bakmalı. Ekran okuyucuda metin iki kez okunabilir (kabul).
### P2 · Ölçüm onarımı: görünüm hook'u + eksik huni olayları
- **Dayanak:** 01 özet m.5, bulgu #5, CTO-2, CTO-6; 04-#8.
- **Sahip olduğu dosyalar:** `src/components/use-gorunum-olayi.ts`, `src/lib/analitik.ts`, `src/features/liste/components/kaydet-banner.tsx`, `src/features/rapor/components/tadimlik-satiri.tsx`, `src/features/sihirbaz/components/{hero-form,cta-sira-form}.tsx`, `src/features/kullanici/components/giris-form.tsx`, `src/features/rapor/components/liste-uretici.tsx`, /sonuc ve /paket'in olay atacak istemci bileşeni, `src/components/rybbit-identify.tsx` + çağıranları.
- **Kabul kriterleri:**
1. Hook, eleman sonradan mount olduğunda da gözlem kurar (callback ref ya da eşdeğeri); mevcut 3 çalışan kullanım (`listem-govde.tsx`, `sihirbaz-cagri-karti.tsx`) bozulmaz; oturum başına 1 tekilleştirme korunur.
2. Yeni olaylar — **yalnızca şunlar**: `cta_form_goruntulendi` (katalog/rehber CTA'sının paydası), `sira_form_hata`, `sonuc_goruntulendi {girisli, sira_kovasi}`, `paket_goruntulendi {kaynak}`, `liste_uretim_hata {kod}`, `giris_hata {status}`. Sıralama her zaman `siraKovasi()` ile; ham sıra/e-posta olay özelliğine girmez.
3. `giris-form.tsx`: 429'da "Çok sık denedin, bir dakika sonra tekrar dene", diğer hatalarda mevcut mesaj.
4. **Ayrı commit, [BİLAL]:** `rybbit-identify` yalnız `kullaniciId` gönderir (e-posta/isim trait'i kalkar).
- **Kapsam dışı:** `giris_basarili` (auth.ts'e dokunur → P3), `odeme_hata`, `sihirbaz_kapatildi` (sihirbaz kaybı %3–11, sağlıklı), `rapor_yazdirildi`, /sonuc `replaceState` pageview şişmesi, iç trafik filtresi (kod değil ayar → §5), `src/app/layout.tsx` (P4'ün).
- **Risk:** Olay adları kalıcı sözleşme; ad değişirse geçmişle kırılır → adlar bu listedeki gibi sabit. 86 oturum/hafta ile anlamlı okuma haftalar alır; amaç 2027 sezonuna ölçümü hazır sokmak.
### P3 · Vaat dili ve güven temizliği (ana sayfa + /paket + risk notu)
- **Dayanak:** 03-G2, G3, G7 (H1, İŞ-1, İŞ-2); ayrı commit'lerde G4 (H3) ve G5 (H4).
- **Sahip olduğu dosyalar:** `src/app/page.tsx`, `src/app/paket/page.tsx`, `src/features/odeme/components/paket-satinal.tsx`, `src/lib/ai/rapor.ts` (yalnız `riskNotuUret`), `src/app/layout.tsx` (yalnız `description`).
- **Kabul kriterleri (commit 1 — [KARAR], tartışmasız doğruluk düzeltmesi):**
1. "yerleşme olasılığı" → "yerleşme riski ve trend analizi (son 5 yıl)"; `riskNotuUret`'in dört cümlesi geçmiş veriye bağlanır (03 İŞ-1'deki öneri metinler temel alınır), "yerleşirsin / ihtimalle" kalkar. `grep -rniE "olasılı|ihtimalle yerleş" src` → yalnızca ilgisiz kod yorumu (`program-tablosu.tsx:176`).
2. "son 4 yıl" geçen 6 yer "son 5 yıl" olur (DB: 2021–2025). Tek sabitten okunması tercih edilir.
- **Commit 2 — [BİLAL] fiyat kıyası:** "2.000–10.000 TL" → "1.000–5.000 TL" + fiyat bölümüne kaynak notu; "onda bir fiyatına" → "çok daha düşük fiyata" (**5 yer**: `page.tsx:90,168,228,484`, `paket/page.tsx:49-52`, `layout.tsx:55`).
- **Commit 3 — [BİLAL] YÖK logosu:** `page.tsx:236-251` logo → "Veri: YÖK Atlas · son güncelleme `<time dateTime={KATALOG_VERI_TARIHI}>`" metin satırı (badge değil, mevcut kutu stili; biçim `veri-kaynagi.tsx` ile aynı). `public/yok-logo.svg` silinmez (karar geri alınabilsin).
- **Kapsam dışı:** Garanti→Güvenli (H2), `/hakkinda` (H5), `/meraklisina` "Sınırlarımız" (H6), hero/kapanış başlıklarının kaygı tonu, SSS metinleri.
- **Risk:** `rapor.ts` risk notu kayıtlı raporlara da yazılıyor olabilir → yalnız yeni üretilenleri etkiler, veri göçü yok; 5/13/6 şeması ve deterministik risk hesabı **değişmez** (yalnız cümle). Davranış değişmediği için `/meraklisina` şeması etkilenmez. Üç commit birbirinden bağımsız cherry-pick edilebilir olmalı (commit 2–3 commit 1'in satırlarına dokunmaz).
### P4 · Giriş e-postası sağlamlaştırma
- **Dayanak:** 04-#3, #4, #5, #6, #10 (yalnız footer), #13; 01 eksik olay #1 (`giris_basarili`).
- **Sahip olduğu dosyalar:** `src/lib/eposta-gonder.ts`, `src/lib/eposta.ts`, `src/lib/auth.ts`, `src/lib/analitik-sunucu.ts`.
- **Kabul kriterleri:**
1. `replyTo: process.env.EMAIL_REPLY_TO ?? "destek@kolaytercih.com"`.
2. `NODE_ENV=production` iken `RESEND_API_KEY` ya da `EMAIL_FROM` yoksa **net hata** (sessiz konsol/`resend.dev` fallback'i yalnız dev'de); token'lı link prod'da asla loglanmaz. Lokal docker testi için açık kaçış: `EPOSTA_KONSOL_FALLBACK=1` (bkz. risk).
3. Aynı e-postaya sunucu tarafı soğuma (60 sn'de 1): süre dolmadan gelen istekte **yeni mail gönderilmez, istek başarı döner** (kullanıcı zaten <60 sn önce mail aldı; hata göstermek e-posta varlığını sızdırır). Kaynak: `verification` tablosundaki son kayıt zamanı — **şema değişikliği yok**.
4. Şablon: Google Fonts `<link>` kalkar; footer'a `kolaytercih.com` + `destek@kolaytercih.com`.
5. `giris_basarili` sunucu olayı (`SunucuOlayAdi`'na eklenir; session create hook'undan, **await edilmeden** — girişi asla geciktirmez/bloklamaz; e-posta özelliğe girmez).
- **Kapsam dışı:** disposable alan adı filtresi (#12 — ürün kararı), hatırlatma mailine vazgeçme linki/`List-Unsubscribe` (#10 — DB alanı + hukuki sınıf gerekir), eski token iptali (#7), Resend webhook/alarm (#9), Traefik IP başlığı ayarı (canlı sistem ayarı), DNS.
- **Risk — "Bilal onayı olmadan merge edilmez":** canlı giriş yoluna dokunuyor; hata = kimse giriş yapamaz. Prod guard, lokal docker doğrulamasını (NODE_ENV=production, anahtarsız) kırar → kaçış env'i şart ve Bilal merge öncesi lokal docker'da magic link akışını denemeli. Soğuma mantığında better-auth `verification.identifier` biçimi sürümde (1.6.23) doğrulanmadan yazılmasın.
**5. paket bilinçli olarak yok.** Adaylar (katalog→sihirbaz köprüsü, sayfalama canonical'ı, 301 haritası, ChunkLoadError) ya veri ya Bilal girdisi bekliyor — §6.
---
## 4. Bilal'in sabah vermesi gereken kararlar
| # | Karar | Tavsiyem | Gerekçe | Gecikmenin maliyeti |
|---|---|---|---|---|
| 1 | Bu gecenin dallarını yayına alma sırası | Önce `gece/rehber-yazilari`'ndan §2.1 yazısı + P1; sonra P3-commit 1; sonra P2; en son P4 (lokal docker testiyle) | §2.1 takvime bağlı; P4 en riskli | §2.1 için **gün bazında**: ÖSYM sonucu açıklandıktan sonra yayımlanırsa yazının varlık nedeni biter |
| 2 | "Garanti" dilim etiketi "Güvenli" olsun mu? (H2) | **Evet** — yalnız görünen etiket; iç anahtar `garanti` kalır; rehberlerde "halk arasında 'garanti tercih'" diye anılır. Onay gelirse sonraki gece tek pakette yapılır (~10 dosya + `SEMA` + aria + figcaption aynı commit) | Ana vaatle ("garanti vermiyoruz") çelişen tek kelime; en yakın rakip bu kelimeyi sahipleniyor; `rapor-yazdir.tsx` zaten "Garanti (Güvenli)" diyerek aynı sezgiyi taşıyor. Trafik dipteyken değiştirmek en ucuzu | Şimdi düşük. Nisan'dan sonra (sezon öncesi funnel dondurma) yapılamaz; her yeni içerik eski sözlükle birikir |
| 3 | Hero'daki YÖK logosu kalksın mı? (H4) | **Evet**, tarihli metin satırıyla (P3-commit 3 hazır) | Footer "YÖK ile bağlantılı değildir" derken hero'da logo resmî onay iması; hukuki teyit yok ama faydası da ölçülmemiş. Tarih damgası daha güçlü ve dürüst sinyal | Düşük olasılıklı ama tek taraflı risk; beklemenin getirisi sıfır |
| 4 | Danışman fiyat kıyası (H3) | "1.000–5.000 TL" + kaynak notu; "onda bir" söylemini bırak (P3-commit 2 hazır). Önce Armut sayfasını kendin aç: `armut.com/fiyatlari/yks-tercih-danismani_93536` | 299 TL, 1.000 TL'nin onda biri değil; kontrol edilebilir rakam abartılıysa diğerlerine de inanılmaz | Düşük (trafik az); `/paket`'te ücretli vaat olduğu için sezon öncesi mutlaka |
| 5 | Kurucu adıyla görünme + satıcı kimliği (H5) | Satıcı unvanı/iletişim: **evet, zorunlu say** (ödeme alınıyor; mesafeli satış bilgilendirmesi — hukuki teyit gerekir). Ad: evet. Fotoğraf: isteğe bağlı. İçeriği sen yazmadan `/hakkinda` hazırlatmıyorum | Veli itirazı #1 "kim bunlar?"; gizlilik/koşullar sayfalarında hâlâ "MVP taslağı" notu var | Sezon dışı düşük; Ekim'de hukukçuyla birlikte kapatılmalı |
| 6 | 2026 kullanıcılarına sonuç anketi (H8) | **Toplu gönderim hayır.** Gerçek kullanıcıda `liste_olusturuldu` = 3, ödeme = 0–1; anket istatistik üretmez, KVKK sınıfı belirsiz. Sipariş tablosunda gerçek müşteri varsa (1–5 kişi) kurucu olarak kişisel e-posta yaz | n yok; şablon işi boşa emek | Hafıza soğur ama kaybedilecek örneklem zaten yok |
| 7 | Tek sosyal kanal (Y7) | **Şimdi kanal açma.** Karar Ocak'a; dağıtacak özgün içerik (2026 veri raporu) olunca YouTube | Kapasite günde 1–2 saat; yarım kanal, olmayan kanaldan kötü | ~0 |
| 8 | Rybbit'e e-posta + isim trait'i gitsin mi? | **Hayır**, yalnız kullanıcı ID (P2'de ayrı commit hazır). İç trafik zaten ID ile filtreleniyor | Gizlilik metni bunu söylemiyor; veri minimizasyonu; self-host olsa da IP takibi açık | Düşük ama hukuki; metinle davranış tutarsız kaldıkça büyür |
| 9 | Tek kullanımlık e-posta → deneme kredisi suistimali (04-#12) | **Şimdilik aksiyon yok**; sezon öncesi yeniden bak | Suistimal kanıtı yok (temp-mail referrer'ı bizim QA); filtre meşru kullanıcıyı da kırabilir | ~0 |
| 10 | Kredi hatırlatma e-postası ticari ileti mi? (vazgeçme linki / İYS) | Ekim'deki hukuki gözden geçirmeye ekle (gizlilik + koşullar + logo + ileti izni tek seans). O zamana kadar şablona satış dili ekleme | Kod yorumunda bile "KVKK sınıfı netleşene dek" notu var; hacim çok düşük (`kredi_bitti` 4 olay) | Düşük; bülten (Y6) bu karar olmadan başlayamaz |
| 11 | 2026 yerleştirme verisi (GEO T8) ne zaman? | **Bu hafta dosyaları indir**, sonraki gece vardiyası yüklesin | Karne (Y2), veri raporu (Y1), `kac-siralama…` (en değerli sayfa, veri 1 yıl geride), §2.3 tablosu, "güncel veri" güven sinyali — hepsi buna bağlı | Yüksek ve bileşik: Kasım'daki rapor/basın penceresi ve tüm 2027 içerikleri kayar |
---
## 5. Bilal'in elle yapması gerekenler (kontrol listesi)
**Bu hafta, ~1 saat:**
- [ ] **DNS (Cloudflare):** `_dmarc.kolaytercih.com TXT "v=DMARC1; p=none; rua=mailto:destek@kolaytercih.com"` (raporlar 2–4 hafta temizse `p=quarantine`) · apex SPF: `kolaytercih.com TXT "v=spf1 include:_spf.google.com ~all"`.
- [ ] **Magic link tıklama testi** (gizli pencere, ikinci bir adresinle): form başarı kutusu + 30 sn geri sayım → maildeki "Giriş yap" → `/giris/dogrula` onayı → oturum açıldı mı, deneme kredisi yazıldı mı, `callbackURL` doğru mu; aynı linke ikinci basışta dostça hata; konsol temiz mi.
- [ ] **Gmail + Outlook gelen kutusu yerleşimi:** birer link iste; spam mı, "Show original"da SPF/DKIM/DMARC satırları.
- [ ] **Rybbit paneli:** Web Vitals'ı aç · kendi IP'ni/ekip cihazlarını dışla (ya da ekip tarayıcılarında Rybbit opt-out bayrağı — adı Rybbit dokümanından doğrulanmalı) · hedef + kayıtlı huni tanımla (`sira_girildi → sihirbaz_tamamlandi → giris_basarili → liste_olusturuldu → odeme_baslatildi → odeme_tamamlandi`; `giris_basarili` P4 yayına girince) · `accounts.google.com` referrer dışlama ayarı varsa ekle.
- [ ] **Resend paneli:** plan/günlük kota, `mail.kolaytercih.com` "Verified", son 7 gün bounce/complaint.
- [ ] **Sipariş tablosu:** `odeme_tamamlandi` 3 kaydı gerçek satış mı, iç test mi? (Karar #6'nın girdisi.)
- [ ] **Şema fontu lisansı:** `el-cizimi-sema.tsx:14-15` "ticari lisans alınmalı" diyor; Sweet Cucumber Mocktail için lisans alındı mı? Alınmadıysa al ya da font değişimi için iş aç — site canlı, 24 yazıda kullanılıyor.
**Bu hafta, ajanların önünü açan:**
- [ ] **ÖSYM 2026 yerleştirme tabloları** (TABLO-3/TABLO-4 "En Küçük ve En Büyük Puanlar" Excel'leri + ek yerleştirme kılavuzu PDF'i) → repoda commit'siz bir klasöre (ör. `data/kaynak/2026/`).
- [ ] **Search Console dışa aktarımları:** (a) 24 rehber URL'sinin indekslenme durumu (özellikle 4 ölü yazı), (b) 404 raporu + eski alan adı backlink'li URL'ler, (c) `/universite/*/sayfa/N` URL'lerinin gösterim/tıklama verisi, (d) katalog sayfalarına trafik getiren ilk 50 sorgu.
- [ ] Bing Webmaster + Yandex Webmaster kaydı (Bing organik = 0; ChatGPT/Copilot araması Bing indeksine dayanıyor).
- [ ] Yayına alınan yeni yazıları Search Console'dan elle "URL denetimi → dizine ekleme iste".
**İsteğe bağlı:** prod `verification` tablosunda `…@sharklasers.com` için 2 süresi dolmuş satır (hesap oluşmadı) · kredi hatırlatma mailini lokal docker'da `KREDI_HATIRLATMA_*` env'leriyle gözle doğrula.
---
## 6. Reddedilen / ertelenen öneriler
| Öneri | Karar | Neden |
|---|---|---|
| SEO yazı 3 `obp-kirilmasi-soru-cevap` | Ayrı yazı olarak **ret** | Aynı kural zaten `obp-nedir…` "Kritik kural" bölümünde ve §2.2'de; 16/24 yazı görünmezken aynı kuralı üçüncü sayfaya bölmek kanibalizasyon. SEO raporu da "teyitsiz yayımlanmasın" diyor. Kılavuz teyidi gelince mevcut OBP yazısına SSS bölümü olarak eklenir |
| Yazı 5 KYK, 6 ikinci üniversite | Ret (bu tur) | Ürün bağı zayıf (raporun kendi tespiti); tarih/tutar açıklanmamış, kaynaklar haber özeti [A]; haber siteleri hâkim |
| Yazı 8 (2027 takvimi), 9 (Maarif) | Ertele → Kasım başı | ÖSYM takvimi çıkmadan sayfa "beklenti"den ibaret; tek kaynaklı bilgi |
| Yazı 4, 10, 11–15 + yedek havuz | Ertele | Önce 4 ölü + 12 zayıf yazının neden görünmediği (indeks verisi) anlaşılsın; 11 ve 13 ayrıca 2026 verisine bağlı |
| §02-3'teki 10+ eski yazı güncellemesi | Yalnız bu gecenin yazılarına dokunan 6 dosya | `guncelleme` altyapısı (P1) yayına girmeden toplu güncelleme tazelik sinyali veremez |
| T4 küme/ilgili yazılar, T8 FAQPage, llms.txt, IndexNow, T6 `/tercih-robotu` link düzeltmesi | Ertele / ret | T4 sonraki tur (P1 ile aynı dosyalar, bu gece kapsamı şişirmesin); FAQPage ve llms.txt'nin kanıtlanmış faydası yok; IndexNow yerine şimdilik elle gönderim; `/tercih-robotu` linkleri landing (GEO T13) kararıyla birlikte çözülür, 24 yazıyı şimdi değiştirmek ters iş |
| Katalog → sihirbaz köprüsü yeniden tasarımı (01-#3) | Ertele → sonraki tur, tasarım önerisiyle | En büyük fırsat ama UI/ürün kararı Bilal'in gözü olmadan yapılmaz; önce payda olayı (P2) |
| /sonuc → /giris duvarı, fiyat/paket optimizasyonu | Ret (sezon dışı) | n = 24–36; `tadimlik_goruntulendi` hiç ölçülmemiş; ödeme başlatan gerçek kullanıcı 0 |
| Sayfalama canonical'ı, eski alan adı 301 haritası | Ertele | Search Console verisi olmadan karar riskli (derin sayfaları indeksten düşürebilir) |
| ChunkLoadError reload, hydration #418, `HierarchyRequestError` | İzle | Toplam 5 olay; yeniden görülürse |
| /sonuc pageview şişmesi (`trackUrlParams`) | Ertele | Raporlamada oturum sayısı kullanılır; `sonuc_goruntulendi` olayı (P2) asıl çözüm |
| Marka H2 (Garanti→Güvenli) hazırlığı | Bu gece **hazırlatılmıyor** | M boyutlu, ~10 dosya + şema; `page.tsx`'te P3 ile çakışır; karar Bilal'in — onaysız hazırlık çöpe gidebilir |
| Marka H5 `/hakkinda`, H6 "Sınırlarımız", H7 ses kılavuzu dokümanı | Ertele | H5 Bilal'in kişisel içeriğine bağlı; H6, H2 ile aynı dosya (`meraklisina-icerik.tsx`) → birlikte; H7 için 03 Ek A bu gece yazarlara yeterli |
| Marka H8 anket şablonu | Ret | §4-#6 |
| Marka Y1–Y8, U1–U5 | Yol haritasında kalır, bu hafta iş yok | Y1/Y2/Y3 → T8 verisine bağlı; Y6 → hukuki izin altyapısı; Y4/Y5 Şubat |
| Disposable e-posta filtresi, eski token iptali, Resend webhook, hatırlatma retry | Ertele | Kanıtlanmış zarar yok; bir kısmı DB alanı ister (bu gece yasak) |
| İç trafik filtresinin kodla yapılması (`layout.tsx` koşulu) | Ret | Ayar işi; kodla yapmak P3 ile dosya çakışması ve gereksiz karmaşıklık |
---
## 7. Sonraki tur için sorular
**Analitik ajanına**
1. `program_eklendi` yapan 91 oturum: hangi sayfa tiplerinde ekliyorlar, ekledikten sonraki ilk 3 adım ne (`get_journeys`), kaçı 3+ program ekliyor (kaydet banner eşiği)? Katalog köprüsü tasarımının tek girdisi bu.
2. Haftada ~86 oturumla P2 olaylarından (`cta_form_goruntulendi → sira_girildi`, `sonuc_goruntulendi → giris_basarili`) yön okuyabilmek için **kaç hafta** beklemeliyiz? "Şu tarihe kadar bu huniye bakmayın" diyebileceğin bir eşik ver.
**SEO/GEO ajanına**
3. (Bilal'in Search Console dışa aktarımı gelince) 4 ölü + ≤3 oturumlu 5 yazı indekslenmiş mi, gösterim alıyor mu, hangi sorguda kaçıncı sırada? Her biri için tek kelimelik hüküm: birleştir / yeniden yaz / iç linkle besle / bırak.
4. `/universite/*/sayfa/N` için kanıta dayalı tek öneri: canonical→1. sayfa mı, kendine canonical + güçlendirilmiş başlık mı? Derin sayfadaki programların başka hangi URL'den erişilebildiğini koddan göster.
**Marka ajanına**
5. Garanti→Güvenli onaylanırsa diye: görünen "garanti" geçen **her** yerin eksiksiz envanteri (`src/` + `content/rehber/` + OG görselleri + e-posta şablonları; `rapor-yazdir.tsx` ve `meraklisina-demo.tsx` ilk raporda eksikti) ve katalog sayfası ilk ekranı için marka sesinde 3 köprü cümlesi varyantı ("bu programa sıralaman yeter mi?" ekseninde, vaat içermeyen).