merge: veri/2026 — P-0 yıl sözleşmesi + P-A veri betikleri

This commit is contained in:
bilalgursen
2026-09-21 17:04:12 +03:00
11 changed files with 2054 additions and 279 deletions

View File

@@ -0,0 +1,230 @@
# 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)
```bash
git switch -c veri/2027 # main'de çalışma
```
`src/lib/veri-yillari.ts` dosyasında **tek satırı** değiştir:
```ts
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:
```bash
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)
```bash
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.
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)
```bash
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)
```bash
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):
```bash
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.
## 6. İndeks + dosyayı toparla (1 dk)
```bash
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)
```bash
pnpm veri-kalite --yil 2027 --db /tmp/veri-2027/yeni.db --onceki /tmp/veri-2027/once.db --arsivli
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 iki satır:
- `ö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:
```bash
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)
```bash
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:
```bash
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:
```bash
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
```bash
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 |
| `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 |
| `scripts/gecmis-doldur.ts` | evet | Yalnız **NULL** geçmiş yıl alanları + `eski_kod` |
| `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 = ?`.