Toplu özelliklerin anında güncelleme durumu
Sorun: Müzik platformunda albümlerin, sanatçıların, türlerin ve çalma listelerinin kaç şarkı içerdiği ve toplam süreleri saklanıyor. Yeni şarkı eklendiğinde, düzenlendiğinde veya silindiğinde bu sayılar otomatik güncellenmeli.
Örnek: Bir albüme yeni şarkı eklediğinizde, albümün "5 şarkı, 18 dakika" bilgisi otomatik olarak "6 şarkı, 21 dakika" olmalı.
Durum: Sistem KISMEN ÇALIŞIYOR. Bazı durumlar otomatik, bazıları manuel güncelleme gerektiriyor.
Migration: 2025_12_26_200000_add_cache_count_fields_to_muzibu_tables.php
Trait: HasCachedCounts (Modules/Muzibu/App/Traits/)
Observer'lar: SongObserver, AlbumObserver, PlaylistObserver
Güncelleme Yöntemleri: incrementCachedCount(), decrementCachedCount(), recalculateCachedCounts()
Çalma Listeleri
songs_count
(int, nullable)
Playlist'teki aktif şarkı sayısı
total_duration
(int, nullable, saniye)
Playlist'teki tüm şarkıların toplam süresi
⚠️ Manuel Güncelleme Gerekli: Playlist'e şarkı eklenirken/çıkarılırken
attachSongWithCache(),
detachSongWithCache(),
syncSongsWithCache() methodları kullanılmalı!
Albümler
songs_count
(int, nullable)
Albümdeki aktif şarkı sayısı
total_duration
(int, nullable, saniye)
Albümdeki tüm şarkıların toplam süresi
✅ Otomatik Güncelleme: SongObserver şarkı eklendiğinde/silindiğinde/güncellendiğinde otomatik olarak album count'larını günceller.
Müzik Türleri
songs_count
(int, nullable)
Bu türdeki aktif şarkı sayısı
total_duration
(int, nullable, saniye)
Bu türdeki tüm şarkıların toplam süresi
✅ Otomatik Güncelleme: SongObserver şarkı genre_id'si değiştiğinde eski ve yeni genre count'larını otomatik günceller.
Sanatçılar
albums_count
(int, nullable)
Sanatçının aktif albüm sayısı
songs_count
(int, nullable)
Sanatçının aktif şarkı sayısı (tüm albümlerden)
total_duration
(int, nullable, saniye)
Sanatçının tüm şarkılarının toplam süresi
✅ Otomatik Güncelleme: SongObserver ve AlbumObserver sanatçı count'larını otomatik günceller (Album üzerinden hasManyThrough ilişkisi).
Radyo İstasyonları
songs_count
(field yok)
Cache edilmiş field yok
total_duration
(field yok)
Cache edilmiş field yok
❌ Runtime Hesaplama: Radio model'inde getTotalDuration()
methodu var ama DB'de cache field'ı YOK. Her seferinde tüm playlist'lerden hesaplıyor (YAVAŞ!).
İş Sektörleri
songs_count
(field yok)
Cache edilmiş field yok
total_duration
(field yok)
Cache edilmiş field yok
❌ Cache Sistemi Yok: Sector model'inde duration/count cache field'ları eklenmemiş.
Dosya: Modules/Muzibu/App/Observers/SongObserver.php
Event'ler: created, updated, deleted, restored, forceDeleted
Dosya: Modules/Muzibu/App/Observers/AlbumObserver.php
Event'ler: created, deleted, restored, forceDeleted
Dosya: Modules/Muzibu/App/Observers/PlaylistObserver.php
Event'ler: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored, forceDeleting, forceDeleted
PlaylistObserver sadece cache temizleme yapıyor. Playlist'e şarkı eklendiğinde/çıkarıldığında songs_count ve total_duration OTOMATIK GÜNCELLENMİYOR!
Sebep: Pivot tablo event'leri (attach/detach/sync) Observer'lar tarafından yakalanmıyor. Laravel pivot event'leri emit etmiyor.
Çözüm: Manuel methodlar kullanılmalı:
attachSongWithCache($song)detachSongWithCache($song)syncSongsWithCache($songIds)attachManySongsWithCache($songIds)detachManySongsWithCache($songIds)Sorun: Playlist'e şarkı eklendiğinde/çıkarıldığında songs_count ve total_duration otomatik güncellenmiyor. Manuel methodlar kullanılmak zorunda.
$playlist->songs()->attach($songId); // Count'lar güncellenMİYOR!
$playlist->attachSongWithCache($songId); // Count'lar güncellenir
Çözüm Önerileri:
Sorun: Radio ve Sector tablolarında songs_count ve total_duration field'ları yok. Her seferinde runtime'da hesaplama yapılıyor (YAVAŞ!).
// Radio Model - Her çağrıda playlists'leri foreach ile dolaşıyor
public function getTotalDuration(): int {
$totalSeconds = 0;
foreach ($this->playlists as $playlist) {
$totalSeconds += $playlist->getTotalDuration();
}
return $totalSeconds;
}
Çözüm Önerisi:
Sorun: attachManySongsWithCache ve detachManySongsWithCache methodları her şarkı için ayrı ayrı hesaplama yapıyor. 100 şarkı eklenirse 100 kez query çalışır.
// Her şarkı için ayrı query
$addedSongs = Song::whereIn('song_id', $newSongIds)
->where('is_active', true)
->get();
$addedCount = $addedSongs->count();
$addedDuration = (int) $addedSongs->sum('duration');
Çözüm Önerisi:
// Şarkı oluştur
$song = Song::create([
'album_id' => 5,
'genre_id' => 3,
'title' => ['tr' => 'Yeni Şarkı'],
'duration' => 240, // 4 dakika
'is_active' => true,
]);
// ✅ OTOMATIK: SongObserver tetiklenir
// - Album 5: songs_count +1, total_duration +240
// - Genre 3: songs_count +1, total_duration +240
// - Artist (Album 5'in sahibi): songs_count +1, total_duration +240
$playlist = Playlist::find(10);
$playlist->songs()->attach($songId); // Count'lar GÜNCELLENMİYOR!
$playlist = Playlist::find(10);
$playlist->attachSongWithCache($songId); // songs_count ve total_duration güncellenir
$song = Song::find(25);
$oldDuration = $song->duration; // 240 saniye
$song->duration = 300; // 5 dakika
$song->save();
// ✅ OTOMATIK: SongObserver tetiklenir
// Diff = 300 - 240 = +60 saniye
// - Album: total_duration +60
// - Genre: total_duration +60
// - Artist: total_duration +60
$song = Song::find(25);
$oldAlbumId = $song->album_id; // 5
$song->album_id = 8; // Yeni albüm
$song->save();
// ✅ OTOMATIK: SongObserver handleAlbumChange() tetiklenir
// Eski Album 5:
// - songs_count -1
// - total_duration -240
// Yeni Album 8:
// - songs_count +1
// - total_duration +240
// Eski ve yeni Artist'ler de güncellenir!
// Eğer cache field'ları NULL ise (henüz hesaplanmamışsa)
$album = Album::find(5);
if ($album->needsCachedCountRecalculation()) {
$values = $album->recalculateCachedCounts();
// ['songs_count' => 12, 'total_duration' => 2940]
}
Modules/Muzibu/database/migrations/tenant/2025_12_26_200000_add_cache_count_fields_to_muzibu_tables.php
Modules/Muzibu/App/Traits/HasCachedCounts.php
Modules/Muzibu/App/Models/Playlist.php
Modules/Muzibu/App/Models/Album.php
Modules/Muzibu/App/Models/Genre.php
Modules/Muzibu/App/Models/Artist.php
Modules/Muzibu/App/Models/Song.php
Modules/Muzibu/App/Models/Radio.php
Modules/Muzibu/App/Observers/SongObserver.php
Modules/Muzibu/App/Observers/AlbumObserver.php
Modules/Muzibu/App/Observers/PlaylistObserver.php