🎵 Muzibu Premium Üyelik Sistemi

v2 - Düzeltilmiş Versiyon

Tenant-Aware & Performans Optimized

📅 26 Kasım 2025 | 🎯 Tenant 1001 (muzibu.com) | 🚀 Production-Ready Design
📋 Sistem Genel Bakış

🎯 3 Seviyeli Üyelik Sistemi

Seviye Durum Dinleme Limiti Özellikler
🚫 ÜYE DEĞİL Kayıtsız ziyaretçi 30 saniye önizleme Her şarkının ilk 30 saniyesi
👤 NORMAL ÜYE Kayıtlı hesap 1 saat/gün toplam Tam şarkı dinleme, günlük reset
PREMIUM/DENEME Ödeme veya trial Sınırsız Tüm yetkiler

⚠️ Tenant-Aware Sistem

SADECE Tenant 1001 (muzibu.com) için aktif!
- Users tablosu universal (tüm tenant'lar paylaşır)
- Premium alanlar sadece ilişki: is_premium, trial_ends_at, daily_listening_seconds
- Diğer tenant'lar bu sistem etkilenmez

✅ v2 Düzeltmeleri

✓ Guest kullanıcılar her şarkının ilk 30 saniyesini dinleyebilir
✓ "Reklamsız" ve "Offline indirme" özellikler kaldırıldı
✓ Deneme süresi geri sayım olarak gösteriliyor
✓ Admin panel tenant 1001'e özel kolonlarla gösteriliyor
✓ Performans optimizasyonları eklendi (Redis, Cache, Lazy Reset)

⚙️ Admin Panel - Tenant 1001 Özel Görünüm Sadece Tenant 1001
UserManagement modülünde tenant kontrolü ile Muzibu'ya özel kolonlar eklenir. Diğer tenant'lar bu kolonları görmez.

📝 Kod Yapısı

// UserManageComponent.php

if (tenant()->id == 1001) {
    $this->columns[] = 'membership_type';
    $this->columns[] = 'daily_listening';
    $this->bulkActions[] = 'make_premium';
    $this->bulkActions[] = 'give_trial_7';
}
Kullanıcı E-posta 🎵 Üyelik Tipi ⏱️ Bugün Dinleme İşlemler
Ahmet Yılmaz ahmet@example.com 👤 Normal Üye 42 dk / 60 dk
Mehmet Demir mehmet@example.com 💎 Premium Sınırsız
Ayşe Kaya ayse@example.com 🎁 Deneme (5 gün) Sınırsız
Zeynep Şahin zeynep@example.com 👤 Normal Üye 60 dk / 60 dk (DOLDU)

Toplu İşlemler (Bulk Actions)

✅ Tenant-Aware Yapı

Universal Users Tablosu:
- is_premium (boolean)
- trial_ends_at (timestamp)
- daily_listening_seconds (integer)
- last_listen_reset (date)

Diğer Tenant'lar: Bu kolonları görmez, etkilenmez

⚡ Performans Optimizasyonları
Premium sistem performans sorunlarına karşı optimize edilmiştir.

⚠️ Potansiyel Performans Sorunları

İşlem Sorun
Her şarkı başlamadan API call N+1 problem, DB yükü
Her saniye dinleme artırma DB'ye sürekli write
Günlük reset (tüm kullanıcılar) 00:00'da DB lock
user_listening_logs tablosu Hızlı şişme (milyon satır)

✅ Çözümler

1️⃣ Cache Strategy (5 dk)

// Her API call'da user bilgisi cache'den
$userAccess = Cache::remember("user_access_{$userId}", 300, function() {
    return [
        'is_premium' => $user->isPremium(),
        'daily_listening_seconds' => $user->daily_listening_seconds,
        'limit' => 3600
    ];
});

2️⃣ Redis Counter (Her 10 saniyede DB flush)

// Frontend: Her timeupdate'de Redis'e yaz
Redis::hincrby("listening:{$userId}", date('Y-m-d'), $seconds);

// Background job: Her 10 saniyede DB'ye flush
$dailySeconds = Redis::hget("listening:{$userId}", date('Y-m-d'));
User::where('id', $userId)->update(['daily_listening_seconds' => $dailySeconds]);

3️⃣ Lazy Daily Reset (Cron job YOK!)

// Kullanıcı şarkı çalarken kontrol:
if ($user->last_listen_reset < today()) {
    $user->update([
        'daily_listening_seconds' => 0,
        'last_listen_reset' => today()
    ]);
    Cache::forget("user_access_{$userId}");
}

4️⃣ Listening Logs - Partitioning & Auto-Delete

// Migration: Aylık partitioning
CREATE TABLE user_listening_logs (
    id BIGINT AUTO_INCREMENT,
    user_id BIGINT,
    song_id BIGINT,
    listened_seconds INT,
    listened_at TIMESTAMP,
    PRIMARY KEY (id, listened_at)
) PARTITION BY RANGE (YEAR(listened_at) * 100 + MONTH(listened_at)) (
    PARTITION p202511 VALUES LESS THAN (202512),
    PARTITION p202512 VALUES LESS THAN (202601)
);

// Cron: 90 günden eski logları sil
DB::table('user_listening_logs')
    ->where('listened_at', '<', now()->subDays(90))
    ->delete();

📊 Performans Metrikleri

Metrik Hedef Optimizasyon
API Response Time < 50ms Cache (5 dk)
DB Write Operations < 6 per minute Redis + 10s flush
Daily Reset Time 0ms (no cron) Lazy reset
Logs Table Size < 10M rows Partitioning + 90d delete