test(eval): profil beklentileri havuz düzeltmeleri sonrası davranışa göre yeniden üretildi

- 22 profilin beklenen değeri (gevşetme, minAday, hedef) B1/B2/B3/B5/B8
  sonrası gerçek havuzOlustur() çıktısına eşitlendi; "liste-24-alti"
  etiketi kalktı, düzelen bugların supheli kayıtları temizlendi.
- robot.ts: "alan-ilsiz-gevsedi" değişmezi artık yalnız alanda adayın
  yazabileceği 24+ program varken ihlal sayar (a07: baraj yüzünden alanda
  1 program kalıyor, gevşetme meşru; beklenti hatasıydı).

Önce: pnpm eval:robot 22 temiz / 18 ihlalli, çıkış 1.
Sonra: 40 temiz / 0 ihlalli, çıkış 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-05 08:12:59 +03:00
parent 065a9c102d
commit e06c486b1a
2 changed files with 116 additions and 108 deletions

View File

@@ -6,7 +6,8 @@
* Kaynak ve kanıt: docs/gece-vardiyasi/2026-10-05/02-profil-matrisi.md
* Kişiler: docs/arastirma/2026-09-24-ogrenci-senaryolari/01–12
*
* `beklenen` alanlarındaki sayılar UYDURMA DEĞİLDİR: 5 Eki 2026'da
* `beklenen` alanlarındaki sayılar UYDURMA DEĞİLDİR: 5 Eki 2026'da (havuz
* düzeltmeleri B1–B5, B8 sonrası; son yeniden üretim commit 065a9c1 üzerinde)
* `havuzOlustur()` + `dilimHedefiHesapla()` gerçek `data/yokatlas.db`
* (2021–2026 verisi) üzerinde koşturularak okundu. Yani bunlar "doğru olması
* gereken" değil "bugünkü davranış" değerleridir; `supheli` dolu profillerde
@@ -64,7 +65,7 @@ export type SenaryoEtiketi =
| "gevsetme-profil" | "gevsetme-profil-il" | "gevsetme-profil-il-kategori"
// dilim dağılımı
| "dagilim-ideal" | "hayal-yetersiz" | "dengeli-yetersiz" | "garanti-yetersiz"
| "yalniz-hayal" | "liste-24-alti"
| "yalniz-hayal"
// danışman profili (sohbette kaydedilenler)
| "profil-dil" | "profil-burs" | "profil-ucret" | "profil-km" | "profil-km-yok-sayilir"
| "profil-ogretim-turu" | "profil-etkisiz"
@@ -98,7 +99,7 @@ export interface EvalProfil {
senaryoEtiketleri: SenaryoEtiketi[];
/** havuzOlustur().gevsetildi — sıra dahil birebir eşleşmeli. */
havuzGevsetmeBasamagi: Gevsetilen[];
/** havuzOlustur().havuz.length (dilim başına 20'ye kırpılmış) alt sınırı; bugünkü gerçek değer. */
/** havuzOlustur().havuz.length alt sınırı; bugünkü gerçek değer (dilim başına 20'ye kırpılır, tek dilime yığılan havuz 24'e tamamlanır). */
minAday: number;
/** dilimHedefiHesapla(havuz) — listenin dilim uzunlukları; toplamı liste boyudur. */
hedef: DilimHedef;
@@ -141,13 +142,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mühendislik & Teknoloji"], iller: ["KOCAELİ", "İSTANBUL"], universiteTipi: "devlet", oncelikler: ["İş bulma kolaylığı", "Yüksek maaş potansiyeli"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-orta", "baraj-ici", "il-cok", "tip-devlet", "gevsetme-yok", "dagilim-ideal", "ozel-kontenjan-satiri", "urun-hizmet-edemiyor"],
senaryoEtiketleri: ["tur-say", "sira-orta", "baraj-ici", "il-cok", "tip-devlet", "gevsetme-yok", "dagilim-ideal", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: [],
minAday: 54,
minAday: 53,
hedef: H_IDEAL,
supheli: ["B8"],
notlar:
"Temiz 5/13/6. Ama havuzdaki 54 programın 7'si '(KKTC Uyruklu)' ya da '(M.T.O.K.)' kontenjan satırı (ör. İTÜ Elektrik Müh. KKTC Uyruklu): Mert bunları tercih edemez (B8).",
"Temiz 5/13/6; 53 programın hepsi seçilen alan ve illerden. Özel kontenjan satırları ('(KKTC Uyruklu)', '(M.T.O.K.)') artık havuza girmiyor (B8 düzeldi, 22ac604).",
},
},
{
@@ -160,13 +160,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Hukuk & Siyasal"], iller: [], universiteTipi: "farketmez", oncelikler: ["Prestijli üniversite"] },
},
beklenen: {
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-kategori", "dagilim-ideal", "kktc-yurtdisi", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: ["kategori"],
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: [],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B2", "B3"],
notlar:
"İl seçilmediği hâlde alan gevşiyor (B3): EA'da bu sıraya 40 dengeli + 260 güvenli 'Hukuk & Siyasal' programı varken havuzdaki 60 programın yalnız 8'i bu alandan. Ayrıca havuzda barajı 100.000 olan ve adayın yazamayacağı 1 hukuk programı var (B2).",
"Alan gevşemez: havuzdaki 60 programın 60'ı 'Hukuk & Siyasal' (B3 düzeldi). Barajı 100.000 olan hukuk programları adayın sırası (105.000) dışında kaldığı için havuza girmez (B2 düzeldi); liste siyaset bilimi/uluslararası ilişkiler ağırlıklıdır. Havuzda baraj kolonu boş 1 'Hukuk' satırı kalıyor (veri eksiği; aday yazamaz). Sohbette: hukuk neden yok sorusuna baraj söylenmeli.",
},
},
{
@@ -200,7 +199,8 @@ export const PROFILLER: EvalProfil[] = [
havuzGevsetmeBasamagi: [],
minAday: 60,
hedef: H_IDEAL,
notlar: "Hiçbir filtre gevşemez, dağılım ideal (havuzda 4 özel kontenjan satırı var — B8). Sohbet sorularının çoğu bu profile bağlı.",
notlar:
"Hiçbir filtre gevşemez, dağılım ideal; havuzda özel kontenjan satırı yok. Sohbet sorularının çoğu bu profile bağlı.",
},
},
{
@@ -248,10 +248,10 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mühendislik & Teknoloji"], iller: ["ANKARA", "İSTANBUL", "İZMİR", "ESKİŞEHİR"], universiteTipi: "farketmez", oncelikler: ["İş bulma kolaylığı"] },
},
beklenen: {
senaryoEtiketleri: ["tur-tyt", "onlisans", "sira-orta", "il-cok", "tip-farketmez", "gevsetme-yok", "dengeli-yetersiz"],
senaryoEtiketleri: ["tur-tyt", "onlisans", "sira-orta", "il-cok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal"],
havuzGevsetmeBasamagi: [],
minAday: 48,
hedef: { hayal: 5, dengeli: 12, garanti: 7 },
minAday: 60,
hedef: H_IDEAL,
notlar: "Ön lisans (TYT) akışı. Sohbette kriz dili ve 'ek tercihte ne olur' soruları bu profile bağlı.",
},
},
@@ -265,13 +265,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mühendislik & Teknoloji"], iller: [], universiteTipi: "devlet", oncelikler: ["İş bulma kolaylığı"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-devlet", "gevsetme-kategori", "dagilim-ideal", "ozel-kontenjan-satiri"],
havuzGevsetmeBasamagi: ["kategori"],
minAday: 60,
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-devlet", "gevsetme-yok", "dagilim-ideal"],
havuzGevsetmeBasamagi: [],
minAday: 57,
hedef: H_IDEAL,
supheli: ["B3", "B8"],
notlar:
"Mühendislikler 300.000 barajının içinde kapanır; alan gevşer ve havuzdaki 60 programın yalnız 4'ü seçilen alandan (devlette bu alanda 26 dengeli + 19 güvenli program olduğu hâlde — B3). 5 satır özel kontenjan (B8). Sohbette baraj dürüstçe söylenmeli.",
"Barajı 300.000 olan mühendislikler adayın sırası (410.000) dışında kaldığı için havuza girmez (B2); alan yine de gevşemez: havuzdaki 57 programın 57'si seçilen alandan, barajı olmayan programlar (B3 düzeldi). Özel kontenjan satırı yok (B8 düzeldi). Sohbette baraj dürüstçe söylenmeli.",
},
},
{
@@ -286,7 +285,7 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-ea", "sira-orta", "il-yok", "tip-devlet", "gevsetme-yok", "dagilim-ideal", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: [],
minAday: 43,
minAday: 51,
hedef: H_IDEAL,
notlar: "Liste YKS tercihi içindir; yatay geçiş hakkını göstermez. Danışman bunu açıkça sınırlamalı.",
},
@@ -303,7 +302,7 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-tyt", "onlisans", "sira-orta", "il-yok", "tip-devlet", "gevsetme-yok", "dagilim-ideal", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: [],
minAday: 59,
minAday: 60,
hedef: H_IDEAL,
notlar: "Liste sorunsuz kurulur ama Emre'nin işine yaramaz: o lisansa DGS ile geçmek istiyor. Danışman DGS verisi olmadığını söylemeli.",
},
@@ -322,9 +321,8 @@ export const PROFILLER: EvalProfil[] = [
havuzGevsetmeBasamagi: ["il"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B4", "B5"],
notlar:
"Kayseri'de EA devlet programı 22 (<24; bunların 9'u iktisat/işletme) → il gevşer. Gevşeyince havuzdaki 60 programın yalnız 1'i Kayseri'de kalıyor (B5): veliye 'Kayseri'ye öncelik verildi' denemez.",
"Kayseri'de EA devlet programı 22 (<24; bunların 9'u iktisat/işletme) → il gevşer. Gevşeyince Kayseri'deki 9 iktisat/işletme programının 9'u da havuzda kalır (B5 düzeldi), kalan 51 başka illerden. Veliye 'Kayseri'de yeterli program yoktu' açıkça söylenmeli.",
},
},
{
@@ -339,11 +337,10 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-soz", "sira-orta", "baraj-ici", "il-tek", "tip-devlet", "gevsetme-il", "garanti-yetersiz", "dengeli-yetersiz", "urun-hizmet-edemiyor"],
havuzGevsetmeBasamagi: ["il"],
minAday: 25,
minAday: 27,
hedef: { hayal: 17, dengeli: 7, garanti: 0 },
supheli: ["B5"],
notlar:
"İl gevşedikten sonra bile güvenli dilim BOŞ: liste 17 hayal + 7 dengeli (SÖZ devlet öğretmenliklerinin 277'si bu sıranın üstünde kapanmış, güvenli aralıkta hiç yok). Havuzda Trabzon'dan tek program kalmıyor (B5). 'Kolay yerleşme' seçilmişken güvenli satırı olmayan liste — ürün bunu açıkça söylemeli.",
"İl gevşedikten sonra bile güvenli dilim BOŞ: liste 17 hayal + 7 dengeli (SÖZ devlet öğretmenliklerinde güvenli aralıkta program yok). Trabzon'daki 4 öğretmenlik programının 4'ü havuzda (B5 düzeldi). 'Kolay yerleşme' seçilmişken güvenli satırı olmayan liste — ürün bunu açıkça söylemeli.",
},
},
{
@@ -356,12 +353,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mühendislik & Teknoloji"], iller: ["KOCAELİ", "İSTANBUL", "SAKARYA", "BURSA"], universiteTipi: "devlet", oncelikler: ["İş bulma kolaylığı", "Kolay yerleşme"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-orta", "baraj-ici", "il-cok", "tip-devlet", "gevsetme-yok", "dagilim-ideal", "ozel-kontenjan-satiri"],
senaryoEtiketleri: ["tur-say", "sira-orta", "baraj-ici", "il-cok", "tip-devlet", "gevsetme-yok", "dagilim-ideal"],
havuzGevsetmeBasamagi: [],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B8"],
notlar: "Çok illi, gevşetmesiz durum; havuzda 6 özel kontenjan satırı var (B8). Sohbette para/yurt/KYK soruları (veri yok) bu profile bağlı.",
notlar:
"Çok illi, gevşetmesiz durum; havuzda özel kontenjan satırı yok (B8 düzeldi). Sohbette para/yurt/KYK soruları (veri yok) bu profile bağlı.",
},
},
{
@@ -394,12 +391,13 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Sağlık & Tıp"], iller: [], universiteTipi: "farketmez", oncelikler: ["Prestijli üniversite"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-uc-deger", "sira-cok-ust", "il-yok", "tip-farketmez", "gevsetme-kategori", "hayal-yetersiz", "dengeli-yetersiz", "liste-24-alti"],
havuzGevsetmeBasamagi: ["kategori"],
minAday: 21,
hedef: { hayal: 0, dengeli: 1, garanti: 20 },
supheli: ["B1", "B3", "B13"],
notlar: "İl seçilmediği hâlde alan gevşiyor ve liste 21 satırda kalıyor (11'i sağlık); oysa SAY'da 1.473 sağlık programı güvenli dilimde (B3 + B1).",
senaryoEtiketleri: ["tur-say", "sira-uc-deger", "sira-cok-ust", "il-yok", "tip-farketmez", "gevsetme-yok", "hayal-yetersiz", "dengeli-yetersiz"],
havuzGevsetmeBasamagi: [],
minAday: 24,
hedef: { hayal: 0, dengeli: 1, garanti: 23 },
supheli: ["B13"],
notlar:
"Alan gevşemez, liste 24 satır (0 hayal + 1 dengeli + 23 güvenli; 24'ü de sağlık). Güvenli dilim 20 yerine 23'e tamamlanır (B1, B3 düzeldi). Dengeli dilimdeki tek satır şüpheli veri olabilir (B13: Medipol sıraları).",
},
},
{
@@ -412,12 +410,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Sağlık & Tıp"], iller: [], universiteTipi: "devlet", oncelikler: ["Prestijli üniversite", "Akademik kariyer"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-cok-ust", "baraj-ici", "il-yok", "tip-devlet", "gevsetme-yok", "hayal-yetersiz", "dengeli-yetersiz", "liste-24-alti"],
senaryoEtiketleri: ["tur-say", "sira-cok-ust", "baraj-ici", "il-yok", "tip-devlet", "gevsetme-yok", "hayal-yetersiz", "dengeli-yetersiz"],
havuzGevsetmeBasamagi: [],
minAday: 22,
hedef: { hayal: 1, dengeli: 1, garanti: 20 },
supheli: ["B1"],
notlar: "Gevşetme yok ama liste 22 satır: devlette 617 güvenli sağlık programı varken güvenli dilim 20'ye kırpıldığı için 24'e tamamlanamıyor.",
minAday: 24,
hedef: { hayal: 1, dengeli: 1, garanti: 22 },
notlar:
"Gevşetme yok, liste 24 satır: 1 hayal + 1 dengeli + 22 güvenli (güvenli dilim 24'e tamamlanır; B1 düzeldi).",
},
},
{
@@ -449,29 +447,29 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-ust", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 44,
minAday: 60,
hedef: H_IDEAL,
supheli: ["B2"],
notlar: "Havuzda adayın yazamayacağı (baraj 50.000) 3 tıp programı var; listeye girerse ölü tercih olur.",
notlar:
"Barajı 50.000 olan tıp programları havuza girmez (B2 düzeldi); 60 programın 60'ı sağlık, tıp dışı (hemşirelik, eczacılık, diş vb.). Havuzda 8 KKTC/yurt dışı üniversite programı var. Sohbette 'tıp neden yok' sorusuna baraj söylenmeli.",
},
},
{
id: "a05-ea-105000-hukuk-kayseri-devlet",
kisi: "algoritma",
aciklama: "Hem il hem alan gevşer: EA 105 bin, hukuk (baraj dışı), yalnız Kayseri, devlet.",
aciklama:
"Yalnız il gevşer: EA 105 bin, hukuk (baraj dışı), yalnız Kayseri, devlet.",
sihirbaz: {
sira: 105_000,
tur: "ea",
secimler: { kategoriler: ["Hukuk & Siyasal"], iller: ["KAYSERİ"], universiteTipi: "devlet", oncelikler: [] },
},
beklenen: {
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-tek", "tip-devlet", "gevsetme-il-kategori", "dagilim-ideal"],
havuzGevsetmeBasamagi: ["il", "kategori"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B2", "B3", "B5"],
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-tek", "tip-devlet", "gevsetme-il", "dengeli-yetersiz"],
havuzGevsetmeBasamagi: ["il"],
minAday: 52,
hedef: { hayal: 5, dengeli: 12, garanti: 7 },
notlar:
"Son basamak (4): seçimlerin ikisi de düşer; liste fiilen 'sırana yakın her şey' (60 programın 5'i seçilen alandan, 1'i Kayseri'den). İl kalkınca devlette 13 dengeli + 165 güvenli 'Hukuk & Siyasal' programı olduğu hâlde alan da gevşiyor (B3). İki gevşetme de söylenmeli.",
"İl gevşer, alan gevşemez (B3 düzeldi): 52 programın 52'si 'Hukuk & Siyasal', 3'ü Kayseri'den (B5 düzeldi). Barajı 100.000 olan hukuk programları havuzda yok (B2 düzeldi); dengeli dilimde 12 program olduğu için hedef 5/12/7. İl gevşetmesi söylenmeli.",
},
},
{
@@ -484,12 +482,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mühendislik & Teknoloji"], iller: [], universiteTipi: "farketmez", oncelikler: ["Yüksek maaş potansiyeli"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-yok", "dengeli-yetersiz", "kktc-yurtdisi"],
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 29,
hedef: { hayal: 9, dengeli: 7, garanti: 8 },
supheli: ["B2"],
notlar: "Havuzda barajı 300.000 olan 5 program var; hayal dilimi bunlarla şişiyor (9 hayal).",
minAday: 60,
hedef: H_IDEAL,
notlar:
"Barajı 300.000 olan mühendislikler havuza girmez (B2 düzeldi); 60 programın 60'ı seçilen alandan ve baraj kolonu boş programlar (çoğu bilişim/teknoloji; 2 'Makine Mühendisliği' satırında baraj boş — veri eksiği olabilir). 6'sı KKTC/yurt dışı üniversitesi. Dağılım ideal.",
},
},
{
@@ -502,13 +500,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Eğitim & Öğretmenlik"], iller: [], universiteTipi: "devlet", oncelikler: ["İş bulma kolaylığı"] },
},
beklenen: {
senaryoEtiketleri: ["tur-soz", "sira-alt", "baraj-disi", "il-yok", "tip-devlet", "gevsetme-kategori", "dagilim-ideal", "ozel-kontenjan-satiri"],
senaryoEtiketleri: ["tur-soz", "sira-alt", "baraj-disi", "il-yok", "tip-devlet", "gevsetme-kategori", "dagilim-ideal"],
havuzGevsetmeBasamagi: ["kategori"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B8"],
notlar:
"SÖZ devlet öğretmenliklerinin 284'ü de bu sıranın üstünde kapanmış: alan gevşer ve havuzda seçilen alandan TEK program kalmaz. Burada gevşetme meşru; ama 3 satır '(M.T.O.K.)' kontenjanı (B8). Danışman barajı (300.000) söylemeli.",
"MEŞRU gevşetme: SÖZ devlet öğretmenliklerinin barajı 300.000, aday 310.000 → alanın baraj içi 1 programı kalır (Balıkesir Özel Eğitim Öğretmenliği; baraj kolonu boş, veri eksiği olabilir), alan gevşer, havuzdaki 60 programın 1'i alan içi. Robot değişmezi bunu ihlal saymaz (alan içi baraj içi program < 24). Açık kalan: kullanıcıya 'seçtiğin alanlarda yeterli program yoktu' deniyor, sebep (baraj) söylenmiyor. Danışman barajı (300.000) söylemeli.",
},
},
{
@@ -521,13 +518,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Mimarlık & Tasarım"], iller: [], universiteTipi: "farketmez", oncelikler: ["Sevdiğim işi yapmak"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-kategori", "dagilim-ideal", "kktc-yurtdisi", "ozel-kontenjan-satiri"],
havuzGevsetmeBasamagi: ["kategori"],
senaryoEtiketleri: ["tur-say", "sira-alt", "baraj-disi", "il-yok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B2", "B3", "B8"],
notlar:
"Alan gevşiyor: SAY'da bu sıraya 47 dengeli + 124 güvenli 'Mimarlık & Tasarım' programı varken havuzda yalnız 5'i var (B3). Havuzda barajı aşılamayan 1 program (B2), 6 KKTC/yurt dışı, 1 özel kontenjan satırı.",
"Alan gevşemez: 60 programın 60'ı 'Mimarlık & Tasarım' (B3 düzeldi). Barajı 250.000 olan mimarlık programları havuzda yok (B2 düzeldi), özel kontenjan satırı yok (B8 düzeldi); 3 KKTC/yurt dışı üniversite programı var.",
},
},
{
@@ -542,10 +538,10 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-dil", "sira-orta", "il-tek", "tip-devlet", "gevsetme-il", "dengeli-yetersiz"],
havuzGevsetmeBasamagi: ["il"],
minAday: 27,
hedef: { hayal: 11, dengeli: 5, garanti: 8 },
supheli: ["B5"],
notlar: "Küçük puan türü + tek il: il gevşer, yine de 11 hayal'li ağır bir liste çıkar.",
minAday: 41,
hedef: { hayal: 7, dengeli: 8, garanti: 9 },
notlar:
"Küçük puan türü + tek il: il gevşer; Konya'daki 3 program havuzda kalır (B5 düzeldi). Dengeli dilimde 8 program olduğu için liste 7 hayal + 8 dengeli + 9 güvenli.",
},
},
{
@@ -560,7 +556,7 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-dil", "sira-orta", "il-cok", "tip-farketmez", "gevsetme-yok", "dagilim-ideal"],
havuzGevsetmeBasamagi: [],
minAday: 56,
minAday: 55,
hedef: H_IDEAL,
notlar: "DİL'in normal durumu.",
},
@@ -575,13 +571,13 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Sosyal & Beşeri Bilimler"], iller: [], universiteTipi: "farketmez", oncelikler: ["Kolay yerleşme"] },
},
beklenen: {
senaryoEtiketleri: ["tur-dil", "sira-cok-dusuk", "sira-uc-deger", "il-yok", "tip-farketmez", "gevsetme-yok", "yalniz-hayal", "dengeli-yetersiz", "garanti-yetersiz", "liste-24-alti", "kktc-yurtdisi"],
senaryoEtiketleri: ["tur-dil", "sira-cok-dusuk", "sira-uc-deger", "il-yok", "tip-farketmez", "gevsetme-yok", "yalniz-hayal", "dengeli-yetersiz", "garanti-yetersiz", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 20,
hedef: { hayal: 20, dengeli: 0, garanti: 0 },
supheli: ["B1", "B6"],
minAday: 24,
hedef: { hayal: 24, dengeli: 0, garanti: 0 },
supheli: ["B6"],
notlar:
"Liste 20 satır ve TAMAMI hayal (riskli). Oysa DİL'de 2026'da kontenjanı dolmayan 109 program var; taban sırası boş olduğu için havuza giremiyorlar (B6).",
"Liste 24 satır ve TAMAMI hayal (riskli); hayal dilimi 24'e tamamlanır (B1 düzeldi). DİL'de 2026'da kontenjanı dolmayan 109 program var; taban sırası boş olduğu için havuza giremiyorlar (B6, açık).",
},
},
{
@@ -594,12 +590,13 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Sağlık & Tıp"], iller: [], universiteTipi: "farketmez", oncelikler: ["Kolay yerleşme"] },
},
beklenen: {
senaryoEtiketleri: ["tur-tyt", "onlisans", "sira-uc-deger", "sira-cok-dusuk", "il-yok", "tip-farketmez", "gevsetme-yok", "yalniz-hayal", "liste-24-alti", "kktc-yurtdisi"],
senaryoEtiketleri: ["tur-tyt", "onlisans", "sira-uc-deger", "sira-cok-dusuk", "il-yok", "tip-farketmez", "gevsetme-yok", "yalniz-hayal", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 20,
hedef: { hayal: 20, dengeli: 0, garanti: 0 },
supheli: ["B1", "B6"],
notlar: "Tabanı en kötü 20 sağlık ön lisansı 'hayal' diye listelenir. Danışman bu listeyi 'güvenli' diye sunmamalı.",
minAday: 24,
hedef: { hayal: 24, dengeli: 0, garanti: 0 },
supheli: ["B6"],
notlar:
"Tabanı en kötü 24 sağlık ön lisansı 'hayal' diye listelenir (B1 düzeldi: 20 → 24). Danışman bu listeyi 'güvenli' diye sunmamalı. Dolmayan programlar havuzda yok (B6, açık).",
},
},
{
@@ -614,10 +611,11 @@ export const PROFILLER: EvalProfil[] = [
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-orta", "baraj-ici", "il-yok", "tip-vakif", "gevsetme-yok", "dagilim-ideal", "kktc-yurtdisi", "burslu-indirimli"],
havuzGevsetmeBasamagi: [],
minAday: 57,
minAday: 60,
hedef: H_IDEAL,
supheli: ["B7"],
notlar: "'Vakıf' seçimi KKTC ve yurt dışı üniversitelerini de getirir (havuzda 10 tane). Burslu/%50/ücretli satırlar ayrı program olarak yan yana.",
notlar:
"'Vakıf' seçimi KKTC ve yurt dışı üniversitelerini de getirir (havuzda 11 tane). Burslu/%50/ücretli satırlar ayrı program olarak yan yana.",
},
},
{
@@ -665,12 +663,12 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Turizm & Gastronomi"], iller: [], universiteTipi: "farketmez", oncelikler: ["Sevdiğim işi yapmak"] },
},
beklenen: {
senaryoEtiketleri: ["tur-ea", "sira-orta", "il-yok", "tip-farketmez", "gevsetme-kategori", "dagilim-ideal", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: ["kategori"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B3"],
notlar: "Hiç il seçilmemişken alan gevşiyor: EA'da 78 turizm/gastronomi programı var (8 hayal, 5 dengeli, 65 güvenli) ama havuzdaki 60 programın yalnız 1'i bu alandan.",
senaryoEtiketleri: ["tur-ea", "sira-orta", "il-yok", "tip-farketmez", "gevsetme-yok", "dengeli-yetersiz", "kktc-yurtdisi"],
havuzGevsetmeBasamagi: [],
minAday: 33,
hedef: { hayal: 8, dengeli: 5, garanti: 11 },
notlar:
"Alan gevşemez (B3 düzeldi): havuzdaki 33 programın 33'ü turizm/gastronomi (8 hayal, 5 dengeli, 20 güvenli). Dengeli dilim dar olduğu için hedef 8/5/11.",
},
},
{
@@ -683,13 +681,13 @@ export const PROFILLER: EvalProfil[] = [
secimler: { kategoriler: ["Tarım & Doğa", "Fen & Temel Bilimler"], iller: ["ADANA", "MERSİN", "HATAY", "OSMANİYE", "KAHRAMANMARAŞ"], universiteTipi: "devlet", oncelikler: ["Kolay yerleşme"] },
},
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-cok-dusuk", "sira-uc-deger", "il-5-ust-sinir", "il-cok", "tip-devlet", "gevsetme-yok", "yalniz-hayal", "dengeli-yetersiz", "garanti-yetersiz", "liste-24-alti", "ozel-kontenjan-satiri"],
senaryoEtiketleri: ["tur-say", "sira-cok-dusuk", "sira-uc-deger", "il-5-ust-sinir", "il-cok", "tip-devlet", "gevsetme-yok", "yalniz-hayal", "dengeli-yetersiz", "garanti-yetersiz"],
havuzGevsetmeBasamagi: [],
minAday: 20,
hedef: { hayal: 20, dengeli: 0, garanti: 0 },
supheli: ["B1", "B6", "B8"],
minAday: 24,
hedef: { hayal: 24, dengeli: 0, garanti: 0 },
supheli: ["B6"],
notlar:
"Beş ilin hepsi korunur ama liste 20 satır ve tamamı hayal: adayın sırası bu illerdeki her tabanın altında. Dolmayan programlar (taban sırası boş) havuza giremediği için gerçek seçenekleri görünmüyor (B6).",
"Beş ilin hepsi korunur; liste 24 satır ve tamamı hayal (B1 düzeldi: 20 → 24): adayın sırası bu illerdeki her tabanın altında. Dolmayan programlar (taban sırası boş) havuza giremediği için gerçek seçenekleri görünmüyor (B6, açık).",
},
},
@@ -778,12 +776,12 @@ export const PROFILLER: EvalProfil[] = [
},
danismanProfili: { ucretUst: 50_000, dil: "ingilizce" },
beklenen: {
senaryoEtiketleri: ["tur-say", "sira-orta", "il-tek", "tip-vakif", "gevsetme-yok", "profil-ucret", "profil-dil", "burslu-indirimli", "yalniz-hayal", "liste-24-alti"],
senaryoEtiketleri: ["tur-say", "sira-orta", "il-tek", "tip-vakif", "gevsetme-yok", "profil-ucret", "profil-dil", "burslu-indirimli", "yalniz-hayal"],
havuzGevsetmeBasamagi: [],
minAday: 20,
hedef: { hayal: 20, dengeli: 0, garanti: 0 },
supheli: ["B1"],
notlar: "Ücret sınırı fiilen 'yalnız tam burslu' demek; hepsi adayın sırasının üstünde kapanmış. 24 eşiği kırpmadan ÖNCE sayıldığı için profil gevşemiyor ve 20 satırlık, tamamı hayal bir liste çıkıyor.",
minAday: 24,
hedef: { hayal: 24, dengeli: 0, garanti: 0 },
notlar:
"Ücret sınırı fiilen 'yalnız tam burslu' demek; hepsi adayın sırasının üstünde kapanmış. Profil gevşemez, liste 24 satır ve tamamı hayal (B1 düzeldi: 20 → 24).",
},
},
{
@@ -801,14 +799,15 @@ export const PROFILLER: EvalProfil[] = [
havuzGevsetmeBasamagi: ["profil", "il"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B5"],
notlar: "İki gevşetme birden; uyarılarda ikisi de söylenmeli.",
notlar:
"İki gevşetme birden; uyarılarda ikisi de söylenmeli. Düzce'deki 10 program havuzda kalır (B5 düzeldi).",
},
},
{
id: "b07-ea-105000-hukuk-kayseri-devlet-profil-ingilizce",
kisi: "algoritma",
aciklama: "Üç gevşetmenin hepsi: profil (İngilizce) + il (Kayseri) + alan (hukuk, baraj dışı).",
aciklama:
"İki gevşetme: profil (İngilizce) + il (Kayseri); alan (hukuk, baraj dışı) korunur.",
sihirbaz: {
sira: 105_000,
tur: "ea",
@@ -816,12 +815,12 @@ export const PROFILLER: EvalProfil[] = [
},
danismanProfili: { dil: "ingilizce", ogretimTuru: "yalniz-orgun" },
beklenen: {
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-tek", "tip-devlet", "gevsetme-profil-il-kategori", "profil-dil", "profil-ogretim-turu", "dagilim-ideal"],
havuzGevsetmeBasamagi: ["profil", "il", "kategori"],
minAday: 60,
hedef: H_IDEAL,
supheli: ["B2", "B5"],
notlar: "Kullanıcının verdiği her şey düşer. Liste kurulur ama seçimlerle ilgisi kalmaz; üç gevşetme de açıkça söylenmeli.",
senaryoEtiketleri: ["tur-ea", "sira-orta", "baraj-disi", "il-tek", "tip-devlet", "gevsetme-profil-il", "profil-dil", "profil-ogretim-turu", "dengeli-yetersiz"],
havuzGevsetmeBasamagi: ["profil", "il"],
minAday: 52,
hedef: { hayal: 5, dengeli: 12, garanti: 7 },
notlar:
"Profil ve il gevşer, alan gevşemez (B3 düzeldi): 52 programın 52'si 'Hukuk & Siyasal', 3'ü Kayseri'den. Barajı 100.000 olan hukuk programları havuzda yok (B2 düzeldi). İki gevşetme de açıkça söylenmeli.",
},
},
{

View File

@@ -31,9 +31,9 @@ import {
} from "./ortak";
import { JEV_EVAL_MODEL, JEV_SORU_GRUPLARI, type JevGerekceState } from "./jev-sorulari";
import { PROFILLER, type EvalProfil } from "./profiller";
import { getDb } from "@/lib/db";
import { getDb, havuzAdaylari } from "@/lib/db";
import { kategoriEslesir } from "@/lib/kategoriler";
import { dilimHedefiHesapla, havuzOlustur, havuzuKompaktJson, turLabel, type AdayProgram, type DilimHedef } from "@/lib/rapor-havuzu";
import { dilimHedefiHesapla, havuzOlustur, havuzuKompaktJson, ozelKontenjanSatiriMi, turLabel, type AdayProgram, type DilimHedef } from "@/lib/rapor-havuzu";
import type { RaporParams, RaporSonuc } from "@/features/rapor/types/rapor";
const DILIMLER = ["hayal", "dengeli", "garanti"] as const;
@@ -115,7 +115,14 @@ function degismezler(p: EvalProfil) {
degismez("liste-24", toplam < 24, ["B1", "B6"], `liste ${toplam} satır`);
degismez("baraj-disi", barajDisi.length > 0, ["B2"], `${barajDisi.length} program adayın yazamayacağı barajda (ör. ${barajDisi[0]?.isim} — ${barajDisi[0]?.universite})`);
degismez("ozel-kontenjan", ozelKontenjan.length > 0, ["B8"], `${ozelKontenjan.length} KKTC Uyruklu/M.T.O.K. satırı (ör. ${ozelKontenjan[0]?.isim} — ${ozelKontenjan[0]?.universite})`);
degismez("alan-ilsiz-gevsedi", gevsetildi.includes("kategori") && s.iller.length === 0, ["B3"], `il seçilmeden alan gevşedi; havuzda alan içi ${alanIci}/${havuz.length}`);
// İl seçilmeden alanın gevşemesi yalnız alanda adayın YAZABİLECEĞİ (baraj içi, özel kontenjan dışı) 24 program
// varken bug'dır (B3). Alan baraj yüzünden gerçekten boşaldıysa (a07: SÖZ 310.000 + öğretmenlik) gevşetme meşrudur.
let alanYazilabilir: number | null = null;
if (gevsetildi.includes("kategori") && s.iller.length === 0) {
const r = havuzAdaylari(params.sira, params.tur, { uniturGrubu: s.universiteTipi === "farketmez" ? undefined : s.universiteTipi });
alanYazilabilir = [...r.hayal, ...r.dengeli, ...r.garanti].filter((x) => !ozelKontenjanSatiriMi(x.isim) && kategoriEslesir(x.isim, s.kategoriler, x.fakulte)).length;
}
degismez("alan-ilsiz-gevsedi", alanYazilabilir != null && alanYazilabilir >= 24, ["B3"], `il seçilmeden alan gevşedi; alanda yazılabilir ${alanYazilabilir} program varken havuzda alan içi ${alanIci}/${havuz.length}`);
degismez("il-korunmadi", gevsetildi.includes("il") && ilIci < Math.min(3, toplam), ["B5"], `il gevşedi; havuzda seçili ilden ${ilIci}/${havuz.length}`);
if (tipIci < havuz.length) bulgular.push({ ad: "tip", durum: "ihlal", neden: `üniversite tipi dışı ${havuz.length - tipIci} program` });
if (yinelenen > 0) bulgular.push({ ad: "yinelenen", durum: "ihlal", neden: `${yinelenen} yinelenen program` });
@@ -134,6 +141,8 @@ function degismezler(p: EvalProfil) {
liste: toplam,
ideal: ayni(hedef, IDEAL),
alanIci,
/** Alan ilsiz gevşediyse: alanda adayın yazabileceği program sayısı (<24 ise gevşetme meşru). */
alanYazilabilir,
ilIci: s.iller.length ? ilIci : null,
tipIci,
barajDisi: barajDisi.length,