v6 27 Şubat 2026

Dinamik İçerik Sistemi — Basit Özet

Ne yapıyoruz, tablolarda ne var, admin'de ne yapılıyor, sitede ne görünüyor.

Ne Yapıyoruz?

Muzibu orta alanını (main) saate, sektöre ve gösterildiği sayfaya göre değişen bir sisteme çeviriyoruz.

Admin panelden "Koleksiyon" denen gruplar oluşturulacak. Her koleksiyonun içine Playlist, Albüm, Radyo, Genre veya Sektör eklenebilecek.

Örnek: "Sabah Kafe Mix" koleksiyonu → sadece 06:00-12:00 arası, sadece anasayfada, sadece Kafe sektörüne gösterilir.

Kullanıcı sayfayı açık bıraksa bile her saat başı içerik otomatik güncellenir, müzik kesilmez.

Neye Dokunuyoruz, Neye Dokunmuyoruz?
Değişecek
Anasayfa + Sektör + Radyo + Genre sayfaları ORTA ALAN (main). Şu anki görünüm fallback olarak korunacak, koleksiyon atanınca değişecek.
Dokunulmayacak
Left sidebar, right sidebar, header, player bar, footer — hepsi aynen kalacak. Sadece ortadaki main alan değişiyor.

Sayfa Yapısı YENİ

Koleksiyon sistemi bu sayfalarda çalışacak:

SayfaURLAlt Sayfavisibility_rules Key
Anasayfa / Yok (tek sayfa) sector_ids (kullanıcı filtresi)
Sektörler /sectors/{slug} Her sektörün kendi sayfası var sector_ids → hangi sektör sayfalarında
Türler /genres/{slug} Her genre'nin kendi sayfası var genre_ids → hangi genre sayfalarında
Radyolar /radios Yok (tek sayfa) Yok — show_on: ["radio"] yeterli
Sektör alt sayfaları (/sectors/{slug}/radios, /sectors/{slug}/playlists) kalkacak. Her sektörün sadece tek bir ana sayfası olacak: /sectors/{slug}

Fallback Sistemi YENİ

Her sayfa için: koleksiyon atanmamışsa mevcut görünüm aynen korunur. Bir tane bile koleksiyon atanırsa → o sayfa koleksiyon sistemine geçer.

Koleksiyon YOK → Fallback
Anasayfa: Şu anki hali — Türler grid, Playlist yatay, Albüm yatay, Radyo yatay, Sektör yatay
Sektör sayfası: Şu anki hali — o sektöre ait radyolar + playlistler
Genre sayfası: Şu anki hali — o türe ait playlistler
Radyo sayfası: Şu anki hali — tüm radyolar listesi
Hiçbir şey değişmez, eski kod çalışır.
1+ Koleksiyon VAR → Yeni Sistem
Anasayfa: Koleksiyonlar sırayla gösterilir (saate, sektöre göre filtrelenir)
Sektör sayfası: O sektöre atanmış koleksiyonlar
Genre sayfası: O genre'a atanmış koleksiyonlar
Radyo sayfası: Radyo sayfasına atanmış koleksiyonlar
Yeni koleksiyon sistemi devreye girer.
Kod mantığı: Her sayfada önce koleksiyon sorgusu yapılır. Sonuç boşsa → mevcut blade kodu çalışır (fallback). Sonuç doluysa → koleksiyon render'ı çalışır.
@if($collections->isNotEmpty())
  {{-- Koleksiyon sistemi --}}
@else
  {{-- Mevcut görünüm (fallback) --}}
@endif
Avantaj: Sayfa sayfa geçiş yapılabilir. Önce anasayfaya koleksiyon at → test et → sonra sektör sayfalarına geç. Sorun olursa koleksiyonu sil/kapat → otomatik fallback'e döner. Sıfır risk.

Her Koleksiyonun 3 Sorusu

Admin bir koleksiyon oluştururken şu 3 şeyi ayarlar. Tasarım otomatik belirlenir.

NEREDE?
Hangi sayfa tiplerinde?
Kolon: show_on
Anasayfa, Sektör, Radyo, Genre... Birden fazla seçilebilir.
NE ZAMAN?
Hangi saatlerde?
Kolon: display_rules
06:00-12:00 arası, veya "Her zaman". Gün seçimi de var.
KİME / HANGİ SAYFAYA?
Hedef kitle + hedef sayfa
Kolonlar: visibility_rules + corporate_account_id
Herkese, belirli sektörlere, belirli genre'lara, firmaya özel...
NASIL?
OTOMATİK
Tasarım admin tarafından seçilmez, içerik tipine göre otomatik belirlenir:
Sadece Genre → Grid (15 kart)
genre-quick-card, yan yana renkli kutucuklar.
Diğer → Yatay Kaydırma (10 kart)
Her öğe kendi kartını kullanır.

visibility_rules Detayı

Tek bir JSON kolon, tüm filtreleri kapsar. Sayfa yapısına göre 2 key kullanılır:

Herkese / Her Yerde
{"show_to_all": true}
veya NULL / boş → filtre yok, show_on'daki tüm sayfalarda görünür.
Sektöre Göre
{"sector_ids": [1, 3]}
Anasayfada: Bu sektördeki kullanıcılar görür.
Sektör sayfasında: Bu sektör sayfalarında görünür.
Örn: Kafe + Restoran sektörüne özel koleksiyon.
Genre'a Göre
{"genre_ids": [5, 8]}
Genre sayfasında: Bu genre sayfalarında görünür.
Örn: Rock + Jazz sayfalarında "Akustik Seçmeler" koleksiyonu.
Karışık
{"sector_ids": [1], "genre_ids": [5, 8]}
Anasayfada Kafe'ye + Genre'da Rock/Jazz'a görünür.
radio_ids YOK: Radyo sayfası tek sayfa (/radios), alt sayfası yok. show_on: ["radio"] ile tüm radyo sayfasında gösterilir, filtrelemeye gerek yok.
corporate_account_id: Ayrı kolon (FK). NULL = herkes, dolu = o firmaya özel. visibility_rules ile birlikte çalışır.

Kullanılacak Kartlar

Yeni kart yapılmayacak. Mevcut component'ler aynen kullanılacak:

ComponentNe İçinTıklanıncaTasarım
x-muzibu.playlist-card Çalma listesi Şarkı listesi açılır Yatay kaydırma
x-muzibu.album-card Albüm Albüm detayı açılır Yatay kaydırma
x-muzibu.radio-card Radyo Hemen çalar (sayfa değişmez) Yatay kaydırma
x-muzibu.genre-quick-card Tür Genre sayfası açılır Grid
x-muzibu.sector-card Sektör Sektör sayfası açılır Yatay kaydırma

Kart Sayısı ve "Tümünü Gör"

Genre-only → Grid
15 kart
Diğerleri → Yatay Kaydırma
10 kart
"Tümünü Gör": Öğe sayısı > gösterilen kart sayısı → buton otomatik çıkar → tıklanınca grid sayfa.

Tablo 1: muzibu_content_collections

Her satır bir koleksiyon. Admin panelden oluşturulur.

KolonTipNe İşe YararÖrnek
collection_idBIGINT PKOtomatik numara1, 2, 3
titleJSONKoleksiyon adı (çoklu dil){"tr": "Sabah Kafe Mix"}
slugJSONURL kısa ismi{"tr": "sabah-kafe-mix"}
descriptionJSON NULLAçıklama (opsiyonel){"tr": "Sabah için..."}
show_on JSON NEREDE: Hangi sayfa tiplerinde? ["homepage", "sector", "radio", "genre"]
display_rules JSON NULL NE ZAMAN: Saat + gün kuralı {"start_hour":6, "end_hour":12, "is_always":false}
visibility_rules JSON NULL KİME: Sektör + genre filtresi (tek yerde) {"sector_ids":[1]} veya {"genre_ids":[5,8]} veya {"show_to_all":true}
corporate_account_id FK NULL KİME (firma): NULL = herkes, dolu = firmaya özel NULL veya 5
iconVARCHAR NULLBaşlık ikonufas fa-coffee
colorVARCHAR NULLRenk kodu#f59e0b
media_idFK NULLKapak görseli42
sort_orderINTSıralama (küçük = üstte)1, 2, 3
is_activeBOOLEANAçık / Kapalı1
Toplam: 12 kolon. visibility_rules tek başına sektör, genre ve radyo filtresini karşılıyor. radio_ids yok (tek sayfa). Kolon sayısı artmadı.

Tablo 2: muzibu_collection_items

Her satır, bir koleksiyona eklenmiş bir öğe.

KolonTipNe İşe YararÖrnek
idBIGINT PKOtomatik numara1, 2, 3
collection_idFKHangi koleksiyona ait1
itemable_typeVARCHARÖğe türü (5 seçenek)playlist, album, radio, genre, sector
itemable_idBIGINTÖğenin ID'si12
sort_orderINTSıralama (sürükle-bırak)1, 2, 3
is_activeBOOLEANAktif mi?1
Örnek: "Sabah Kafe Mix" koleksiyonu (id=1)
collection_id=1, type=radio, id=5 (Jazz FM), sort_order=1
collection_id=1, type=playlist, id=12 (Sabah Akustik), sort_order=2
collection_id=1, type=playlist, id=45 (Kahve Molası), sort_order=3
collection_id=1, type=album, id=8 (Cafe Classics), sort_order=4

Ek: users Tablosuna Eklenen Kolon

KolonTipNe İşe YararÖrnek
sector_idFK NULLKullanıcının sektörü. Kafe sahibi = Kafe koleksiyonlarını görür.1

Admin Panelde Ne Yapılacak?

1
Koleksiyon Oluştur
İsim ver, ikon ve renk seç. Kapak görseli ekle (opsiyonel).
2
Nerede Görünsün?
Anasayfa, Sektör, Radyo, Genre... Birden fazla seçilebilir.
3
Saat Ayarla
Başlangıç-bitiş saati (00:00-23:00) veya "Her zaman".
4
Kime / Hangi Sayfaya?
Herkese → hiçbir şey seçme
Sektöre göre → sektör seç (Kafe, Spor Salonu...) — anasayfada kullanıcı filtresi + sektör sayfasında sayfa filtresi
Genre'a göre → genre seç (Rock, Jazz...) — genre sayfasında sayfa filtresi
Firmaya özel → corporate hesap seç
5
İçerik Ekle
Playlist, Albüm, Radyo, Genre veya Sektör ekle. Sürükle-bırak ile sırala.
6
Koleksiyonları Sırala
sort_order ile sürükle-bırak (küçük numara üstte).

Sitede Ne Olacak?

1
Sayfa Açılır
Sistem o sayfa için koleksiyon var mı kontrol eder. Yoksa → fallback (mevcut görünüm). Varsa → koleksiyon sistemi.
2
Kişisel Karşılama (anasayfa)
"Günaydın, Ahmet!" + "Kafe & Restoran için seçilmiş içerikler"
3
Koleksiyonlar Listelenir
O saatte + o hedefe uygun koleksiyonlar sırayla görünür. Genre-only → grid (15), diğer → yatay kaydırma (10).
4
Tıklama
Radyo → hemen çalar   Playlist/Albüm → şarkı listesi   Genre/Sektör → ilgili sayfa
5
"Tümünü Gör" + Otomatik Güncelleme
Kart sayısı aşılırsa → buton çıkar. Her saat başı orta alan sessizce güncellenir (müzik kesilmez).

Senaryo Örnekleri YENİ

Senaryo 1: Henüz hiç koleksiyon yok
Anasayfa → Fallback: Şu anki hali (Türler grid, Playlistler yatay, Albümler yatay...)
Sektör sayfaları → Fallback: Şu anki hali
Genre sayfaları → Fallback: Şu anki hali
Radyo sayfası → Fallback: Şu anki hali
Senaryo 2: Sadece anasayfaya 3 koleksiyon atandı
Anasayfa → Koleksiyon sistemi: 3 koleksiyon sırayla görünür
Sektör sayfaları → Fallback: Hâlâ eski görünüm
Genre sayfaları → Fallback: Hâlâ eski görünüm
Radyo sayfası → Fallback: Hâlâ eski görünüm
Senaryo 3: Anasayfa + Rock genre sayfasına koleksiyon atandı
Anasayfa → Koleksiyon sistemi
Rock genre sayfası → Koleksiyon sistemi
Jazz genre sayfası → Fallback: Eski görünüm (Jazz'a koleksiyon yok)
Sektör sayfaları → Fallback
Radyo sayfası → Fallback

Referans: Şu Anki Sayfa Görünümleri (Fallback Değerleri)

SayfaMevcut İçerikKart / Tasarım
Anasayfa Türler (15, grid) + Playlistler (10, yatay) + Albümler (10, yatay) + Radyolar (10, yatay) + Sektörler (10, yatay) 5 bölüm, 55 kart toplam
/sectors/{slug} O sektöre ait radyolar (10) + playlistler (10) 2 bölüm, yatay kaydırma
/genres/{slug} O türe ait playlistler Hero + playlist listesi
/radios Tüm radyolar listesi Grid/liste görünüm
Versiyon Geçmişi
v1: İlk özet. type ENUM, priority, is_featured, cache_ttl, business_rules.
v2: type kaldırıldı → show_on + template. priority → sort_order. is_featured + cache_ttl kaldırıldı.
v3: business_rules kaldırıldı. corporate_account_id FK eklendi.
v4: template kolonu kaldırıldı (otomatik tespit). Mevcut kartlar, kart sayıları (15/10), "Tümünü Gör". 13→12 kolon.
v5: sector_rules → visibility_rules. Sektör + genre + radyo filtresi tek JSON'da.
v6: Sayfa yapısı netleşti: sektör ve genre'nin bireysel sayfaları var, radyo tek sayfa (radio_ids yok). Fallback sistemi eklendi: koleksiyon yoksa mevcut görünüm korunur, 1+ koleksiyon varsa yeni sisteme geçer. Sektör alt sayfaları kalkacak. Senaryo örnekleri eklendi.

Teknik detaylar, kod örnekleri ve tüm kararlar için:

Tam Dokümantasyon (v10)

Not: v10 henüz v6 değişikliklerini içermiyor, güncellenecek.