Files
kolaytercih/docs/gece-vardiyasi/2026-09-21/10-marka-seo-tur2.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

34 KiB
Raw Blame History

10 — Marka + SEO, Tur 2 — 2026-09-21 gece vardiyası

Hazırlayan: Marka + SEO ajanı · Girdi: 05-ceo-kararlari.md §7 (soru 4 ve 5), 03-marka-stratejisi.md, 02-seo-geo-konu-plani.md · Yöntem: yalnızca kod okuma (main @ 56925e1), lokal .next build çıktısı (BUILD_ID 21 Eyl 00:42) ve data/*.db dosyalarının salt-okunur (immutable=1) sorgusu. Kod/içerik değiştirilmedi. Satır numaraları main içindir; gece/p3-vaat-dili page.tsx ve rapor.ts satırlarını kaydırır.

Özet (5 madde)

  1. "Garanti" envanteri CEO'nun tahmin ettiği ~10 dosya değil, ~33 dosya: src/ içinde 13 dosyada görünen metin/prompt (≈30 satır), content/rehber/ içinde 19 yazıda dilim anlamında ≈40 geçiş (4 şema düğümü + 3 %% aria + 1 %% altyazi dahil), + AGENTS.md. OG görselleri, e-posta şablonları (src/lib/eposta.ts) ve public/ temiz (0 geçiş; llms.txt yok).
  2. "Etiket değişir, tanımlayıcı kalır" stratejisi uygulanabilir, ama etiket tek sözlükten gelmiyor: aynı etiket 3 ayrı sabitte (rapor-listesi.tsx:38, rapor-yazdir.tsx:10, program-tablosu.tsx:44) + 1 union tipte (tercih-degerlendirme.ts:14 "Daha güvenli") + elle yazılmış JSX/SVG metinlerinde duruyor. sohbet-client.tsx:111 ise zaten "Güvenli dilimden…" diyor (beşinci sözlük). Yeniden adlandırmadan önce tek DILIM_ETIKET kaynağı açılmalı. DB göçü gerekmez (drizzle migration'larında CHECK yok).
  3. İki tuzak: (a) etiket "Güvenli" olunca rapor-listesi.tsx:83 "Güvenli · Güvenli", rapor-yazdir.tsx:13 "Güvenli (Güvenli)" üretir — dilim ve risk etiketi çakışır, küçük bir gösterim kararı gerekir; (b) LLM'e dilim adı ham anahtarla gidiyor (rapor.ts:62,68, listeOzetiCikar → [garanti | Güvenli]), bu yüzden serbest metinde "garanti dilimi" geri sızıyor — lokal DB'de 2 rapordan 1'inin genelDegerlendirme ve uyarilar alanında, 2 sohbet mesajında kelime var. Prompt'a sözlük satırı eklenmeden UI temizliği yarım kalır.
  4. Sayfalama için tek öneri: mevcut "kendine canonical + index" KALSIN; 1. sayfaya canonical VERİLMESİN; başlık/açıklama/H1 içerikle farklılaştırılsın. Kanıt: 363 derin üniversite sayfası (180/229 üniversite) + 304 derin bölüm sayfası (132/635 bölüm) var; program detay sayfası yok; 1. sayfa HTML'i derin sayfadaki programları içermiyor; programların ~%53'ü üniversite tarafında yalnızca derin sayfada listeleniyor. Google'ın sayfalama rehberi de "ilk sayfayı canonical yapma" diyor.
  5. Katalog köprüsünde bugünkü metin marka yasağını deliyor: universite-icerik.tsx:303 "…programlarına yerleşir misin?", cta-sira-form.tsx:143,164,194,204 "nereye yerleşirsin?". Ayrıca /bolum/[slug] sayfasında hiç CTA yok, üniversite sayfasında CTA tablonun ve sayfalamanın altında (ilk ekranda değil). Aşağıda vaat içermeyen 3 varyant var.

A. "Garanti → Güvenli" eksiksiz envanter

Arama: grep -rniI "garant" → src/ scripts/ public/ content/ toplam 193 satır, 56 dosya. Aşağıda sınıflandırılmış hâli. Sütun "Değişir mi?": evet / hayır-iç (iç tanımlayıcı) / hayır-anlam (dilim dışı anlam, marka vaadinin kendisi) / dikkat-DB (kayıtlı değer).

A1. src/ — kullanıcıya görünen dilim etiketi ve anlatım (DEĞİŞİR)

dosya:satır görünen metin tür değişir mi?
src/features/rapor/components/rapor-listesi.tsx:41 garanti: "Garanti" (DILIM_ETIKET; satır detayı başlığı :83 ve tadımlık satırı bunu kullanır) UI etiketi (sözlük 1) evet → "Güvenli" · dikkat: :83 {DILIM_ETIKET[dilim]} · {RISK_ETIKET[risk]} → "Güvenli · Güvenli" olur
src/features/rapor/components/rapor-listesi.tsx:348 "…{n} dengeli · {n} garanti olarak kuruldu." açıklama metni evet
src/features/rapor/components/rapor-yazdir.tsx:13 garanti: "Garanti (Güvenli)" (DILIM_LABEL, PDF/yazdır tablosu :94) UI etiketi (sözlük 2) evet → "Güvenli" (parantez düşer; "Güvenli (Güvenli)" olmasın)
src/features/rapor/components/rapor-yazdir.tsx:53 "…{n} garanti olarak kuruldu." açıklama metni evet
src/features/liste/components/program-tablosu.tsx:68 etiket: "Garanti" (/sonuc dilim sekmesi) UI etiketi (sözlük 3) evet
src/features/pazarlama/components/meraklisina-demo.tsx:149 aria-label: "…Garanti diliminde {n} program var." UI / erişilebilirlik evet
src/features/pazarlama/components/meraklisina-demo.tsx:207 SVG <text> "Garanti" UI etiketi (elle yazılmış) evet
src/features/pazarlama/components/meraklisina-icerik.tsx:71 <span …emerald>Garanti</span> dilimidir açıklama metni evet
src/features/pazarlama/components/meraklisina-icerik.tsx:76 "Garanti diliminin bir sonu yok: …" açıklama metni evet
src/features/pazarlama/components/meraklisina-icerik.tsx:134 "geçen yıl “garanti” görünen bir bölüm bu yıl dolabilir" açıklama (tırnak içinde halk dili) isteğe bağlı — tırnaklı kullanım marka mesajını destekliyor; tutarlılık için "güvenli görünen" önerilir
src/features/pazarlama/components/huni-semasi.tsx:28 L3("sonda garanti — hedef 6, …") şema düğüm metni (SEMA) evet → "sonda güvenli"
src/features/pazarlama/components/huni-semasi.tsx:45 ariaLabel: "…üstte hayal, ortada dengeli, sonda garanti olacak şekilde…" şema aria evet (aynı commit, AGENTS.md)
src/app/page.tsx:114 SSS: "Hayal, dengeli ve garanti dilimlerine dağıtılmış…" — aynı faqs dizisi :197 faqPageJsonLd(faqs) ile FAQPage JSON-LD'ye de gidiyor, tek düzeltme ikisini de günceller açıklama metni + yapılandırılmış veri evet
src/app/page.tsx:132 (ikinci geçiş) "…listeyi hayal/dengeli/garanti dilimleriyle kurarak…" açıklama metni evet
src/features/sihirbaz/components/cta-sira-form.tsx:147 "…hayal, dengeli ve garanti dilimlerindeki programların hazır." açıklama metni evet
src/features/sihirbaz/components/cta-sira-form.tsx:168 "…hayal, dengeli ve garanti dilimlerindeki programları anında listele." açıklama metni evet
src/features/sihirbaz/components/cta-sira-form.tsx:213 "…hayal, dengeli ve garanti dilimlerindeki programları bu sayfadan ayrılmadan gör." açıklama metni evet
src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx:309 "…hayal, dengeli ve garanti dilimlerine dağıtılmış 24 tercihi…" açıklama metni evet
src/features/rapor/components/revizyon-kutusu.tsx:79 placeholder: "…garanti dilimini genişlet…" UI (placeholder) evet
src/lib/ai/rapor.ts:434 yedek genelDegerlendirme: "…hayal, dengeli ve garanti dilimleri sıralamana göre dengelendi." (kullanıcıya gösterilir ve DB'ye yazılır) açıklama metni evet
src/lib/ai/rapor.ts:237,242 dev-mock metni ("hayal/dengeli/garanti dağılımlı", "Garanti dilimindeki son tercihleri…") yalnız dev'de görünür evet (düşük öncelik)

Sözlük birleştirme için "garanti" içermeyen ama aynı commit'e girmesi gereken satırlar (03-G1): src/features/liste/components/secimlerim-paneli.tsx:161 (etiket="Daha güvenli"), src/lib/tercih-degerlendirme.ts:14,72 ("Daha güvenli" union + değer; :60,80,114 cümle içi "daha güvenli" sıfat olarak kalabilir). sohbet-client.tsx:111 zaten "Güvenli dilimden" diyor — dokunulmaz, yeni sözlükle uyumlu.

A2. LLM prompt'ları

dosya:satır metin tür değişir mi?
src/lib/ai/rapor.ts:62 "…üç listeyi doldurmak: hayal (…), dengeli (…), garanti (…)" prompt (JSON alan adı) alan adı kalır (zod şeması :41,51 anahtarı garanti); prompt'a sözlük satırı eklenir
src/lib/ai/rapor.ts:68 "…dengeli ve garanti için de aynısı." prompt kalır (alan adı)
src/lib/ai/rapor.ts:73 ASLA "garanti", "kesin", "yüzde yüz" deme — yalnızca gerekce maddesinin içinde prompt (yasak) genişletilir: yasak genelDegerlendirme ve uyarilar için de geçerli olmalı + "üçüncü dilimi kullanıcıya 'güvenli' diye an"
src/lib/ai/rapor.ts:338,351 yeniden deneme geri bildirimi: "…garanti ${n} olmalı" prompt (LLM'e gider, kullanıcı görmez) hayır-iç
src/lib/ai/rapor.ts:452 listeOzetiCikar: [${t.dilim} | ${RISK_ETIKET}] → sohbet modeline [garanti | Güvenli] prompt verisi evet — ham anahtar yerine etiket sözlüğü kullanılmalı; yoksa sohbet cevaplarında "garanti dilimi" sızar
src/app/api/soru/route.ts:48 "ASLA yerleşme garantisi verme; …" prompt (yasak, vaat anlamı) hayır-anlam · not: devamındaki "yüksek/orta/düşük ihtimal dili kullan" 03-G3 ile çelişiyor (bu envanterin konusu değil, P3 kapsamına not)
scripts/tadimlik-uret.ts:70 ASLA "garanti", "kesin", "yüzde yüz" deme; "yüksek/orta/düşük ihtimal"… prompt (yasak) hayır-anlam · aynı "ihtimal" notu; ayrıca :73 "son 4 yılın" → 5 yıl (P3 notu)
src/lib/ai/client.ts:53 SORUMLULUK_REDDI: "…yerleşme garantisi verilmez." açıklama (vaat reddi) hayır-anlam

A3. Dilim dışı anlamlar — DEĞİŞMEZ (markanın ana cümlesi ya da başka kavram)

dosya:satır metin not
src/app/page.tsx:130 "Yerleşme garantisi veriyor musunuz?" vaat reddi — kalır
src/app/page.tsx:132 (ilk geçiş) "…kimse garanti veremez." kalır
src/app/page.tsx:388 "Yerleşme garantisi vermiyoruz — çünkü kimse veremez." markanın ana cümlesi — kalır
src/app/paket/page.tsx:63 "…yerleşme garantisi verilmez." kalır
src/app/kosullar/page.tsx:43 "…garantisi vermez ve ÖSYM ya da YÖK ile bağlantılı değildir." hukuki metin — kalır
src/app/sonuc/page.tsx:130 "…yerleşme garantisi vermez…" kalır
src/components/site-footer.tsx:133 "…yerleşme garantisi vermez." kalır
src/features/kullanici/components/giris-karti.tsx:85 "KolayTercih yerleşme garantisi vermez." kalır
src/features/rapor/components/rapor-yazdir.tsx:109 "…garantisi vermez." kalır
src/features/sihirbaz/sihirbaz-sabitler.ts:11 "İş garantisi" (sihirbaz öncelik çipi; sihirbaz-adimlar.tsx render eder) ayrı karar: dilimle ilgisiz ama "garanti" kelimesini UI'da tutan tek aksiyon etiketi. Öneri: "İş bulma kolaylığı". dikkat-DB: öncelikler düz metin dizisi olarak saklanıyor (rapor.ts tipi :65 oncelikler?: string[]; kod eşleşmesi metinle yapılıyor, ör. tercih-degerlendirme.ts:58 includes("Kolay yerleşme")). "İş garantisi" metniyle eşleşen kod yok → değiştirmek güvenli; eski kayıtlar eski metni taşır (lokal DB'de 0 kayıt)
"ödeme garantisi / iade garantisi" — kodda yok (0 geçiş). Ödeme tarafında yalnızca "iyzico güvenli ödeme" var (paket-satinal.tsx:114,120, odeme-sayfasi.tsx:36,86, site-footer.tsx:163, listem-govde.tsx:378, page.tsx:542, odeme/page.tsx:10). Yeniden adlandırma sonrası "Güvenli" kelimesi hem dilim hem ödeme bağlamında geçecek; aynı ekranda yan yana gelmiyorlar (dilim: /sonuc, /listem tablo; ödeme: /paket, /odeme) — kabul edilebilir, listem-govde.tsx:378 tek yakın temas noktası

A4. Kod tanımlayıcıları / enum / DB değerleri — AYRI LİSTE (DEĞİŞMEZ)

dosya:satır tanımlayıcı tür
src/types/yokatlas.ts:34,39,54 DilimKey = "hayal" | "dengeli" | "garanti", garanti: Program[] union tipi / alan
src/lib/rapor-havuzu.ts:12,29,30,35,40,47,50,51,74,81,86 Dilim tipi, IDEAL_HEDEF.garanti, sayaçlar tip / sabit
src/lib/risk.ts:25,41 dilim === "garanti" → "guvenli" karşılaştırma (eski raporlar için köprü)
src/lib/db.ts:41,52,69,147,152,156,179 dilimAra(..., "garanti"), yorumlar sorgu parametresi
src/lib/ai/rapor.ts:28,41,51,59,90,94,114,117,204,215,266,363,374,382,412 zod şema anahtarı, DILIMLER, log satırı şema / kod
src/app/api/programlar/route.ts:12, src/app/api/facetler/route.ts:44, src/features/pazarlama/pazarlama-queries.ts:13 ["hayal","dengeli","garanti"] · /api/programlar?dilim=garanti sorgu parametresi API sözleşmesi (kullanıcı görmez)
src/features/liste/components/program-tablosu.tsx:67,84,88,91,127,128, src/features/liste/liste-queries.ts:34,52 key: "garanti", varsayılan sekme durum anahtarı
src/features/pazarlama/components/meraklisina-demo.tsx:204,210, rapor-listesi.tsx:348/rapor-yazdir.tsx:53 içindeki dagilim.garanti alan erişimi kod
src/features/pazarlama/components/huni-semasi.tsx:34,39 + 24 rehber yazısının tamamında classDef garanti … / class X garanti mermaid classDef adı (renk sınıfı; CEO §2 "yalnızca iç anahtar") şema iç anahtarı — render edilmez
scripts/tadimlik-uret.ts:106,115 ["dengeli","garanti"] kod
src/lib/appdb/schema.ts:185 tadimlik_havuzu.dilim enum ["hayal","dengeli","garanti"] dikkat-DB
reports.result JSON (schema.ts:160) tercihler[].dilim: "garanti", kapsam.dagilim.garanti dikkat-DB (kayıtlı JSON)
ilgisiz fiil kullanımı: tercih-profili-kapisi.tsx:205, use-tercih-profili.ts:276, scripts/refresh.ts:125, page.tsx:355 "garanti edilir" (kod yorumu) yorum — kullanıcı görmez

DB kanıtı (lokal data/app.db, salt-okunur): tadimlik_havuzu 514 satır → dilim='garanti' 86, 'dengeli' 428. reports 2 kayıt → 2'sinde "dilim":"garanti" anahtarı; 1'inde LLM'in yazdığı genelDegerlendirme ve uyarilar serbest metninde "garanti" kelimesi. chat_messages içinde 2 mesajda kelime geçiyor. tadimlik_havuzu metin alanlarında 3/514 satırda geçiyor. drizzle/*.sql içinde "garanti" yok → SQLite tarafında CHECK kısıtı yok, enum yalnızca TypeScript düzeyinde. Prod sayıları bilinmiyor (prod'a erişim yasak).

A5. "UI etiketi değişir, tanımlayıcı kalır" — koddan değerlendirme

Uygulanabilir: evet. Ham "garanti" anahtarı kullanıcıya hiçbir yerde doğrudan basılmıyor; her render noktası bir etiket sözlüğünden ya da elle yazılmış metinden geçiyor. risk.ts:41 eski raporları (dilim === "garanti") zaten guvenli riskine çeviriyor; anahtar kaldığı için kayıtlı raporlar, tadımlık havuzu ve API sözleşmesi bozulmaz, migration gerekmez.

Ama etiket dağınık: tek sözlük yok. Aynı bilgi 3 sabitte + 1 union tipte + 2 elle yazılmış JSX/SVG'de + ~10 düzyazı cümlede tekrar ediyor. Önerilen uygulama sırası (tek PR içinde):

  1. src/lib/risk.ts içinde (RISK_ETIKET'in yanında) tek DILIM_ETIKET: Record<Dilim, string> aç; rapor-listesi.tsx:38, rapor-yazdir.tsx:10, program-tablosu.tsx:44-73, meraklisina-demo.tsx:207, listeOzetiCikar (rapor.ts:452) buradan okusun. (rapor-listesi.tsx'teki mevcut export başka yerde import edilmiyor — grep DILIM_ETIKET tek dosya.)
  2. Çakışma kararı (Bilal'in gözü gerekir): dilim etiketi = risk etiketi olunca başlık "Güvenli · Güvenli" olur. Öneri: satır detayında risk etiketi yalnızca dilimin varsayılan riskinden farklıysa gösterilsin (dilimdenRisk(dilim) !== risk); yazdır tablosunda "Hayal (Riskli) / Dengeli (Az riskli) / Güvenli". Eşikler aynı olduğu için (risk.ts:25 yorumu) pratikte tek kelime görünür.
  3. Prompt sözlüğü: sistemMetni'ne "JSON alan adı garanti teknik addır; adaya dönük hiçbir metinde 'garanti' kelimesini kullanma, bu dilimi 'güvenli' diye an" satırı; soru/route.ts kurallarına aynı satır.
  4. Düzyazı cümleler (A1 tablosu).

Kalan sızıntı (kabul edilmesi gereken): eski kayıtlı raporların LLM serbest metni (genelDegerlendirme, uyarilar, gerekce) ve sohbet geçmişi "garanti" kelimesini taşımaya devam eder; veri göçü önerilmez (rapor yeniden üretildiğinde kendiliğinden temizlenir). Tadımlık havuzu için prompt değişikliğinden sonra pnpm tadimlik yeniden koşulmalı (zaten hafızadaki "deploy sonrası prod'da koş" notuyla aynı iş).

A6. content/rehber/*.md — dilim anlamında geçişler (DEĞİŞİR; SEO ile eşgüdüm)

Kural (CEO §2 ile aynı): her yazıda ilk geçişte "güvenli (halk arasında 'garanti tercih')", sonrasında "güvenli". "hayal dengeli garanti" arama kalıbı olduğu için pillar yazıda (tercih-listesi-nasil-yapilir) terim açıklama ve ilk paragrafta anılarak korunur, silinmez.

dosya:satır görünen metin tür
ais-tercih-nasil-yapilir-onaylama.md:54 (2 geçiş), :58 "Listenin sonu gerçekten garanti mi?", "hayal/dengeli/garanti dağılımı", "…dilimleriyle çıkar" metin
bolumun-is-imkanini-nasil-arastirirsin.md:71 "hayal–dengeli–garanti dağılımı" metin
ek-yerlestirme-2026.md:52 "dengeli-garanti ağırlıklı, gerçekçi bir liste" metin
kac-siralama-ile-hangi-bolume-girebilirim.md:10 (ilk geçiş) %% aria: "…hayal, dengeli ve garanti dilimlerini tek bakışta…" şema aria
kac-siralama-ile-hangi-bolume-girebilirim.md:16 düğüm: R("Hayal / dengeli / garanti<br/>dilimleri saniyede çıkar") şema düğümü
kac-siralama-ile-hangi-bolume-girebilirim.md:52 "hayal/dengeli/garanti dilimleriyle ayırıp" metin
merkezi-yerlestirme-nasil-calisir.md:34, :47 "dengeli ve garanti tercihlerinin", "razı olacağın garantileri koy" metin
olu-tercih-nedir.md:42 "hayal/dengeli/garanti dilimleriyle etiketlenir" metin
onlisans-mi-lisans-mi.md:48 "hayal/dengeli/garanti dilimleriyle görürsün" metin
ozel-kosullu-programlar.md:72 "hayal–dengeli–garanti dağılımını temel al" metin
siralama-sartlari-2026.md:17 düğüm: L("Gerçekçi satırları<br/>hayal / dengeli / garanti diz") şema düğümü
taban-puan-mi-siralama-mi.md:48 "hayal/dengeli/garanti dilimleriyle gör" metin
taban-siralamalar-nasil-degisir.md:43, :46, :55 "garanti" davranabilirsin, "garanti bölgesine koyma", "hayal/dengeli/garanti dağılımı" metin
tercih-listesi-nasil-yapilir.md:3 frontmatter aciklama: "…hayal, dengeli ve garanti bölgeleri tek şemada" (meta description + OG) meta — terim anılarak korunur
tercih-listesi-nasil-yapilir.md:7 "hayal / dengeli / garanti mantığıyla" metin — "güvenli (halk arasında 'garanti')"
tercih-listesi-nasil-yapilir.md:16 %% aria: "Son 4-6 satır garanti tercihler…" şema aria
tercih-listesi-nasil-yapilir.md:17 %% altyazi: "…altta garanti (yeşil)…" şema altyazı
tercih-listesi-nasil-yapilir.md:21 düğüm: G("Garanti · son 4-6 satır<br/>…") şema düğümü
tercih-listesi-nasil-yapilir.md:40 (2 geçiş), :52, :54 "3) Garanti tercihleri", "Garanti dilimi …demektir", "…dilimlerini saniyede", "sonu gerçekten garanti mi?" metin / H-benzeri başlık
tercih-robotu-nedir-yok-atlas-nasil-kullanilir.md:14, :62 "hayal / dengeli / garanti mantığıyla", "…dilimlerine ayrılmış aday havuzu" metin
tercih-robotu-nedir-yok-atlas-nasil-kullanilir.md:31 %% aria: "…hayal, dengeli ve garanti dilimlerine ayırır…" şema aria
tercih-robotu-nedir-yok-atlas-nasil-kullanilir.md:35 düğüm: C("Robot dilimler:<br/>hayal / dengeli / garanti") şema düğümü
tercih-sonuclari-ne-zaman-2026.md:63 "hayal/dengeli/garanti dilimleriyle görebilirsin" metin
veliler-icin-tercih-rehberi.md:52 "hayal–dengeli–garanti dağılımı" metin
yatay-gecis-cap-yandal.md:79 "hayal, dengeli ve garanti bloklarını" metin
yerlesemedim-ne-yapmaliyim.md:55 "razı olacağın garantiler koymak" metin
yks-tercih-takvimi-2026.md:49 "altta gerçekten gideceğin garanti" metin

Rehberde DEĞİŞMEYEN (dilim dışı / halk dili eleştirisi): bolum-mu-universite-mi-sehir-mi.md:62 ("yatay geçiş… garanti değildir"), devlet-mi-vakif-mi.md:51 ve veliler-icin-tercih-rehberi.md:58 ("garanti olsun" diye yazılan… — eleştirilen halk kullanımı), kac-siralama…md:10 (ikinci geçiş, "Bant pusuladır, garanti değildir") ve :58, obp-nedir-nasil-hesaplanir.md:34 ("garantim olsun"), siralama-sartlari-2026.md:10,45 ("yerleşmeyi garanti etmez"), taban-siralamalar-nasil-degisir.md:3 ("…ben 85 binim, garanti" demeden önce oku), yatay-gecis-cap-yandal.md:12,13,69, yurt-burs-ve-yillik-maliyet.md:47. Bunlar markanın "garanti yoktur" sesini taşıyor — kalmalı.

Yalnızca classDef garanti içeren (dokunulmayacak) yazılar: hazirlik-sinifi-ve-ogretim-dili, universite-kayit-rehberi-2026 (+ yukarıdaki dilim-dışı listesindekiler: bolum-mu…, devlet-mi…, obp…, yurt-burs…).

Henüz main'de olmayan 3 yazı (gece/rehber-yazilari): üçü de kurala uygun yazılmış ("güvenli … halk arasında 'garanti tercih'"). Tek düzeltme: hedef-siralama-nasil-belirlenir.md:83 "…üründe dilimin adı da böyle geçer" cümlesi yeniden adlandırma sonrası yanlış olur → cümle o PR'da silinmeli.

A7. Temiz çıkan kapsam (0 geçiş — kanıt: aynı grep)

17 adet opengraph-image.tsx (rehber OG'si yazı başlığını basıyor; hiçbir baslik alanında "garanti" yok), src/lib/eposta.ts + eposta-gonder.ts, src/lib/og-sayfa.tsx, public/ (metin dosyası yok; llms.txt yok, robots/sitemap koddan üretiliyor), src/lib/seo.tsx JSON-LD üreticileri.

A8. Boyut, PR planı, AGENTS.md gereği

  • Dosya sayısı: src/ 13 (A1+A2: rapor-listesi, rapor-yazdir, program-tablosu, meraklisina-demo, meraklisina-icerik, huni-semasi, page.tsx, cta-sira-form, sihirbaz-cagri-karti, revizyon-kutusu, ai/rapor.ts, api/soru/route.ts, risk.ts) + sözlük birleştirme 2 (secimlerim-paneli, tercih-degerlendirme) + content/rehber 19 (+1 yeni yazı) + AGENTS.md 1 ≈ 35 dosya, ≈75 satır. İsteğe bağlı iç dokümanlar: docs/urun/gamification.md, vizyon.md, prd-kapi1-ucretsiz-funnel.md, docs/tasarim/ux-duzeltmeler.md.
  • Tek PR'da yapılabilir mi: Evet — tip/şema/DB değişikliği yok, iş mekanik. Öneri: tek PR, iki commit: (1) src/ + AGENTS.md, (2) content/rehber/. Böylece içerik commit'i SEO gözden geçirmesi için ayrı okunur. tsc etkisi yalnızca tercih-degerlendirme.ts union değerinde ("Daha güvenli" → "Güvenli"; kullanan yerler grep riskEtiketi ile kapatılmalı).
  • Sıra/çakışma: page.tsx ve ai/rapor.ts P3 ile, content/rehber/* P1 ve gece/rehber-yazilari ile çakışır → bu PR o dallar merge edildikten sonra açılmalı.
  • AGENTS.md gereği aynı commit'te güncellenecekler: huni-semasi.tsx SEMA düğümü :28 + ariaLabel :45 (figcaption'da kelime yok — değişmez) + meraklisina-icerik.tsx:71,76 (dilim anlatımı; 4. bölüm metninde kelime geçmiyor ama şemayla birlikte okunuyor) + meraklisina-demo.tsx:149,207. Davranış değişmediği için şemanın yapısı aynı kalır; risk renk dili (yeşil + metin etiketi) korunur. AGENTS.md:28'in kendisi "hayal/dengeli/garanti dağılımı" diyor → "hayal/dengeli/güvenli" olarak güncellenmeli, yoksa bir sonraki ajan eski sözlüğü geri getirir.
  • Kabul kriteri önerisi: grep -rniI "garant" src content | grep -v "classDef garanti\|class [A-Za-z0-9_,]* garanti" çıktısında yalnızca A3 (vaat reddi + halk dili) ve A4 (tanımlayıcı) satırları kalır.

A9. Katalog ilk ekranı için 3 köprü cümlesi (vaat yok; "yerleşirsin / garanti / olasılık" yok)

Bağlam (koddan): üniversite sayfasında CTA tablonun ve sayfalamanın altında (universite-icerik.tsx:301-305), bölüm sayfasında hiç yok (bolum-icerik.tsx CtaSiraForm import etmiyor). İlk ekran = H1 + giriş paragrafının hemen altı. CTA biçimi AGENTS.md deseni: metin + sonda <ArrowRight className="size-4" aria-hidden />, başta ikon yok; üstüne rozet gerekirse SectionEyebrow. "Son 5 yıl" ifadesi DB ile tutarlı (sira2021…sira2025).

# Köprü cümlesi CTA metni Hitap ettiği niyet
V1 "Bu tablodaki tabanlar geçen yılın sonucu. Sıralamanı yaz; her programın tabanı senin sıranın önünde mi gerisinde mi, satır satır gör." Sıralamamı tabanlarla karşılaştır → "Bu programa sıralamam yeter mi?" — tabloya bakıp kendi sırasıyla kafadan kıyas yapan, tek bir programı yoklayan aday.
V2 "{Üniversite / Bölüm} içinde sıralamana yakın programlar hangileri? Sıralamanı gir, 2025 tabanına göre sana en yakın olanları öne alalım." Sıralamama yakın programları göster → Keşif — üniversiteyi/bölümü seçmiş ama hangi program/şehir varyantının ulaşılabilir olduğunu bilmeyen aday.
V3 "Tek yılın tabanı yanıltabilir. Sıralamanı gir; bu programların son 5 yıldaki taban seyrini ve senin sıran karşısındaki risk seviyesini saklamadan gösterelim." Risk seviyesini satır satır gör → Temkinli aday ve veli — "geçen yıl tutuyordu" güvenine şüpheyle bakan, markanın dürüstlük vaadine en açık kitle.

Not: mevcut başlıklar ("…programlarına yerleşir misin?", "Sıralamanla nereye yerleşirsin?") 03 Ek A yasak listesine takılıyor; köprü yapılırken cta-sira-form.tsx:143,164,194,204 ve universite-icerik.tsx:303 de aynı işte düzeltilmeli. Hangi varyantın kazandığını okumak için P2'nin cta_form_goruntulendi paydası yayında olmalı (CEO §6 sırası doğru).


B. /universite/*/sayfa/N ve /bolum/*/sayfa/N — tek öneri

B1. Koddan mevcut durum

Soru Bulgu Kanıt
Rota nerede? src/app/universite/[slug]/sayfa/[no]/page.tsx, src/app/bolum/[slug]/sayfa/[no]/page.tsx; ikisi de generateStaticParams ile 2..N üretir, no < 2 ya da tamsayı değilse notFound() dosyaların :13-20; içerik features/katalog/components/{universite,bolum}-icerik.tsx
Sayfa boyu / sıra SAYFA_BOYU = 50. Üniversite: fakülte → efektif sıra ASC. Bölüm: efektif sıra ASC (lisans, sonra önlisans) sayfalama.tsx:6, src/lib/katalog.ts:138,364
Kaç sayfa? 363 derin üniversite sayfası (229 üniversitenin 180'i çok sayfalı; en çok 9 sayfa: Medipol, Nişantaşı) + 304 derin bölüm sayfası (635 bölümün 132'si). Toplam 667 URL lokal .next/server/app/{universite,bolum}/*/sayfa/N.html sayımı
Canonical Kendine: path: /universite/${slug}/sayfa/${sayfa} → alternates.canonical universite-icerik.tsx:61, bolum-icerik.tsx:53, seo.tsx:51; build HTML: <link rel="canonical" href="https://kolaytercih.com/universite/istanbul-medipol-universitesi/sayfa/2"/>
Robots index, follow (layout varsayılanı; sayfa özelinde direktif yok). robots.ts yalnızca /api/ engelliyor src/app/layout.tsx:67; build HTML <meta name="robots" content="index, follow"/>
Title / description "{Ad} Taban Puanları 2026 (Sayfa N)" + "…tablosunun N. sayfası — toplam X programın 2025 yerleştirme verileri." — sayfalar arası tek fark sayfa numarası universite-icerik.tsx:59-60, bolum-icerik.tsx:51-52
H1 / giriş Üniversite: "… — Sayfa N" + satır aralığı cümlesi + 1. sayfaya link (:184-187, 261-274). Bölüm: H1 1. sayfayla birebir aynı ("Psikoloji"); fark yalnızca paragraf sonundaki "— sayfa N" (bolum-icerik.tsx:122-129). Bölümün görünür breadcrumb'ında üst bölüm linki de yok (:116-118; JSON-LD'de var) build HTML'de iki sayfanın <h1>'i: Psikoloji / Psikoloji
Sitemap Girmiyor. Yalnızca /bolum/{slug} ve /universite/{slug} src/app/sitemap.ts:31-44
Keşif yolu Sayfalama gerçek <a href> üretir (rel="prev"/"next" anchor niteliğiyle; <link rel> yok). Pencere: 1 … c-1 c c+1 … son sayfalama.tsx:52-60, 63-79
Program detay sayfası var mı? Yok. src/app altında /program/… rotası yok (21 page.tsx listelendi) find src/app -name page.tsx
Derin sayfadaki programa başka nereden ulaşılır? Her program tam iki listede görünür: üniversitesinin sayfası (k. sayfa) ve bölümünün sayfası (j. sayfa). Üniversite satırı → /bolum/{slug} linki (universite-program-tablosu.tsx:71-77); bölüm satırı → /universite/{slug} linki (bolum-program-listesi.tsx:206-211). Linkler 1. sayfaya gider; programın o listede kaçıncı sayfada olduğu bilinmez —
1. sayfa HTML'i derin programları içeriyor mu? Hayır. bolum/psikoloji.html 51 <tr>; 2. sayfadaki üniversite slug'ları (ör. izmir-bakircay-universitesi) 1. sayfa HTML'inde hiç geçmiyor. (Bölüm listesi istemci bileşenine tüm programları prop olarak alıyor ama prerender HTML'ine gömülmüyor.) build HTML karşılaştırması
Ne kadar içerik derinde? Üniversite tarafında programların ≈ %53'ü (ham ada göre 12.538 / 23.610) yalnızca sayfa/2+'da listeleniyor data/yokatlas.db salt-okunur sorgu (slug birleştirmesi nedeniyle yaklaşık)
Sorgu parametreli varyant? Sayfalama'nın sorgu prop'u hiçbir yerde kullanılmıyor; istemci sıralaması URL değiştirmiyor → filtre/sıralama kaynaklı kopya URL riski yok grep "sorgu=" src → 0

B2. Öneri (tek): kendine canonical + index kalsın; canonical→1. sayfa YAPILMASIN; derin sayfaların başlık/açıklama/H1'i sayfanın gerçek içeriğiyle farklılaştırılsın.

Gerekçe:

  1. Google'ın sayfalama rehberi (Search Central, "Pagination, incremental page loading…": developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading) açıkça: her sayfaya benzersiz URL ver, sayfaları sıralı <a href> ile bağla, "ilk sayfayı dizinin canonical'ı olarak kullanma; her sayfaya kendi canonical'ını ver". Kod bugün bu üçünü de yapıyor. (Not: bu gece yalnızca kod okundu; sayfa açılıp teyit edilmedi — Bilal/SEO ajanı uygulamadan önce linki bir kez açsın. rel=prev/next Google tarafından 2019'dan beri kullanılmıyor; anchor'daki nitelik zararsız.)
  2. Canonical→1. sayfa burada olgusal olarak yanlış sinyal olur: canonical "bu sayfa şunun kopyası" demektir; derin sayfanın 50 satırı 1. sayfada yok (B1). Google ya sinyali yok sayar ya da derin sayfaları dizinden düşürür; ikinci durumda 667 URL'deki programlar (üniversite tarafında programların ~%53'ü) arama için yalnızca diğer eksendeki listeye — o da çoğu zaman yine bir derin sayfaya — kalır. Program detay sayfası olmadığı için telafi edecek başka URL yok.
  3. Asıl zayıflık canonical değil, ayırt edilemezlik: başlık ve açıklama yalnızca sayfa numarasıyla ayrışıyor, bölüm derin sayfasının H1'i 1. sayfayla aynı. Oysa içerik gerçekten farklı ve aranabilir biçimde farklı: bölüm sayfaları taban sırasına göre dizili → N. sayfa belirli bir sıralama aralığını kapsıyor ("Psikoloji — taban sırası 95.000–180.000 arası programlar"); üniversite sayfaları fakülteye göre dizili → N. sayfa belirli fakülteleri kapsıyor ("… — Sağlık Bilimleri Fakültesi, Tıp Fakültesi"). Bu, "X bin sıralama ile psikoloji" türü sorgularla doğrudan örtüşür; veri zaten BolumIcerik/UniversiteIcerik içinde hesaplı (dilim, gruplar).
  4. Risk profili: canonical/robots'a dokunulmadığı için indeks kaybı riski yok — CEO'nun §6'daki erteleme gerekçesi ("derin sayfaları indeksten düşürebilir") bu öneri için geçerli değil; Search Console verisi beklenmeden yapılabilir. GSC dışa aktarımı (§5-c) yalnızca etkiyi ölçmek için gerekir: /sayfa/ URL'lerinde "Kopya, kullanıcı canonical seçmedi" / "Tarandı — dizine eklenmedi" sayısı önce/sonra.

Bilinçli olarak önerilmeyenler: noindex,follow (Google uzun süre noindex kalan sayfanın linklerini de izlemeyi bırakır; derin programların tek keşif yolu kesilir), sitemap'e ekleme (zorunlu değil; öncelik sinyali 1. sayfalarda kalsın — mevcut hâl doğru), SAYFA_BOYU büyütme / "tümünü göster" (ayrı ürün/performans kararı; 428 satırlık tablo).

B3. Değişecek dosyalar (uygulama YOK — yalnızca liste)

Dosya Değişiklik
src/features/katalog/components/bolum-icerik.tsx bolumSayfaMetadata sayfa > 1 dalı (:49-60): başlık ve açıklamaya o sayfanın taban sırası aralığı (dilimdeki ilk/son efektifSira; null'lar için "taban verisi olmayan programlar" yedeği). H1 (:122-124) derin sayfada ayrışsın ("Psikoloji — Sayfa 2" + aralık alt satırı). Görünür breadcrumb (:116-118) üst bölüm linkini de göstersin (üniversite sayfasındaki desenle birebir — AGENTS.md "tek kaynak" ilkesi)
src/features/katalog/components/universite-icerik.tsx uniSayfaMetadata sayfa > 1 dalı (:57-69): açıklamaya (ve uzunluk elverirse başlığa) o sayfadaki fakülte adları (gruplar ile aynı hesap; ilk 2 ad + "ve N birim daha"). Giriş paragrafı (:261-274) fakülte adlarını da saysın. Üniversite adları uzun olduğu için <title> ~60 karakteri aşmasın: farklılaştırıcı öncelikle description + H1 altına
(ortak yardımcı, isteğe bağlı) src/features/katalog/components/sayfalama.tsx ya da yeni küçük yardımcı Dilim hesabı (slice((sayfa-1)*SAYFA_BOYU, …)) metadata ve gövdede iki kez yazılmasın diye tek fonksiyon
Değişmeyecek src/lib/seo.tsx (sayfaMetadata canonical mantığı doğru), src/app/sitemap.ts, src/app/robots.ts, iki sayfa/[no]/page.tsx rota dosyası

Kabul kriteri önerisi: build sonrası universite/<slug>/sayfa/2.html ve sayfa/3.html'in <title> + <meta name="description"> çifti sayfa numarası dışında da farklı; canonical hâlâ kendine; <meta name="robots"> hâlâ index, follow; bölüm derin sayfasında <h1> 1. sayfadan farklı.