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ör —
users.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ı Route —
GET /koleksiyon/{slug} → Grid görünüm, aynı tıklama kuralları geçerli.Veritabanı Şeması
Migration 1
users tablosuna sector_id ekleme
| Kolon | Tip | Default | Index | Açı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)
| Kolon | Tip | Default | Index | Açıklama |
|---|---|---|---|---|
| collection_id | BIGINT UNSIGNED AUTO | — | PK | Birincil anahtar |
| title | JSON | — | — | {"tr": "Sabah Kafe Mix", "en": "..."} |
| slug | JSON | — | — | {"tr": "sabah-kafe-mix"} |
| description | JSON NULL | NULL | — | Çoklu dil açıklama |
| type | ENUM | — | INDEX | curated | daypart | sector | featured |
| icon | VARCHAR(50) NULL | NULL | — | FontAwesome ikon (fa-mug-hot) |
| color | VARCHAR(20) NULL | NULL | — | Hex renk (#f59e0b) |
| media_id | BIGINT UNSIGNED NULL | NULL | — | Kapak görseli |
| display_rules | JSON NULL | NULL | — | {time_slots, days, is_always} |
| sector_rules | JSON NULL | NULL | — | {mode, sector_ids, show_to_all} |
| business_rules | JSON NULL | NULL | — | {subscription, min_months} |
| priority | INT | 0 | INDEX | Koleksiyonlar arası sıralama (büyük = önce) |
| is_active | BOOLEAN | 1 | INDEX | Aktif/Pasif |
| is_featured | BOOLEAN | 0 | — | Öne çıkan |
| cache_ttl | INT | 300 | — | Cache süresi (saniye) |
| created_at / updated_at | TIMESTAMP | — | — | Laravel timestamps |
Migration 3
muzibu_collection_items (Yeni Tablo)
| Kolon | Tip | Default | Index | Açıklama |
|---|---|---|---|---|
| id | BIGINT UNSIGNED AUTO | — | PK | Birincil anahtar |
| collection_id | BIGINT UNSIGNED | — | FK + INDEX | → muzibu_content_collections.collection_id |
| itemable_type | VARCHAR(255) | — | COMPOSITE | Playlist | Album | Radio | Genre | Sector |
| itemable_id | BIGINT UNSIGNED | — | Polimorfik FK | |
| position | INT | 0 | INDEX | Sürükle-bırak sıralama |
| is_active | BOOLEAN | 1 | — | 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ı
| Method | URI | Controller | Açı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ı
| Tip | Kart | Tıklanınca | Sayfa 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] →
[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] →
[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)
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)