Manuel listenin haritası /sonuc'ta tablonun altından sayfanın en üstüne
alındı: listesini kurmuş ziyaretçi ekranda önce kendi listesini görür.
Liste boşken harita DOM'a hiç girmez — yer tutucu da çizilmez, tadımlık
main'in ilk çocuğu kalır ve first:mt-0 çalışmayı sürdürür. Yani ürünü ilk
kez gören ziyaretçide sayfa sırası hiç değişmiyor.
Çerez neden gerekti: manuel liste localStorage'ta yaşıyor, store'un sunucu
snapshot'ı her zaman boş liste dönüyor. Harita yukarıdayken kayıtlı liste
ancak hidrasyondan sonra okunabildiği için harita sonradan belirip sayfayı
itiyordu (mobilde ~146 px, masaüstünde ~368 px; CLS ~0,13 / ~0,35). Client
artık listenin yalnızca UZUNLUĞUNU kolaytercih.liste-sayi çerezine aynalıyor
(kişisel veri ya da program kimliği yok, öznitelikleri kolaytercih.profil ile
birebir aynı); sunucu bunu okuyup haritaya ilk boyada tam ölçülü yer ayırıyor,
chunk inince kutunun yalnızca içi doluyor. Çerez hidrasyona kadar geçerli:
store okunduktan sonra tek doğru kaynak listenin kendisi, böylece bayat çerez
ya da çekmeceden boşaltılan liste durumunda boş harita ekranda kalmıyor.
Yanında: harita iskeletine motion-reduce:animate-none (artık katlamanın
üstünde, durdurulamaz nabız gösterilmemeli), yurt dışı şeridine sabit
yükseklikli loading yer tutucu (ssr:false + loading'siz dynamic, yoktan
beliren ~104 px). Kararın tersini belgeleyen üç yorum bloğu da güncellendi.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Buton "24 satırın tamamı" iddiasından arındırılmıştı (2373a9a) ama iki
eleman yukarıdaki paragraf aynı vaadi sürdürüyordu: "24 tercihlik
listenin her satırı bu formatta kurulur". Maske girişsiz/paketsiz
kullanıcıya 3 satır açıyor (rapor-maske.ts:12 ACIK_SATIR), kalan 21'in
gerekçe/risk/trend metni maskeli geliyor.
Cümleye "ilk üçü hemen açılır" eklendi — sayı yazıldı, bulanıklaştırma
ve garanti dili yok. "3" elle yazıldığı için (ACIK_SATIR `server-only`,
bu dosya "use client") tek kaynak bağı koda yorum olarak iliştirildi.
Bulgu: 36-tasarimci-g1-ve-navbar.md B2. Metin yönü Bilal'in.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Liste store'unun sunucu snapshot'ı her zaman boş liste döner
(liste-store.ts:86), kayıtlı manuel liste ancak hidrasyondan sonra
okunur. Harita sayfanın tepesindeyken kayıtlı listesi olan dönüş
ziyaretçisinde ~368 px yüksekliğinde sonradan beliriyor ve tadımlık ile
tabloyu aşağı itiyordu; main'in ilk çocuğu olduğu için impact fraction
~1, CLS eşiğinin çok üstü. Silinen placeholder bunu yeri sunucuda
rezerve ederek engelliyordu.
Harita tablonun altına alındı: sonradan belirdiğinde yalnızca sihirbaz
ile dipnotu iter, ikisi de katlanın altında. Bilgi mimarisi olarak da
doğru sıra — harita, tablodan kurulan listenin görselleştirmesi.
Yeni sıra: tadımlık → tablo → harita → sihirbaz → dipnot.
Sıraya bağlı stiller yeni sıraya göre doğrulandı: tadımlığın
first:mt-0'ı artık her durumda geçerli (üstünde kardeş kalmadı), harita
kendi mt-16'sını alıyor (tablo section'ı ve sihirbaz kartlarıyla aynı
ritim — eskiden üst boşluğu main'in py-12'sinden geliyordu).
Bulgu: 36-tasarimci-g1-ve-navbar.md B1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sunucu artık paketliden kredi düşmüyor; arayüz hâlâ "3 kredi düşer" ve
"Listemi güncelle — 3 kredi" diyordu. raporKredi prop'u paketliye 0
iner, modal tek `ucretsiz` bayrağıyla üç metin yerini buna bağlar.
Kredi mantığı (krediYeter, KrediYetersiz dalı) olduğu gibi kalır.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
/paket "liste ve revizyon dâhil" diyor, kod her üretimde 3 kredi
düşüyordu. Tek `maliyet = user.hasPaket ? 0 : RAPOR_KREDI` değişkeni
harcama, iade ve dönen bakiye satırlarını birden kapatıyor.
spendCredits/grantCredits çağrıları bilerek duruyor: ledger'daki
UNIQUE(reason, ref_id) üretimin tek idempotency çapası ve DUPLICATE
dalındaki "önceki deneme başarısızdı" çıkarımı refund satırının
varlığına dayanıyor. İade tutarı da koşullu — yoksa harcaması 0 olan
paketli her başarısız denemede bedava 3 kredi kazanırdı.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ÖNERİ — tek başına düşürülebilir (git reset --hard HEAD~1). Bir önceki
commit yalnız yanlış iddiayı kaldırdı ve kendi başına tutarlı; bu commit
CTA'ya yeni bir cümle öneriyor, karar Bilal'in.
Buton: "Giriş yap ve listeni oluştur" -> "Kendi listemi oluştur"
Alt satır: "· Giriş sonrası liste hemen üretilir" eklenir.
Sayı YOK ve bilerek: ACIK_SATIR (rapor-maske.ts, server-only) ve
DENEME_KREDISI (credits.ts, appdb import ediyor) bu "use client" dosyaya
import edilemez; elle "3"/"5" yazmak tek kaynak kuralını bozar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Maske girişsiz kullanıcıya 24 satırın tamamını değil yalnız ilk birkaçının
analizini açıyor (rapor-maske.ts); "5 deneme kredin hazır" da butonun
götürdüğü yerin sözü değil. Buton metni yeni vaat eklemeden yanlış olanı
bırakıyor: "Giriş yap ve listeni oluştur". Kanonik sağ ok yerinde duruyor.
Üstteki "Bu, 24 satırlık Yapay Zeka listenden yalnızca bir örnek." cümlesi
doğru olduğu için değişmedi — üretilen liste gerçekten 24 satır.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tadımlık CTA'sının giriş callback'i sonucHref() yerine
listemUretHref("tadimlik") — kullanıcı /sonuc'a geri bırakılmak yerine
üretimin koştuğu /listem'e iner, liste ek tık olmadan başlar.
"tadimlik" IZINLI_KAYNAKLAR'a eklendi, yoksa ölçüm "bilinmiyor"a düşerdi.
Ayrıca tadimlik_goruntulendi'nin üstüne seri kırılması notu: olay bugüne
kadar sayfanın ~2.200 px altında yaşıyordu, bundan sonra ilk ekranda —
iki dönem karşılaştırılamaz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Yeni sıra: ManuelHarita -> TadimlikBolumu -> SonucProgramTablosu. Tadımlık
ödeme öncesi gösterebildiğimiz tek gerçek önizleme; tablonun ~1.500 px
altında değil ilk ekranda durmalı. Props ve bileşen içleri değişmedi.
Tadımlık <section>'ına first:mt-0: harita boş durumda null döndüğü için bu
bölüm main'in ilk DOM çocuğu olabiliyor, main'in py-12'si yeterli.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
/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>
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>
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>
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>
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>
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>
- 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>
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.
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.
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.
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.
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.
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>
- 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>
- 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>