Files
kolaytercih/docs/urun/prd-kapi1-ucretsiz-funnel.md
bilalgursen e62c6f07df
Some checks failed
Deploy / deploy (push) Failing after 1h28m6s
Update package.json scripts, enhance layout with new components, and improve API error handling
- Added new scripts for database operations and temporary production in package.json.
- Integrated KaydetBannerLazy component into the layout for improved user notifications.
- Enhanced API error handling in the soru route to mark credit exhaustion.
- Updated the IletisimPage for better button styling and user experience.
- Refactored ListemPage to streamline user flow and improve session handling.
- Removed unused ListePaneli component to clean up the codebase.
2026-08-06 02:27:42 +03:00

190 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kapı 1 Güçlendirme PRD — Ücretsiz Değerden Ücretli Akışa
> Durum: Taslak v1 · Sahip: Bilal · Tarih: 6 Ağustos 2026
> Gösterim: 🔶 Varsayım (makul ama doğrulanmamış) · 🔵 Açık soru (keşif gerekiyor)
## 1. Yönetici Özeti
Sıralamasını girip `/sonuc`'u gören anonim YKS öğrencisine, giriş yapmadan önce ürünün asıl farklılaştırıcı değerini (yapay zekâ gerekçeli tercih satırı) tattıran ve harcadığı emeği (manuel liste + sihirbaz profili) "kaydet, kaybetme" gerekçesiyle girişe bağlayan bir deneyim kuruyoruz. Amaç **Kapı 1 dönüşümünü (sıra girişi → giriş)** artırmak; kapı ölçümleri ve kredi-bitti e-posta dönüşüyle döngüyü kapatmak. Fiyat ve kredi kurgusu (299 TL paket, 5 deneme kredisi, 3 kredi/liste) bu PRD'de sabittir.
## 2. Problem Tanımı
### Problemi kim yaşıyor?
Sıralamasını girip ücretsiz tabloyu gören ama giriş yapmayan anonim öğrenciler (ve ödemeyi çoğu zaman onaylayan velileri).
### Problem ne?
1. **Ürünün asıl değeri kapıdan önce görünmüyor.** Anonim kullanıcı `/sonuc`'ta yalnızca ham YÖK tablosunu görüyor; "yapay zekâ gerekçeli liste"nin nasıl bir şey olduğunu giriş yapıp 3 kredi harcayana kadar hiç tatmıyor. `?hazir=1` panelinin ikna gücü tamamen metne dayanıyor (`src/app/sonuc/sihirbaz-cagri-karti.tsx:262-292`).
2. **Kullanıcı emeği uçucu.** Manuel 24'lük liste ve sihirbaz profili yalnızca localStorage'da (`src/components/manuel-liste/store.ts:16`, `src/lib/sihirbaz.ts:36`); cihaz/tarayıcı değişince kayboluyor ve "listeni kaydet" doğal giriş gerekçesi olarak kullanılmıyor.
3. **Kapılarda ölçüm yok.** `hazir=1` panel gösterimi, paywall/kilit satır görüntülenmesi ve kredi bitişi için event yok (`src/lib/analitik.ts:14-25`'teki union'da karşılıkları yok). Hangi kapıda ne kadar döküldüğü bilinmiyor.
4. **Kredisi biten kullanıcı çıkmaz sokakta.** 5 deneme kredisi tam 1 liste + 2 soruya yetiyor; sonrasında ödeme yoksa kullanıcıyı geri çağıran hiçbir mekanizma yok.
### Neden acı verici?
- **Kullanıcı:** Tercih dönemi kısa ve stresli; değer görmeden hesap açmak ekstra sürtünme. Emeğinin kaybolması güveni zedeliyor.
- **İş:** Kapı 1 funnel'ın en kalabalık geçişi — burada kaybedilen her kullanıcı, alttaki ödeme dönüşümüne hiç ulaşmıyor. Ölçüm olmadığı için iyileştirme de doğrulanamıyor.
### Kanıt
- Kod: maskeleme sunucuda, anonim tarafta hiç AI çıktısı yok (`src/lib/rapor-maske.ts`); liste/profil client-only; event listesi eksik.
- 🔶 Kapı 1 dönüşümünün düşük olduğu varsayımdır — baseline yok. (Bu, ölçüm iş paketinin kendisini gerekçelendiriyor: İP-A önce baseline kurar.)
- 🔵 Rybbit'te mevcut `sira_girildi``giris_denendi` oranına bakılarak kaba bir baseline bugün çıkarılabilir mi?
## 3. Hedef Kullanıcılar ve Personalar
### Birincil: Sıralı Öğrenci
- YKS sonucu açıklanmış, elinde sıralaması var; tercih penceresi ~2 hafta.
- Mobil ağırlıklı, hızlı ve güven veren bir cevap arıyor; hesap açmaya karşı sürtünme eşiği yüksek.
- Davranış: sıralamasını girer, tabloyu karıştırır, birkaç program ekler, sekmesini kapatır — geri gelmesi garantili değil.
### İkincil: Veli
- Ödemenin fiili onaycısı; "danışman 2.00010.000 TL, bu 299 TL" karşılaştırmasına duyarlı.
- Çocuğunun kurduğu listeyi görmek ve güvenilirlik sinyali (gerekçe, risk notu) ister.
## 4. Stratejik Bağlam
- **İş hedefi:** Tek seferlik 299 TL'lik ürünün geliri doğrudan Kapı 1 hacmiyle çarpılır; funnel'ın en üst geçişini iyileştirmek alttaki her adıma bileşik etki yapar.
- **Neden şimdi:** Ürün sezonluk — yoğunluk tercih döneminde. Sezon öncesi funnel'ın oturması gerekiyor; sezon içinde büyük değişiklik riskli.
- **Rekabet:** İnsan danışmanlar (2.00010.000 TL) ve ücretsiz robotlar. Farklılaştırıcı, gerekçeli + risk analizli liste; bu değer şu an kapının arkasında saklı.
## 5. Çözüm Özeti — 4 İş Paketi
> Sıralama bilinçli: önce ölç (A), sonra değeri göster (B), emeği bağla (C), teaser'ı parlat (D).
### İP-A · Kapı ölçümü (temel)
Funnel'ın üç kapısına gösterim/sonuç event'leri eklenir; Kapı 1 baseline'ı kurulur.
- Yeni event'ler (`OlayAdi` union'ına): `hazir_panel_goruntulendi`, `giris_cta_tiklandi` (prop: `kaynak`), `kilit_goruntulendi` (paywall satırı/kartı viewport'a girince), `kredi_bitti` (KREDI hatası panelinde).
- Gösterim event'leri viewport-temelli ve oturum başına 1 kez; `siraKovasi` dışında ham veri gönderilmez (mevcut gizlilik deseni korunur).
### İP-B · Girişsiz yapay zekâ tadımlığı
Anonim kullanıcı `/sonuc`'ta, kendi sıra kovası + alan tercihine uyan **1 örnek tercih satırını gerçek ürün formatında** (gerekçe + risk notu + trend özeti) görür; hemen altında "24 satırın tamamı için giriş yap — 5 deneme kredin hazır" CTA'sı durur.
- **Maliyet/istismar tasarımı:** Tadımlık canlı AI çağrısıyla değil, **önceden üretilmiş havuzdan** servis edilir (sıra kovası × alan kombinasyonları için batch üretim; `src/lib/rapor-havuzu.ts` altyapısıyla ilişkisi 🔵 incelenecek). Anonim istek başına LLM maliyeti sıfır, prompt-injection yüzeyi yok.
- Tadımlık satır, gerçek rapor bileşeniyle (`rapor-listesi.tsx` satır formatı) birebir aynı görünür — "demo" değil "ürünün kendisi" hissi.
- 🔶 Tek satır yeterli tatma sağlar; 2+ satır ücretsiz değeri fazla büyütüp Kapı 1'i zayıflatabilir (guardrail metriğiyle izlenecek).
- 🔵 Tadımlık satırın programı nasıl seçilecek? (Kullanıcının manuel listesindeki ilk program mı, kovadaki en popüler program mı?)
### İP-C · Liste kaydetme = giriş gerekçesi
Manuel liste ve sihirbaz profili girişte sunucuya taşınır; anonim kullanıcıya emeği büyüdükçe "listen yalnızca bu tarayıcıda — kaydet" tetikleyicileri gösterilir.
- Şema: `savedLists` (userId unique, items JSON, profil JSON) — mevcut `reports` deseniyle aynı upsert yaklaşımı.
- Girişte merge: localStorage listesi sunucudakiyle birleşir (çakışmada localStorage kazanır, 24 sınırı korunur 🔶).
- Tetikleyiciler: liste 3+ programa ulaştığında bir kez gösterilen yumuşak banner; "Seçimlerim" panelinde kalıcı satır. Agresif exit-intent popup **yok**.
- Giriş sonrası dönen kullanıcı listesini her cihazda bulur — ürün "kaydettiğin yer" kimliği kazanır.
### İP-D · Teaser zenginleştirme (ikincil metrik: ödeme dönüşümü)
Maskeli rapor deneyiminde kilidin "ne sakladığı" daha somutlaştırılır:
- `uyarilar` tamamen boşaltılmak yerine **1 uyarıık, kalanı "N uyarı daha kilitli"** göstergesi (`src/lib/rapor-maske.ts:41` değişir; maskeleme sunucuda kalır).
- Kilit satırı (`rapor-listesi.tsx:331-337`) satır sayısı + kişiye özel içerik iması taşır ("21 satırda senin sıralamana özel gerekçe ve risk notu hazır").
-ık satır sayısı `ACIK_SATIR = 3` sabit kalır 🔶 (değiştirme kararı ölçüm sonrası ayrı deney).
### Kullanıcı akışı (hedef durum)
```
sıra girildi → /sonuc: ham tablo + TADIMLIK AI SATIRI (B)
→ manuel liste büyüdükçe "kaydet" tetikleyicisi (C)
→ sihirbaz biter → hazir=1 paneli [ölçülüyor] (A)
→ giriş (5 kredi) → liste üretimi → maskeli rapor (zengin teaser, D)
→ ödeme 299 TL
↳ kredi bitti [ölçülüyor] → 48 saat sonra hatırlatma e-postası (A)
```
## 6. Başarı Metrikleri
### Birincil
**Kapı 1 dönüşümü:** `sira_girildi` (tekil oturum) → başarılı giriş oranı.
- Mevcut: bilinmiyor → İP-A ilk 2 hafta baseline kurar.
- 🔶 Hedef: baseline'a göre **göreli +%30** (baseline netleşince revize edilir).
### İkincil
- `hazir_panel_goruntulendi``giris_cta_tiklandi` tıklama oranı.
- Giriş → `liste_olusturuldu` aktivasyon oranı.
- `kilit_goruntulendi``odeme_baslatildi` (İP-D'nin metriği).
- Kredi-bitti e-postası → geri dönüş oturumu oranı.
### Korkuluk (guardrail)
- **Ödeme dönüşümü düşmemeli:** tadımlık, ücretsiz katmanı "yeterli" hissettirip paketi kanibalize etmemeli.
- **AI maliyeti artmamalı:** tadımlık batch-üretim; anonim trafik LLM'e istek atmaz.
- `/sonuc` LCP/performans gerilemez; ham tablo "her zaman ücretsiz" vaadi korunur.
## 7. Kullanıcı Hikâyeleri ve Gereksinimler
### Epik hipotezi
Anonim kullanıcıya gerçek ürün formatında bir yapay zekâ tadımlığı gösterip emeğini kaydetme gerekçesiyle girişe bağlarsak, Kapı 1 dönüşümü artar; çünkü kullanıcı bugün ne alacağını görmeden ve emeğini korumak için hiçbir neden olmadan hesap açmaya itiliyor. Başarıyı `sira_girildi → giriş` oranıyla ölçeceğiz.
### Hikâyeler
**A1 — Kapı event'leri.** Ürün sahibi olarak funnel'ın her kapısında gösterim ve sonuç sayısını görmek istiyorum.
- [ ] `hazir_panel_goruntulendi`, `giris_cta_tiklandi(kaynak)`, `kilit_goruntulendi(yer)`, `kredi_bitti` event'leri `OlayAdi` union'ına eklendi ve ilgili bileşenlerde ateşleniyor.
- [ ] Gösterim event'leri IntersectionObserver ile, oturum başına en fazla 1 kez.
- [ ] Ham sıra gönderilmiyor; `siraKovasi` deseni korunuyor.
**A2 — Kredi-bitti dönüş e-postası.** Kredisi biten kullanıcı olarak, listemin beni beklediğini hatırlatan bir e-posta almak istiyorum.
- [ ] `kredi_bitti` durumuna düşen kullanıcıya 48 saat sonra tek seferlik e-posta (Resend, `eposta.ts` şablon dili).
- [ ] E-posta `/listem`'e deep-link verir; ödeme baskısı ikinci planda, "3 açık satırın hazır" birinci planda.
- [ ] 🔵 Gönderim zamanlaması için altyapı: cron/queue mu, giriş anında lazy-check mi?
- [ ] 🔵 KVKK: işlemsel hatırlatma mı pazarlama izni gerektiren ileti mi — hukuki sınıflandırma netleşecek.
**B1 — Tadımlık satır.** Anonim kullanıcı olarak, sıralamama uygun bir programın yapay zekâ gerekçesini giriş yapmadan görmek istiyorum.
- [ ] `/sonuc`'ta, sıra kovası + (varsa) sihirbaz alan tercihine uyan 1 tadımlık satır gerçek rapor satırı formatında render edilir.
- [ ] İçerik önceden üretilmiş havuzdan gelir; anonim istek LLM'e gitmez.
- [ ] Satırın altında giriş CTA'sı: metin sonunda `ArrowRight`, `Sparkles` yok (CTA kuralı).
- [ ] Havuzda uygun içerik yoksa bileşen hiç render edilmez (boş/generic tadımlık gösterilmez).
- [ ] 🔵 Havuz üretim kapsamı: kova × alan kombinasyon sayısı ve tazeleme sıklığı.
**C1 — Liste sunucuya taşınır.** Giriş yapan kullanıcı olarak, anonimken kurduğum listeyi hesabımda bulmak istiyorum.
- [ ] Girişte localStorage listesi + sihirbaz profili sunucuya merge edilir (çakışmada client kazanır, 24 sınırıılmaz).
- [ ] Farklı cihazdan girişte liste sunucudan yüklenir; localStorage ile iki yönlü senkron kuralı belgelenir.
- [ ] Merge idempotent — çift giriş çift kayıt üretmez.
**C2 — Kaydet tetikleyicisi.** Anonim kullanıcı olarak, listem büyüdüğünde kaybolabileceğini öğrenmek istiyorum.
- [ ] Liste 3. programa ulaştığında bir kez yumuşak banner: "Listen yalnızca bu tarayıcıda — giriş yap, kaydet."
- [ ] "Seçimlerim" panelinde kalıcı "listeni kaydet" satırı.
- [ ] Banner kapatılabilir; kapatma oturumda kalıcı. Exit-intent popup yok.
**D1 — Zengin teaser.** Maskeli raporu gören kullanıcı olarak, kilidin arkasında ne olduğunu somut görmek istiyorum.
- [ ] `uyarilar`dan 1 tanesi açık, kalanı "N uyarı daha kilitli" sayacıyla gösterilir; maskeleme sunucuda kalır.
- [ ] Kilit satırı kişiselleştirilmiş metin taşır (kalan satır sayısı + "senin sıralamana özel").
- [ ] `?acildi=1` unblur akışı bozulmaz.
### Kısıtlar
- Maskeleme ve tadımlık seçimi **her zaman sunucuda** — kilitli gerçek içerik client'a asla inmez.
- Badge/eyebrow, kapatma çarpısı ve CTA ok deseni proje kurallarına uyar (`AGENTS.md`).
- Sihirbaz/liste mimarisinde davranış değişirse `/meraklisina` şeması aynı commit'te güncellenir (`src/app/meraklisina/huni-semasi.tsx`).
## 8. Kapsam Dışı
- Fiyat, paket yapısı, kredi miktarları (sabit — kullanıcı kararı).
- Abonelik, ara paket, referral programı.
- Canlı AI tadımlığı (anonim kullanıcıya gerçek zamanlı LLM çağrısı).
- Exit-intent popup ve agresif e-posta dizileri.
- `ACIK_SATIR` sayısını değiştirme (ölçüm sonrası ayrı deney).
- Mobil uygulama, push notification.
## 9. Bağımlılıklar ve Riskler
### Bağımlılıklar
- **E-posta:** Resend + `eposta.ts` şablonları hazır; yalnızca yeni şablon + tetikleme mekanizması gerekir.
- **Tadımlık havuzu:** `rapor-havuzu.ts` mevcut altyapısının kapsamı incelenecek 🔵; batch üretim script'i gerekebilir.
- **Şema değişikliği:** `savedLists` tablosu (drizzle migration).
- **`/meraklisina` şema senkronu:** İP-B ve İP-C davranış değiştiriyor → şema + anlatım metni aynı PR'da güncellenir.
### Riskler
- **Kanibalizasyon:** Tadımlık + zengin teaser ücretsiz deneyimi "yeterli" hissettirebilir. → Korkuluk metriği; tadımlık 1 satırda sabit başlar.
- **Baseline'sız iterasyon:** A'dan önce B/C/D'ye başlanırsa etki ölçülemez. → İP-A her zaman önce gider; B/C/D en az 2 hafta baseline'dan sonra açılır 🔶.
- **Merge karmaşası (C1):** İki cihazda farklı listeler → sessiz veri kaybı algısı. → Çakışma kuralı basit ve tek yönlü tutulur, edge case'ler kabul kriterlerinde.
- **Sezon zamanlaması:** Yoğun dönemde funnel değişikliği riskli. → Sezon öncesi yayın; sezon içi yalnızca metin/ölçüm ayarı.
- **KVKK/e-posta:** Hatırlatma e-postasının hukuki sınıfı belirsiz 🔵 → netleşene dek A2 yalnızca işlemsel dille yazılır.
## 10. Açık Sorular
1. 🔵 Rybbit'teki mevcut event'lerden bugün kaba bir Kapı 1 baseline'ı çıkarılabilir mi (`sira_girildi` vs `giris_denendi` tekil oranı)?
2. 🔵 Tadımlık satırın program seçimi: manuel listedeki ilk program mı, kova için önceden seçilmiş popüler program mı?
3. 🔵 `rapor-havuzu.ts` bugün ne yapıyor; tadımlık havuzu onun üstüne mi kurulur?
4. 🔵 Kredi-bitti e-postası için zamanlama altyapısı (cron vs lazy-check) ve KVKK sınıfı.
5. 🔵 `savedLists` mi yoksa mevcut `reports.params` üzerinde genişletme mi — şema kararı.
6. 🔶 +%30 göreli hedef baseline sonrası revize edilecek.
---
## Öz Değerlendirme (şablon gereği)
- **En güçlü bölüm:** Problem tanımı — kod referanslarıyla somut.
- **En zayıf bölüm:** Başarı metrikleri — baseline yok; hedefler İP-A tamamlanana dek varsayımsal.
- **Önce doğrulanacak varsayımlar:** (1) Kapı 1 dönüşümünün gerçekten düşük olduğu, (2) tek satır tadımlığın kanibalize etmeden ikna ettiği.
- **Önerilen ilk adım:** İP-A'yı uygula (küçük, risksiz, 1-2 gün) + Rybbit'ten retrospektif baseline denemesi; 2 hafta veriyle B/C önceliği netleştir.