Commit Graph

33 Commits

Author SHA1 Message Date
bilalgursen
26893ce7cf feat(olcum): sihirbazın 1. adımı ve kaynaksız /paket linkleri ölçülür
(a) `sihirbaz_adim{adim:1}` artık sihirbaz modalı açıldığında atılıyor.
Bugüne kadar olay yalnız `adimaGit`in ileri geçişinde atılıyordu; modal
zaten 1. adımda açıldığı için 1. adım hiç "geçilmiyor", dolayısıyla hiç
sayılmıyordu ve huninin paydası `sira_girildi`den türetilmek zorunda
kalıyordu. Mount effect'i + `olayBirKez` ile tam bir kez düşüyor:
1→2→1→2 gezinmesi bileşeni unmount etmediği için tekrar tetiklemiyor,
sessionStorage tekilleştirmesi de aynı sekmede ikinci açılışı sayıyor.

SERİ KIRILMASI: bu değişikliğin canlıya çıktığı tarihten ÖNCEKİ
`sihirbaz_adim` serisinin paydası farklıdır — o dönemde `adim:1` hiç
atılmadı, seri yalnız 2 ve 3'ten oluşuyor. Öncesi ve sonrası
karşılaştırılamaz; huni okumalarında kırılma tarihi dipnot edilmeli.
Aynı desen `program_eklendi` için 21 Eylül'de uygulanmıştı.

(b) Kaynaksız 10 `/paket` linkine tekil `?kaynak=` eklendi; sitedeki 14
`/paket` linkinin 14'ünde artık kaynak var. Değerler mevcut şemayla
(`kilit`, `kredi_bitti`, `nav`) aynı dilde: fiyat_paket, fiyat_kredi,
kosullar, tercih_degisti, tercih_degisti_yetersiz, danisman_rozet,
danisman_kredi_bitti, danisman_kredi_az, odeme_geri, odeme_hata.

`paket-gorunum-olayi.tsx`'teki `KAYNAKLAR` allowlist'i de genişletildi:
listede olmayan her değer `"diger"`e düştüğü için, genişletilmeseydi 10
yeni kaynağın tamamı tek kovada toplanır ve ölçüm deliği kapanmazdı
(bağımlılık kapanışı — dosya şartnamenin listesinde yoktu, raporda
sapma olarak yazıldı).

Görsel değişiklik yok; yeni olay adı ya da yeni ölçüm yüzeyi eklenmedi.
Doğrulama: `next typegen` + `tsc --noEmit` + `lint` temiz.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 00:17:21 +03:00
bilalgursen
9bd448bd16 fix(kredi): kullanıcı başına üretim kilidi — çifte harcama kapanır
All checks were successful
Deploy / deploy (push) Successful in 10m52s
credit_ledger.ref_id benzersizliği yalnız AYNI denemenin tekrarını koruyordu
(ağda kaybolan cevap → aynı requestId ile retry). requestId istemcide her
mount'ta yeniden üretildiği için "aynı kullanıcı üretimi iki kez başlattı"
durumu hiç yakalanmıyordu: üretim sürerken (20-60 sn) ikinci sekmede açılan
/listem?uret=1 ya da geri→ileri ikinci bir ListeUretici monte edip 3 krediyi
ikinci kez yakıyordu. Karşılığında tek rapor çıkıyordu, çünkü reports.user_id
benzersiz ve ikinci üretim birincinin üstüne yazıyor. Bakiyesi yetmeyen
deneme kullanıcısı ise akışın ortasında "kredi yetersiz" ekranı görüyordu.

- report_locks (user_id birincil anahtar): ikinci INSERT benzersizlik
  ihlaliyle düşer, bu da "üretim sürüyor" demektir. Kilit kredi
  harcamasından ÖNCE alınır, finally'de bırakılır.
- Bayat kilit (süreç OOM'la öldü, deploy) 180 sn sonra devralınabilir;
  devir koşullu UPDATE olduğu için iki eşzamanlı devralmadan yalnız biri
  kazanır. Salım requestId koşullu: geç uyanan eski sahip devralanın
  kilidini silemez.
- Yeni SURUYOR kodu: istemci bunu "hata" sayıp taze requestId ile yeniden
  denerse çifte harcama kapısı yeniden açılırdı. Ekranda "Tekrar dene"
  bilerek yok; kullanıcı listeye yönlendiriliyor, kredi harcanmadı.
- DUPLICATE dalının "İstek tekrarlandı" HATA'sı da SURUYOR'a çevrildi
  (BACKLOG #1'deki ikinci çifte harcama yolu). Revizyon dalı değişmedi.

BACKLOG #1 · güvenlik denetimi G5

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:54:21 +03:00
bilalgursen
bca1849eee fix(olcum): otomatik üretimin kaynağı gerçek yüzeyden gelir (G3)
/sonuc'taki otomatik üretim kaynağı sabit "giris_donusu" yazıyordu; oysa
?sihirbaz=1 üreten hiçbir yer giriş dönüşü değil — gerçek giriş dönüşü
/listem'e doğrudan iniyor, /sonuc'a uğramıyor. Hero, CTA formu, arama kartı,
+ kapısı, boş liste ekranı ve rapor-yok CTA'sı tek yanlış kovada
toplanıyordu, yani P2'nin ölçmek istediği soru ölçülmüyordu.

Etiket artık ?sihirbaz=1'i üreten tarafta kuruluyor ve /sonuc üzerinden
geçiriliyor; kapıdan gelenler tetikten türetiliyor. giris_donusu yalnız
gerçek callback yolunda kalıyor.

Güvenlik denetimi G3 · docs/ekip-raporlari/2026-09-22/07-guvenlik-denetimi.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:45:31 +03:00
bilalgursen
d720e1888f merge(funnel/listem-girisi): fix(giris): callback yalnız better-auth'un kabul ettiği yollarda takılır
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:38:36 +03:00
bilalgursen
1364f8cb43 feat(olcum): /listem boş ekranından açılan kapı ayrı tetikle sayılır
Bu kapı huninin en sonunda açılıyor (giriş yaptı, listesi yok, profili de
yok). "diger" ile sayılınca arama kartı gibi genel yüzeylerle aynı kovaya
düşüyordu; ayrı değer bu dilimi görünür kılar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:33:01 +03:00
bilalgursen
419b617cab fix(listem): boş durum CTA'sı ana sayfaya atmaz, tercih kapısını açar
Profil yokken CTA kullanıcıyı "/"'a gönderiyordu: /listem'e kadar gelmiş
adayı ana sayfaya geri atmak huninin ortasında bağlam kaybı. Artık kapı
aynı sayfada açılıyor (hedef "sihirbaz", tanıtım adımı atlanıyor);
tamamlanınca mevcut yol işliyor — /sonuc?sihirbaz=1 → /listem?uret=1.

Profilli dalda hedefe kaynak etiketi eklendi (uret=1 ilk parametre kalır).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:21:46 +03:00
bilalgursen
f60fbd135d feat(olcum): liste_uretim_basladi olayı — üretim denemesinin paydası
Bugüne kadar yalnız başarı (liste_olusturuldu) ölçülüyordu; kaç kişinin
üretimi denediği bilinmiyordu. /listem?uret=1 ile üretim gövdesi mount
olduğunda yeni bileşen `liste_uretim_basladi` atar.

Olay bilerek liste-uretici.tsx'e değil, listem-icerik.tsx'te ona kardeş
mount edilen yeni bir istemci bileşenine kondu (o dosya bu turda başka bir
işin altında). İkisi aynı `uret` dalında render edildiği için koşulları
birebir aynı.

`kaynak` URL'den, yani kullanıcı denetiminden geldiği için allowlist'ten
geçirilir; listede olmayan değer "bilinmiyor" raporlanır. Giriş
round-trip'inde değerin kaybolmaması için geriYol da kaynağı taşır —
`uret=1` her zaman ilk parametre kalır (giris-karti.tsx:31 sözleşmesi).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:18:15 +03:00
bilalgursen
d41120c3ce fix(liste): üretim sonrası sunucu yanıt vermezse 502 sayfasına gidilmiyor
iPad raporu: liste üretildikten sonra ekran "Bad Gateway" gösterdi ve
tarayıcı `listem.txt` indirdi. Sıra şu: liste DB'ye yazıldı → `router.replace`
→ Next'in RSC isteği ters vekilden 502 aldı → Next tam-sayfa gezinmeye düştü
(WebKit düz metin cevabı dosya olarak kaydetti) → 6 sn'lik emniyet supabı
`window.location.replace` ile aynı 502'yi ekrana getirdi.

Üç değişiklik:

- Dockerfile runner katmanına `--max-old-space-size=768`. V8 cgroup sınırını
  görmez, heap üst sınırını host RAM'ine göre seçer; `mem_limit: 1g` ile
  birleşince V8 daha GC yapmadan konteyner OOM ile ölüyor ve açık istek 502'ye
  düşüyor. Sınır builder katmanında vardı, runner'a miras kalmıyordu.
- `/api/saglik`: DB/oturum/AI'ya dokunmayan en ucuz uç. Dockerfile HEALTHCHECK
  bunu yokluyor — süreç ölüp açılırken `docker ps` "unhealthy" gösterir, bir
  sonraki 502'nin kaynağı tahmine kalmaz.
- Emniyet supabı tam-sayfa gezinmeden önce sunucuyu yokluyor. Sunucu yoksa
  ekranda kalınıp "listen oluşturuldu ve kaydedildi, kredin yeniden harcanmaz"
  ekranı + sunucuyu yeniden yoklayan buton gösteriliyor; `liste_uretim_hata
  {kod:"SUNUCUYA_ULASILAMIYOR"}` olayı düşüyor. Sunucu yokken `router.refresh`
  de aynı tuzağa düştüğü için o dalda atlanıyor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 01:08:18 +03:00
bilalgursen
ea3310ac5b fix(liste): üretim sonrası ekran listeye kesin geçer
replaceState + router.refresh() ikilisinde Next yönlendirici kuyruğu refresh'i
hiç çalıştırmıyordu (ekran 'Listen hazırlanıyor'da kalıyor, yenileyince geliyordu).
Tek router.replace; 6 sn emniyet supabı (tam yükleme); 90 sn'de 'hâlâ hazırlanıyor'.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 23:34:52 +03:00
bilalgursen
3e75a6fbbd fix(rapor): yazdırma dipnotundaki yıl aralığı raporun üretildiği veri penceresinden
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:05:14 +03:00
bilalgursen
2356e8aa38 merge: veri/2026-pc~1 — metinler ve meraklısına şeması ([Bilal] başlık-2027 commit'i hariç) 2026-09-21 17:04:25 +03:00
bilalgursen
ceeb70375d feat(veri): bileşenler yılsız Program'a ve veri-yillari sözlüğüne geçti (P-B b)
- SiraSerisi = { siraGecmisi, ilkYil? }; yardımcılar dizinin kendi son iki
  elemanıyla çalışır, yıl ilkYil + indeks. raporSiraSerisi diziyi doldurmaz:
  5 elemanlı eski raporlar 2024→2025 trendini göstermeye devam eder.
- Tablo başlıkları "Son ${VERI_YIL_SAYISI} yıl"; rapor listesi başlığı kaydın
  kendi pencere uzunluğunu söyler (eski rapor: 5).
- siraYiliEtiketi SON_YIL/ONCEKI_YIL'dan; bölüm/üniversite sayfa metinleri ve
  metadata SON_YIL, TERCIH_YILI, BASLIK_YILI sözlüğünden.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:00:39 +03:00
bilalgursen
ce40b7c5b3 feat(veri): Program tipi yılsız — db eşleyicisi, lib ve snapshot ilkYil (P-B a)
Program artık siraGecmisi (YILLAR ile hizalı) + efektifSira + siraSon/puanSon/
kontenjanSon/yerlesenSon taşır. db.ts kolonları YILLAR'dan üretip takma adla
seçer, programSatiri eşleyicisi ham satırı Program'a çevirir; SELECT_COLS'un
üç tüketicisi de eşleyiciden geçer. EFEKTIF_SIRA veri-yillari'dan gelir.

- trend: ILK_YIL tek kaynaktan, opsiyonel ilkYil parametresi
- rapor snapshot'ına opsiyonel ilkYil yazılır (eski kayıtlar: okurken ILK_YIL)
- rapor promptu son 4 yılı göndermeye devam eder, anahtarlar dinamik
- tadımlık "son N yıl" filtresi genel: N != VERI_YIL_SAYISI ise servis edilmez
- veri-kapsami VERI_YIL_SAYISI'nı veri-yillari'dan türetir

Bileşenler bir sonraki commit'te yeni tipe geçer (ikisi birlikte derlenir).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 17:00:39 +03:00
bilalgursen
3fa5cab906 feat(veri): katalog/OG/rapor metinleri yılı veri-yillari.ts'ten okur — 2026 yüklemesi P-C
- "2025 yerleştirme" → SON_YIL, "2026 tercihleri" → TERCIH_YILI, başlık yılı → BASLIK_YILI
- yazdırılabilir rapor dipnotu: "2021–2025" → VERI_ARALIGI
- meraklısına 1. bölüm: efektif sıra açıklaması yılsız
- KATALOG_VERI_TARIHI: 2026-09-21 (2026 verisinin çekim tarihi)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:53:42 +03:00
bilalgursen
d7c29ac4a6 merge: entegrasyon/guvenli-etiket — görünen 'Garanti' dilim adı 'Güvenli'
# Conflicts:
#	src/features/sihirbaz/components/cta-sira-form.tsx
2026-09-21 16:13:04 +03:00
bilalgursen
f7ed8f2f0b fix: denetim bulguları — çip adı sahte 'tercihlerin değişmiş', çekmece kartı, senkron riski
- tercihFarki eski 'İş garantisi' parametresini yeni ada eşleyerek kıyaslar;
  ad değişikliği 3 kredilik güncelleme çağrısı üretmesin
- çekmece kartı yalnız profil yokken sıra ister, butonu sıra kapısını açar
  (profilsiz ziyaretçi /listem giriş duvarına gönderilmiyordu → çıkmaz)
- sunucuylaBirlestir risksiz gelen kayıtların riskini doldurur
- /paket'teki fiyat kıyasına kaynak satırı

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:06:15 +03:00
bilalgursen
5853b7d091 feat(etiket): görünen "Garanti" dilim adı site genelinde "Güvenli"
Yalnız kullanıcıya görünen etiket değişir; iç anahtar, tip, DB değeri, API
parametresi, mermaid classDef ve analitik değeri `garanti` olarak kalır
(veri göçü yok).

- risk.ts: tek kaynak DILIM_ETIKET + dilimdenFarkliRiskEtiketi; rapor
  listesi, yazdır tablosu, /sonuc sekmeleri, seçimlerim paneli ve
  meraklısına şeridi buradan okur
- "Güvenli · Güvenli" / "Güvenli (Güvenli)": satır detayında risk etiketi
  yalnız dilimin varsayılanından farklıysa, yazdır ve seçimlerimde yalnız
  kelime farklıysa yazılır
- LLM prompt'ları: `garanti` teknik anahtar, adaya "güvenli" denir sözlüğü
  (rapor, soru, tadımlık); liste özeti modele görünen dilim adıyla gider
- meraklısına şeması (SEMA düğümü, aria-label), 2. bölüm anlatımı ve
  AGENTS.md şema kuralı görünen adla eşitlendi
- "yerleşme garantisi vermez" türü vaat reddi cümleleri aynen kaldı

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 16:03:22 +03:00
bilalgursen
cf19903e19 feat(analitik): huni olayları
Huninin kör noktalarına altı olay (adlar kalıcı sözleşme):
- cta_form_goruntulendi: programatik sayfalardaki CTA kartı, yalnız
  profilsiz dalda (görünüm hook'u; sayfa ayrımı Rybbit pathname'inden)
- sira_form_hata {kaynak: hero|cta|kapi|duzenle}: facet isteği hatası;
  geçersiz sayı doğrulaması sayılmaz
- sonuc_goruntulendi {girisli, sira_kovasi}: /sonuc pathname'i maskeli,
  huni adımı bu olayla kurulur; oturum başına girişli/anonim birer kez
- paket_goruntulendi {kaynak: kilit|kredi_bitti|nav|diger}: sayfaya
  dokunmadan yeni paket/layout.tsx + client bileşenle; /paket linklerine
  ?kaynak= eklendi (listem kilit kartları, kredi-yetersiz, nav kredi pill'i)
- liste_uretim_hata {kod: HATA|ISTISNA}: AUTH/KREDI/PAKET dalları atmaz
- giris_hata {yontem: eposta|google, status}

Ham sıra ve e-posta hiçbir olaya girmez; sıra yalnız siraKovasi() ile.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 04:49:09 +03:00
bilalgursen
30b9b41a22 refactor: update site header and chat components for improved user experience
All checks were successful
Deploy / deploy (push) Successful in 12m16s
Replaced the static logo in the SiteHeader with an animated component for enhanced visual feedback. Updated the PaketSatinAl component to include a dynamic link based on user context. Enhanced the ListeUretici and ListemGovde components with improved layout and messaging features, including the addition of a new initial preference comment display in the SohbetClient. Adjusted styling for consistency across components and improved loading states with skeleton screens.
2026-08-11 12:54:46 +03:00
bilalgursen
15e2c4c961 feat: implement chat history deletion functionality
All checks were successful
Deploy / deploy (push) Successful in 8m4s
Added a new DELETE endpoint to allow users to clear their chat history. This functionality ensures that while the chat messages are removed, any credits spent remain intact. Additionally, updated the ListemGovde component to reflect changes in user preferences and integrated a modal for notifying users about preference changes. Enhanced the SohbetClient component to include a button for clearing chat history, improving user experience and interface clarity.
2026-08-09 04:44:19 +03:00
bilalgursen
8870845fa1 refactor: remove TercihDegistiUyarisi component
Deleted the TercihDegistiUyarisi component from the project. This component was responsible for notifying users about changes in their preferences and suggesting a list update. The removal is part of a broader effort to streamline the codebase and improve maintainability.
2026-08-09 04:44:13 +03:00
bilalgursen
437e2bc96a fix: update callback handling and user profile management in list components
All checks were successful
Deploy / deploy (push) Successful in 7m23s
Enhanced the handling of user profiles and callback URLs in various components. Updated the `GirisKarti` to support multiple callback scenarios, ensuring seamless user experience. Improved the `ListeUretici` and `ListemIcerik` components to manage profile data more effectively, including handling cases where the profile is stored in cookies. Additionally, refined the logic for redirecting users based on their profile status, ensuring they are directed to the appropriate pages without losing context. Updated the database file to reflect these changes.
2026-08-09 04:15:53 +03:00
bilalgursen
696dc69763 refactor: optimize AramaFunnelKarti styles and enhance city data structure
All checks were successful
Deploy / deploy (push) Successful in 7m30s
Removed unnecessary elements and optimized styles in the AramaFunnelKarti component for improved layout. Updated the city data structure in harita-ulkeler.ts to include coordinates, enhancing geographical data handling. Additionally, refactored risk color definitions in risk.ts for better clarity and maintainability.
2026-08-09 03:55:56 +03:00
bilalgursen
ce6871d623 refactor: güncellenmiş profil çerezi ile sonuç sayfası yönlendirmeleri
Some checks failed
Deploy / deploy (push) Has been cancelled
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.
2026-08-09 03:31:42 +03:00
bilalgursen
14f9b622b0 feat: tadımlık havuzuna üniversite tipi boyutu
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>
2026-08-09 00:12:25 +03:00
bilalgursen
78d7c51a7a perf: deterministik dekor memo'ları ve küçük render süpürmeleri (Faz 7)
Some checks failed
Deploy / deploy (push) Has been cancelled
- pixel-decor: PixelField/PixelDivider piksel üretimi useMemo([seed]) —
  504 iterasyon + ~150 element çekmece reorder'ının her karesinde
  yeniden üretiliyordu
- rapor-listesi: acikSira effect'i önceki-prop desenine döndü (çift render
  ve eslint-disable kalktı), Set lazy init, tekIl useMemo
- program-tablosu: 3 dilimin spread'i useMemo
- typing-animation: displayedText state yerine türetme; kaynak reset'i
  render sırasında — tick başına state yazımı ve effect bağımlılığı azaldı
- site-top-banner: saniyelik geri sayım tiki startTransition'da
- program-liste-verileri: sparkline 6 dizi geçişi tek döngüde
- secimlerim-paneli: SecimSatiri profili prop'tan alır + memo (24 ayrı
  store aboneliği kalktı)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 14:29:14 +03:00
bilalgursen
f3d8bf9b94 perf: harita/tablo re-render'ları + content-visibility (Faz 6)
- tercih-haritasi: viewBox animasyonu transient — kare başına setState
  (380ms × ~23 render × 81 path) yerine svg.setAttribute; il path ref
  callback'leri key başına stabil; il özetleri/şerit/pin grupları useMemo;
  reduce×3+baskinRisk tek geçiş; çift lookup ve çift uniLogoYoluFromAd kalktı
- liste-store: O(1) idSet + useListedeMi/useListeDoluMu primitive selector'ları;
  program-ekle-butonu artık tüm listeye abone değil — 50 satırlık tabloda
  mutasyon başına 50 yerine yalnız değişen buton render olur
- bolum-program-listesi: decorate-sort-undecorate yerine stable toSorted;
  sıralama/sayfalama startTransition'da
- il-secim-haritasi: normalizeIlAdi modül seviyesinde precompute (render
  başına ~1000 string normalizasyonu vardı); Map/Set/sort useMemo
- kt-cv-satir utility: uzun tablo satırlarında content-visibility:auto +
  contain-intrinsic-size (program/bolum/universite/rapor tabloları)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 14:23:05 +03:00
bilalgursen
668568b5b5 perf: istemci istek cache'i (dedup+TTL) ve profil cache (Faz 5)
- lib/istek-cache: modül seviyesi in-flight dedup + 5dk TTL cache (SWR
  bağımlılığı olmadan); caller iptali paylaşılan fetch'i düşürmez
- /api/facetler'in 5 çağrı yeri (hero, cta, kapı, sihirbaz adımları, demo)
  ve /api/katalog-ara cache'e bağlandı — sihirbazda 2↔3 adım geçişi ve
  tekrarlanan aramalar artık ağa çıkmıyor; /api/soru GET dedup-only (ttl 0)
- katalog-arama: elle yukleniyor state'i kalktı, "cevaplanmamış sorgu"
  türetmesi + startTransition; rehber puanlaması Schwartzian; ⌘K listener'ı
  useEffectEvent ile tek sefer bağlanıyor
- sihirbaz-adimlar: il sort/filter useMemo (çip başına 81 eleman kopyalanıp
  sıralanıyordu, harita dizisi referansı sabitlendi)
- sohbet-client: stream chunk güncellemeleri startTransition'da — cevap
  akarken input yazımı bloklanmıyor
- sihirbaz-profil: modül cache + event/storage geçersizlemesi (tek "+"
  tıklamasında 3 localStorage okuma + JSON.parse vardı)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 14:11:05 +03:00
bilalgursen
90ac590737 perf: sohbet markdown lazy + marked client'tan çıktı, mermaid görünürlükte (Faz 4)
- markdown.tsx: blok bölme marked.lexer yerine çit-farkındalıklı boş satır
  bölücüsü — react-markdown'ın yanında ikinci tam parser (~460 KB paket)
  client'a inmiyordu artık gerekmiyor; memoized blok yapısı aynen korunur
- markdown-lazy: react-markdown+remark zinciri (~215 KB) lazy; fallback
  aynı class'lı düz metin (stream'de flash/CLS yok), sohbet mount'unda
  preloadMarkdown ile chunk önden ısınır — /listem 1315->1133 KB eager JS
- el-cizimi-sema: mermaid importu IntersectionObserver'a bağlandı
  (rootMargin 200px); şemalar hep fold altında, ~1 MB mount'ta inmiyor

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 14:01:48 +03:00
bilalgursen
b7e10efd1d perf: TercihHaritasi dinamik + lazy sarmalayıcılara kapı/preload (Faz 3)
- tercih-haritasi-lazy: turkey-map-react il geometrisi (~197 KB) dynamic
  ssr:false + viewBox oranlı iskelet (CLS yok); /sonuc 1286->1099 KB,
  /listem 1503->1315 KB eager JS
- manuel-harita: liste boşken harita hiç render edilmez (boş haritaya
  197 KB iniyordu) — aynı oranlı placeholder alanı korur
- program tablosu section'ına hover/focus preload (niyet anında ısıtma)
- liste-cekmecesi/kaydet-banner/tercih-profili-kapisi lazy sarmalayıcıları
  kapı kazandı: koşul sağlanana dek chunk inmez; açan butonlara
  (listem-butonu, + butonu, navbar sıralama butonları) hover/focus preload
- liste-cekmecesi: kullanılmayan DrawerDescription importu temizlendi

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:57:48 +03:00
bilalgursen
22e2fde058 refactor: /sonuc senkron kompozisyona geçti (Faz 9)
- liste-queries.ts (siraylaProgramAra) ve sihirbaz-queries.ts
  (getSihirbazFacetleri) eklendi — /sonuc'un SQLite okumaları feature
  sorgularına indi
- Yeni sunucu sarmalayıcıları: SonucProgramTablosu (+skeleton),
  TadimlikBolumu (girişliyse null — gruplu sınırda skeleton bilerek yok),
  SonucSihirbazi (session + rapor-varlığı + facetler içeride; client
  orkestratöre çözülmüş değerler iner)
- Sayfa senkron: searchParams.then() içinde sıra doğrulaması; geçersiz sıra
  SiraGerekli'ye düşer; geçerli akışta tablo+tadımlık+sihirbaz+dipnot+footer
  tek gruplu Suspense'te (bugünkü tek await'li akışla aynı anda belirir)
- sonuc/loading.tsx silindi; geometrisi sayfadaki fallback'te yaşıyor
- Davranış değişikliği yok (getSession React cache ile tek okuma)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 01:42:32 +03:00
bilalgursen
fbd184e2be refactor: rapor feature'ı — listem, yazdır, sohbet ve actions taşındı (Faz 8)
- app/sonuc/actions.ts → features/rapor/rapor-actions.ts birebir taşındı
  (kredi harcama/iade idempotency yolları bayt bayt aynı, yalnızca import
  yolları değişti); liste-uretici/revizyon-kutusu action'ı doğrudan import
  ediyor
- lib/rapor-kaydi.ts rapor-queries.ts'e emildi: kullanicininRaporu aynı tek
  okuma kapısı; listem sayfasındaki inline drizzle sorgusu sohbetGecmisiGetir
  oldu; tadimlikSec re-export'u eklendi
- listem-govde, sohbet-client, revizyon-kutusu, liste-uretici, listem-bos-cta,
  rapor-listesi, tadimlik-satiri, yazdir-butonu features/rapor/components/'a
- Yeni async ListemIcerik (verifySession + maskeleme + bosDurum dalı içeride;
  çift await searchParams kalktı) ve RaporYazdir (3 redirect + yazdırılabilir
  belge); skeleton'lar eski loading.tsx geometrileriyle aynı dosyada
- /listem ve /rapor/yazdir senkron: searchParams.then() + sayfada Suspense;
  maxDuration=300 ve metadata sayfada kaldı; iki loading.tsx silindi
- Davranış değişikliği yok; /api/soru el değmedi

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 01:39:33 +03:00
bilalgursen
820eea7eca refactor: ortak tipler @/types/yokatlas + features/rapor/types'a çıkarıldı, server-only korumaları eklendi (Faz 1)
- Program/PUAN_TURLERI/DilimKey/RankResults/UniturGrubu/ProgramNetSatiri/
  SihirbazFacetleri artık src/types/yokatlas.ts'te; lib/db.ts yalnızca sorgu
  fonksiyonları barındırıyor
- RaporSonuc/RaporKapsam/RaporParams/MaskeliRapor src/features/rapor/types/
  rapor.ts'e taşındı; ölü kalan TercihSchema/RaporSchema silindi
- 11 lib dosyasına import "server-only" eklendi; scripts'in düz node ile
  import ettiği dosyalara (db, appdb, rapor-havuzu, tadimlik-havuzu, ai/client,
  ai/cagri, credits) bilinçli eklenmedi
- Davranış değişikliği yok; pnpm build yeşil

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 01:06:06 +03:00