// Program özellikleri: YÖK Atlas API'sinden scripts/program-ozellik.ts ile // `program_ozellik` ve `kosul` tablolarına yazılan, yıl anlamı olmayan alanlar // (ücret, burs, dil, öğretim türü, akreditasyon, kadro, baraj, ilçe, koşullar). // Sıra/puan/kontenjan gibi yıllık alanlar burada DEĞİL (bkz. db.ts). import { getDb } from "./db"; export type ProgramOzellik = { id: string; /** Vakıf/KKTC yıllık öğrenim ücreti (TL, KDV dahil, kılavuz yılı); devlette null */ ucret: number | null; /** "Burslu" | "%50 İndirimli" | "%25 İndirimli" | "Ücretli"; devlette null */ bursOrani: string | null; /** "Türkçe" | "İngilizce" | "İngilizce (%30)" | "Almanca" … */ ogrenimDili: string | null; /** "Örgün Öğretim" | "Uzaktan Öğretim" | "Açık Öğretim" | "UOLP" */ ogrenimTuru: string | null; /** Program akreditasyonu (MÜDEK, TEPDAD, FEDEK …) */ akreditasyon: string | null; /** Üniversite akreditasyonu (YÖKAK …) */ uniAkreditasyon: string | null; prof: number | null; doc: number | null; dou: number | null; argor: number | null; /** Tercih edebilmek için gereken en düşük başarı sırası (baraj) */ minBasariSirasi: number | null; /** Kampüs ilçesi (büyük harf, API'den) */ ilce: string | null; /** Yerleşme koşulu kodları (kosul tablosundan metne çevrilir) */ kosulKodlari: string[]; /** Kılavuz yılı */ yil: number; }; type HamSatir = { id: string; ucret: number | null; burs_orani: string | null; ogrenim_dili: string | null; ogrenim_turu: string | null; akreditasyon: string | null; uni_akreditasyon: string | null; prof: number | null; doc: number | null; dou: number | null; argor: number | null; min_basari_sirasi: number | null; ilce: string | null; kosul_kodlari: string | null; yil: number; }; const OZELLIK_COLS = `id, ucret, burs_orani, ogrenim_dili, ogrenim_turu, akreditasyon, uni_akreditasyon, prof, doc, dou, argor, min_basari_sirasi, ilce, kosul_kodlari, yil`; function satir(r: HamSatir): ProgramOzellik { return { id: r.id, ucret: r.ucret, bursOrani: r.burs_orani, ogrenimDili: r.ogrenim_dili, ogrenimTuru: r.ogrenim_turu, akreditasyon: r.akreditasyon, uniAkreditasyon: r.uni_akreditasyon, prof: r.prof, doc: r.doc, dou: r.dou, argor: r.argor, minBasariSirasi: r.min_basari_sirasi, ilce: r.ilce, kosulKodlari: r.kosul_kodlari ? r.kosul_kodlari.split(",") : [], yil: r.yil, }; } /** Tablo yoksa (eski DB) her okuma null/boş döner; sayfa kırılmaz. */ function tabloVar(): boolean { return ( getDb() .prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='program_ozellik'") .get() !== undefined ); } export function programOzellikGetir(id: string): ProgramOzellik | null { if (!tabloVar()) return null; const r = getDb() .prepare(`SELECT ${OZELLIK_COLS} FROM program_ozellik WHERE id = ?`) .get(id) as HamSatir | undefined; return r ? satir(r) : null; } export function programOzellikleriGetir( ids: readonly string[] ): Record { const sonuc: Record = {}; if (ids.length === 0 || !tabloVar()) return sonuc; const satirlar = getDb() .prepare( `SELECT ${OZELLIK_COLS} FROM program_ozellik WHERE id IN (${ids.map(() => "?").join(",")})` ) .all(...ids) as HamSatir[]; for (const r of satirlar) sonuc[r.id] = satir(r); return sonuc; } /** Koşul kodlarının kılavuz metinleri, kod sırasıyla. Bilinmeyen kod atlanır. */ export function kosulMetinleri(kodlar: readonly string[]): { kod: string; metin: string }[] { if (kodlar.length === 0 || !tabloVar()) return []; const satirlar = getDb() .prepare(`SELECT kod, metin FROM kosul WHERE kod IN (${kodlar.map(() => "?").join(",")})`) .all(...kodlar) as { kod: string; metin: string }[]; const harita = new Map(satirlar.map((s) => [s.kod, s.metin])); return kodlar.flatMap((k) => (harita.has(k) ? [{ kod: k, metin: harita.get(k)! }] : [])); } /** Kadro toplamı (prof + doç + dr. öğr. üyesi); hiçbiri yoksa null. */ export function ogretimUyesiToplami(o: ProgramOzellik): number | null { const parcalar = [o.prof, o.doc, o.dou].filter((x): x is number => x != null); return parcalar.length ? parcalar.reduce((a, b) => a + b, 0) : null; } /** Öğrenciye okunan kısa özet: "İngilizce · Burslu · MÜDEK akreditasyonlu". */ export function ozellikOzeti(o: ProgramOzellik): string[] { const parcalar: string[] = []; if (o.ogrenimDili && o.ogrenimDili !== "Türkçe") parcalar.push(o.ogrenimDili); if (o.ogrenimTuru && o.ogrenimTuru !== "Örgün Öğretim") parcalar.push(o.ogrenimTuru); if (o.bursOrani) parcalar.push(o.bursOrani); if (o.ucret != null && o.bursOrani !== "Burslu") { parcalar.push(`yıllık ${o.ucret.toLocaleString("tr-TR")} TL`); } if (o.akreditasyon) parcalar.push(`${o.akreditasyon} akreditasyonlu`); if (o.minBasariSirasi != null) { parcalar.push(`baraj ${o.minBasariSirasi.toLocaleString("tr-TR")}. sıra`); } return parcalar; }