feat(universite): "Tür" kartının yerine URAP Türkiye sırası
/universite/[slug] metrik ızgarasında takas: URAP listesinde olan üniversitede "Tür" kartının yerini "URAP TÜRKİYE · 18 / 198 · 2025-2026" alır, olmayan 31 kurumda "Tür" yerinde kalır. Kart sayısı 4'te kalıyor, lg ızgara şablonu değişmiyor, yeni bileşen yok, hiçbir sayfada "—" ya da delik yok. Payda kartın içinde: "18." tek başına yanıltır. Tablonun altına AYRI ikinci kaynak satırı eklendi; VeriKaynagi kullanılmadı ve kopyalanmadı, çünkü o satır YÖK Atlas'ın yerleştirme yılına ve son güncelleme tarihine bağlı — URAP'ın dönemi başka. Satırda metodoloji uyarısı da var: URAP akademik yayın ve araştırma performansını ölçer, eğitim kalitesini ya da iş bulma oranını ölçmez. URAP listesinde olmayan üniversitede eksiklik gizlenmiyor, nedeni tek cümleyle yazılıyor (KKTC/yurt dışı ile MYO/yeni için ayrı cümle). URAP'ın yayımlama izni "urapcenter.org adresine aktif bağlantı/atıf vermek" şartına bağlıdır. Kaynak satırındaki bağlantı bu yüzden gerçek bir <a href>: adres URAP_KAYNAK_URL sabitinden, target="_blank", rel="noopener", nofollow YOK. Sıranın göründüğü ekran ile atıfın göründüğü ekran aynı sayfadır; URAP sayısı yalnız ilk sayfada gösterildiği için kaynak satırı da yalnız ilk sayfada çiziliyor. Renk yok, rozet yok; URAP risk dili değildir. /universiteler hub'ında URAP'a göre sıralama/filtre eklenmedi. URAP 24'lük listeye, /sonuc tablosuna ve LLM prompt'una girmiyor — dokunulan dosya kümesi bunu zaten dışlıyor. veri-kalite.ts'e 5 URAP kontrolü (dosyanın en sonunda, tek satırlık çağrıyla): (1) her URAP slug'ı bir üniversite sayfasına bağlı — eşleşmeyen sessizce düşmüyor, adıyla listeleniyor; (2) kayıt sayısı = URAP_TOPLAM; (3) sıralar 1..N tekrarsız ve boşluksuz; (4) puanlar sıraya göre azalan; (5) kapsama boşluğu — URAP dışında kalan 150+ programlı bir Türkiye üniversitesi varsa UYARI (ad değişikliği işareti). Beşi de geçiyor, boşluk 31 kurum. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,10 @@ import {
|
|||||||
tabloVar,
|
tabloVar,
|
||||||
yilArgumani,
|
yilArgumani,
|
||||||
} from "./yokatlas-goc";
|
} from "./yokatlas-goc";
|
||||||
|
// URAP kontrolleri (dosya sonundaki urapKontrolleri) — salt okunur sabit.
|
||||||
|
import type { Db } from "./yokatlas-goc";
|
||||||
|
import { uniSayfaSlug } from "../src/lib/slug";
|
||||||
|
import { URAP_DONEM, URAP_SIRA, URAP_TOPLAM } from "../src/lib/urap-siralama";
|
||||||
|
|
||||||
const TURLER = ["SAYISAL", "EŞİT AĞIRLIK", "SÖZEL", "DİL", "TYT"];
|
const TURLER = ["SAYISAL", "EŞİT AĞIRLIK", "SÖZEL", "DİL", "TYT"];
|
||||||
|
|
||||||
@@ -291,9 +295,94 @@ async function main() {
|
|||||||
console.log(` şimdi, tüm satırlar (yeni dahil) : ${toplamlar(simdi)}`);
|
console.log(` şimdi, tüm satırlar (yeni dahil) : ${toplamlar(simdi)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
urapKontrolleri(db, zorunlu, bilgi);
|
||||||
|
|
||||||
db.close();
|
db.close();
|
||||||
console.log(`\nSonuç: ${basarisiz} ZORUNLU kontrol kaldı, ${uyari} uyarı.`);
|
console.log(`\nSonuç: ${basarisiz} ZORUNLU kontrol kaldı, ${uyari} uyarı.`);
|
||||||
if (basarisiz > 0) process.exit(1);
|
if (basarisiz > 0) process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.argv[1]?.endsWith("veri-kalite.ts")) calistir(main);
|
if (process.argv[1]?.endsWith("veri-kalite.ts")) calistir(main);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URAP Türkiye sıralaması sabiti (`src/lib/urap-siralama.ts`) denetimi.
|
||||||
|
* Amaç: yıllık tazelemede eşleşmeyen bir URAP satırı SESSİZCE DÜŞMESİN —
|
||||||
|
* düşerse üniversitenin adı değişmiş demektir ve o sayfada sıra kaybolur.
|
||||||
|
* DB'ye yazmaz; sabit ile DB'deki üniversite slug'larını karşılaştırır.
|
||||||
|
*/
|
||||||
|
function urapKontrolleri(
|
||||||
|
db: Db,
|
||||||
|
zorunlu: (ad: string, tamam: boolean, detay: string) => void,
|
||||||
|
bilgi: (ad: string, sorunlu: boolean, detay: string) => void
|
||||||
|
) {
|
||||||
|
const kayitlar = Object.entries(URAP_SIRA);
|
||||||
|
|
||||||
|
// (1) Sabitteki her slug DB'de karşılık bulmalı — bulamayan = ad değişikliği.
|
||||||
|
const dbToplam = new Map<string, { unitur: string | null; program: number }>();
|
||||||
|
const satirlar = db
|
||||||
|
.prepare("SELECT universite, unitur, COUNT(*) AS n FROM programs GROUP BY 1, 2")
|
||||||
|
.all() as { universite: string; unitur: string | null; n: number }[];
|
||||||
|
for (const r of satirlar) {
|
||||||
|
const slug = uniSayfaSlug(r.universite);
|
||||||
|
if (!slug) continue;
|
||||||
|
const kayit = dbToplam.get(slug) ?? { unitur: null, program: 0 };
|
||||||
|
kayit.program += r.n;
|
||||||
|
if (!kayit.unitur && r.unitur) kayit.unitur = r.unitur;
|
||||||
|
dbToplam.set(slug, kayit);
|
||||||
|
}
|
||||||
|
const karsiliksiz = kayitlar.filter(([slug]) => !dbToplam.has(slug));
|
||||||
|
zorunlu(
|
||||||
|
"URAP: her sıra bir üniversite sayfasına bağlı",
|
||||||
|
karsiliksiz.length === 0,
|
||||||
|
karsiliksiz.length === 0
|
||||||
|
? `${kayitlar.length} slug'ın tamamı DB'de var`
|
||||||
|
: `DB'de karşılığı olmayan (ad değişmiş olabilir): ${karsiliksiz.map(([slug, v]) => `${slug}(#${v.sira})`).join(", ")}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// (2) Kayıt sayısı payda ile aynı olmalı — payda kartta gösteriliyor.
|
||||||
|
zorunlu(
|
||||||
|
"URAP: kayıt sayısı = URAP_TOPLAM",
|
||||||
|
kayitlar.length === URAP_TOPLAM,
|
||||||
|
`kayıt ${kayitlar.length}, URAP_TOPLAM ${URAP_TOPLAM} (dönem ${URAP_DONEM})`
|
||||||
|
);
|
||||||
|
|
||||||
|
// (3) Sıralar 1..URAP_TOPLAM; tekrarsız ve boşluksuz.
|
||||||
|
const siralar = kayitlar.map(([, v]) => v.sira).sort((a, b) => a - b);
|
||||||
|
const bozukSira = siralar.findIndex((s, i) => s !== i + 1);
|
||||||
|
zorunlu(
|
||||||
|
"URAP: sıralar 1..N tekrarsız ve boşluksuz",
|
||||||
|
bozukSira === -1 && siralar.length === URAP_TOPLAM,
|
||||||
|
bozukSira === -1
|
||||||
|
? `1..${siralar.length} kesintisiz`
|
||||||
|
: `${bozukSira + 1}. sırada beklenen ${bozukSira + 1}, gelen ${siralar[bozukSira]}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// (4) Puan sıraya göre azalmalı — sıra 1 en yüksek puan.
|
||||||
|
const sirali = [...kayitlar].sort((a, b) => a[1].sira - b[1].sira);
|
||||||
|
const bozukPuan = sirali.findIndex(
|
||||||
|
(k, i) => i > 0 && sirali[i - 1][1].puan < k[1].puan
|
||||||
|
);
|
||||||
|
zorunlu(
|
||||||
|
"URAP: puanlar sıraya göre azalan",
|
||||||
|
bozukPuan === -1,
|
||||||
|
bozukPuan === -1
|
||||||
|
? `${sirali[0][1].puan} → ${sirali[sirali.length - 1][1].puan}`
|
||||||
|
: `#${sirali[bozukPuan][1].sira} (${sirali[bozukPuan][0]}) puanı bir önceki sıradan yüksek`
|
||||||
|
);
|
||||||
|
|
||||||
|
// (5) Kapsama boşluğu: URAP yalnız Türkiye'yi sıralar, KKTC/yurt dışı ve
|
||||||
|
// yalnız MYO'su olan kurumlar listede olmaz — bu normaldir. Ama büyük bir
|
||||||
|
// Türkiye üniversitesinin düşmesi neredeyse her zaman ad değişikliğidir.
|
||||||
|
const disarida = [...dbToplam.entries()].filter(([slug]) => !(slug in URAP_SIRA));
|
||||||
|
const turkiyeBuyuk = disarida.filter(
|
||||||
|
([, v]) =>
|
||||||
|
(v.unitur === "DEVLET" || v.unitur === "VAKIF") && v.program >= 150
|
||||||
|
);
|
||||||
|
bilgi(
|
||||||
|
"URAP: kapsama boşluğu",
|
||||||
|
turkiyeBuyuk.length > 0,
|
||||||
|
turkiyeBuyuk.length === 0
|
||||||
|
? `URAP dışında ${disarida.length} kurum (KKTC/yurt dışı, MYO ve yeni üniversiteler); 150+ programlı Türkiye üniversitesi yok`
|
||||||
|
: `URAP dışında kalan 150+ programlı Türkiye üniversitesi (ad değişmiş olabilir): ${turkiyeBuyuk.map(([slug, v]) => `${slug}(${v.program})`).join(", ")}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ import { UniversiteKonumHaritasi } from "./universite-konum-haritasi";
|
|||||||
import { uniUlkeKonum } from "@/lib/harita-ulkeler";
|
import { uniUlkeKonum } from "@/lib/harita-ulkeler";
|
||||||
import { UniversiteProgramTablosu } from "./universite-program-tablosu";
|
import { UniversiteProgramTablosu } from "./universite-program-tablosu";
|
||||||
import { VeriKaynagi } from "./veri-kaynagi";
|
import { VeriKaynagi } from "./veri-kaynagi";
|
||||||
|
import {
|
||||||
|
URAP_DONEM,
|
||||||
|
URAP_KAYNAK_URL,
|
||||||
|
URAP_TOPLAM,
|
||||||
|
} from "@/lib/urap-siralama";
|
||||||
import { UniLogo } from "@/components/uni-logo";
|
import { UniLogo } from "@/components/uni-logo";
|
||||||
import { uniLogoYolu } from "@/lib/uni-logolar";
|
import { uniLogoYolu } from "@/lib/uni-logolar";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
@@ -109,6 +114,48 @@ function fakulteOzeti({
|
|||||||
return `${adlar[0]}, ${adlar[1]} ve ${adlar.length - 2} birim daha`;
|
return `${adlar[0]}, ${adlar[1]} ve ${adlar.length - 2} birim daha`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tablonun altındaki AYRI ikinci kaynak satırı. `VeriKaynagi` kullanılmaz ve
|
||||||
|
* kopyalanmaz: o satır YÖK Atlas'ın yerleştirme yılına ve son güncelleme
|
||||||
|
* tarihine bağlı, URAP'ın dönemi başka — aynı satırda birleşirlerse URAP
|
||||||
|
* verisi YÖK Atlas tarihiyle sunulmuş olur.
|
||||||
|
*
|
||||||
|
* Atıf pazarlık dışı: URAP'ın izni "urapcenter.org adresine aktif bağlantı"
|
||||||
|
* şartına bağlı, o yüzden gerçek <a href>, yeni sekme, rel="noopener" ve
|
||||||
|
* nofollow YOK. Sıra payda ("198 üniversite arasında") ve dönem olmadan
|
||||||
|
* gösterilmez. URAP listesinde olmayan üniversitede sayı yoktur; eksiklik
|
||||||
|
* gizlenmez, nedeni tek cümleyle yazılır.
|
||||||
|
*/
|
||||||
|
function UrapKaynakSatiri({ uni }: { uni: UniDetay }) {
|
||||||
|
if (!uni.urap) {
|
||||||
|
const yurtDisi =
|
||||||
|
uni.unitur === "KKTC" || uni.unitur?.startsWith("YURTDISI");
|
||||||
|
return (
|
||||||
|
<p className="mt-2 text-xs leading-5 text-slate-500">
|
||||||
|
{yurtDisi
|
||||||
|
? "Bu üniversite URAP Türkiye sıralamasında yer almıyor — URAP yalnız Türkiye'deki üniversiteleri sıralıyor."
|
||||||
|
: `Bu üniversite URAP Türkiye Sıralaması ${URAP_DONEM} listesinde yer almıyor.`}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<p className="mt-2 text-xs leading-5 text-slate-500">
|
||||||
|
URAP Türkiye Sıralaması {URAP_DONEM} ({sayi(URAP_TOPLAM)} üniversite
|
||||||
|
arasında) — akademik yayın ve araştırma performansını ölçer; eğitim
|
||||||
|
kalitesini ya da iş bulma oranını ölçmez. Kaynak:{" "}
|
||||||
|
<a
|
||||||
|
href={URAP_KAYNAK_URL}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
className="font-medium text-primary hover:underline"
|
||||||
|
>
|
||||||
|
urapcenter.org
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function uniSayfaMetadata(slug: string, sayfa: number): Metadata {
|
export function uniSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||||
const uni = getUniversiteBySlug(slug);
|
const uni = getUniversiteBySlug(slug);
|
||||||
if (!uni) return {};
|
if (!uni) return {};
|
||||||
@@ -308,17 +355,37 @@ export function UniversiteIcerik({
|
|||||||
{sayi(uni.fakulteSayisi)}
|
{sayi(uni.fakulteSayisi)}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
{/* URAP'ta olan üniversitede "Tür" kartının yeri URAP'a
|
||||||
|
bırakılır (kart sayısı 4'te kalır, ızgara şablonu değişmez);
|
||||||
|
olmayanda "Tür" yerinde durur — hiçbir sayfada boş kutu yok.
|
||||||
|
Payda kartın içindedir: "18." tek başına yanıltır. */}
|
||||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
{uni.urap ? (
|
||||||
Tür
|
<>
|
||||||
</dt>
|
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
URAP Türkiye
|
||||||
{uni.unitur === "DEVLET"
|
</dt>
|
||||||
? "Devlet"
|
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||||
: uni.unitur
|
{sayi(uni.urap.sira)} / {sayi(URAP_TOPLAM)}
|
||||||
? trBaslikDuzeni(uni.unitur)
|
<span className="mt-0.5 block font-sans text-xs font-medium text-slate-500">
|
||||||
: "—"}
|
{URAP_DONEM}
|
||||||
</dd>
|
</span>
|
||||||
|
</dd>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||||
|
Tür
|
||||||
|
</dt>
|
||||||
|
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||||
|
{uni.unitur === "DEVLET"
|
||||||
|
? "Devlet"
|
||||||
|
: uni.unitur
|
||||||
|
? trBaslikDuzeni(uni.unitur)
|
||||||
|
: "—"}
|
||||||
|
</dd>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||||
@@ -371,6 +438,8 @@ export function UniversiteIcerik({
|
|||||||
veya o yıl yerleşen çıkmayan program).{" "}
|
veya o yıl yerleşen çıkmayan program).{" "}
|
||||||
</VeriKaynagi>
|
</VeriKaynagi>
|
||||||
|
|
||||||
|
{ilkSayfa ? <UrapKaynakSatiri uni={uni} /> : null}
|
||||||
|
|
||||||
<Sayfalama
|
<Sayfalama
|
||||||
tabanYol={`/universite/${slug}`}
|
tabanYol={`/universite/${slug}`}
|
||||||
sayfa={sayfa}
|
sayfa={sayfa}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type { Program } from "@/types/yokatlas";
|
|||||||
import { kategoriBul, type Kategori } from "./kategoriler";
|
import { kategoriBul, type Kategori } from "./kategoriler";
|
||||||
import { uniAdiNormalize } from "./harita";
|
import { uniAdiNormalize } from "./harita";
|
||||||
import { bolumBazAdi, turkishSlugify, trBaslikDuzeni } from "./slug";
|
import { bolumBazAdi, turkishSlugify, trBaslikDuzeni } from "./slug";
|
||||||
|
import { urapSirasiBul, type UrapSira } from "./urap-siralama";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Programatik SEO sayfalarının veri katmanı (/bolum, /universite, hub'lar).
|
* Programatik SEO sayfalarının veri katmanı (/bolum, /universite, hub'lar).
|
||||||
@@ -224,6 +225,11 @@ export type UniOzet = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type UniDetay = UniOzet & {
|
export type UniDetay = UniOzet & {
|
||||||
|
/**
|
||||||
|
* URAP Türkiye genel sıralaması; listede olmayan üniversitede null.
|
||||||
|
* Gösterildiği her yüzeyde URAP_KAYNAK_URL'ye aktif atıf zorunludur.
|
||||||
|
*/
|
||||||
|
urap: UrapSira | null;
|
||||||
fakulteler: { fakulte: string; programlar: Program[] }[];
|
fakulteler: { fakulte: string; programlar: Program[] }[];
|
||||||
stats: {
|
stats: {
|
||||||
minSira: number | null;
|
minSira: number | null;
|
||||||
@@ -393,6 +399,7 @@ export function getUniversiteBySlug(slug: string): UniDetay | null {
|
|||||||
const ozet = getAllUniversiteler().find((u) => u.slug === slug)!;
|
const ozet = getAllUniversiteler().find((u) => u.slug === slug)!;
|
||||||
return {
|
return {
|
||||||
...ozet,
|
...ozet,
|
||||||
|
urap: urapSirasiBul(slug),
|
||||||
fakulteler: [...gruplar.entries()]
|
fakulteler: [...gruplar.entries()]
|
||||||
.map(([fakulte, programlar]) => ({ fakulte, programlar }))
|
.map(([fakulte, programlar]) => ({ fakulte, programlar }))
|
||||||
.sort((a, b) => a.fakulte.localeCompare(b.fakulte, "tr-TR")),
|
.sort((a, b) => a.fakulte.localeCompare(b.fakulte, "tr-TR")),
|
||||||
|
|||||||
Reference in New Issue
Block a user