Üye Aktivite Takip Sistemi

Kapsamlı Analiz ve Sistem Değerlendirmesi

Sistem Aktif 9 Tablo Analiz Multi-Tenant

📊 Genel Durum

Müjdeli Haber: Sisteminizde çok kapsamlı bir aktivite takip sistemi zaten çalışıyor! Üyelerinizin sitede yaptığı neredeyse her işlem kayıt altına alınıyor.

✅ 95%
Aktivite Kapsama
4
Ana Sistem
15+
İzlenen Aktivite

📝 Basit Anlatım (Herkes İçin)

Hangi Aktiviteler Kayıt Ediliyor?

Giriş/Çıkış İşlemleri:

Üye ne zaman siteye girdi, ne zaman çıktı, hangi cihazdan bağlandı

Profil Değişiklikleri:

İsim, e-posta, telefon gibi hangi bilgileri ne zaman güncelledi

Şarkı Dinleme:

Hangi şarkıyı, ne kadar süre dinledi, atladı mı, nereden çaldı (playlist, albüm...)

Favorileme:

Hangi şarkı, albüm veya playlist'i favorilerine ekledi/çıkardı

Playlist İşlemleri:

Playlist oluşturma, düzenleme, silme, şarkı ekleme/çıkarma

Yorum/Değerlendirme:

Ne zaman yorum yaptı, hangi içeriğe yorum yaptı

Cihaz Bilgileri:

Hangi cihazdan (telefon, tablet, bilgisayar), hangi tarayıcıdan bağlandı

Oturum Bilgileri:

Kaç aktif oturum var, son aktivite ne zaman

Bu Veriler Neden Önemli?

  • Kullanıcı Davranışını Anlama: Üyeler hangi saatlerde aktif, hangi içerikleri tercih ediyor?
  • Güvenlik: Şüpheli aktiviteler (çok fazla başarısız giriş, farklı cihazdan erişim) tespit edilebilir
  • İçerik Stratejisi: Hangi şarkılar çok dinleniyor, hangileri atlanıyor? Buna göre öneriler yapılabilir
  • Kullanıcı Desteği: Üyenin geçmiş aktiviteleri görülerek sorunlar daha hızlı çözülebilir

Bu Kayıtlar Nasıl Görülebilir?

Admin Paneli:
  • /admin/activity-logs → Tüm sistem aktivitelerini gösterir
  • /admin/users/[id]/activity-logs → Belirli bir üyenin tüm aktivitelerini gösterir
Filtreleme Özellikleri:
  • • Tarih aralığı seçme (belirli bir ay, hafta, gün)
  • • Aktivite tipine göre filtreleme (sadece giriş/çıkış, sadece dinlemeler...)
  • • Modüle göre filtreleme (Müzik, Kullanıcı, Playlist...)
  • • Arama yapma (örn: "Yağmur Yağar" şarkısı kim dinledi?)

Eksik veya Geliştirilebilir Alanlar

İndirme Kayıtları:

Şarkı indirme işlemleri için özel bir tablo yok. Activity log'dan takip edilebilir ama daha detaylı olabilir.

Analitik Dashboard:

Veriler toplanıyor ama görsel istatistik paneli (günlük aktif kullanıcı, en çok dinlenen saatler...) geliştirilebilir.

🔧 Teknik Detaylar (Geliştiriciler İçin)

Sistem Mimarisi

Aktivite takip sistemi 4 ana bileşenden oluşuyor:

1. Spatie Activity Log

Genel aktivite logları (CRUD işlemleri, kullanıcı işlemleri)

activity_log

2. Song Plays System

Müzik dinleme analitikleri (duration, skip, source tracking)

muzibu_song_plays

3. Session Management

Aktif oturum takibi (device, IP, last_activity)

user_active_sessions

4. User Model Fields

Kullanıcı tablosunda doğrudan saklanan aktivite verileri

users (last_login_at, last_played_song_id)

1. Activity Log Tablosu (activity_log)

Tablo Yapısı:

CREATE TABLE activity_log (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    log_name VARCHAR(255) NULL COMMENT 'Modül adı (Song, Album, User...)',
    description TEXT NOT NULL COMMENT 'İşlem açıklaması',
    subject_type VARCHAR(255) NULL COMMENT 'Etkilenen model (polymorphic)',
    subject_id BIGINT UNSIGNED NULL,
    causer_type VARCHAR(255) NULL COMMENT 'İşlemi yapan (User)',
    causer_id BIGINT UNSIGNED NULL,
    event VARCHAR(255) NULL COMMENT 'created, updated, deleted...',
    properties JSON NULL COMMENT 'Ek bilgiler',
    batch_uuid CHAR(36) NULL COMMENT 'Toplu işlem UUID',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,

    INDEX causer (causer_type, causer_id, created_at),
    INDEX subject (subject_type, subject_id, created_at),
    INDEX created_at,
    INDEX log_name,
    INDEX event,
    FULLTEXT KEY activity_search (description, properties)
) ENGINE=InnoDB;

Properties JSON Yapısı:

{
    "baslik": "Model başlığı (Song name, User name...)",
    "modul": "Song / Album / User / Playlist...",
    "degisenler": ["field1", "field2", "field3"],
    "event_key": "oluşturuldu / güncellendi / silindi",
    "eski_baslik": "Eski başlık (değişmişse)"
}

Log Oluşturma Helper:

// Lokasyon: /app/Helpers/Functions.php

function log_activity(
    \Illuminate\Database\Eloquent\Model $model,
    string $event,
    ?array $degisenler = null,
    $old_title = null
): void {
    activity()
        ->causedBy(auth()->user())
        ->performedOn($model)
        ->event($event)
        ->withProperties([
            'baslik' => $model->name ?? $model->title,
            'modul' => class_basename($model),
            'degisenler' => $degisenler,
            'event_key' => $event,
            'eski_baslik' => $old_title
        ])
        ->log($event);
}

Kullanım Örneği (Observer):

// Örnek: SongObserver

public function updated(Song $song)
{
    $changes = $song->getDirty();
    unset($changes['play_count']); // play_count her dinlemede değişir, log'lama

    if (!empty($changes)) {
        log_activity(
            $song,
            'güncellendi',
            array_keys($changes),
            $song->getOriginal('title')
        );
    }
}
📍 Dosya Konumları:
  • • Helper: /app/Helpers/Functions.php
  • • Config: /config/activitylog.php
  • • Migration: /database/migrations/*_create_activity_log_table.php
  • • Fulltext Index: /Modules/UserManagement/database/migrations/2026_01_18_020000_add_fulltext_index_to_activity_log.php

2. Song Plays System (muzibu_song_plays)

Tablo Yapısı:

CREATE TABLE muzibu_song_plays (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    song_id BIGINT UNSIGNED NOT NULL,
    user_id BIGINT UNSIGNED NULL COMMENT 'NULL = Anonymous',

    -- Dinleme Detayları
    created_at TIMESTAMP NULL COMMENT 'Başlangıç zamanı',
    ended_at TIMESTAMP NULL COMMENT 'Bitiş zamanı',
    listened_duration INT NULL COMMENT 'Dinlenen süre (saniye)',
    was_skipped BOOLEAN DEFAULT 0 COMMENT 'Atlanan mı?',

    -- Kaynak Bilgisi
    source_type VARCHAR(50) NULL COMMENT 'playlist, album, artist, search, radio, queue',
    source_id BIGINT UNSIGNED NULL,

    -- Cihaz Bilgileri
    ip_address VARCHAR(45) NULL,
    user_agent TEXT NULL,
    device_type VARCHAR(20) NULL COMMENT 'mobile, tablet, desktop',
    browser VARCHAR(50) NULL COMMENT 'Chrome, Firefox, Safari...',
    platform VARCHAR(50) NULL COMMENT 'Windows, iOS, Android...',

    updated_at TIMESTAMP NULL,

    INDEX user_ended (user_id, ended_at),
    INDEX source (source_type, source_id),
    INDEX song_created (song_id, created_at)
) ENGINE=InnoDB;

Model Scopes ve Analitik Metodlar:

// Lokasyon: /Modules/Muzibu/App/Models/SongPlay.php

// Zaman Filtreleri
SongPlay::today()->get();              // Bugün dinlenenler
SongPlay::thisWeek()->get();           // Bu hafta
SongPlay::thisMonth()->get();          // Bu ay

// Cihaz Filtreleri
SongPlay::byDevice('mobile')->get();   // Mobil cihazlardan
SongPlay::byDevice('desktop')->get();  // Masaüstünden

// Davranış Filtreleri
SongPlay::skipped()->get();            // Atlanan şarkılar
SongPlay::completed()->get();          // Tamamlanan
SongPlay::shortListens(10)->get();     // 10 saniyeden az dinlenenler (abuse detection)

// Kaynak Filtreleri
SongPlay::fromSource('playlist', 123)->get();  // Playlist'ten çalınanlar
SongPlay::fromSource('album', 456)->get();     // Albümden çalınanlar

// Analitik Metodlar
SongPlay::getTopSongs(10, 'week');             // Haftanın en çok dinlenen 10 şarkısı
SongPlay::getDeviceDistribution();             // Cihaz dağılımı (% mobile, % desktop)
SongPlay::getHourlyDistribution();             // Saatlik dinleme dağılımı
SongPlay::getUniqueListenersCount($songId);    // Benzersiz dinleyici sayısı
SongPlay::getSkipRate($userId);                // Kullanıcının atlama oranı
SongPlay::getAverageListenDuration($songId);   // Ortalama dinleme süresi
📍 Dosya Konumları:
  • • Model: /Modules/Muzibu/App/Models/SongPlay.php
  • • Migration: /Modules/Muzibu/database/migrations/*_create_song_plays_table.php
  • • Observer: /Modules/Muzibu/App/Observers/SongObserver.php

3. Session Management (user_active_sessions)

Tablo Yapısı:

CREATE TABLE user_active_sessions (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL,
    session_id VARCHAR(255) NOT NULL,
    ip_address VARCHAR(45) NULL,
    user_agent TEXT NULL,
    last_activity TIMESTAMP NULL COMMENT 'Son aktivite zamanı',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,

    INDEX user_last_activity (user_id, last_activity),
    UNIQUE KEY unique_session (session_id)
) ENGINE=InnoDB;

Kullanım Senaryoları:

  • Çoklu Oturum Kontrolü:

    Kullanıcı aynı anda kaç cihazdan bağlı?

  • Şüpheli Aktivite Tespiti:

    Farklı IP'lerden eş zamanlı giriş var mı?

  • Cihaz Yönetimi:

    Kullanıcı diğer oturumlarını sonlandırabilir

💡 Özellik:

last_activity alanı her sayfa isteğinde güncelleniyor. Bu sayede kullanıcının ne zaman son aktif olduğu anında görülebilir.

4. User Model Fields (Doğrudan Kullanıcı Tablosu)

Aktivite İle İlgili Alanlar:

ALTER TABLE users ADD COLUMN:
    last_login_at TIMESTAMP NULL COMMENT 'Son giriş zamanı',
    last_played_song_id BIGINT UNSIGNED NULL COMMENT 'Son çalınan şarkı',
    subscription_expires_at DATETIME NULL COMMENT 'Abonelik bitiş tarihi',
    failed_login_attempts INT DEFAULT 0 COMMENT 'Başarısız giriş denemesi',
    locked_until TIMESTAMP NULL COMMENT 'Hesap kilitli mi?';

Model Metodları:

// Güvenlik Metodları
$user->incrementFailedLogins();   // Başarısız giriş sayısını artır
$user->resetFailedLogins();       // Sayacı sıfırla (başarılı giriş sonrası)
$user->isLocked();                // Hesap kilitli mi kontrol et

// Son Aktivite
$user->last_login_at;             // Son giriş zamanı
$user->lastPlayedSong;            // Son çalınan şarkı (relation)

Admin Panel Görüntüleme

Livewire Components:

ActivityLogComponent.php

Tüm sistem aktivitelerini görüntüler

Lokasyon: /Modules/UserManagement/App/Http/Livewire/ActivityLogComponent.php

Route: /admin/activity-logs

UserActivityLogComponent.php

Belirli bir kullanıcının aktivitelerini görüntüler

Lokasyon: /Modules/UserManagement/App/Http/Livewire/UserActivityLogComponent.php

Route: /admin/users/{id}/activity-logs

Filtreleme Özellikleri:

  • search: Fulltext arama (description, baslik, modul)
  • userFilter: Kullanıcıya göre filtreleme
  • moduleFilter: Modüle göre (Song, Album, User...)
  • eventFilter: Event tipine göre (created, updated, deleted)
  • dateFrom, dateTo: Tarih aralığı
🔒 Yetki Sistemi:
  • • Root user'ın aktiviteleri sadece root user tarafından görülebilir
  • • Aktivite silme yetkisi sadece root user'da

Favorileme Sistemi (favorites)

Tablo Yapısı (Polymorphic):

CREATE TABLE favorites (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL,
    favoritable_id BIGINT UNSIGNED NOT NULL,
    favoritable_type VARCHAR(255) NOT NULL COMMENT 'Song, Album, Playlist...',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,

    UNIQUE KEY unique_favorite (user_id, favoritable_id, favoritable_type),
    INDEX favoritable (favoritable_type, favoritable_id)
) ENGINE=InnoDB;

Observer (FavoriteObserver):

// Lokasyon: /Modules/Favorite/App/Observers/FavoriteObserver.php

created()  → Cache temizle + log_activity('favorilere eklendi')
updated()  → Cache temizle + log_activity('favori güncellendi', changed_fields)
deleted()  → Cache temizle + log_activity('favorilerden çıkarıldı')

Helper Metodlar:

// Kontrol Et
Favorite::check($userId, 'Song', $songId);  // Boolean döner

// İlişkiler
$user->favorites()->where('favoritable_type', 'Song')->get();
$song->favorites()->count();  // Kaç kişi favoriledi?
📍 Dosya Konumları:
  • • Model: /Modules/Favorite/App/Models/Favorite.php
  • • Observer: /Modules/Favorite/App/Observers/FavoriteObserver.php

Aktivite Kapsam Tablosu

Aktivite Tablo Durum Kapsam
Login/Logout activity_log, user_active_sessions ✅ Tam Zaman, IP, cihaz, başarısız denemeler
Profil Güncelleme activity_log ✅ Tam Hangi alanlar değişti, eski/yeni değer
Şarkı Dinleme muzibu_song_plays ✅ Çok Detaylı Duration, skip, source, cihaz, browser
Favorileme/Çıkarma activity_log, favorites ✅ Tam Hangi içerik, ne zaman
Playlist CRUD activity_log ✅ Tam Oluşturma, düzenleme, silme, şarkı ekle/çıkar
Yorum/Değerlendirme activity_log, reviews ✅ Tam Hangi içeriğe yorum, ne zaman
Cihaz Bilgisi user_active_sessions, song_plays ✅ Tam Device type, browser, platform, user agent
Abuse Detection song_plays ✅ Tam Skip rate, short listens, IP tracking
İndirme activity_log ⚠️ Kontrol Gerekli Özel tablo yok, activity_log'dan izlenebilir
Analitik Dashboard - ❌ Yok Veriler var ama görsel dashboard geliştirilebilir

Örnek Analitik Sorgular

1. Bir kullanıcının son 30 günlük aktiviteleri:

$activities = \Spatie\Activitylog\Models\Activity::query()
    ->where('causer_id', $userId)
    ->where('created_at', '>=', now()->subDays(30))
    ->orderBy('created_at', 'desc')
    ->get();

2. En çok dinlenen şarkılar (bu hafta):

use Modules\Muzibu\App\Models\SongPlay;

$topSongs = SongPlay::getTopSongs(10, 'week');
// [song_id => play_count]

3. Cihaz dağılımı (bugün):

$distribution = SongPlay::today()->getDeviceDistribution();
// ['mobile' => 65%, 'desktop' => 30%, 'tablet' => 5%]

4. Kullanıcının atlama oranı:

$skipRate = SongPlay::where('user_id', $userId)
    ->whereNotNull('ended_at')
    ->selectRaw('AVG(was_skipped) * 100 as skip_rate')
    ->value('skip_rate');
// 25.5 (% olarak)

5. Şüpheli aktiviteler (kısa dinlemeler):

$suspicious = SongPlay::shortListens(10)  // 10 saniyeden az
    ->where('created_at', '>=', now()->subHour())
    ->groupBy('user_id')
    ->selectRaw('user_id, COUNT(*) as count')
    ->having('count', '>', 20)  // Saatte 20+ kısa dinleme
    ->get();

6. Aktif oturum sayısı:

$activeSessions = DB::table('user_active_sessions')
    ->where('user_id', $userId)
    ->where('last_activity', '>=', now()->subMinutes(30))
    ->count();

Geliştirme Önerileri

1. İndirme Takibi

Özel bir downloads tablosu oluşturulabilir:

  • • user_id, song_id, downloaded_at
  • • file_format (mp3, flac, wav...)
  • • quality (320kbps, lossless...)
  • • ip_address, user_agent

2. Analitik Dashboard

Admin paneline görsel istatistik paneli:

  • • Günlük/Haftalık aktif kullanıcı grafiği
  • • Saatlik dinleme dağılımı
  • • Cihaz dağılımı (pie chart)
  • • Top 10 şarkılar/albümler
  • • Kullanıcı büyüme trendi

3. Real-time Monitoring

Anlık aktivite izleme:

  • • Şu anda dinlenen şarkılar (live)
  • • Aktif kullanıcı sayısı (canlı)
  • • Son login'ler feed'i

4. Otomatik Veri Temizleme

Eski kayıtları otomatik sil:

  • • activity_log: 1 yıldan eski kayıtlar (zaten config'de var: 365 gün)
  • • song_plays: 2 yıldan eski kayıtlar (istatistik özetleri tutularak)
  • • user_active_sessions: 30 günden eski oturumlar

5. Performans Optimizasyonu

Büyük veri setleri için:

  • • activity_log partition'lama (aylık)
  • • song_plays için aggregate tables (günlük/aylık özetler)
  • • Index optimizasyonu (yavaş sorgular için)

🎯 Sonuç ve Değerlendirme

Sisteminizde çok kapsamlı ve profesyonel bir aktivite takip sistemi mevcut. Üyelerinizin site üzerindeki neredeyse tüm işlemleri kayıt altına alınıyor ve analiz edilebilir durumda.

✅ Güçlü Yönler:

  • • Observer pattern ile otomatik log'lama
  • • Çok detaylı dinleme analitikleri
  • • Multi-tenant uyumlu
  • • Abuse detection yetenekleri
  • • Fulltext search desteği

⚡ Geliştirme Alanları:

  • • İndirme takibi özel tablo ile geliştirilebilir
  • • Görsel analitik dashboard eklenebilir
  • • Real-time monitoring sistemi
  • • Aggregate tables (performans için)

Önemli Not: Tüm bu veriler zaten toplanıyor ve admin panelinden görüntülenebilir durumda. Sadece görselleştirme ve raporlama tarafı daha da geliştirilebilir.