feat: update app.db and BACKLOG.md with new decisions and adjustments
All checks were successful
Deploy / deploy (push) Successful in 7m45s

- Updated the app.db file to reflect recent changes in the application state.
- Modified BACKLOG.md to include new entries regarding the removal of certain wizard steps, adjustments to priority chips, and the introduction of special quota conditions for candidates.
- Added details on the decision to link priority chips to data sources and clarified the implications for user experience and data handling.
This commit is contained in:
bilalgursen
2026-10-06 17:17:49 +03:00
parent c0696e2cbc
commit a3cb058a3b
74 changed files with 10334 additions and 445 deletions

View File

@@ -311,8 +311,30 @@ yanındaki 2×2).
sığar. Daha uzun sayı gelecekse önce ölç (§9.2), sonra yaz. Ölçülen sınır: 36 px'te
"1.618.988" 123 px — ikonun altına girer. 6–7 haneli sayı birimle kısalır: 245.300 →
`245` + birim `bin`, 1.618.988 → `1,62` + birim `milyon` (bölüm sayfasındaki `kartSayisi`).
- Kullanıldığı yerler: üniversite ve bölüm sayfası (bölümde dört kart: Program, Devlet,
Vakıf, En iyi sıralama; `grid grid-cols-2 gap-4 lg:grid-cols-4`, haritası olmadığı için).
- Kullanıldığı yerler: üniversite ve bölüm sayfası. **Kartlar sayım değil cevaptır** (Bilal,
6 Eki 2026: "program/kontenjan/devlet/vakıf adedi ilgi çekmiyor, öğrencinin işine yaramıyor"):
öğrencinin sorusu "girmesi ne kadar zor, yıllar içinde nereye gidiyor, boş kalıyor mu".
Adetler özet paragrafta kalır, karta çıkmaz. Hesap `src/lib/taban-ozeti.ts`
(KKTC uyruklu, açıköğretim ve uzaktan satırları yelpazeye girmez; doluluk bütün satırlar.
KKTC üniversitesinin kendi sayfasında kıyas evreni kurumun kendisidir: il/kampüs dışlaması kalkar,
ad kuralı kalır — yoksa DAÜ gibi kurumlarda kartlar "henüz taban oluşmadı" der, 6 Eki 2026 QA).
Doluluk yüzdesi boş koltuk varken 100'e yuvarlanmaz, en çok 99 yazar.
- **Bölüm** (`grid grid-cols-2 gap-4 lg:grid-cols-4`, haritası yok): En seçici (sıra +
üniversite adı linkli) · En geniş kapı (ücretsiz devlet örgün programı ≥3 ise devlet
kümesinde, açıklama "Devlet · Bingöl Üni. · 2026 taban sırası"; etiket "Devlette en geniş"
131 px'te iki satıra kırıldığı için kısa tutulur) · Orta taban (devlet programlarını sıraya
dizince ortadakinin sırası; açıklamada "Devlet · 2021'de 105 bin · gevşedi") · Boş koltuk.
Kartın içinde piksel çizgi/seri **yok** (Bilal, 6 Eki 2026: "çok boğdu"); yön kelimesi yeter.
- **Üniversite** (harita yanındaki 2×2): En seçici bölüm (sıra + bölüm adı linkli) · Orta
taban (lisans programlarının ortası) · Doluluk (`%97`) · Türkiye sırası (URAP; listede
olmayan kurumda Kontenjan).
- Sayının yanındaki ad (`KartBaglantisi`, `taban-karti.tsx`) karşı sayfaya gider: bölümde
üniversiteye, üniversitede bölüme; stil kaynak linkiyle aynı (`font-medium text-primary
hover:text-orange-500 hover:underline`). Üniversite adı kısaltılır ("Koç Üni.", "… MYO").
- Yıl yıl ayrıntı çekmecesi ("Yıllara göre taban ›": tablo + kayıtlı sıraya göre "senin
sıran nereye yetti") 6 Eki 2026'da Bilal'in isteğiyle **şimdilik kaldırıldı**; kartların
altında yalnız eski ayrıntı satırı (Akademik göstergeler / Mezun istihdamı) durur. Geri
gelirse sayı dili konuşma Türkçesi olur: "sıranın yettiği program" — "yerleşirsin" denmez.
- Tıklanabilir kart (ör. Türkiye sırası → sıralama sayfası): kartın tamamı link olur
(`after:absolute after:inset-0` gerilmiş link), iç kaynak linki `relative z-10` ile üstte
kalır; hover §2.1.
@@ -327,6 +349,9 @@ yanındaki 2×2).
altında **önizleme** `truncate text-sm text-slate-500` — içeride ne olduğunu söyler ("Hoca
başına 25 öğrenci"), boş "Daha fazla" yazmaz. Sağda `ChevronRight size-5 text-slate-400`.
- Dokununca alt sayfa açılır (§4.10).
- Bir sayfada birden çok satır alt alta durabilir; her biri `mt-4`, kartlara en yakın konu
en üstte. Bugün her sayfada tek satır var (üniversite: "Akademik göstergeler"; bölüm: "Mezun
istihdamı").
### 4.10 Alt sayfa (Drawer) içeriği
Ayrıntı her zaman **alttan açılan sayfada** (`Drawer handleOnly`, tutamaçlı); ekranın ortasında
@@ -548,10 +573,10 @@ telefonda tam genişlik), "Şehre göre" çipleri (sayfa içi `#sehir-…` çapa
- `/universiteler` dizinindeki "Devlet Üniversiteleri" / "Vakıf Üniversiteleri" başlıkları da
tür sayfasına link.
### 4.19 Netler paneli — `program-netleri.tsx` ("Son yerleşenin netleri")
### 4.19 Program ayrıntı çekmecesi — `program-ayrinti.tsx` (eski adı "Netler paneli")
Bilal (24 Eyl 2026): "bu kısımlar design md'ye uygun yap, belirt ki bir daha bu hata olmasın".
Panel ortada açılan `Dialog` ve `text-xs` hücreli bir tabloydu; iki kural birden çiğnenmişti.
**Kural:** program satırından açılan her ayrıntı (netler, akademik göstergeler, ileride
**Kural:** program satırından açılan her ayrıntı (netler, akademik göstergeler,
kontenjan geçmişi) §4.10 **alt sayfadır** — `Drawer handleOnly`, kap ve çarpı `cta-sira-form.tsx`
çekmecesiyle birebir, başlık `px-10 text-center font-heading text-2xl font-bold`, altında tek
cümle bağlam `text-sm text-slate-500`. İçindeki tablo §4.15'tir: başlık `SATIR_BASLIK`, hücre
@@ -561,6 +586,105 @@ puanı") `border-t border-slate-200` + `font-semibold text-slate-900`; ilk sütu
hata durumu `text-base text-slate-500`. Denetim: `tablo-minik-yazi` (hata) — `TableCell`/
`TableHead` içinde `text-xs` yazılamaz. `Dialog` yalnız arama penceresi (`katalog-arama`) ve
sihirbaz modalı içindir; yeni bir ayrıntı için `Dialog` açılmaz.
- **6 Eki 2026 — netlerden tüm ayrıntıya:** satırın yuvarlak düğmesi (`Info` ikonu, "ayrıntı")
tek çekmece açar; veri `/api/program-ayrinti`. Sıra: başlık = program adı, bağlam =
üniversite · il · fakülte; **künye hapları** (§4.12 ölçüsü, link değil: süre + tür, dil,
öğretim türü (örgün değilse), burs/ücret, akreditasyon, baraj, öğretim üyesi sayısı,
yalnız kız/erkek koşulu, kampüs ilçesi — yalnız verisi olanlar); "Yıllara göre" tablosu
(yıl, taban sıra, puan, kontenjan, yerleşen); "Kontenjan türleri (yıl)" `dl` satırları
(yalnız >0 olanlar; özel kontenjanın ayrı taban sırasının elimizde olmadığı notu);
"Son yerleşenin netleri" (eski tablo + OBP katsayısı satırı; 0,18 = meslek lisesi ek
puanı notu); "Yerleşme koşulları (N)" yerel `details` ile kapalı başlar; "Mezun
istihdamı" ve "Üniversite" tek paragraf; en altta kaynak satırı `border-t border-slate-100
text-xs`. Bölüm başlıkları `font-heading text-base font-bold`, notlar `text-sm text-slate-500`;
süs ayraç yok, kart yok. İçerik uzun olduğu için çekmece **kaydırılır** (liste çekmecesi
gibi; §4.10 tek ekran kuralının ikinci istisnası). Açık listem satırında aynı çekmece
`varyant="metin"` ile "Program ayrıntısı" metin düğmesinden açılır ("Haritada gör" kalıbı).
### 4.20 Danışman sohbeti — `sohbet-client.tsx`, `arac-pilleri.tsx`
Sohbet kabuğu **prompt-kit** bileşenleridir (`src/components/ui/`: `prompt-input`, `message`,
`chat-container` + `scroll-button`, `prompt-suggestion`, `loader`, `markdown`); yeni bir sohbet
parçası gerekince önce prompt-kit'e bakılır (`shadcn add https://prompt-kit.com/c/<ad>.json`).
Bilal (6 Eki 2026): "tool use durumunda pill'li bir UI; danışmanla konuş alanı motion ile
genişletilebilir olmalı; UI için prompt-kit kullan."
- **Araç hapları** (`AracPilleri`): danışman veriye bakarken cevabın **üstünde** hap satırı —
§4.17 kompakt çip (`inline-flex h-8 items-center gap-1.5 rounded-full border border-slate-200
bg-card pl-2.5 pr-3 text-xs font-semibold text-slate-700`), başta durum ikonu `size-3.5`:
sürüyor `Loader2 animate-spin text-primary`, bitti `Check text-emerald-600`, hata
`CircleAlert text-red-600`. Metin öğrenci dilinde ve zamanı söyler ("Programlara bakıyorum…"
→ "Programlara baktım"); hata **sözle** ("… (veri gelmedi)"), renk tek başına değil (§2.2).
Aynı araç birden çok kez çağrıldıysa tek hap + "×2". Haplar cevap bitince **kalır**
(danışmanın neye baktığı güven verir); kayıtlı geçmişte araç parçası olmadığından yalnız canlı
cevapta görünür. Hap aşağıdan 4 px gelir, ikon durumla çapraz söner (yay, bounce 0,
0,3/0,2 s); hareketi azalt'ta yalnız opaklık. `role="status" aria-live="polite"`.
prompt-kit'in `Tool` bileşeni **kullanılmaz**: ham araç adı (`program_ara`), İngilizce rozet,
JSON girdi/çıktı ve `dark:` sınıfı taşır — öğrenciye araç adı ve iç kimlik gösterilmez
(`danisman-prompt.ts`); yalnız durum modeli (input-streaming → output-available | output-error)
ortaktır.
- **Genişletme — yerinde büyür, komşular yeniden akar** (Bilal, 6 Eki 2026: tam ekran/perde
denemesi "çok kötü"; "div'in smooth genişlemesi, diğer alanların kendini yeniden
boyutlandırması"). Başlıktaki `Maximize2` düğmesi (`size-7`, öteki başlık düğmeleriyle aynı
sınıf) iki şeyi aynı yayla (§6, `SOHBET_GENISLEME_GECISI`) sürer: sayfa önce panelin üstü
sticky hizasına (`top-28`, 7rem) gelecek kadar yayla kayar, panelin **boyu** oradan alt progressive
blur'un (`.kt-sayfa-blur-alt`, 7rem) üstüne kadar uzar — yani ekran − 14rem; sayfa o kadar
kaymıyorsa kalan fark boydan düşülür, panel bulanık şeride girmez (Bilal, 6 Eki 2026: "aşağı
kısmı progressive blura takılıyor") (ölçülen px'ten hedefe `animate(el, { height })`, bitince satır
içi değer bırakılır) ve `/listem` ızgarasında sohbet **sütunu** genişler — sütun genişliği CSS
değişkeni `--sohbet-kolon` (lg 380 px, xl 440 px; `lg:grid-cols-[minmax(0,1fr)_var(--sohbet-kolon)]`),
`animate(izgara, { "--sohbet-kolon": "<px>" })` ile ızgara genişliğinin %60'ına (en çok 760 px)
büyür; liste ve harita daralan sol sütunda kendini yeniden akıtır. Telefonda (lg altı) yalnız boy
uzar. `Minimize2` geri alır; sohbet durumu (useChat, kaydırma) korunur. Hareketi azalt: geçişsiz.
Perde, sabit konum, ayrı `Dialog`/`Drawer` **yok** — sohbet yeniden kurulmaz, sayfa zıplamaz.
- **Bağlantı hapları** (`sohbet-baglanti.tsx`, Bilal 6 Eki 2026: "chat link verdiğinde kod gibi
veriyor"): danışman cevabındaki site içi adres (`/rehber/…`, `/universite/…`, `/bolum/…`,
`/universiteler/<il>`, `/paket`, `/listem`) prompt-kit `Source` kalıbında **küçük satır içi hap**
(ilk sürüm h-7 "çok yer kaplıyordu"): `inline-flex h-6 items-center gap-1 rounded-full border
border-slate-200 bg-card pl-1.5 pr-2 text-xs font-medium text-primary` + türü söyleyen `size-3.5`
ikon (`BookOpen` rehber, `Landmark` üniversite, `GraduationCap` bölüm, `MapPin` şehir, `Coins`
paket, `ListChecks` listem), hover §2.1, `sr-only` tür etiketi. Metin markdown bağlantısının
başlığıdır (prompt kuralı: `[Yazının başlığı](/rehber/slug)`); model adresi çıplak ya da backtick
içinde yazarsa aynı hap slug'dan türetilen adla çizilir (`baglantilariIsaretle`, `InlineKod`).
Dış bağlantı (`https://`) yeni sekmede açılan altı çizili düz link. prompt-kit `Source`'un Google
favicon'u ve `muted` paleti dış siteler içindir, alınmadı. Sohbet balonu `prose` sınıfı taşır ama
typography eklentisi yok — bağlantı/kod görünümü bu bileşenlerden gelir.
- **Bağlantı önizlemesi — imleci izleyen mini pencere** (Bilal, 6 Eki 2026: motion-primitives
`Cursor` örneği + "aramada yaptığın gibi MacBook penceresi gibi bir kanvas"): rehber, üniversite,
bölüm ve şehir haplarının üzerine gelince (yalnız `(hover: hover) and (pointer: fine)`; dokunmatikte
yok) body'ye portal'lanan 288 px'lik pencere imleci yayla izler (`useSpring` stiffness 450 /
damping 40, imlecin 18 px sağ altı; kenara sığmazsa sol/üst) ve `height 0 → auto, opacity, scale
0,3 → 1` ile açılır, aynı yoldan kapanır (`spring`, 0,3 s, bounce 0 — §6; örnekteki 0,1 bilinçli
alınmadı). Pencere dili aramadaki mini tarayıcıyla aynı (`katalog-arama.tsx` KESFET_TONLARI slate):
`rounded-xl border border-slate-200/80 bg-card shadow-lg shadow-slate-900/5`, çubuk `h-6 bg-slate-50/90`
+ üç `size-2 bg-slate-300` nokta (1 / 0,65 / 0,35) + adres hapı (`kolaytercih.com/rehber/…`,
`text-xs text-slate-500`). Rehberde gövde **yalnız kapak**: tam `RehberKapak` (compact yok)
1200×630 çizilip `scale(288/1200)` ile pencereye oturur — yazı, logo ve piksel süs kesilmez;
başlık/özet/iskelet yok. Üniversite/bölüm/şehir gövdesi `p-3`: `UniLogo md` ya da §4.4 ikon
kutusu, başlık `font-heading text-sm font-bold line-clamp-2`, özet `text-xs leading-5
text-slate-500 line-clamp-3`, künye `text-xs font-medium text-slate-500` ("URAP 18/198").
Veri `/api/onizleme?yol=` (bir gün cache, hap başına bir kez; iskelet yok, başlık hap
metninden hemen çizilir). `pointer-events-none`, `aria-hidden` — bilgi hapın kendisinde.
Hareketi azalt: izleme yok, yalnız opaklık.
- **Araç adımları — prompt-kit `Steps`** (`src/components/ui/steps.tsx` + `collapsible.tsx`;
Bilal: "Steps de olsun duruma göre"): bir cevapta **iki ve daha çok** araç varsa haplar yerine
Steps: başlık `text-xs font-semibold text-slate-500` sürerken "Veriye bakıyorum · 2/3", bitince
"3 adımda baktım", solunda durum ikonu (hover'da prompt-kit'in ok değişimi); açılır gövdede solda
`w-0.5 bg-slate-200` çubuk, sağda her adım `text-xs font-medium text-slate-700` + durum ikonu.
Açık başlar, kullanıcı kapatabilir; açılma `animate-collapsible-down/up` (tw-animate-css),
hareketi azalt'ta geçişsiz. Tek araçta hap kalır. Palet slate'e çevrildi (`muted`/`popover` yok).
- **Liste uyarıları sohbette, danışmanın ağzından** (Bilal, 6 Eki 2026: "bu tarz uyarıları
danışmanın turuncu danışmanla konuş logosu ile chatte vermesi daha uygun"). Listenin kendisinden
çıkan uyarılar (dağılım havuza uyarlandı, tüm tercihler tek şehirde — `liste-uyarilari.ts`)
listenin üstünde sarı kutu olarak **çizilmez**; sohbetin açılışında, "Danışman özeti"nin hemen
altında "Danışman uyarısı" mesajı olur: avatar `DanismanAvatar renk="turuncu"` (panel başlığındaki
işaretin rengi, durağan — avatarda hareket yalnız "düşünüyor" demektir), etiket özetle aynı
(`text-xs font-semibold text-slate-500`), balon işaretin turuncusunda dolu zemin
(`bg-orange-500 font-medium text-white` — Bilal, 6 Eki 2026: "uyarı bubble'ı danışmanın logosu
backgroundında olmalı"); birden çok uyarı tek avatarın altında ayrı balonlardır. Bu, §2.2'deki
"turuncu dolu zeminde uzun metin konmaz" kuralının bilinen **tek istisnasıdır**: uyarı en çok iki
kısa cümledir, daha uzun metin bu balona konmaz; öteki danışman balonları gri kalır
(`bg-slate-100 text-slate-800`). Renk tek başına anlam taşımaz: "Danışman uyarısı" etiketi her
zaman yazılıdır (§2.2). Sohbet ilerlese de kalır. Yeni bir liste uyarısı gerekince
`listeUyarilari`'na eklenir, sayfaya yeni kutu açılmaz.
## 5. Yerleşim