Some checks failed
Deploy / deploy (push) Failing after 1h28m6s
- 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.
190 lines
15 KiB
Markdown
190 lines
15 KiB
Markdown
# 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.000–10.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.000–10.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ı açı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").
|
||
- Açı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ı aşı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.
|