Files
kolaytercih/src/lib/program-ozellik.ts
bilalgursen c23910cc79 feat(veri): program_ozellik tablosu — YÖK Atlas API'den ücret, burs, dil, öğretim türü, akreditasyon, kadro, baraj, ilçe, koşullar
scripts/program-ozellik.ts (pnpm ozellik --yil --db [--ham]) API'nin
kılavuz alanlarını program_ozellik ve kosul tablolarına yazar; 25 Eyl
2026 çekimi: 21.493 program, 194 koşul metni. src/lib/program-ozellik.ts
okuyucu + öğrenciye okunan kısa özet. Tablo yoksa okuma boş döner.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-25 01:02:39 +03:00

138 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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<string, ProgramOzellik> {
const sonuc: Record<string, ProgramOzellik> = {};
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;
}