v2 #10

Merged
bilal merged 34 commits from v2 into main 2026-10-11 01:38:50 +03:00
5 changed files with 20 additions and 9 deletions
Showing only changes of commit e4c06f54d9 - Show all commits

View File

@@ -485,6 +485,10 @@ elle yazılmaz. Başka yerde tekrarlanmaz — SectionEyebrow kuralının tek ist
Sınıf dizileri tek dosyada (`SATIR_AD`, `SATIR_META`, `SATIR_CIP`, `SATIR_MOBIL_SAYI`,
`SATIR_BUTON_KABI`…); üniversite, bölüm ve `/sonuc` tabloları oradan okur. Yeni bir liste
tablosu bu sabitleri kullanır, sınıfı elle yazmaz.
- **Varyant çipi** (7 Eki 2026): burs / öğretim dili / öğretim türü etiketi (`Program.varyant`,
`src/lib/program-varyant.ts`, ör. "Burslu · İngilizce", "%50 İndirimli", "Açık Öğretim") tür
çipinin hemen ardından `SATIR_CIP` ile; null ise çizilmez. Aynı üniversite + aynı bölüm adı
taşıyan kayıtlar (Başkent Tıp ×6 gibi) ancak bu çiple ayırt edilir; tekilleştirme yapılmaz.
- Risk sütunu (`/sonuc`) sm'den itibaren ayrı sütun; telefonda adın altındaki sayı satırına
iner. Etiket §4.5: `size-2` nokta + `text-xs font-semibold text-{renk}-600` + `RISK_ETIKET`.
- Veride BÜYÜK HARF gelen üniversite adı ekranda `trBaslikDuzeni` ile yazılır.
@@ -661,6 +665,9 @@ sihirbaz modalı içindir; yeni bir ayrıntı için `Dialog` açılmaz.
solma (§6). Akademik göstergeler çekmecesi (§4.9) aynı bileşenin kartlı modunu kullanır.
### 4.20 Danışman sohbeti — `sohbet-client.tsx`, `arac-pilleri.tsx`
- **Soru formu hazırlanırken** (7 Eki 2026): `soru_sor` aracı tamamlanana dek cevap iskeleti değil
`TextShimmerLoader` "Soruları hazırlıyorum…" (`role=status`); danışman araç çalıştırırken avatar
header logosuyla aynı `"rota"` koreografisini oynatır (`AnimasyonluMark`), farklı bir animasyon yazılmaz.
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`).
@@ -941,6 +948,9 @@ alanı §4.6 hapı (`h-11 rounded-full`). Düğmeler sitenin `Button`'u (`sm`):
font-medium text-red-600`. Kapanmış form tek satır: "Formu cevapladın." (yeşil tik) ya da "Form
kapandı; isteğini yazarak söyleyebilirsin." Yeni bir anket/soru akışı gerekince bu bileşen kullanılır;
radio/checkbox'lı yeni form tasarlanmaz.
Sorular arası geçiş **sihirbaz adım geçişiyle birebir aynı** (7 Eki 2026): yay ve varyantlar tek
kaynak `src/lib/adim-gecisi.ts` (`adimGecisiVaryantlari`, `adimGecisi`); yön index'ten türer. Pasif
sorular DOM'da kalır (mutlak/saydam/`inert`) ki FormData toplanmaya devam etsin.
## 5. Yerleşim

View File

@@ -12,6 +12,8 @@ const eslintConfig = defineConfig([
"out/**",
"build/**",
"next-env.d.ts",
// Paralel ajan worktree'leri (typegen çıktıları lint'e girmesin).
".claude/worktrees/**",
]),
]);

View File

@@ -443,8 +443,7 @@ export function ListemGovde({
bildikleri={danismaninBildikleri}
genis={sohbetGenis}
onGenisDegistir={sohbetGenisligiAyarla}
// 0/1 bayrak; prop adı entegrasyonda revizyonAcik olur
revizyonHakki={hasPaket ? 1 : 0}
revizyonAcik={hasPaket}
/>
</div>
) : (

View File

@@ -350,7 +350,7 @@ export function SohbetClient({
genis: genisProp,
onGenisDegistir,
genisYukseklik = GENIS_YUKSEKLIK,
revizyonHakki = 0,
revizyonAcik = false,
}: {
baslangicKredi: number;
/** Sunucu tarafında çekilmiş danışman profili; verilirse mount fetch'i atlanır */
@@ -382,8 +382,8 @@ export function SohbetClient({
/** Genişletilmiş panelin yüksekliği; verilmezse ekrana göre hesaplanır
* (üst 7rem sticky hizası, alt 7rem progressive blur payı). */
genisYukseklik?: string;
/** Kalan liste revizyonu hakkı (paketli); 0 ise revizyon örneği gösterilmez. */
revizyonHakki?: number;
/** Liste revizyonu açık mı (paketli aday); kapalıysa revizyon örneği ve ipucu gösterilmez. */
revizyonAcik?: boolean;
}) {
const [girdi, setGirdi] = useState("");
const [yuklendi, setYuklendi] = useState(initialMesajlar != null);
@@ -942,7 +942,7 @@ export function SohbetClient({
!ozet && "justify-center",
)}
>
{[...(revizyonHakki > 0 ? [REVIZYON_ORNEGI] : []), ...ORNEK_SORULAR].map((s) => (
{[...(revizyonAcik ? [REVIZYON_ORNEGI] : []), ...ORNEK_SORULAR].map((s) => (
<PromptSuggestion
key={s}
size="sm"
@@ -1092,7 +1092,7 @@ export function SohbetClient({
>
<PromptInputTextarea
placeholder={
revizyonHakki > 0
revizyonAcik
? "Sorunu yaz ya da listende ne değişsin söyle… (1 kredi)"
: "Sorunu yaz… (1 kredi)"
}

View File

@@ -689,7 +689,7 @@ export async function raporUretAyrintili(
let kaynak: RaporTani["kaynak"] = "model";
if (!enIyi || enIyi.onarim.modelSecimi === 0) {
// Revizyonda kodla kurulan liste adayın isteğini yok sayar ve bir
// revizyon hakkını yakardı: hata fırlar (çağıran krediyi/hakkı iade eder).
// sohbet kredisini yakardı: hata fırlar (çağıran krediyi iade eder).
if (!zamanAsimi || revizyonNotu || !ZAMAN_ASIMINDA_KODLA_KUR) {
// Zaman aşımı hatası olduğu gibi fırlar: çağıran "çok uzun sürdü,
// kredin iade edildi" mesajını bu hatadan tanıyor.
@@ -797,7 +797,7 @@ export async function raporUretAyrintili(
p.kontenjanSon,
p.yerlesenSon,
params.sira,
...metindekiSayilar(p.isim, p.universite),
...metindekiSayilar(p.isim, p.universite, p.varyant ?? ""),
// Koddan gelen "öne çıkan" cümlelerdeki sayılar meşrudur (TÜİK %, URAP sırası, km…)
...metindekiSayilar(...(p.oneCikan ?? [])),
...profilSayilari,