diff --git a/src/app/sonuc/page.tsx b/src/app/sonuc/page.tsx index f6451a9..e41766d 100644 --- a/src/app/sonuc/page.tsx +++ b/src/app/sonuc/page.tsx @@ -32,6 +32,7 @@ export default function SonucPage({ sira?: string; tur?: string; sihirbaz?: string; + kaynak?: string; hazir?: string; il?: string | string[]; tip?: string; @@ -122,6 +123,7 @@ export default function SonucPage({ sira={sira} tur={turKey} otomatikAc={params.sihirbaz === "1"} + kaynak={params.kaynak} secimlerHazir={params.hazir === "1"} /> diff --git a/src/components/arama-funnel-karti.tsx b/src/components/arama-funnel-karti.tsx index 6e59359..6c3b9b7 100644 --- a/src/components/arama-funnel-karti.tsx +++ b/src/components/arama-funnel-karti.tsx @@ -91,7 +91,7 @@ export function AramaFunnelKarti({ onSec }: { onSec: () => void }) { return; } if (profil) { - router.push(sonucHref({ sihirbaz: "1" })); + router.push(sonucHref({ sihirbaz: "1", kaynak: "arama" })); return; } // Yapay Zeka niyetli CTA: kapı tamamlanınca /sonuc'ta üretim akışı devam diff --git a/src/features/liste/hooks/use-tercih-profili.ts b/src/features/liste/hooks/use-tercih-profili.ts index 1e77c03..0f543e2 100644 --- a/src/features/liste/hooks/use-tercih-profili.ts +++ b/src/features/liste/hooks/use-tercih-profili.ts @@ -298,11 +298,24 @@ export function programEkleIste(opts: { /** Profil yazıldıktan sonra; bekleyen hedef varsa yönlendirme href'i döner. * `girisli`, "sihirbaz" hedefinde üretimin otomatik başlayıp başlamayacağını * belirler (kapı bileşeni oturumu facet isteğiyle paralel çözer). */ +/** Kapı tetiği → üretim denemesinin ölçüm etiketi. Yalnız `hedef="sihirbaz"` + * dalında kullanılır; listede olmayan tetik `bilinmiyor` sayılır (izinli + * değerlerin tek kaynağı: rapor/components/uretim-basladi-olayi.tsx). */ +const KAYNAK_TETIKTEN: Partial> = { + arti: "arti", + arti_toast: "arti", + listem_bos: "bos_durum", + sihirbaz: "sihirbaz", + sonuc: "sonuc_kapi", +}; + export function profilTamamlandi( profil: TercihProfili, girisli = false, ): string | null { const duzenle = durum.duzenle; + // durum aşağıda sıfırlanıyor (tetik: "diger"); ölçüm etiketi için önce yakala + const tetik = durum.tetik; riskleriYenile(profil); const bekleyen = durum.bekleyen; const hedef = durum.bekleyenHedef; @@ -332,7 +345,15 @@ export function profilTamamlandi( // Yapay Zeka niyetli giriş: kapıda sihirbazı zaten doldurdu, /sonuc'ta // akış kesilmesin — girişliyse üretim otomatik başlar (?sihirbaz=1), // girişsizse ücretsiz tablo + giriş CTA paneli (?hazir=1) karşılar. - return sonucHref(girisli ? { sihirbaz: "1" } : { hazir: "1" }); + // + // `kaynak`: girişli dalda /sonuc üretimi kendiliğinden başlatıyor, yani + // denemeyi başlatan yüzey bu kapıdır. Tetikten türetiliyor ki hero ya da + // arama kartıyla aynı kovaya düşmesin (bkz. uretim-basladi-olayi.tsx). + return sonucHref( + girisli + ? { sihirbaz: "1", kaynak: KAYNAK_TETIKTEN[tetik] ?? "bilinmiyor" } + : { hazir: "1" }, + ); } if (hedef === "sonuc") return sonucHref(); // Düzenleme /sonuc'a götürür: tablo profil çerezinden SSR'lanır diff --git a/src/features/odeme/components/rapor-yok-cta.tsx b/src/features/odeme/components/rapor-yok-cta.tsx index 8fabe8b..30863e3 100644 --- a/src/features/odeme/components/rapor-yok-cta.tsx +++ b/src/features/odeme/components/rapor-yok-cta.tsx @@ -21,7 +21,7 @@ export function RaporYokCta() { asChild className="h-11 cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600" > - + 24'lük listeni oluştur diff --git a/src/features/rapor/components/uretim-basladi-olayi.tsx b/src/features/rapor/components/uretim-basladi-olayi.tsx index d3bdff4..9215dfb 100644 --- a/src/features/rapor/components/uretim-basladi-olayi.tsx +++ b/src/features/rapor/components/uretim-basladi-olayi.tsx @@ -25,9 +25,18 @@ import { tercihProfiliOku } from "@/features/sihirbaz/sihirbaz-profil"; const IZINLI_KAYNAKLAR = new Set([ "sihirbaz", "hazir_cta", + // Gerçek giriş dönüşü: /giris callback'i doğrudan /listem'e iner. "giris_donusu", "bos_durum", "odeme_sonrasi", + // /sonuc'ta ?sihirbaz=1 ile otomatik başlayan üretimin gerçek yüzeyleri. + // Eskiden hepsi "giris_donusu" sayılıyordu (güvenlik denetimi G3). + "hero", + "cta", + "arama", + "arti", + "sonuc_kapi", + "rapor_yok", "bilinmiyor", ]); diff --git a/src/features/sihirbaz/components/cta-sira-form.tsx b/src/features/sihirbaz/components/cta-sira-form.tsx index 8f69a7c..3766868 100644 --- a/src/features/sihirbaz/components/cta-sira-form.tsx +++ b/src/features/sihirbaz/components/cta-sira-form.tsx @@ -169,7 +169,7 @@ export function CtaSiraForm({ const yeniProfil = { sira, tur, secimler }; tercihProfiliYaz(yeniProfil); setAcik(false); - router.push(sonucHref(girisli ? { sihirbaz: "1" } : { hazir: "1" })); + router.push(sonucHref(girisli ? { sihirbaz: "1", kaynak: "cta" } : { hazir: "1" })); } function acikDegisti(v: boolean) { diff --git a/src/features/sihirbaz/components/hero-form.tsx b/src/features/sihirbaz/components/hero-form.tsx index ec4f94e..d0549c1 100644 --- a/src/features/sihirbaz/components/hero-form.tsx +++ b/src/features/sihirbaz/components/hero-form.tsx @@ -101,7 +101,7 @@ export function HeroForm() { const profil = { sira, tur, secimler }; tercihProfiliYaz(profil); setModalAcik(false); - router.push(sonucHref(girisli ? { sihirbaz: "1" } : { hazir: "1" })); + router.push(sonucHref(girisli ? { sihirbaz: "1", kaynak: "hero" } : { hazir: "1" })); } // Kayıtlı profil varsa sihirbazı atla, doğrudan sonuç sayfasına götür. diff --git a/src/features/sihirbaz/components/sihirbaz-bolumu.tsx b/src/features/sihirbaz/components/sihirbaz-bolumu.tsx index 8f813b2..b6da341 100644 --- a/src/features/sihirbaz/components/sihirbaz-bolumu.tsx +++ b/src/features/sihirbaz/components/sihirbaz-bolumu.tsx @@ -12,11 +12,14 @@ export async function SonucSihirbazi({ sira, tur, otomatikAc, + kaynak, secimlerHazir, }: { sira: number; tur: PuanTuruKey; otomatikAc: boolean; + /** ?sihirbaz=1'i üreten yüzey; otomatik üretimin ölçüm etiketi olur. */ + kaynak?: string; secimlerHazir: boolean; }) { // Kullanıcının kayıtlı raporu var mı? Yalnızca CTA'nın hangi hâlde render @@ -35,6 +38,7 @@ export async function SonucSihirbazi({ girisliMi={Boolean(session)} raporVar={Boolean(raporSatiri?.result)} otomatikAc={otomatikAc} + kaynak={kaynak} secimlerHazir={secimlerHazir} /> ); diff --git a/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx index a89c8fc..43837b8 100644 --- a/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx +++ b/src/features/sihirbaz/components/sihirbaz-cagri-karti.tsx @@ -58,6 +58,7 @@ export function SihirbazBolumu({ girisliMi, raporVar, otomatikAc, + kaynak, secimlerHazir, }: { sira: number; @@ -68,6 +69,7 @@ export function SihirbazBolumu({ raporVar: boolean; /** ?sihirbaz=1 ile gelindiyse modalı otomatik aç */ otomatikAc?: boolean; + kaynak?: string; /** ?hazir=1 (hero sihirbazından girişsiz geliş): seçimler storage'da, panel giriş CTA'sına döner. URL'den gelir ki SSR'da doğru panel render edilsin. */ @@ -222,7 +224,11 @@ export function SihirbazBolumu({ if (otomatikGonder && !otomatikBasladi.current) { otomatikBasladi.current = true; // replace: geri tuşu bu sayfaya dönünce tekrar /listem'e sekmesin - router.replace(listemUretHref("giris_donusu")); + // Etiket ?sihirbaz=1'i ÜRETEN yüzeyden gelir. Eskiden burası sabit + // "giris_donusu" yazıyordu; oysa gerçek giriş dönüşü /listem'e + // doğrudan iner, /sonuc'a hiç uğramaz — hero, katalog, arama, + ve + // ödeme-sonrası tek yanlış kovada toplanıyordu. + router.replace(listemUretHref(kaynak ?? "bilinmiyor")); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [otomatikGonder]);