Program artık siraGecmisi (YILLAR ile hizalı) + efektifSira + siraSon/puanSon/ kontenjanSon/yerlesenSon taşır. db.ts kolonları YILLAR'dan üretip takma adla seçer, programSatiri eşleyicisi ham satırı Program'a çevirir; SELECT_COLS'un üç tüketicisi de eşleyiciden geçer. EFEKTIF_SIRA veri-yillari'dan gelir. - trend: ILK_YIL tek kaynaktan, opsiyonel ilkYil parametresi - rapor snapshot'ına opsiyonel ilkYil yazılır (eski kayıtlar: okurken ILK_YIL) - rapor promptu son 4 yılı göndermeye devam eder, anahtarlar dinamik - tadımlık "son N yıl" filtresi genel: N != VERI_YIL_SAYISI ise servis edilmez - veri-kapsami VERI_YIL_SAYISI'nı veri-yillari'dan türetir Bileşenler bir sonraki commit'te yeni tipe geçer (ikisi birlikte derlenir). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
91 lines
3.3 KiB
TypeScript
91 lines
3.3 KiB
TypeScript
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<RiskSeviyesi, string> = {
|
||
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<Dilim, string> = {
|
||
hayal: "Hayal",
|
||
dengeli: "Dengeli",
|
||
garanti: "Güvenli",
|
||
};
|
||
|
||
/** Harita pinlerinin SVG dolgu renkleri — risk renk dilinin oklch karşılığı. */
|
||
export const RISK_PIN_RENK: Record<RiskSeviyesi, string> = {
|
||
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.";
|
||
}
|
||
}
|