diff --git a/scripts/tadimlik-uret.ts b/scripts/tadimlik-uret.ts
index a869324..4e2c351 100644
--- a/scripts/tadimlik-uret.ts
+++ b/scripts/tadimlik-uret.ts
@@ -67,9 +67,10 @@ KURALLAR (kesin):
- METİN DİYETİ: her alan TEK kısa cümle, dolgu söz yok.
- gerekce: bu programın bu aday için neden mantıklı olduğu (TEK cümle,
en fazla ~15 kelime, Türkçe).
-- riskNotu: yerleşme ihtimali değerlendirmesi (TEK kısa cümle). ASLA "garanti",
- "kesin", "yüzde yüz" deme; "yüksek/orta/düşük ihtimal" dili kullan.
-- trendOzeti: son 4 yılın taban sıralaması hareketi, TEK cümle (ör. "2022'den
+- riskNotu: geçmiş taban verisine dayalı risk değerlendirmesi (TEK kısa cümle).
+ ASLA garanti/kesin/yüzde/olasılık/ihtimal deme; "güvenli / az riskli /
+ riskli" etiketleriyle konuş.
+- trendOzeti: son 5 yılın taban sıralaması hareketi, TEK cümle (ör. "2022'den
beri taban 45B'den 38B'ye indi, bölüm zorlaşıyor").
- Adayın sıralaması yaklaşıktır; kesin sıra telaffuz etme, banda göre konuş.`;
@@ -82,9 +83,9 @@ function mockMetin(p: Program, temsiliSira: number, kategori: string | null) {
return {
gerekce: `(Dev mock) ${p.isim}, ${kategori ? `${kategori} ilgisiyle ve ` : ""}~${temsiliSira.toLocaleString("tr-TR")} bandındaki sıralamanla uyumlu bir aday.`,
riskNotu:
- "(Dev mock) Taban sıralaması senin civarında; orta-yüksek ihtimalle yerleşilebilir.",
+ "(Dev mock) Son taban sıralaması sırana yakın; küçük bir kayma sonucu değiştirebilir.",
trendOzeti:
- "(Dev mock) Son 4 yılda taban sıralaması görece stabil seyretti.",
+ "(Dev mock) Son 5 yılda taban sıralaması görece stabil seyretti.",
};
}
diff --git a/src/app/api/soru/route.ts b/src/app/api/soru/route.ts
index 305f284..01c0cfc 100644
--- a/src/app/api/soru/route.ts
+++ b/src/app/api/soru/route.ts
@@ -45,7 +45,8 @@ KURALLAR:
sıralaması adayın belirgin altında, Az riskli (sarı) = adayın sıralaması
civarında, Riskli (kırmızı) = geçen yıl adayın sıralamasının üzerinde
kapandı. Risk sorularında bu etiketleri ve taban sıralarını kullan.
-- ASLA yerleşme garantisi verme; "yüksek/orta/düşük ihtimal" dili kullan.
+- ASLA yerleşme garantisi verme; olasılık, yüzde ya da "ihtimal" dili kullanma —
+ güvenli / az riskli / riskli etiketleri ve taban sıralarıyla konuş.
- Bilmediğin güncel veriyi uydurma; emin değilsen YÖK Atlas'a bakmasını söyle.
- Taban sıralamalarının her yıl değiştiğini gerektiğinde hatırlat.
- Cevapları kısa ve öz tut (genelde 3-6 cümle); istenirse detaylandır.
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 6303e82..f9e2ed5 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -52,7 +52,7 @@ export const metadata: Metadata = {
template: "%s — KolayTercih",
},
description:
- "YKS sıralamana göre gerçek YÖK Atlas verisiyle dengeli 24 tercihlik liste. İnsan danışmanın onda bir fiyatına, yapay zekâ destekli tercih danışmanlığı.",
+ "YKS sıralamana göre gerçek YÖK Atlas verisiyle dengeli 24 tercihlik liste. İnsan danışmandan çok daha düşük fiyata, yapay zekâ destekli tercih danışmanlığı.",
applicationName: "KolayTercih",
openGraph: {
type: "website",
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 0a06a1e..c9fa786 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -12,7 +12,6 @@ import {
TrendingUp,
Wallet,
} from "lucide-react";
-import Image from "next/image";
import Link from "next/link";
import { Suspense } from "react";
import { ComparisonCell } from "@/features/pazarlama/components/landing-parcalari";
@@ -30,6 +29,7 @@ import {
SectionEyebrow,
} from "@/components/pixel-decor";
import { MAX_REVIZYON, URUNLER } from "@/lib/credits";
+import { VERI_YIL_SAYISI } from "@/lib/veri-kapsami";
import {
Accordion,
AccordionContent,
@@ -54,9 +54,11 @@ import {
import type { Metadata } from "next";
import {
JsonLd,
+ KATALOG_VERI_TARIHI,
faqPageJsonLd,
softwareApplicationJsonLd,
} from "@/lib/seo";
+import { KATALOG_TARIH_METNI } from "@/features/katalog/components/veri-kaynagi";
import { SiteFooter } from "@/components/site-footer";
export const metadata: Metadata = {
@@ -87,7 +89,7 @@ const problems = [
icon: Wallet,
title: "Danışman lüks haline geldi",
description:
- "İyi bir tercih danışmanı 2.000–10.000 TL istiyor. Ücretsiz robotlar ise sadece liste filtreliyor, akıl vermiyor.",
+ "İyi bir tercih danışmanı 1.000–5.000 TL istiyor. Ücretsiz robotlar ise sadece liste filtreliyor, akıl vermiyor.",
},
];
@@ -103,8 +105,7 @@ const steps = [
icon: BarChart3,
step: "2",
title: "Yapay zekâ veriyi tarasın",
- description:
- "Son 4 yılın YÖK Atlas verisi — taban sıralaması trendleri, kontenjan değişimleri, doluluk oranları — senin için analiz edilsin.",
+ description: `Son ${VERI_YIL_SAYISI} yılın YÖK Atlas verisi — taban sıralaması trendleri, kontenjan değişimleri, doluluk oranları — senin için analiz edilsin.`,
},
{
icon: ShieldCheck,
@@ -118,8 +119,7 @@ const steps = [
const faqs = [
{
question: "KolayTercih'in önerileri neye dayanıyor?",
- answer:
- "Tüm öneriler YÖK Atlas'ın resmî verisine dayanır: son 4 yılın taban başarı sıralamaları, kontenjanlar, yerleşme istatistikleri ve doluluk oranları. Yapay zekâ bu veriyi yorumlar; veri olmadan tahmin yürütmez.",
+ answer: `Tüm öneriler YÖK Atlas'ın resmî verisine dayanır: son ${VERI_YIL_SAYISI} yılın taban başarı sıralamaları, kontenjanlar, yerleşme istatistikleri ve doluluk oranları. Yapay zekâ bu veriyi yorumlar; veri olmadan tahmin yürütmez.`,
},
{
question: "Ücretsiz tercih robotlarından farkı ne?",
@@ -145,7 +145,7 @@ const comparison = [
tercihai: true,
},
{
- feature: "Son 4 yılın trend analizi",
+ feature: `Son ${VERI_YIL_SAYISI} yılın trend analizi`,
robot: false,
danisman: true,
tercihai: true,
@@ -165,7 +165,7 @@ const comparison = [
{
feature: "Fiyat",
robot: "Ücretsiz",
- danisman: "2.000–10.000 TL",
+ danisman: "1.000–5.000 TL",
tercihai: `${PAKET_FIYATI} TL · tek seferlik`,
},
];
@@ -177,7 +177,7 @@ const paketOzellikleri = [
},
{
icon: ShieldCheck,
- text: "Her tercih için yerleşme olasılığı ve risk analizi (son 4 yıl)",
+ text: `Her tercih için yerleşme riski ve trend analizi (son ${VERI_YIL_SAYISI} yıl)`,
},
{ icon: FileText, text: "Veliyle paylaşılabilir PDF rapor" },
{ icon: RefreshCcw, text: `${MAX_REVIZYON} liste revizyon hakkı` },
@@ -222,11 +222,6 @@ export default function Home() {
className="mx-auto flex min-h-[calc(100svh-5.5rem)] max-w-6xl flex-col items-center justify-center px-4 pb-4 pt-12 text-center sm:pb-36 sm:pt-4"
>
- KolayTercih, gerçek YÖK Atlas verisiyle çalışan yapay zekâ tercih - danışmanın. İnsan danışmanın binlerce lira aldığı işi — dengeli - liste, risk analizi, soru-cevap — onda bir fiyatına yapar. -
*/}- İnsan danışmanın 2.000–10.000 TL aldığı işi tek seferlik{" "} + İnsan danışmanın 1.000–5.000 TL aldığı işi tek seferlik{" "} {PAKET_FIYATI} TL'ye alırsın. Abonelik yok, gizli ücret yok.
++ Danışman fiyat aralığı: Armut, 2026. +
diff --git a/src/app/paket/page.tsx b/src/app/paket/page.tsx index 9e1eab4..4931153 100644 --- a/src/app/paket/page.tsx +++ b/src/app/paket/page.tsx @@ -46,10 +46,10 @@ export default function PaketPage({- Tercih danışmanları bu dönemde 2.000–10.000 TL alıyor. KolayTercih + Tercih danışmanları bu dönemde 1.000–5.000 TL alıyor. KolayTercih aynı işi gerçek YÖK Atlas verisiyle, dakikalar içinde yapar.
diff --git a/src/components/arama-funnel-karti.tsx b/src/components/arama-funnel-karti.tsx index 29b8c5a..6e59359 100644 --- a/src/components/arama-funnel-karti.tsx +++ b/src/components/arama-funnel-karti.tsx @@ -35,7 +35,7 @@ const FUNNEL_METINLERI = [ "Sıralaman ne söylüyor? Birlikte bakalım.", "Her satırı senin için hesaplıyoruz.", "Akıllı tercih, içi rahat bir bekleyiş.", - "Yerleşme ihtimalini görerek seç.", + "Yerleşme riskini görerek seç.", "Sana özel liste birkaç dakikada hazır.", "İlgi alanların ve şehrin, tek listede.", "Boş kalan tercih, kaçan fırsattır.", diff --git a/src/features/katalog/components/veri-kaynagi.tsx b/src/features/katalog/components/veri-kaynagi.tsx index c8f174c..d1485e5 100644 --- a/src/features/katalog/components/veri-kaynagi.tsx +++ b/src/features/katalog/components/veri-kaynagi.tsx @@ -1,7 +1,9 @@ import { KATALOG_VERI_TARIHI } from "@/lib/seo"; import { cn } from "@/lib/utils"; -const TARIH_METNI = new Date( +// Veri tarihinin görünür biçimi ("9 Ağustos 2026") — tek biçim kaynağı; ana +// sayfa hero'sundaki veri satırı da bunu kullanır. +export const KATALOG_TARIH_METNI = new Date( `${KATALOG_VERI_TARIHI}T00:00:00Z`, ).toLocaleDateString("tr-TR", { day: "numeric", @@ -23,7 +25,7 @@ export function VeriKaynagi({{children} Kaynak: YÖK Atlas 2025 yerleştirme sonuçları. Son güncelleme:{" "} - . + .
); } diff --git a/src/features/odeme/components/paket-satinal.tsx b/src/features/odeme/components/paket-satinal.tsx index 6693d6f..5ebf077 100644 --- a/src/features/odeme/components/paket-satinal.tsx +++ b/src/features/odeme/components/paket-satinal.tsx @@ -12,6 +12,7 @@ import { } from "lucide-react"; import { getCurrentUser } from "@/lib/session"; import { URUNLER, DENEME_KREDISI } from "@/lib/credits"; +import { VERI_YIL_SAYISI } from "@/lib/veri-kapsami"; import { Button } from "@/components/ui/button"; import { Parallax } from "@/components/parallax"; import { Skeleton } from "@/components/ui/skeleton"; @@ -28,7 +29,7 @@ const OZELLIKLER = [ }, { icon: ShieldCheck, - text: "Her tercih için yerleşme olasılığı ve risk analizi (son 4 yıl trend)", + text: `Her tercih için yerleşme riski ve trend analizi (son ${VERI_YIL_SAYISI} yıl)`, }, { icon: FileText, text: "Veliyle paylaşılabilir PDF rapor" }, { icon: RefreshCcw, text: "2 liste revizyon hakkı" }, diff --git a/src/lib/ai/rapor.ts b/src/lib/ai/rapor.ts index 7d6e305..3141b23 100644 --- a/src/lib/ai/rapor.ts +++ b/src/lib/ai/rapor.ts @@ -18,7 +18,12 @@ import { type AdayProgram, } from "../rapor-havuzu"; import { secimOzeti } from "@/features/sihirbaz/sihirbaz-sabitler"; -import { RISK_ETIKET, dilimdenRisk, riskHesapla } from "../risk"; +import { + RISK_ETIKET, + dilimdenRisk, + riskHesapla, + riskNotuMetni, +} from "../risk"; // Yapay zekâdan istenen küçük şema (kullanıcı kararı, 6 Ağu 2026): riskNotu // ve trendOzeti gerçek sıra geçmişinden deterministik üretilir; dilim iskeleti @@ -161,16 +166,7 @@ function trendOzetiUret(p: AdayProgram): string { } function riskNotuUret(p: AdayProgram, adaySira: number): string { - switch (riskHesapla(p.sira2025 ?? p.sira2024, adaySira)) { - case "guvenli": - return "Taban sıralaması senin sıranın belirgin altında; yüksek ihtimalle yerleşirsin."; - case "az-riskli": - return "Taban sıralaması sırana yakın; orta ihtimalle yerleşilebilir."; - case "riskli": - return "Taban sıralaması senin sıranın üstünde kapandı; yerleşme ihtimali düşük."; - default: - return "Güncel taban sıralaması verisi yok; ihtimal öngörülemez, temkinli yaklaş."; - } + return riskNotuMetni(riskHesapla(p.sira2025 ?? p.sira2024, adaySira)); } /** Havuz programını render için gereken bilgiye indirger. */ diff --git a/src/lib/risk.ts b/src/lib/risk.ts index 4b7c151..8d7898d 100644 --- a/src/lib/risk.ts +++ b/src/lib/risk.ts @@ -42,3 +42,22 @@ export function dilimdenRisk(dilim: Dilim | string): RiskSeviyesi { if (dilim === "dengeli") return "az-riskli"; return "riskli"; } + +/** + * Risk seviyesinin tek cümlelik açıklaması (rapor satırları + tadımlık). + * Ürün yerleşme olasılığı HESAPLAMAZ; yalnızca son taban sıralamasını adayın + * sırasıyla kıyaslar. Bu yüzden metin olasılık/ihtimal/"yerleşirsin" demez. + * "Geçen yıl" da denmez: efektif sıra 2025 yoksa 2024'e düşüyor. + */ +export function riskNotuMetni(risk: RiskSeviyesi | null): string { + switch (risk) { + case "guvenli": + return "Son taban sıralaması senin sıranın belirgin altında; geçmiş veriye göre güvenli aralıkta."; + case "az-riskli": + return "Son taban sıralaması sırana yakın; küçük bir kayma sonucu değiştirebilir."; + case "riskli": + return "Son taban sıralaması senin sıranın üstünde kapandı; hayal tercihi olarak düşün."; + default: + return "Güncel taban verisi yok; bu satırı temkinli değerlendir."; + } +} diff --git a/src/lib/tadimlik-havuzu.ts b/src/lib/tadimlik-havuzu.ts index 62dd85b..e1df7ae 100644 --- a/src/lib/tadimlik-havuzu.ts +++ b/src/lib/tadimlik-havuzu.ts @@ -8,6 +8,7 @@ import { turkishSlugify } from "./slug"; import type { PuanTuruKey } from "@/types/yokatlas"; import type { Dilim } from "./rapor-havuzu"; import type { RaporSonuc } from "@/features/rapor/types/rapor"; +import { dilimdenRisk, riskHesapla, riskNotuMetni } from "./risk"; /** Sihirbaz kategorisi seçilmemiş kullanıcı için kova×tür başına fallback satır. */ export const GENEL_KATEGORI = "genel"; @@ -76,13 +77,20 @@ export async function tadimlikSec( ), }); if (satir) { + const program = satir.program as RaporSonuc["programlar"][string]; return { programId: satir.programId, dilim: satir.dilim, gerekce: satir.gerekce, - riskNotu: satir.riskNotu, + // DB'deki riskNotu batch'te LLM'in temsili sıraya göre yazdığı + // cümledir; servis EDİLMEZ. Not, rozetle (tadimlik-satiri.tsx) aynı + // formülden adayın gerçek sırasına göre okuma anında üretilir — metin + // ile rozet çelişemez, olasılık dili sızamaz. + riskNotu: riskNotuMetni( + riskHesapla(program.efektifSira, sira) ?? dilimdenRisk(satir.dilim), + ), trendOzeti: satir.trendOzeti, - program: satir.program as RaporSonuc["programlar"][string], + program, }; } } diff --git a/src/lib/veri-kapsami.ts b/src/lib/veri-kapsami.ts new file mode 100644 index 0000000..937f77a --- /dev/null +++ b/src/lib/veri-kapsami.ts @@ -0,0 +1,6 @@ +/** + * Taban sıralaması geçmişinin kapsadığı yıl sayısı. Veritabanında + * sira2021–sira2025 kolonları var (5 yıl); "son N yıl" diyen tüm metinler bu + * sabitten okur. Yeni veri yılı eklenince (ör. sira2026) burayı güncelle. + */ +export const VERI_YIL_SAYISI = 5;