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>
This commit is contained in:
bilalgursen
2026-09-21 16:03:22 +03:00
parent d79758adc0
commit 5853b7d091
17 changed files with 103 additions and 51 deletions

View File

@@ -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<string, string> = {
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 (
<>
<div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-slate-500">
<stil.icon className="size-3.5" aria-hidden />
<span className="font-medium">
{DILIM_ETIKET[dilim]} · {RISK_ETIKET[risk]}
{DILIM_ETIKET[dilim as Dilim] ?? dilim}
{farkliRisk ? ` · ${farkliRisk}` : null}
</span>
{unitur ? <span>· {unitur}</span> : null}
</div>
@@ -345,7 +346,7 @@ export function RaporListesi({
<p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-900">
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.
</p>
) : null}

View File

@@ -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<string, string> = {
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.
</p>
) : null}
</header>
@@ -91,7 +94,7 @@ export async function RaporYazdir() {
{p?.universite} · {p?.il ?? "—"}
</span>
</td>
<td className="py-2 pr-2">{DILIM_LABEL[t.dilim]}</td>
<td className="py-2 pr-2">{dilimLabel(t.dilim)}</td>
<td className="py-2 pr-2">{t.gerekce}</td>
<td className="py-2 pr-2">{t.riskNotu}</td>
<td className="py-2">{t.trendOzeti}</td>

View File

@@ -76,7 +76,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
onChange={(e) => setFeedback(e.target.value)}
rows={2}
maxLength={1000}
placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, garanti dilimini genişlet…"
placeholder="ör. İlk 5 tercihte daha fazla İstanbul olsun, güvenli dilimi genişlet…"
disabled={pending}
className="w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
/>