v7 — SON PLAN 24 Şubat 2026

Dinamik İçerik Sistemi — Kesinleşmiş Plan

Tüm kararlar, tüm tablolar, tüm dosyalar, tüm TODO'lar. Tek doküman.

Kesinleşen Kararlar

B2B Only — Her kullanıcı bir işletme sahibi. Guest/bireysel yok. Soundtrack Your Brand modeli.
5 Polimorfik Tip — Playlist, Album, Radio, Genre, Sector. Aynı koleksiyonda karışık kullanılır.
Users Sektörusers.sector_id FK → muzibu_sectors.sector_id. Kullanıcı profilinden seçer.
Dayparting (6 Dilim) — Açılış 06-09, Sabah 09-11:30, Öğle 11:30-14, Ö.Sonra 14-17, Akşam 17-21, Gece 21-06.
Koleksiyon Tipleri — curated (el seçimi), daypart (zamana göre), sector (sektöre göre), featured (öne çıkan).
Tıklama Davranışları — Radio → hemen çalar. Playlist/Album → şarkı listesi açılır. Genre → genre sayfası. Sector → sektör sayfası.
"Tümü" Butonu — Koleksiyonda 6'dan fazla öğe varsa görünür, /koleksiyon/{slug} sayfasına gider. 6 ve altı → buton gizli, yatay scroll yeterli.
Sıralama — Koleksiyon içi: position (sürükle-bırak). Koleksiyonlar arası: priority (büyük = önce).
Cache — Key: smart_feed:{userId}:{sectorId}:{30dk_block}, TTL: 300 saniye.
Koleksiyon Sayfası RouteGET /koleksiyon/{slug} → Grid görünüm, aynı tıklama kuralları geçerli.

Veritabanı Şeması

Migration 1 users tablosuna sector_id ekleme
KolonTipDefaultIndexAçıklama
sector_id BIGINT UNSIGNED NULL NULL INDEX FK → muzibu_sectors.sector_id
Konum: corporate_account_id kolonundan sonra
Migration 2 muzibu_content_collections (Yeni Tablo)
KolonTipDefaultIndexAçıklama
collection_id BIGINT UNSIGNED AUTOPK Birincil anahtar
title JSON {"tr": "Sabah Kafe Mix", "en": "..."}
slug JSON {"tr": "sabah-kafe-mix"}
description JSON NULLNULL Çoklu dil açıklama
type ENUMINDEX curated | daypart | sector | featured
icon VARCHAR(50) NULLNULL FontAwesome ikon (fa-mug-hot)
color VARCHAR(20) NULLNULL Hex renk (#f59e0b)
media_id BIGINT UNSIGNED NULLNULL Kapak görseli
display_rules JSON NULLNULL {time_slots, days, is_always}
sector_rules JSON NULLNULL {mode, sector_ids, show_to_all}
business_rules JSON NULLNULL {subscription, min_months}
priority INT0INDEX Koleksiyonlar arası sıralama (büyük = önce)
is_active BOOLEAN1INDEX Aktif/Pasif
is_featured BOOLEAN0 Öne çıkan
cache_ttl INT300 Cache süresi (saniye)
created_at / updated_at TIMESTAMP Laravel timestamps
Migration 3 muzibu_collection_items (Yeni Tablo)
KolonTipDefaultIndexAçıklama
id BIGINT UNSIGNED AUTOPK Birincil anahtar
collection_id BIGINT UNSIGNEDFK + INDEX → muzibu_content_collections.collection_id
itemable_type VARCHAR(255)COMPOSITE Playlist | Album | Radio | Genre | Sector
itemable_id BIGINT UNSIGNED Polimorfik FK
position INT0INDEX Sürükle-bırak sıralama
is_active BOOLEAN1 Aktif/Pasif
created_at / updated_at TIMESTAMP Laravel timestamps
Composite index: (itemable_type, itemable_id) + Unique: (collection_id, itemable_type, itemable_id)

Dosya Haritası

Modules/Muzibu/
├── database/migrations/
│   ├── 2026_02_24_000001_add_sector_id_to_users.php          ← Migration 1 (central)
│   ├── 2026_02_24_000002_create_content_collections.php       ← Migration 2 (central)
│   ├── 2026_02_24_000003_create_collection_items.php          ← Migration 3 (central)
│   └── tenant/
│       ├── 2026_02_24_000001_add_sector_id_to_users.php      ← Migration 1 (tenant)
│       ├── 2026_02_24_000002_create_content_collections.php   ← Migration 2 (tenant)
│       └── 2026_02_24_000003_create_collection_items.php      ← Migration 3 (tenant)
│
├── App/Models/
│   ├── ContentCollection.php                                  ← Yeni Model
│   └── CollectionItem.php                                     ← Yeni Model
│
├── App/Services/
│   └── SmartFeedService.php                                   ← Yeni Servis
│
├── App/Http/Controllers/
│   └── Front/
│       └── CollectionController.php                           ← show() metodu
│
├── App/Http/Livewire/
│   ├── CollectionComponent.php                                ← Admin liste
│   └── CollectionManageComponent.php                          ← Admin form (5 tab)
│
└── resources/views/livewire/
    ├── collection-component.blade.php                         ← Admin liste blade
    └── collection-manage-component.blade.php                  ← Admin form blade

resources/views/themes/muzibu/
├── index.blade.php                                            ← Anasayfa güncelleme (SmartFeed)
└── collection/
    └── show.blade.php                                         ← Koleksiyon detay (grid)

app/Models/
└── User.php                                                   ← sector() relationship ekleme

routes/
└── tenant.php                                                 ← GET /koleksiyon/{slug} route

Route Haritası

MethodURIControllerAçıklama
GET /koleksiyon/{slug} CollectionController@show Koleksiyon detay — tüm öğeler grid
GET /admin/koleksiyonlar Livewire: CollectionComponent Admin liste sayfası
GET /admin/koleksiyonlar/manage/{id?} Livewire: CollectionManageComponent Admin oluştur/düzenle (5 tab)

UX Kuralları

Tıklama Davranışları

TipKartTıklanıncaSayfa Değişir?
Radyo Kare + play ikonu Hemen çalar Hayır — player bar güncellenir
Playlist Kare + ok ikonu Şarkı listesi açılır Evet — playlist detay sayfası
Albüm Kare + ok ikonu Şarkı listesi açılır Evet — albüm detay sayfası
Genre Kare + ok ikonu Genre sayfası Evet — o türün içerikleri
Sektör Kare + ok ikonu Sektör sayfası Evet — o sektörün içerikleri

"Tümü" Butonu Kuralı

6 ve altı öğe
"Tümü" butonu GİZLİ. Yatay scroll ile tümüne erişilir.
☕ Sabah Mix                 
[R1] [P2] [P3] [A4] →
7+ öğe
"Tümü" butonu GÖRÜNÜR. Tıklanınca /koleksiyon/{slug} açılır.
☕ Sabah Mix         Tümü ›
[R1] [P2] [P3] [A4] [P5] [G6] [R7] →
@if($collection->items_count > 6)
    <a href="/koleksiyon/{{ $collection->slug }}">Tümü <i class="fas fa-chevron-right"></i></a>
@endif

Anasayfa Yapısı

☀️ Günaydın, Ahmet!
Kafen için seçilmiş sabah listeleri
★ Editörün Seçimi Tümü ›
[Radio] [Playlist] [Album] [Playlist] [Genre] [Sector] [Radio] →
☕ Sabah Kafe Mix
[Radio] [Playlist] [Playlist] [Album] →
← 4 öğe, "Tümü" butonu yok
👆 Türkçe Pop Klasikler Tümü ›
[Radio] [Playlist] [Album] [Playlist] [Genre] [Radio] [Playlist] [Album] →
← 8 öğe, "Tümü" butonu VAR

Uygulama Fazları & TODO

Faz 1 — Migration & Modeller
1
Migration: users.sector_id ekle
Central + Tenant migration. FK → muzibu_sectors.sector_id. Konum: corporate_account_id sonrası.
add_sector_id_to_users.php
2
Migration: muzibu_content_collections tablosu
Central + Tenant migration. 15 kolon. ENUM type, JSON rules alanları.
create_content_collections.php
3
Migration: muzibu_collection_items tablosu
Central + Tenant migration. Polimorfik yapı. Composite + Unique index.
create_collection_items.php
4
Model: ContentCollection
$translatable: title, slug, description. $casts: JSON rules. Relationships: items(), activeItems().
ContentCollection.php
5
Model: CollectionItem
Polimorfik: itemable() → morphTo. Morph map: playlist, album, radio, genre, sector.
CollectionItem.php
6
User Model: sector() relationship ekle
belongsTo(Sector::class, 'sector_id', 'sector_id'). isMuzibuTenant() guard.
User.php
Faz 2 — SmartFeedService & Controller
7
SmartFeedService oluştur
getFeed(User): greeting + koleksiyonlar. 3 filtre: matchesTimeRules, matchesSectorRules, matchesBusinessRules. Cache: smart_feed:{userId}:{sectorId}:{30dk_block}, TTL: 300s.
SmartFeedService.php
8
CollectionController@show
GET /koleksiyon/{slug} → Koleksiyon detay sayfası. items() eager load with morphTo.
CollectionController.php
9
HomeController güncelle
Mevcut statik sorguları SmartFeedService ile değiştir. Eski verileri de geçir (backward compat).
HomeController.php
10
Route ekle: /koleksiyon/{slug}
tenant.php'ye GET route.
tenant.php
Faz 3 — Admin Panel (Livewire)
11
CollectionComponent (Admin Liste)
Tablo: başlık, tip, sektör, zaman, öğe sayısı, öncelik, durum. Filtreler: tip, sektör, aktif. Bulk actions.
CollectionComponent.php collection-component.blade.php
12
CollectionManageComponent (Admin Form — 5 Tab)
Tab 1: Temel (title, slug, tip, ikon, renk, media, açıklama, aktif/featured)
Tab 2: Zaman (is_always toggle, time_slots checkboxlar, günler)
Tab 3: Sektör (show_to_all toggle, mode include/exclude, dual listbox)
Tab 4: İş Kuralları (subscription dropdown, min_months)
Tab 5: İçerikler (5 tip ekleme butonları, Sortable.js sürükle-bırak, position)
CollectionManageComponent.php collection-manage-component.blade.php
13
Admin route ve menü kaydı
Muzibu admin menüsüne "Koleksiyonlar" ekle. Route: /admin/koleksiyonlar, /admin/koleksiyonlar/manage/{id?}
Faz 4 — Frontend
14
Anasayfa blade güncelle (SmartFeed entegrasyonu)
Greeting bölümü (saat + isim + sektör). Koleksiyonları döngüle: başlık + yatay scroll kartlar. "Tümü" butonu: items_count > 6 ise göster.
index.blade.php
15
Koleksiyon detay sayfası (grid görünüm)
GET /koleksiyon/{slug}. Tüm öğeler grid olarak. Aynı tıklama kuralları (Radio=çal, Playlist=detay...).
collection/show.blade.php
16
Kart bileşenleri (5 tip için)
Her tip için kart tasarımı: Radio (play butonu), Playlist/Album (ok butonu), Genre/Sector (kare kart). Hover efektleri.
17
Radio tıklama: player entegrasyonu
Radio kartına tıklanınca sayfa değişmeden player-core.js üzerinden radyo çalma. Alpine event dispatch.
Versiyon Geçmişi (v1-v7)
v1 — İlk analiz (Spotify + Apple + Soundtrack benchmark)
v2 — B2B pivot (Soundtrack Your Brand modeli, dayparting)
v3 — Görsel simülasyon (renk kodlu kartlar, veri akışı)
v4 — 5 polimorfik tip kesinleşti (Playlist, Album, Radio, Genre, Sector)
v5 — Örnek veri tabloları + Users sektör alanı + Draft admin paneli
v6 — Kullanıcı deneyimi mockup: Ahmet'in ekranı + tıklama davranışları
v7 — SON PLAN: Tüm kararlar + DB şeması + Dosya haritası + Route + UX kuralları + 17 TODO (4 faz)