import type { Dilim } from "./rapor-havuzu"; /** * Satır bazlı yerleşme riski. Renk dili ürünün her yerinde aynı: * yeşil = güvenli, sarı = az riskli, kırmızı = riskli. */ export type RiskSeviyesi = "guvenli" | "az-riskli" | "riskli"; export const RISK_ETIKET: Record = { guvenli: "Güvenli", "az-riskli": "Az riskli", riskli: "Riskli", }; /** * Dilimin kullanıcıya GÖRÜNEN adı — tek kaynak. Üçüncü dilimin iç anahtarı * (tip, DB değeri, API parametresi, mermaid classDef, analitik) `garanti` * olarak kalır; ekranda "Güvenli" yazar. Ham anahtarı kullanıcıya basma, * buradan oku. */ export const DILIM_ETIKET: Record = { hayal: "Hayal", dengeli: "Dengeli", garanti: "Güvenli", }; /** Harita pinlerinin SVG dolgu renkleri — risk renk dilinin oklch karşılığı. */ export const RISK_PIN_RENK: Record = { guvenli: "oklch(0.696 0.17 162.5)", // emerald-500 "az-riskli": "oklch(0.769 0.188 70.1)", // amber-500 riskli: "oklch(0.637 0.237 25.3)", // red-500 }; /** * Deterministik risk: programın efektif taban sıralaması (son yılın sırası, * yoksa bir önceki yılınki) adayın sıralamasıyla kıyaslanır. Eşikler * db.ts'teki dilim aralıklarıyla birebir aynı (dengeli: [sira, 1.4×sira], * garanti: (1.4×sira, ∞)). */ export function riskHesapla( efektifSira: number | null | undefined, adaySira: number, ): RiskSeviyesi | null { if (efektifSira == null || !Number.isFinite(adaySira) || adaySira < 1) { return null; } if (efektifSira > Math.round(adaySira * 1.4)) return "guvenli"; if (efektifSira >= adaySira) return "az-riskli"; return "riskli"; } /** Eski raporlar için (efektifSira kaydedilmemiş): dilimden risk türet. */ export function dilimdenRisk(dilim: Dilim | string): RiskSeviyesi { if (dilim === "garanti") return "guvenli"; if (dilim === "dengeli") return "az-riskli"; return "riskli"; } /** * Dilim başlığının yanına yazılacak risk etiketi. Yalnızca satırın riski * dilimin varsayılanından FARKLIYSA döner; aynıysa null. Üçüncü dilimin adı * risk etiketiyle aynı kelime olduğu için aksi hâlde "Güvenli · Güvenli" * görünürdü. */ export function dilimdenFarkliRiskEtiketi( dilim: Dilim | string, risk: RiskSeviyesi, ): string | null { return dilimdenRisk(dilim) === risk ? null : RISK_ETIKET[risk]; } /** * 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, son yılın verisi yoksa bir önceki * yılınkine 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."; } }