Dün Aşama D yalnız `programs`'a uygulanmıştı; `programs_arsiv`'de aynı yanlış
etiket duruyordu (31 ULUSLARARASI BALKAN + 30 ULUSLARARASI SARAYBOSNA
`unitur='DEVLET'`, Balkan'ın 24 satırında il Saraybosna). Kapanan programlar
arşive `programs`'tan olduğu gibi taşındığı için etiket oraya da yazılmış.
- `unitur-onar.ts` Aşama D iki tabloyu da tarar (`programs_arsiv` varsa).
Dokunulan kolon yalnız `unitur` ve `il`; A/B/C aşamaları `programs`'ta kalır.
- `veri-kalite.ts` kontrol 13 ve 14 arşivi de tarar. Genişletme olmadan iki
tablo ayrışabilir ve denetim bunu görmez.
- Yanlış etiket duran DB'de iki kontrol de KALDI veriyor (çıkış kodu 1):
`baz ad başına tek unitur — … BALKAN/YURTDISI KAMU,DEVLET/81 ; … SARAYBOSNA/68`
`DEVLET etiketi Türkiye ili ile destekli — … /SARAYBOSNA - BOSNA - HERSEK/31 ; /30`
Kullanıcıya bugün yansımıyor: `src/` tarafında `programs_arsiv`'i okuyan SQL
yok. Düzeltme tablo ileride okunduğunda sızıntının geri gelmemesi içindir.
Dünkü veri commit'inin (1df86cf) gövdesindeki rakam düzeltmesi: "/universiteler
hub'ında Devlet listesi 170 → 166" YANLIŞTIR. 170/166 ham `programs.universite`
ad sayısıdır, hub satırı değil; `uniAdiNormalize` parantezli eki attığı için
Kıbrıs Amerikan'ın iki yazımı tek slug. Hub'daki doğru değişim 132 → 129 kurum
(3 kurum). Kaynak: `12-kod-denetimi.md` O1, dalın kendi build HTML'i.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3 kurum (Kıbrıs Amerikan, Uluslararası Balkan, Uluslararası Saraybosna)
kaynak CSV'den `unitur='DEVLET'` geliyordu. `db.ts:79-82` filtreleri
yüzünden "devlet üniversitesi istiyorum" diyen öğrencinin aday havuzuna
27 KKTC/yurt dışı programı sızıyor, "vakıf" diyende aynı 27'si eksik
kalıyordu. Kullanıcının fark edemeyeceği bir doğruluk hatasıydı.
unitur-onar.ts — Aşama D (KURUM_DUZELT):
A/B/C yalnız `unitur IS NULL` satırlara dokunuyordu; bu satırlar NULL
değil, DOLU ve YANLIŞ. D koşulsuz çalışır ve Aşama A'dan ÖNCE koşar ki
yanlış değer başka satırlara kopyalanmasın. İdempotent (2. koşu: 0/0).
Her düzeltmenin kanıtı kurumun YÖK Atlas'taki kendi parantezli ikinci
yazımı: "(ÜSKÜP-MAKEDONYA)" → YURTDISI KAMU, "(KKTC-LEFKOŞA)" → KKTC.
refresh.ts:519 `uniturSec` DB'deki değeri kopyaladığı için düzeltme
buraya yazılınca her tazelemede kalıcı olur.
veri-kalite.ts — iki yeni ZORUNLU kontrol (dosyanın sonuna):
13. "baz ad başına tek unitur" — kök neden buydu: unitur-onar.ts'in
eski çelişki koruması GROUP BY universite (TAM ad) ile çalıştığı
için aynı kurumun iki yazımı arasındaki DEVLET↔YURTDISI KAMU
çelişkisini hiç görmüyordu.
14. "DEVLET etiketi Türkiye ili ile destekli" — 13'ün kör noktası:
Kıbrıs Amerikan'ın İKİ yazımı da yanlış etiketli olduğu için
ortada çelişki yok. 13 tek başına 100 satırın yalnız 58'ini
koruyordu. Şartnamenin ötesinde, gerekçesi raporun §4'ünde.
Doğrulama: düzeltme öncesi DB'de iki kontrol de KALDI (çıkış kodu 1);
sonrasında 0 ZORUNLU kaldı, 3 uyarı (üçü de önceden vardı). Tek satır
bilerek bozulduğunda ikisi de yakaladı. tsc + eslint temiz.
Veri (126 satır) ayrı commit'te. Rapor: docs/gece-vardiyasi/2026-09-22/
09-p2-unitur.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
/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>
Added a new router and middleware for handling www to apex domain redirection, ensuring that Let's Encrypt certificates are obtained for both domains. Updated the docker-compose.yml file to include necessary rules and middleware for proper redirection and TLS handling.
Also, updated the CEO agent description to remove redundant details and clarified the QA engineer's responsibilities regarding testing critical flows and error reporting. Adjusted the CTO agent's section for consistency in expert guidance and clarified the designer's tools to include 'Skill' for better design resource management.
Kılavuz kodu başka programa devredildiğinde (ör. 209210292: Diş Hekimliği SAY
lisans → İlk ve Acil Yardım TYT önlisans) refresh yalnız koda bakıp yıl
kolonlarını yazıyordu; satır eski adıyla yeni programın sırasını gösteriyordu.
- scripts/kimlik.ts (yeni): kimlik = puan türü + önlisans + baz ad slug'ı.
Devir yılı kanıt zinciriyle bulunur (API …1/…2/…3 sıra/puanı DB ile eşleşen
ardışık yıllar + netler.puanTuru); API geçmişi kod bazlı ve kirli olduğu
için (gk2, bazı basariSirasi3) zincirsiz güvenilmez. Yalnız adı değişen ve
API penceresinin tamamında sürekliliği olan satır "ad değişimi"dir, geçmişi
korunur.
- refresh: uyumsuz satır varsa listeler ve HİÇBİR ŞEY yazmadan durur;
--kimlik-onar ile isim/tur/onlisans/fakulte/sure API'den yazılır, devir
öncesi tüm yıl kolonları NULL'lanır, eski kimlik + geçmişi programs_arsiv'e
<kod>~<yıl> id'siyle kopyalanır, eski yılların netleri oraya taşınır,
veri_meta'ya kimlik_onar:<kod> kaydı düşer. Önceki-yıl sağlaması onarılanlar
dışındaki satırlar için aynen geçerli. --isim-esitle (varsayılan kapalı):
kimliği aynı, yalnız burs/dil eki farklı satırlarda isim API'den.
- gecmis-doldur: onarılmış satırda devir öncesi yılları hiçbir kaynaktan
doldurmaz (yoksa API'nin kod bazlı …N alanları eski programı geri yazar).
- veri-kalite: --ham ile ZORUNLU kimlik kontrolü (0 uyumsuz beklenir);
--onceki karşılaştırmasında onarılanlar ayrı doğrulanır.
- docs/veri/yillik-guncelleme.md: kimlik kilidi adımı.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- yokatlas-goc: idempotent şema göçü (yıl kolonları, son_kilavuz_yili, eski_kod,
programs_arsiv, veri_meta) + betiklerin ortak yardımcıları
- refresh: --yil/--db zorunlu, YIL KİLİDİ (…1 = DB sira<yil-1> ≥%95 ve eksiz ≠),
yıl asla r.yil'den türetilmez; ham veri data/ham/*.jsonl.gz, --ham ile API'siz
tekrar; benzersiz kod = totalElements; tek transaction + önceki yıl sağlaması;
yeni programda …1/2/3 → üç önceki yıl; efektif indeks EFEKTIF_SIRA_SQL ile
- gecmis-doldur: yalnız NULL alan; API …1/2/3 → eski_kod → kanıtlı 1:1 ad eşleşmesi
- eski-arsivle: güncel kılavuzda olmayanlar → programs_arsiv, netler yeni koda; --kuru
- detay: netler bağımsız + yıl sağlaması; kırılım yalnız --kirilim, alan yoksa durur,
mevcut değerin üstüne NULL yazılmaz; `yil - 1` varsayımı kalktı
- veri-kalite: salt okunur kalite kapısı, zorunlu kontrol kalırsa çıkış kodu 1
- docs/veri/yillik-guncelleme.md: adım adım runbook + geri alma
DB commit'lenmedi (arşivleme kararı [Bilal]).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Prompt ve mock metni "son ${VERI_YIL_SAYISI} yıl" der; program seçimi
yerlesenSon'a göre; snapshot rapor.ts programBilgisi ile aynı şekilde
siraGecmisi + ilkYil yazar.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Girişsiz /sonuc tadımlığının riskNotu'su LLM üretimiydi ve DB'den olduğu
gibi servis ediliyordu; prompt'u da açıkça "yüksek/orta/düşük ihtimal dili
kullan" diyordu. Rozet ise aynı satırda canlı hesaplanıyor → metinle rozet
çelişebiliyordu.
- tadimlikSec(): riskNotu okuma anında riskNotuMetni(riskHesapla(...) ??
dilimdenRisk(...)) ile üretilir (rozetle aynı formül). DB satırları ve
şema değişmez; prod'da havuzu yeniden üretmek gerekmez, /api/tadimlik de
kapsanır
- tadimlik-uret prompt'u + mock metinleri: ihtimal dili yasaklandı,
"son 4 yıl" → "son 5 yıl" (çıktı şeması aynı; script koşulmadı)
- danışman sohbeti sistem prompt'u: "ihtimal dili kullan" → olasılık/yüzde/
ihtimal yasak, risk etiketleri + taban sıralarıyla konuş
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Profil çerezinin SSR'da kullanılmasını sağlayarak, sonuç sayfasındaki yönlendirmeleri güncelledik. Artık profil bilgileri URL parametreleri yerine çerezden alınarak işleniyor. Ayrıca, profil çerezi olmayan kullanıcılar için yönlendirme mantığı iyileştirildi. Çeşitli bileşenlerdeki URL oluşturma fonksiyonları güncellenerek, profil bilgileri çerezden okunacak şekilde düzenlendi. Bu değişiklikler, kullanıcı deneyimini artırmayı ve daha tutarlı bir veri akışı sağlamayı hedefliyor.
Tadımlık satırı batch üretildiği için sihirbazdaki devlet/vakıf seçimini
bilmiyor, vakıf seçen kullanıcıya devlet örneği gösteriyordu. Havuz
anahtarı kova×tür×kategori×tip'e genişledi (migration 0001; mevcut
satırlar tip='genel'). Üretim scripti tip varyantlarını uniturGrubu
filtresiyle seçer; tadimlikSec tip verildiğinde kategori→genel fallback'i
korur ama tip fallback'i YAPMAZ — uygun satır yoksa bileşen gizlenir,
yanlış tipte örnek asla gösterilmez. Client profildeki tipi de gönderir ve
SSR "genel" satırı tipe uymuyorsa fetch bitene kadar gizler.
Not: prod app.db volume'de — `pnpm tadimlik` prod DB'ye karşı ayrıca
koşulmalı.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
YÖK Atlas API'sinin universiteTuru döndürmediği ~2.081 satır (Nişantaşı,
Beykent gibi vakıflar + KKTC kampüsleri) devlet/vakıf filtrelerinden ve
sihirbaz sayaçlarından sessizce düşüyordu. unitur-onar üç aşamada doldurur:
aynı üniversitenin dolu satırından kopya → KKTC ili kuralı → manuel eşleme
(Cerrahpaşa, MSB/İçişleri SBÜ, Alanya, Manas, Yesevi, Az. Pedagoji).
"ÜNİVERSİTESİ- CERRAHPAŞA" tarzı tire etrafı boşluklu duplikat adlar da
normalize edilir; refresh.ts hem insert yolunda adı normalize eder hem her
tazeleme sonunda onarımı idempotent olarak koşar.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Volume'deki app.db yalnızca ilk kurulumda seed'den kopyalanıyordu; sonraki
deploy'larda şemaya eklenen kolonlar (son örnek: kredi_bitti_at,
kredi_hatirlatma_gonderildi_at) prod'a hiç ulaşmıyor ve 'no such column'
hatalarıyla kırılıyordu.
- drizzle-kit generate ile baseline migration üretildi (drizzle/0000_baslangic)
- scripts/db-goc.mjs: entrypoint'te server'dan önce koşan migration runner;
drizzle migrator protokolünü birebir taklit eder (__drizzle_migrations,
sha256, created_at=journal.when) ama yalnızca @libsql/client'a dayanır —
drizzle-orm standalone imajda bundle'landığından paket olarak çözülemiyor
- Benimseme: migration kaydı olmayan mevcut volume'lerde baseline additive
uzlaştırılır (IF NOT EXISTS + snapshot'tan eksik kolon ALTER'ları) ve
damgalanır; sonraki migration'lar normal akışla uygulanır
- sema-guvence.ts kaldırıldı: elle DDL aynalama yerini migration'lara bıraktı
- Yeni akış: şema değişikliğinde pnpm db:generate ile migration commit'lenir
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Tüm AI akışı OpenRouter üzerinden (openai SDK, varsayılan model
deepseek/deepseek-v4-flash, OPENROUTER_MODEL ile değiştirilebilir);
Anthropic/Gemini/lokal sağlayıcı seçimi ve SDK'ları kaldırıldı.
- Rapor: aday havuzu dilim başına 20 (60 program, ~8k token prompt);
AI şeması sabit uzunluklu üç liste (hayal 5 / dengeli 13 / garanti 6 —
dağılım şema düzeyinde zorlanır), sıra + dilim + riskNotu + trendOzeti
gerçek sıra geçmişinden deterministik üretilir; 184 sn → ~12 sn.
- Sohbet: akış ortası zaman aşımı artık sessizce yutulmaz (kesik cevap
tam cevap gibi kaydedilmiyordu, kredi iadesi çalışmıyordu); istemci
hata anında durumu sunucudan senkronlar, boş balon bırakmaz.
- aiHataMesaji, openai SDK'nın .name'i "Error" kalan abort/timeout
hatalarını da yakalar; meraklisina şeması yeni akışla senkronlandı.
- CI: OPENROUTER_API_KEY / OPENROUTER_MODEL secret'ları; eski AI
secret'ları kaldırıldı. next.config serverExternalPackages sadeleşti.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Added new scripts for database operations and temporary production in package.json.
- Integrated KaydetBannerLazy component into the layout for improved user notifications.
- Enhanced API error handling in the soru route to mark credit exhaustion.
- Updated the IletisimPage for better button styling and user experience.
- Refactored ListemPage to streamline user flow and improve session handling.
- Removed unused ListePaneli component to clean up the codebase.
- Introduced a new "detay" script in package.json for additional processing.
- Refactored ListemSekmeleri component to improve tab functionality and state management.
- Updated UI elements for better user interaction and clarity, including renaming "Seçtiklerim" to "Kendi Listem" for consistency across the application.
- Made adjustments to related components for improved integration and user experience.
- better-auth ile giriş/oturum yönetimi (src/lib/auth, giris sayfası)
- iyzico ödeme entegrasyonu ve paket satın alma akışı
- kredi sistemi ve uygulama veritabanı şeması (drizzle)
- AI destekli rapor üretimi ve tercih sihirbazı
- rapor yazdırma sayfası ve site header/kullanıcı menüsü
Co-authored-by: Cursor <cursoragent@cursor.com>