Arşivlenen slug'lar 200 + 'sayfa yok' dönüyordu (soft 404). Eşlemenin tek kaynağı src/lib/kapanan-sluglar.ts; alt yollar (/sayfa/N) hedefin köküne gider; zincir ya da çift kaynak build'i durdurur. Yıllık güncelleme kılavuzuna 5b adımı eklendi. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
15 KiB
Yıllık veri güncellemesi (YÖK Atlas → data/yokatlas.db)
Her yıl yerleştirme sonuçları açıklandıktan sonra bir kez yapılır. Bu sayfayı yukarıdan aşağıya izleyen biri, betiklerin içini bilmeden güncellemeyi tamamlayabilir. Toplam süre: yaklaşık 30 dakika (çoğu bekleme ve gözle kontrol).
Ürünün bütün değeri bu verinin doğruluğuna dayanır. Yanlış bir taban sıralaması, bir öğrencinin yanlış tercih yapması demektir. Bu yüzden betikler şüphede durur; "DURDU:" ile başlayan bir mesaj hata değil, emniyet kilididir. Kilidi aşmaya çalışma — mesajı oku, aşağıdaki "Bir şey durursa" tablosuna bak.
Örneklerde yeni yıl 2027 diye yazıldı; o yıl hangisiyse onu yaz.
0. Ne zaman?
- ÖSYM yerleştirme sonuçlarını açıklar (genelde Ağustos sonu), YÖK Atlas verisini birkaç gün–birkaç hafta sonra günceller. Tarih her yıl değişir → doğrulanmalı.
- Erken koşmanın zararı yok: YÖK Atlas henüz güncellenmediyse 3. adım
"
… hâlâ 2026 verisi" diyerek hiçbir şey yazmadan durur. Bir hafta sonra tekrar dene. - Dosya indirmen gerekmez. Veri, YÖK Atlas'ın herkese açık tercih kılavuzu
servisinden (
https://yokatlas.yok.gov.tr/api/tercih-kilavuz/search) betikle çekilir: 43 istek, aralarında yarım saniye — kaynağı yormaz. Betiği art arda defalarca koşma; ilk çekimden sonra hep kaydedilmiş ham dosyayı (--ham) kullan.
1. Hazırlık (5 dk)
git switch -c veri/2027 # main'de çalışma
src/lib/veri-yillari.ts dosyasında tek satırı değiştir:
export const SON_YIL = 2027;
Betikler ve site yılı yalnız buradan okur. Betiğe verdiğin --yil bununla aynı
değilse betik durur (yanlış kolona yazmayı önler).
2. Kopya al — asıl dosyaya dokunma (1 dk)
Dev sunucusu açıksa kapat. Sonra:
mkdir -p /tmp/veri-2027
sqlite3 data/yokatlas.db ".backup '/tmp/veri-2027/once.db'" # güncelleme ÖNCESİ hâl (geri dönüş + karşılaştırma)
cp /tmp/veri-2027/once.db /tmp/veri-2027/yeni.db # üzerinde çalışılacak kopya
Bundan sonraki her adım /tmp/veri-2027/yeni.db üzerinde koşar. data/yokatlas.db
ancak 8. adımda, her şey yeşilken değişir.
3. Yeni yılı çek (3 dk)
pnpm refresh --yil 2027 --db /tmp/veri-2027/yeni.db
Ne yapar: şemaya sira2027/puan2027/kontenjan2027/yerlesen2027 kolonlarını ekler,
yıl kilidini sınar, tüm kılavuzu çeker, ham hâlini data/ham/2027-<tarih>.jsonl.gz
olarak saklar (git'e girmez), sonra tek seferde DB'ye yazar.
Görmen gerekenler:
Yıl kilidi: basariSirasi1 = sira2026 → 480/480 (%100.0); eksiz basariSirasi = sira2026 → 0/480 (%0.0)
Çekilen: 21… kayıt, benzersiz kod: 21…, kodsuz: 0, API toplamı: 21… ← üç sayı aynı
Güncellenen: 19…, eklenen: 1…, atlanan: 0
-
Yıl kilidi şunu kanıtlar: servisin "bir önceki yıl" diye verdiği sıralar bizim 2026 kolonumuzla birebir aynı ve "bu yıl" diye verdikleri ondan farklı. Yani yazacağımız veri gerçekten 2027'dir. (Servisteki
yilalanına güvenilmez; 2026'da bu alan yüzünden 2025 verisi bozulmak üzereydi.) -
"atlanan" 0 değilse satırlar altında listelenir: kaynağın puan türü vermediği yeni programlardır; uydurulmaz. Sayıyı not et.
-
Bu betik mevcut programların eski yıl kolonlarına dokunmaz; dokunursa kendi sağlaması bunu yakalar ve her şeyi geri alır.
-
Kimlik kilidi. ÖSYM bazen bir kılavuz kodunu BAŞKA programa verir (2025'te
209210292"Diş Hekimliği"nden "İlk ve Acil Yardım" önlisansına geçti). Betik her mevcut satırın puan türü / önlisans / bölüm adını servistekiyle kıyaslar; uyuşmayan varsa listeyi basıp hiçbir şey yazmadan durur (KİMLİĞİ KAYMIŞ N satır). Listeye göz at (yılda birkaç–birkaç on satır beklenir; yüzlerce ise servis biçim değiştirmiştir, veri mühendisine göster), sonra aynı komutu--kimlik-onarekleyerek, ham dosyadan tekrarla:pnpm refresh --yil 2027 --db <db> --ham data/ham/2027-<tarih>.jsonl.gz --kimlik-onar. Onarım: ad/tür/önlisans/fakülte/süre servisten yazılır; devirden önceki yılların tüm değerleri o satırda boşaltılır (başka programa aitti), eski kimlik + geçmişiprograms_arsiv'e<kod>~<yıl>id'siyle kopyalanır, eski yılların netleri oraya taşınır. ÇıktıdakiKİMLİĞİ ONARILANtablosunu commit mesajına/rapora koy. "AD DEĞİŞİMİ" yazan satırlarda yalnız ad güncellenir, geçmiş korunur.
Aynı işlemi servise gitmeden tekrarlamak için (ör. 8. adımda):
pnpm refresh --yil 2027 --db <db> --ham data/ham/2027-<tarih>.jsonl.gz
4. Geçmiş boşluklarını doldur (1 dk)
pnpm gecmis-doldur --yil 2027 --db /tmp/veri-2027/yeni.db
Kılavuz kodu değişen ya da yeni koda taşınan programların eski yıllarını tamamlar. Yalnız boş alanı doldurur; dolu değeri asla ezmez, tahmin yapmaz. Kaynak sırası: servisin kendi geçmiş alanları → servisin bildirdiği eski kod → aynı üniversitede bire bir aynı adlı ve en az bir yılı kanıtla örtüşen tek satır.
Çıktının sonundaki "Dolu olup kaynağın FARKLI söylediği alanlar" listesine bak.
Birkaç onluk fark olağandır (kaynak eski sıraları ufak düzeltmelerle yeniden yayımlıyor;
2026'da sira2024 farklarının %95'i on binde birin altındaydı). Binlerce satırda büyük
fark görürsen dur ve veri mühendisine sor.
5. Kılavuzdan çıkan programlar: önce sadece raporla (1 dk)
pnpm eski-arsivle --yil 2027 --db /tmp/veri-2027/yeni.db --kuru
Hiçbir şey yazmaz. Şunu söyler: bu yılın kılavuzunda olmayan kaç satır var ve
bunlar siteden kalkarsa hangi /bolum/... ve /universite/... sayfaları tamamen
kapanır (adlarıyla). Bu liste [BİLAL] kararıdır — sayfa kapanışı SEO'yu etkiler,
gerekirse yönlendirme (redirect) eklenir.
Onaydan sonra gerçek taşıma (silmez; satırlar programs_arsiv tablosuna geçer):
pnpm eski-arsivle --yil 2027 --db /tmp/veri-2027/yeni.db
Neden gerekli: arşivlenmezse eski kodlu satırlar listelerde bir yıl önceki sırayla görünmeye devam eder; öğrenci o kodu tercih ekranında bulamaz, kodu değişen program iki kez listelenir.
5b. Kapanan sayfaları yönlendir (5–15 dk)
--kuru raporundaki KAPANACAK /bolum/<slug> ve KAPANACAK /universite/<slug>
listelerindeki her adres (ve --kimlik-onar sonrası kapanan sayfa olduysa onlar da)
src/lib/kapanan-sluglar.ts içindeki KAPANAN_SLUGLAR listesine eklenir; site bu
adresleri yaşayan en yakın sayfaya kalıcı (308) yönlendirir (next.config.ts →
redirects(), /sayfa/N alt yolları dahil). Eklemezsen kapanan adres Google'da
"sayfa yok" gövdesiyle kalır.
- Hedef sırası: (1) program/kurum ad değiştirdiyse yeni adı — kanıt: aynı
üniversitede geçmiş yıl sıraları yeni adlı satıra birebir taşınmış, ya da Resmî
Gazete kararı; (2) aynı alanın lisans/önlisans karşılığı; (3) emin değilsen hub:
/bolumlerya da/universiteler. Uydurma eşleme yapma;gerekcealanına kanıtı yaz. - Hedef slug
programstablosundan türemeli ve kendisi listede kaynak olmamalı (zincir). Zinciri dosyadakikapananYonlendirmeleri()build'de yakalar; hedefin yaşadığını sen kontrol et: 8. adımda hedef adresi tarayıcıda aç. - Bu yıl yeniden açılan bir sayfa listede kaynak olarak duruyorsa kaydını sil —
yönlendirme sayfadan önce çalışır, silmezsen yeni sayfa hiç görünmez. Kontrol:
8. adımda listedeki
kaynakadlarını/bolumlerve/universitelersayfasında ara; çıkan varsa kaydını sil. - Hedef seçimi SEO'yu etkilediği için [BİLAL] kararıdır; listeyi commit'ten önce göster.
6. İndeks + dosyayı toparla (1 dk)
pnpm db:index --db /tmp/veri-2027/yeni.db --vacuum
Son satırda USING INDEX idx_programs_tur_onlisans_efektif yazmalı. Yazmıyorsa betik
zaten hata verir: sitedeki sıralama aralığı sorguları yavaşlar.
7. Kalite kapısı (1 dk)
pnpm veri-kalite --yil 2027 --db /tmp/veri-2027/yeni.db --onceki /tmp/veri-2027/once.db --arsivli --ham data/ham/2027-<tarih>.jsonl.gz
echo "çıkış kodu: $?" # 0 olmalı
(--arsivli'yi yalnız 5. adımda gerçek arşivlemeyi yaptıysan ekle.)
- Her satır
GEÇTİ,KALDI,UYARIya dabilgiile başlar. Tek birKALDIvarsa yayına çıkılmaz; çıkış kodu 1 olur. - En önemli üç satır:
kimlik (tur/önlisans/baz ad = API) — … uyumsuz: 0— her kod hâlâ aynı programı gösteriyor (uyumsuzsa satır eski adıyla başka programın sırasını gösterir).önceki DB: geçmiş yıllar korunmuş — … değişen/silinen satır: 0sira2027/sira2026 ∈ [0,5; 2] — … (%9x)— programların büyük çoğunluğunun sırası bir yılda yarıya inmez, iki katına çıkmaz. Oran düşükse yıllar kaymıştır.
UYARI'lar bilgilendirir (ör. ili boş 110 program, yetim net satırları); yeni bir uyarı türü ya da sayıda sıçrama varsa veri mühendisine göster.
Elle 3 program seç (biri çok bilinen: ör. Boğaziçi Bilgisayar Mühendisliği), YÖK Atlas sitesindeki 2027 taban sırasıyla karşılaştır:
sqlite3 /tmp/veri-2027/yeni.db "SELECT id, universite, isim, sira2026, sira2027, puan2027 FROM programs WHERE isim LIKE 'Bilgisayar Mühendisliği%' AND universite LIKE 'BOĞAZİÇİ%';"
8. Yerine koy ve siteyi kontrol et (5 dk)
cp /tmp/veri-2027/yeni.db data/yokatlas.db
rm -f data/yokatlas.db-wal data/yokatlas.db-shm # eski dosyanın artıkları; yenisi temiz (checkpoint yapılmış)
pnpm build # katalog sayfaları yeni veriden üretilir; hata vermemeli
Netler (yerleşen son kişinin netleri) ayrı bir servisten gelir ve genelde daha geç güncellenir; hazır olduğunda:
pnpm detay --yil 2027 --db data/yokatlas.db # ~127 istek, ~2 dk; yıl sağlaması tutmazsa durur
--kirilim bayrağını kullanma: kontenjan kırılımını (okul birincisi, şehit-gazi…)
sitede okuyan kod yok ve servis bu alanları Eylül 2026'dan beri yayımlamıyor. Bayrak
verilse bile alanlar yoksa adım kendini durdurur, mevcut değerlerin üstüne boş yazmaz.
Yıl değişince koddaki metinler ("son 6 yıl", başlıklardaki yıl vb.) veri-yillari.ts
sabitlerinden türediği için kendiliğinden güncellenir. Elle yıl yazılmış yer kaldıysa bul:
grep -rnE "sira20[0-9]{2}|20(2[1-9])[–-]20" src scripts --include='*.ts' --include='*.tsx' | grep -v veri-yillari
Tadımlık havuzu ve kayıtlı raporlar eski sıralarla üretilmiştir → yayından sonra prod'da
pnpm tadimlik --force (Bilal koşar; ayrıntı scripts/tadimlik-uret.ts başlığında).
9. Commit ve yayın
git add src/lib/veri-yillari.ts data/yokatlas.db
git commit -m "veri: 2027 yerleştirme verisi"
data/ham/ git'e girmez (yerelde sakla; bir sonraki yıl karşılaştırma için işe yarar).
Push öncesi AGENTS.md'deki "Push öncesi build zorunlu" kuralı geçerli. Yayın kararı Bilal'in.
Geri alma
| Ne zaman | Nasıl | Süre |
|---|---|---|
| 8. adımdan önce | Hiçbir şey yapma; data/yokatlas.db hiç değişmedi. /tmp/veri-2027/ silinebilir. |
0 |
| 8. adımdan sonra, commit'ten önce | git checkout -- data/yokatlas.db data/yokatlas.db-wal data/yokatlas.db-shm |
1 dk |
| Commit/yayından sonra | git revert <commit> + yeniden yayın. SON_YIL da aynı commit'te geri döner; site bir önceki yılın verisiyle tutarlı çalışır. |
10 dk |
| Yalnız arşivlemeyi geri almak | INSERT INTO programs SELECT * FROM programs_arsiv; DELETE FROM programs_arsiv; (kopyada dene, sonra pnpm db:index). Netler yeni kodda kalır; zararsız. |
5 dk |
/tmp/veri-2027/once.db dosyasını yayından bir hafta sonrasına kadar silme.
Bir şey durursa
| Mesaj | Anlamı | Ne yap |
|---|---|---|
--yil … ≠ SON_YIL |
1. adım atlanmış | veri-yillari.ts'i güncelle |
eksiz alanları hâlâ <geçen yıl> verisi |
YÖK Atlas henüz yeni yılı yayımlamamış | Bekle, bir hafta sonra tekrar dene |
"…1" alanları DB'deki … verisiyle eşleşmiyor |
Servis bir yıl daha ilerlemiş (bir yılı atladık) ya da servis biçim değiştirmiş ya da yanlış DB | Yazma. Veri mühendisine göster |
Benzersiz kod sayısı … ≠ API toplamı |
Çekim sırasında servis sayfaları kaydırdı | Birkaç dakika sonra 3. adımı tekrarla (DB'ye bir şey yazılmadı) |
Aynı üniversitede birden fazla unitur |
Bir kurumun türü iki farklı yazılmış | Listelenen kurumları veri mühendisine göster; scripts/unitur-onar.ts |
Güncel satır sayısı … refresh kaydıyla uyuşmuyor (arşivle) |
refresh yarım kalmış | 3. adımı tekrarla; arşivleme bilerek çalışmıyor |
N satırın kimliği API ile uyuşmuyor (refresh) |
Kılavuz kodu başka programa devredilmiş (ya da program ad değiştirmiş) | Listeye bak; 3. adımdaki gibi --ham … --kimlik-onar ile tekrarla (DB'ye bir şey yazılmadı) |
veri-kalite içinde KALDI |
O kontrol tutmadı | Yayına çıkma; satırdaki sayıyı ve örnek kodları veri mühendisine ilet |
Betikler ve dokundukları
| Betik | Yazar mı? | Ne yazar |
|---|---|---|
scripts/yokatlas-goc.ts (pnpm yokatlas:goc) |
evet | Yalnız şema: yıl kolonları, son_kilavuz_yili, eski_kod, programs_arsiv, veri_meta. refresh bunu kendisi çağırır. |
scripts/refresh.ts |
evet | sira/puan/kontenjan/yerlesen<yıl>, son_kilavuz_yili, eski_kod; yeni programlar; ham dosya. --kimlik-onar ile: kimliği kaymış satırın ad/tür/önlisans/fakülte/süresi, devir öncesi yıl kolonları (NULL), programs_arsiv kopyası, netler.program_id, veri_meta kimlik_onar:<kod> |
scripts/gecmis-doldur.ts |
evet | Yalnız NULL geçmiş yıl alanları + eski_kod; kimliği onarılmış satırda devir öncesi yılları doldurmaz |
scripts/eski-arsivle.ts |
--kuru ile hayır |
Satır taşıma programs → programs_arsiv; netler.program_id yeni koda |
scripts/db-index.ts |
evet | İndeks, --vacuum, WAL checkpoint |
scripts/veri-kalite.ts |
hayır | Salt okunur; çıkış kodu 0/1 |
scripts/detay.ts |
evet | netler; --kirilim ile (alanlar varsa) bir önceki yılın kırılım kolonları |
Kolon sözlüğü: son_kilavuz_yili = programın görüldüğü son tercih kılavuzu (NULL = 2024
ve öncesi, bilinmiyor). eski_kod = kılavuz kodu değiştiyse bir önceki kod — kayıtlı
listelerdeki eski kodları yeni koda çevirmek için SELECT id FROM programs WHERE eski_kod = ?.