From 5853b7d0915ad7c5a0a1cfa6beeb03aabfc0bb7d Mon Sep 17 00:00:00 2001
From: bilalgursen
Date: Mon, 21 Sep 2026 16:03:22 +0300
Subject: [PATCH] =?UTF-8?q?feat(etiket):=20g=C3=B6r=C3=BCnen=20"Garanti"?=
=?UTF-8?q?=20dilim=20ad=C4=B1=20site=20genelinde=20"G=C3=BCvenli"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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
---
AGENTS.md | 2 +-
scripts/tadimlik-uret.ts | 2 ++
src/app/api/soru/route.ts | 3 +++
src/app/page.tsx | 4 +--
.../liste/components/program-tablosu.tsx | 8 +++---
.../liste/components/secimlerim-paneli.tsx | 15 +++++++----
.../pazarlama/components/huni-semasi.tsx | 6 +++--
.../pazarlama/components/meraklisina-demo.tsx | 9 ++++---
.../components/meraklisina-icerik.tsx | 6 ++---
.../rapor/components/rapor-listesi.tsx | 17 +++++++------
.../rapor/components/rapor-yazdir.tsx | 19 ++++++++------
.../rapor/components/revizyon-kutusu.tsx | 2 +-
.../sihirbaz/components/cta-sira-form.tsx | 6 ++---
.../components/sihirbaz-cagri-karti.tsx | 2 +-
src/lib/ai/rapor.ts | 17 ++++++++++---
src/lib/risk.ts | 25 +++++++++++++++++++
src/lib/tercih-degerlendirme.ts | 11 ++++----
17 files changed, 103 insertions(+), 51 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index c203da0..e5dcc88 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -25,5 +25,5 @@ Funnel CTA butonlarında ("Listemi oluştur", "Tercihlerimi belirle", giriş/öd
# Meraklısına'daki mermaid şeması mimariyle senkron kalmalı
-`/meraklisina` sayfasındaki sihirbaz akış şeması (`src/features/pazarlama/components/huni-semasi.tsx` içindeki `SEMA` sabiti) ürünün gerçek davranışının belgesidir, dekor değildir. Sihirbaz/listeleme mimarisinde davranış değiştiren her değişiklikte bu şema da aynı PR/commit içinde güncellenmeli: sihirbaz adımlarının sayısı-sırası-içeriği (alan → il → devlet/vakıf), aday havuzu kuralları, 24'lük liste iskeleti (hayal/dengeli/garanti dağılımı), havuz 24'ün altına düşünce filtre gevşetme sırası ve yapay zekânın havuz-dışına-çıkamama kuralı. Şemayı güncellerken çevresindeki unsurları da eşitle: bölümdeki anlatım metni (`src/features/pazarlama/components/meraklisina-icerik.tsx`, 4. bölüm), kabın `aria-label`'ı ve figcaption. Şema öğrenci diliyle kalmalı (SQL/prompt/teknik detay yok) ve ürünün risk renk dilini korumalı — kırmızı/sarı/yeşil her zaman metin etiketiyle birlikte, renk tek başına anlam taşımaz.
+`/meraklisina` sayfasındaki sihirbaz akış şeması (`src/features/pazarlama/components/huni-semasi.tsx` içindeki `SEMA` sabiti) ürünün gerçek davranışının belgesidir, dekor değildir. Sihirbaz/listeleme mimarisinde davranış değiştiren her değişiklikte bu şema da aynı PR/commit içinde güncellenmeli: sihirbaz adımlarının sayısı-sırası-içeriği (alan → il → devlet/vakıf), aday havuzu kuralları, 24'lük liste iskeleti (hayal/dengeli/güvenli dağılımı — üçüncü dilimin kullanıcıya görünen adı "Güvenli"dir; iç anahtar, tip, DB değeri, mermaid `classDef` ve analitik değeri `garanti` olarak kalır, görünen etiketin tek kaynağı `src/lib/risk.ts` içindeki `DILIM_ETIKET`), havuz 24'ün altına düşünce filtre gevşetme sırası ve yapay zekânın havuz-dışına-çıkamama kuralı. Şemayı güncellerken çevresindeki unsurları da eşitle: bölümdeki anlatım metni (`src/features/pazarlama/components/meraklisina-icerik.tsx`, 4. bölüm), kabın `aria-label`'ı ve figcaption. Şema öğrenci diliyle kalmalı (SQL/prompt/teknik detay yok) ve ürünün risk renk dilini korumalı — kırmızı/sarı/yeşil her zaman metin etiketiyle birlikte, renk tek başına anlam taşımaz.
diff --git a/scripts/tadimlik-uret.ts b/scripts/tadimlik-uret.ts
index 4e2c351..697c6dd 100644
--- a/scripts/tadimlik-uret.ts
+++ b/scripts/tadimlik-uret.ts
@@ -70,6 +70,8 @@ KURALLAR (kesin):
- 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ş.
+- Programın "dilim" alanındaki "garanti" değeri teknik anahtardır; adaya dönük
+ hiçbir metinde bu kelimeyi kullanma, o dilimi "güvenli" diye an.
- 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ş.`;
diff --git a/src/app/api/soru/route.ts b/src/app/api/soru/route.ts
index 01c0cfc..6d86900 100644
--- a/src/app/api/soru/route.ts
+++ b/src/app/api/soru/route.ts
@@ -41,6 +41,9 @@ iş imkânları, tercih sırası) net ve dürüst yanıtlamak.
KURALLAR:
- Cevaplarını adayın 24'lük listesi ve seçimleri bağlamında ver; listedeki
programlara referans verebilirsin.
+- Dilimlerin adı Hayal, Dengeli ve Güvenli'dir. Üçüncü dilime her zaman
+ "Güvenli" de; "garanti dilimi", "garanti tercih" gibi ifadeler KULLANMA
+ (aday ya da eski mesajlar böyle dese bile sen "güvenli" diye düzelt).
- Listedeki her satırda dilim ve risk etiketi var: Güvenli (yeşil) = taban
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
diff --git a/src/app/page.tsx b/src/app/page.tsx
index d2e9544..8a3a48a 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -112,7 +112,7 @@ const steps = [
step: "3",
title: "Dengeli 24'lük listeni al",
description:
- "Hayal, dengeli ve garanti dilimlerine dağıtılmış, her satırı gerekçeli tercih listeni indir; aklına takılanı listen üzerinden yapay zekâya sor.",
+ "Hayal, dengeli ve güvenli dilimlerine dağıtılmış, her satırı gerekçeli tercih listeni indir; aklına takılanı listen üzerinden yapay zekâya sor.",
},
];
@@ -129,7 +129,7 @@ const faqs = [
{
question: "Yerleşme garantisi veriyor musunuz?",
answer:
- "Hayır — ve verdiğini iddia eden herkesten uzak dur. Taban sıralamaları her yıl adayların davranışına göre değişir; kimse garanti veremez. Biz riski şeffaf gösterir, listeyi hayal/dengeli/garanti dilimleriyle kurarak boşta kalma ihtimalini en aza indiririz. Tercih listenin son hali ve ÖSYM başvurusu her zaman senin sorumluluğundadır.",
+ "Hayır — ve verdiğini iddia eden herkesten uzak dur. Taban sıralamaları her yıl adayların davranışına göre değişir; kimse garanti veremez. Biz riski şeffaf gösterir, listeyi hayal/dengeli/güvenli dilimleriyle kurarak boşta kalma ihtimalini en aza indiririz. Tercih listenin son hali ve ÖSYM başvurusu her zaman senin sorumluluğundadır.",
},
{
question: "Fiyatlandırma nasıl çalışıyor?",
diff --git a/src/features/liste/components/program-tablosu.tsx b/src/features/liste/components/program-tablosu.tsx
index 5f35ec2..e71c009 100644
--- a/src/features/liste/components/program-tablosu.tsx
+++ b/src/features/liste/components/program-tablosu.tsx
@@ -20,7 +20,7 @@ import type {
PuanTuruKey,
RankResultsListe,
} from "@/types/yokatlas";
-import { riskHesapla, type RiskSeviyesi } from "@/lib/risk";
+import { DILIM_ETIKET, riskHesapla, type RiskSeviyesi } from "@/lib/risk";
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
import {
ProgramSiraGecmisi,
@@ -51,21 +51,21 @@ const DILIMLER: {
}[] = [
{
key: "hayal",
- etiket: "Hayal",
+ etiket: DILIM_ETIKET.hayal,
icon: Rocket,
renk: "text-red-500",
renkAktif: "text-red-400",
},
{
key: "dengeli",
- etiket: "Dengeli",
+ etiket: DILIM_ETIKET.dengeli,
icon: Scale,
renk: "text-amber-500",
renkAktif: "text-amber-400",
},
{
key: "garanti",
- etiket: "Garanti",
+ etiket: DILIM_ETIKET.garanti,
icon: ShieldCheck,
renk: "text-emerald-600",
renkAktif: "text-emerald-400",
diff --git a/src/features/liste/components/secimlerim-paneli.tsx b/src/features/liste/components/secimlerim-paneli.tsx
index 1cc08c8..d49d218 100644
--- a/src/features/liste/components/secimlerim-paneli.tsx
+++ b/src/features/liste/components/secimlerim-paneli.tsx
@@ -13,7 +13,7 @@ import {
X,
} from "lucide-react";
import { Button } from "@/components/ui/button";
-import { RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
+import { DILIM_ETIKET, RISK_ETIKET, type RiskSeviyesi } from "@/lib/risk";
import { sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import {
tercihDegerlendir,
@@ -156,9 +156,12 @@ export function SecimlerimPaneli() {
{ozet ? (
-
-
-
+
+
+
) : null}
@@ -272,7 +275,9 @@ const SecimSatiri = memo(function SecimSatiri({
/>
) : null}
{degerlendirme.riskEtiketi}
- {risk ? (
+ {/* Dilim adı ile risk etiketi aynı kelimeyse ("Güvenli")
+ parantez yazılmaz — "Güvenli (Güvenli)" olmasın. */}
+ {risk && RISK_ETIKET[risk] !== degerlendirme.riskEtiketi ? (
({RISK_ETIKET[risk]})
diff --git a/src/features/pazarlama/components/huni-semasi.tsx b/src/features/pazarlama/components/huni-semasi.tsx
index 85557c5..2224b19 100644
--- a/src/features/pazarlama/components/huni-semasi.tsx
+++ b/src/features/pazarlama/components/huni-semasi.tsx
@@ -6,6 +6,8 @@ import { ElCizimiSema } from "@/features/rehber/components/el-cizimi-sema";
// Renkler ürünün risk dilinden (kırmızı/sarı/yeşil) ve slate paletinden;
// renk tek başına anlam taşımaz, her düğüm metinle etiketlidir.
+// Üçüncü dilimin görünen adı "güvenli"dir; `classDef garanti` yalnızca iç
+// renk sınıfıdır (render edilmez), iç anahtarla aynı kalır.
const SEMA = `---
config:
look: handDrawn
@@ -25,7 +27,7 @@ flowchart TD
R --> L("En fazla 24 tercihlik liste")
L --> L1("üstte hayal — hedef 5, havuz elverdiğince")
L --> L2("ortada dengeli — hedef 13, havuz elverdiğince")
- L --> L3("sonda garanti — hedef 6, havuz elverdiğince")
+ L --> L3("sonda güvenli — hedef 6, havuz elverdiğince")
classDef havuz fill:#eff6ff,stroke:#3b82f6,color:#1e3a8a
classDef uyari fill:#fffbeb,stroke:#f59e0b,color:#92400e
@@ -42,7 +44,7 @@ export function HuniSemasi() {
return (
Her adım havuzu biraz daha daraltır; yapay zekâ listeyi bu havuzun{" "}
diff --git a/src/features/pazarlama/components/meraklisina-demo.tsx b/src/features/pazarlama/components/meraklisina-demo.tsx
index 03a9476..d34ff55 100644
--- a/src/features/pazarlama/components/meraklisina-demo.tsx
+++ b/src/features/pazarlama/components/meraklisina-demo.tsx
@@ -20,6 +20,7 @@ import { useTercihProfili } from "@/features/liste/hooks/use-tercih-profili";
import { PUAN_TURU_ETIKET, sonucHref } from "@/features/sihirbaz/sihirbaz-sabitler";
import type { DilimKey, SihirbazFacetleri } from "@/types/yokatlas";
import { onbellekliJsonGetir } from "@/lib/istek-cache";
+import { DILIM_ETIKET } from "@/lib/risk";
export type DemoVeri = {
facetler: SihirbazFacetleri;
@@ -146,7 +147,7 @@ export function DilimSeridiCanli() {
- Garanti diliminin bir sonu yok: 87. sıradaki bir adayın da 500
+ Güvenli diliminin bir sonu yok: 87. sıradaki bir adayın da 500
bininci sıradaki bir adayın da ulaşabildiği bütün{" "}
programlar listededir. Liste sana en yakın tabandan başlar; aşağı
indikçe ve “Daha fazla göster”e bastıkça senden
@@ -131,7 +131,7 @@ export function MeraklisinaIcerik() {
Tüm bu hesaplar geçen yılların{" "}
yerleştirme sonuçlarına dayanır. Kontenjanlar, tercih davranışları
- ve puanlar her yıl değişir; geçen yıl “garanti”
+ ve puanlar her yıl değişir; geçen yıl “güvenli”
görünen bir bölüm bu yıl dolabilir. Bu yüzden satırlarda son beş
yılın taban seyrini de gösteririz — çizgi yukarı tırmanıyorsa
bölüm zorlaşıyor demektir. KolayTercih karar destek{" "}
diff --git a/src/features/rapor/components/rapor-listesi.tsx b/src/features/rapor/components/rapor-listesi.tsx
index 52ca845..b8af439 100644
--- a/src/features/rapor/components/rapor-listesi.tsx
+++ b/src/features/rapor/components/rapor-listesi.tsx
@@ -29,17 +29,14 @@ import {
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
import type { RaporSonuc } from "@/features/rapor/types/rapor";
import {
+ DILIM_ETIKET,
RISK_ETIKET,
+ dilimdenFarkliRiskEtiketi,
dilimdenRisk,
riskHesapla,
type RiskSeviyesi,
} from "@/lib/risk";
-
-export const DILIM_ETIKET: Record = {
- hayal: "Hayal",
- dengeli: "Dengeli",
- garanti: "Garanti",
-};
+import type { Dilim } from "@/lib/rapor-havuzu";
// Risk renk dili: yeşil = güvenli, sarı = az riskli, kırmızı = riskli.
// Nokta hiçbir yerde tek başına durmaz; yanındaki etiket dar ekranda sr-only
@@ -75,12 +72,16 @@ export function RaporSatirDetayi({
trendOzeti: string;
}) {
const stil = RISK_STIL[risk];
+ // Risk etiketi yalnızca dilimin varsayılanından farklıysa yazılır; yoksa
+ // üçüncü dilimde başlık "Güvenli · Güvenli" olurdu (bkz. risk.ts).
+ const farkliRisk = dilimdenFarkliRiskEtiketi(dilim, risk);
return (
<>
@@ -345,7 +346,7 @@ export function RaporListesi({
Tercihlerine göre {rapor.kapsam.toplam} uygun program bulundu; listen{" "}
{rapor.kapsam.dagilim.hayal} hayal · {rapor.kapsam.dagilim.dengeli}{" "}
- dengeli · {rapor.kapsam.dagilim.garanti} garanti olarak kuruldu. Daha
+ dengeli · {rapor.kapsam.dagilim.garanti} güvenli olarak kuruldu. Daha
fazla seçenek için alan veya il filtreni genişletebilirsin.
) : null}
diff --git a/src/features/rapor/components/rapor-yazdir.tsx b/src/features/rapor/components/rapor-yazdir.tsx
index 18b93ea..20cf054 100644
--- a/src/features/rapor/components/rapor-yazdir.tsx
+++ b/src/features/rapor/components/rapor-yazdir.tsx
@@ -2,16 +2,19 @@ import Image from "next/image";
import { redirect } from "next/navigation";
import { verifySession, getCurrentUser } from "@/lib/session";
import { kullanicininRaporu } from "../rapor-queries";
-import { PUAN_TURLERI } from "@/types/yokatlas";
+import { PUAN_TURLERI, type DilimKey } from "@/types/yokatlas";
+import { DILIM_ETIKET, RISK_ETIKET, dilimdenRisk } from "@/lib/risk";
import type { RaporParams, RaporSonuc } from "../types/rapor";
import { Skeleton } from "@/components/ui/skeleton";
import { YazdirButonu } from "./yazdir-butonu";
-const DILIM_LABEL: Record = {
- hayal: "Hayal (Riskli)",
- dengeli: "Dengeli (Az riskli)",
- garanti: "Garanti (Güvenli)",
-};
+// Dilim sütunu: dilim adı + varsayılan riski. Üçüncü dilimde ikisi aynı
+// kelime ("Güvenli") olduğu için parantez düşer — "Güvenli (Güvenli)" yazmaz.
+function dilimLabel(dilim: DilimKey): string {
+ const ad = DILIM_ETIKET[dilim] ?? dilim;
+ const risk = RISK_ETIKET[dilimdenRisk(dilim)];
+ return ad === risk ? ad : `${ad} (${risk})`;
+}
export async function RaporYazdir() {
const session = await verifySession("/rapor/yazdir");
@@ -50,7 +53,7 @@ export async function RaporYazdir() {
Not: Tercihlerine göre {rapor.kapsam.toplam} uygun program bulundu;
liste {rapor.kapsam.dagilim.hayal} hayal ·{" "}
{rapor.kapsam.dagilim.dengeli} dengeli ·{" "}
- {rapor.kapsam.dagilim.garanti} garanti olarak kuruldu.
+ {rapor.kapsam.dagilim.garanti} güvenli olarak kuruldu.