Files
kolaytercih/docs/veri/yillik-guncelleme.md
bilalgursen 507bf53a95
All checks were successful
Deploy / deploy (push) Successful in 6m50s
feat(seo): kapanan 28 bölüm + 2 üniversite sayfası benzer sayfaya kalıcı yönlendirilir
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>
2026-09-21 23:34:52 +03:00

15 KiB
Raw Permalink Blame History

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 yil alanı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-onar ekleyerek, 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şi programs_arsiv'e <kod>~<yıl> id'siyle kopyalanır, eski yılların netleri oraya taşınır. Çıktıdaki KİMLİĞİ ONARILAN tablosunu 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: /bolumler ya da /universiteler. Uydurma eşleme yapma; gerekce alanına kanıtı yaz.
  • Hedef slug programs tablosundan türemeli ve kendisi listede kaynak olmamalı (zincir). Zinciri dosyadaki kapananYonlendirmeleri() 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 kaynak adlarını /bolumler ve /universiteler sayfası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, UYARI ya da bilgi ile başlar. Tek bir KALDI varsa 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: 0
    • sira2027/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 = ?.