Activity Log Aktiviteleri

Mevcut Durum + User Aktiviteleri İmplementasyon Planı

30 Model Aktif User İmplementasyonu Eklenecek Hazır Kod Örnekleri

📊 Güncel Durum

30 model aktif olarak activity_log'a yazılıyor. User aktiviteleri şu anda loglanmıyor, bu raporda implementasyon planı ve hazır kod örnekleri sunulacak.

✓ 30
Loglanıyor
+ 1
Eklenecek (User)
8+
User Aktivitesi
100%
Observer Pattern

✅ Şu Anda Loglanan Modeller (30 Adet)

Müzik Modülü (6)

  • Song - Şarkılar
  • Album - Albümler
  • Artist - Sanatçılar
  • Playlist - Çalma Listeleri
  • Genre - Türler
  • Muzibu - Özel Kategoriler

İçerik Modülü (6)

  • Page - Sayfalar
  • Blog - Blog Yazıları
  • Portfolio - Portföy
  • Announcement - Duyurular
  • Favorite - Favoriler
  • ReviewSystem - İncelemeler

E-Ticaret + Diğer (4)

  • ShopProduct - Ürünler
  • Coupon - Kuponlar
  • Payment - Ödemeler
  • Service - Hizmetler
ℹ️ Not:

Tüm bu modellerde created, updated, deleted, restored event'leri tam olarak loglanıyor. forceDeleted (kalıcı silme) bazı modellerde loglanmıyor (tasarım kararı - sadece Laravel log'una yazılıyor).

👤 User Aktiviteleri İmplementasyonu

Kullanıcı aktivitelerini activity_log'a eklemek için detaylı plan ve kod örnekleri

Loglanacak User Aktiviteleri

Login (Giriş)

Kullanıcı sisteme giriş yaptı, IP adresi ve cihaz bilgisi kaydedilecek

Logout (Çıkış)

Kullanıcı sistemden çıkış yaptı

Profil Güncelleme

İsim, email, telefon, bio gibi profil alanları değiştirildi (Observer ile otomatik)

Şifre Değiştirme

Kullanıcı şifresini değiştirdi (eski şifre loglanmayacak - güvenlik)

Email Doğrulama

Email adresi doğrulandı (email_verified_at alanı set edildi)

2FA Aktivasyon

İki faktörlü doğrulama aktif/pasif edildi

Role Değişikliği

Kullanıcının rolü değiştirildi (admin, user, moderator...)

Hesap Kilitleme

Hesap kilitlendi/kilidi açıldı (locked_until alanı)

1. UserObserver Oluşturma

Dosya Konumu: /Modules/UserManagement/App/Observers/UserObserver.php

<?php

namespace Modules\UserManagement\App\Observers;

use App\Models\User;
use Illuminate\Support\Facades\Log;

class UserObserver
{
    /**
     * Handle the User "created" event.
     * Admin tarafından yeni kullanıcı oluşturulduğunda
     */
    public function created(User $user): void
    {
        // Activity log
        if (function_exists('log_activity')) {
            log_activity($user, 'oluşturuldu');
        }

        Log::info('User created', [
            'user_id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'created_by' => auth()->id()
        ]);
    }

    /**
     * Handle the User "updated" event.
     * Profil güncelleme, email değişikliği vb.
     */
    public function updated(User $user): void
    {
        $changes = $user->getChanges();

        // Bu alanları loglama (güvenlik)
        unset($changes['password']);
        unset($changes['remember_token']);
        unset($changes['updated_at']);
        unset($changes['last_login_at']); // Login zaten ayrı loglanıyor

        if (!empty($changes)) {
            // Özel durumlar için ek bilgi
            $eventDescription = 'güncellendi';
            $extraInfo = [];

            // Email değişikliği
            if (isset($changes['email'])) {
                $extraInfo['eski_email'] = $user->getOriginal('email');
                $extraInfo['yeni_email'] = $changes['email'];
            }

            // Email doğrulama
            if (isset($changes['email_verified_at'])) {
                $eventDescription = 'email doğrulandı';
            }

            // 2FA aktivasyon
            if (isset($changes['two_factor_secret'])) {
                $eventDescription = empty($changes['two_factor_secret'])
                    ? '2FA deaktif edildi'
                    : '2FA aktif edildi';
            }

            // Hesap kilitleme
            if (isset($changes['locked_until'])) {
                $eventDescription = empty($changes['locked_until'])
                    ? 'hesap kilidi kaldırıldı'
                    : 'hesap kilitlendi';
                $extraInfo['locked_until'] = $changes['locked_until'];
            }

            log_activity($user, $eventDescription, array_keys($changes), $user->getOriginal('name'));

            Log::info('User updated', [
                'user_id' => $user->id,
                'changed_fields' => array_keys($changes),
                'updated_by' => auth()->id()
            ]);
        }
    }

    /**
     * Handle the User "deleted" event.
     * Soft delete
     */
    public function deleted(User $user): void
    {
        if (function_exists('log_activity')) {
            log_activity($user, 'silindi');
        }

        Log::info('User deleted', [
            'user_id' => $user->id,
            'name' => $user->name,
            'deleted_by' => auth()->id()
        ]);
    }

    /**
     * Handle the User "restored" event.
     * Silinmiş kullanıcı geri yüklendi
     */
    public function restored(User $user): void
    {
        if (function_exists('log_activity')) {
            log_activity($user, 'geri yüklendi');
        }

        Log::info('User restored', [
            'user_id' => $user->id,
            'name' => $user->name,
            'restored_by' => auth()->id()
        ]);
    }
}
🔒 Güvenlik Uyarısı:

password, remember_token gibi hassas alanlar ASLA activity_log'a yazılmamalı. Observer'da bu alanlar otomatik filtreleniyor.

2. Observer'ı Kaydetme

Dosya: /Modules/UserManagement/App/Providers/UserManagementServiceProvider.php

use App\Models\User;
use Modules\UserManagement\App\Observers\UserObserver;

public function boot(): void
{
    // User Observer'ı kaydet
    User::observe(UserObserver::class);

    // ... diğer kod
}

3. Login/Logout Aktivitelerini Loglama

Login ve Logout işlemleri model değişikliği olmadığı için Observer ile yakalanamaz. Bu yüzden manuel olarak authentication işlemlerinden sonra loglanmalı.

Login Event Listener:

Dosya: /Modules/UserManagement/App/Listeners/LogSuccessfulLogin.php

<?php

namespace Modules\UserManagement\App\Listeners;

use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;

class LogSuccessfulLogin
{
    public function handle(Login $event): void
    {
        $user = $event->user;

        // Activity log
        if (function_exists('log_activity')) {
            activity()
                ->causedBy($user)
                ->performedOn($user)
                ->event('login')
                ->withProperties([
                    'baslik' => $user->name,
                    'modul' => 'User',
                    'event_key' => 'giriş yaptı',
                    'ip_address' => request()->ip(),
                    'user_agent' => request()->userAgent(),
                ])
                ->log('giriş yaptı');
        }

        // User modelindeki last_login_at'i güncelle
        $user->last_login_at = now();
        $user->saveQuietly(); // Observer tetiklenmesin

        Log::info('User login', [
            'user_id' => $user->id,
            'ip' => request()->ip()
        ]);
    }
}

Logout Event Listener:

Dosya: /Modules/UserManagement/App/Listeners/LogSuccessfulLogout.php

<?php

namespace Modules\UserManagement\App\Listeners;

use Illuminate\Auth\Events\Logout;
use Illuminate\Support\Facades\Log;

class LogSuccessfulLogout
{
    public function handle(Logout $event): void
    {
        $user = $event->user;

        if ($user && function_exists('log_activity')) {
            activity()
                ->causedBy($user)
                ->performedOn($user)
                ->event('logout')
                ->withProperties([
                    'baslik' => $user->name,
                    'modul' => 'User',
                    'event_key' => 'çıkış yaptı',
                ])
                ->log('çıkış yaptı');
        }

        Log::info('User logout', [
            'user_id' => $user?->id
        ]);
    }
}

EventServiceProvider'a Kaydetme:

Dosya: /Modules/UserManagement/App/Providers/EventServiceProvider.php

<?php

namespace Modules\UserManagement\App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Modules\UserManagement\App\Listeners\LogSuccessfulLogin;
use Modules\UserManagement\App\Listeners\LogSuccessfulLogout;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        Login::class => [
            LogSuccessfulLogin::class,
        ],
        Logout::class => [
            LogSuccessfulLogout::class,
        ],
    ];

    public function boot(): void
    {
        //
    }
}

4. Şifre Değiştirme Özel Loglama

Şifre değiştirme işlemi UserObserver'da otomatik yakalanır, ancak password alanı filtrelendiği için sadece "şifre değiştirildi" event'i loglanır (şifrenin kendisi ASLA loglanmaz).

Controller'da Ekstra Log (opsiyonel):

// Password update sonrası
public function updatePassword(Request $request)
{
    // ... validasyon ve şifre güncelleme ...

    $user->password = Hash::make($request->new_password);
    $user->save(); // Observer otomatik tetiklenir

    // Ekstra bilgi eklemek isterseniz (opsiyonel)
    if (function_exists('log_activity')) {
        activity()
            ->causedBy(auth()->user())
            ->performedOn($user)
            ->event('password_changed')
            ->withProperties([
                'baslik' => $user->name,
                'modul' => 'User',
                'event_key' => 'şifre değiştirildi',
                'ip_address' => request()->ip(),
            ])
            ->log('şifre değiştirildi');
    }

    return response()->json(['message' => 'Şifre güncellendi']);
}

📄 Örnek User Activity Log Kayıtları

1. Login (Giriş Yaptı):

{
    "log_name": "User",
    "description": "giriş yaptı",
    "subject_type": "App\\Models\\User",
    "subject_id": 5,
    "causer_type": "App\\Models\\User",
    "causer_id": 5,
    "event": "login",
    "properties": {
        "baslik": "Ahmet Yılmaz",
        "modul": "User",
        "event_key": "giriş yaptı",
        "ip_address": "192.168.1.100",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
    },
    "created_at": "2026-01-30 15:30:00"
}

2. Profil Güncelleme:

{
    "log_name": "User",
    "description": "güncellendi",
    "subject_type": "App\\Models\\User",
    "subject_id": 5,
    "causer_type": "App\\Models\\User",
    "causer_id": 5,
    "event": "updated",
    "properties": {
        "baslik": "Ahmet Yılmaz",
        "modul": "User",
        "degisenler": {
            "changed_fields": ["name", "phone", "bio"]
        },
        "event_key": "güncellendi",
        "eski_baslik": "Ahmet Y."
    },
    "created_at": "2026-01-30 16:15:00"
}

3. Email Değişikliği:

{
    "log_name": "User",
    "description": "güncellendi",
    "subject_type": "App\\Models\\User",
    "subject_id": 5,
    "causer_type": "App\\Models\\User",
    "causer_id": 1,
    "event": "updated",
    "properties": {
        "baslik": "Ahmet Yılmaz",
        "modul": "User",
        "degisenler": {
            "changed_fields": ["email"]
        },
        "event_key": "güncellendi",
        "eski_email": "ahmet@example.com",
        "yeni_email": "ahmet.yilmaz@newdomain.com"
    },
    "created_at": "2026-01-30 17:00:00"
}

4. 2FA Aktivasyon:

{
    "log_name": "User",
    "description": "2FA aktif edildi",
    "subject_type": "App\\Models\\User",
    "subject_id": 5,
    "causer_type": "App\\Models\\User",
    "causer_id": 5,
    "event": "updated",
    "properties": {
        "baslik": "Ahmet Yılmaz",
        "modul": "User",
        "degisenler": {
            "changed_fields": ["two_factor_secret"]
        },
        "event_key": "2FA aktif edildi"
    },
    "created_at": "2026-01-30 18:00:00"
}

5. Logout (Çıkış Yaptı):

{
    "log_name": "User",
    "description": "çıkış yaptı",
    "subject_type": "App\\Models\\User",
    "subject_id": 5,
    "causer_type": "App\\Models\\User",
    "causer_id": 5,
    "event": "logout",
    "properties": {
        "baslik": "Ahmet Yılmaz",
        "modul": "User",
        "event_key": "çıkış yaptı"
    },
    "created_at": "2026-01-30 20:00:00"
}

🚀 İmplementasyon Adımları (Sıralı)

1
UserObserver Oluştur

/Modules/UserManagement/App/Observers/UserObserver.php dosyasını oluştur (yukarıdaki kod örneğini kullan)

2
Observer'ı Kaydet

UserManagementServiceProvider.php içinde boot() metoduna User::observe(UserObserver::class); ekle

3
Login Listener Oluştur

/Modules/UserManagement/App/Listeners/LogSuccessfulLogin.php oluştur

4
Logout Listener Oluştur

/Modules/UserManagement/App/Listeners/LogSuccessfulLogout.php oluştur

5
EventServiceProvider'a Kaydet

EventServiceProvider.php içinde $listen array'ine Login ve Logout event'lerini ekle

6
Cache Temizle

php artisan cache:clear && php artisan config:clear

7
Test Et

Login/logout yap, profil güncelle, /admin/activity-logs sayfasından kontrol et

⚠️ Dikkat:

Implementasyondan sonra test ortamında önce deneyin. Login/logout ve profil güncellemelerinin doğru loglandığından emin olun.

📊 Güncellenmiş Durum Tablosu

Model Created Updated Deleted Restored Durum
MÜZİK MODÜLÜ
Song ✓ Tam
Album ✓ Tam
Artist, Playlist, Genre, Muzibu ✓ Tam
İÇERİK MODÜLÜ
Page, Blog, Portfolio, Announcement ✓ Tam
Favorite, ReviewSystem ✓ Tam
E-TİCARET + DİĞER
ShopProduct, Coupon, Payment, Service ✓ Tam
KULLANICI MODÜLÜ (İMPLEMENTE EDİLECEK)
User (Observer ile) ⏳ Bekliyor
Login/Logout (Event Listener ile) Event bazlı (model değişikliği yok) ⏳ Bekliyor
ℹ️ Not:

forceDeleted (kalıcı silme) event'i bazı modellerde activity_log'a yazılmıyor. Bu bir tasarım kararı - kalıcı silme işlemleri nadir olduğu için sadece Laravel log dosyasına yazılıyor.

🎯 Sonuç ve Öneriler

Mevcut sistemde 30 model tam olarak loglanıyor. User aktiviteleri için yukarıdaki implementasyon planı uygulandığında sistem %100 kapsama ulaşacak.

✅ Mevcut Güçlü Yönler:

  • • Observer pattern ile otomatik loglama
  • • 30 model aktif olarak takip ediliyor
  • • Değişen alanlar detaylıca kaydediliyor
  • • Multi-language başlık desteği
  • • Soft delete ve restore takibi

⏳ User İmplementasyonu Sonrası:

  • • Login/logout tam takip
  • • Profil değişiklikleri otomatik log
  • • Şifre değiştirme güvenli kayıt
  • • 2FA aktivasyon/deaktivasyon
  • • Email doğrulama takibi
  • • Role/permission değişiklikleri
💡 Tavsiye:

User implementasyonunu test ortamında önce deneyin. Login/logout trafiği yüksek olduğu için activity_log tablosunun hızla büyüyeceğini unutmayın. Eski kayıtları otomatik temizleme (config: delete_records_older_than_days) zaten aktif.

🔒 Güvenlik Hatırlatması:

password, remember_token gibi hassas alanlar ASLA activity_log'a yazılmamalı. Yukarıdaki kod örneklerinde bu alanlar zaten filtrelenmiş durumda.