COMPLETE INTEGRATION v3 6 Ocak 2026

Akıllı Öneri Sistemi - Complete Solution

Content Collections + Sector System + Tag/Category Integration + Enhanced Frontend

📝 Basit Anlatım (Herkes İçin)

Ne Yapıldı?

Müzik platformunuz artık akıllı bir sistem haline geldi! Kullanıcılar anasayfaya girdiklerinde:

  • Sektörünü seçiyor (Cafe, Restaurant, Gym, SPA) ve o sektöre özel müzikler görüyor
  • Günün saatine göre farklı öneriler alıyor (sabah enerjik, akşam rahatlatıcı)
  • Müzik tarzını filtreleyebiliyor (Hard Rock, Jazz, Acoustic)
  • Kullanım senaryolarına göre kategoriler görebiliyor (Güne Başlangıç, Gece Müzikleri)

Neden Önemli?

👤 Kullanıcı İçin:
  • • Aradığı müziği hızlı buluyor
  • • Sektörüne uygun öneriler alıyor
  • • Saate göre otomatik içerik değişiyor
  • • Spotify gibi profesyonel deneyim
💼 İşletme İçin:
  • • Kullanıcı memnuniyeti artıyor
  • • Dinleme süreleri uzuyor
  • • Premium üyelik teşviki kolay
  • • Rakiplerden farklılaşma

Örnek Senaryo

Ahmet, Ankara'da bir cafe işletiyor. Sabah saat 09:00'da sisteme giriş yapıyor.

Sektör: Cafe seçiyor
Saat: 09:00 (Sabah)
Tercih: Jazz seçiyor

Sistem otomatik olarak şunları gösteriyor:

  • "Kahve Keyfi" koleksiyonu (Cafe + Sabah saati)
  • 🎵 "Sabah Jazz" kategorisi (Jazz tag'i filtrelenmiş)
  • ☀️ "Güne Başlangıç" kategorisi (Sabah kategorisi)

→ Ahmet tam ihtiyacı olan müziği 3 saniyede buldu!

🔧 Teknik Detaylar (Geliştiriciler İçin)

Mimari Genel Bakış

Layer 1: Sectors
muzibu_sectors
(Cafe, Restaurant, Gym)
Layer 2: Tags
muzibu_tags
(Hard Rock, Jazz, Chill)
Layer 3: Categories
muzibu_playlist_categories
(Güne Başlangıç, Gece)
Layer 4: Collections
muzibu_content_collections
(Dynamic smart groups)

Dosya Konumları

Models:
• Modules/Muzibu/app/Models/Sector.php
• Modules/Muzibu/app/Models/Tag.php
• Modules/Muzibu/app/Models/PlaylistCategory.php
• Modules/Muzibu/app/Models/ContentCollection.php
Services:
• Modules/Muzibu/app/Services/ContentCollectionService.php
• Modules/Muzibu/app/Services/SmartRecommendationService.php
Controllers:
• Modules/Muzibu/app/Http/Controllers/Front/HomeController.php
• Modules/Muzibu/app/Http/Controllers/Admin/ContentCollectionController.php
Views:
• resources/views/themes/muzibu/home.blade.php
• Modules/Muzibu/resources/views/admin/content-collections/

Kullanılan Teknolojiler

🐘
Laravel 10
Backend Framework
📊
MariaDB
Database
Livewire
Admin Panel
🎨
Tailwind CSS
Frontend Styling
🔥
Alpine.js
Frontend Reactivity
📦
JSON
Rules & Conditions
🔗
Polymorphic
Relations
🌐
Multi-Tenant
Architecture

Complete Database Schema

muzibu_content_collections

collection_id BIGINT PK
name JSON (tr, en)
slug JSON
type VARCHAR (time_based, sector_based...)
icon VARCHAR (FontAwesome)
color VARCHAR (hex)
display_rules JSON ⭐
visibility_conditions JSON ⭐
priority INT (0-100)
is_active BOOLEAN
• timestamps
Akıllı koleksiyonlar - Saat/Sektör/Kullanıcı bazlı dinamik gruplar

muzibu_collection_items

id BIGINT PK
collection_id BIGINT FK
item_type VARCHAR (playlist, album, radio)
item_id BIGINT
position INT (sort order)
• timestamps
Polymorphic pivot - Koleksiyonların içeriği

muzibu_sectors

sector_id BIGINT PK
title JSON (tr, en)
slug JSON
description JSON
cover_media_id FK
is_active BOOLEAN
• timestamps
Sektörler - Cafe, Restaurant, Gym, SPA

muzibu_tags

tag_id BIGINT PK
name JSON (tr, en)
slug JSON
type VARCHAR (style, mood, tempo)
color VARCHAR (hex)
icon VARCHAR (FA class)
is_active BOOLEAN
• timestamps
Müzik karakteristikleri - Hard Rock, Jazz, Chill

muzibu_playlist_categories

category_id BIGINT PK
sector_id BIGINT FK (nullable)
name JSON (tr, en)
slug JSON
sort_order INT
is_active BOOLEAN
• timestamps
Kullanım senaryoları - Güne Başlangıç, Gece Müzikleri

muzibu_playlistables

id BIGINT PK
playlist_id BIGINT FK
playlistable_type VARCHAR
playlistable_id BIGINT
• timestamps
Polymorphic pivot - Playlist bağlantıları:
→ type='sector', id=1 (Cafe)
→ type='tag', id=3 (Hard Rock)
→ type='category', id=1 (Güne Başlangıç)

İlişkiler Diyagramı

Sector playlistables Playlist
Tag playlistables Playlist
Category playlistables Playlist
Collection collection_items Playlist/Album/Radio

Backend Service Logic

SmartRecommendationService.php

class SmartRecommendationService
{
    public function getRecommendations($sectorId = null, $tagId = null, $user = null)
    {
        $now = now();
        $dayOfWeek = $now->format('D');
        $currentTime = $now->format('H:i');

        // 1. Get active content collections (time/sector/user based)
        $collections = ContentCollection::where('is_active', true)
            ->get()
            ->filter(function($collection) use ($user, $dayOfWeek, $currentTime, $sectorId) {
                return $this->checkDisplayRules($collection, $dayOfWeek, $currentTime, $sectorId)
                    && $this->checkVisibilityConditions($collection, $user);
            })
            ->sortByDesc('priority');

        // 2. Get categories for selected sector
        $categories = PlaylistCategory::query()
            ->where('is_active', true)
            ->when($sectorId, function($q) use ($sectorId) {
                $q->where(function($query) use ($sectorId) {
                    $query->where('sector_id', $sectorId)
                          ->orWhereNull('sector_id'); // Global categories
                });
            })
            ->orderBy('sort_order')
            ->get();

        // 3. For each category, get playlists
        $categories = $categories->map(function($category) use ($sectorId, $tagId) {
            $category->playlists = $this->getPlaylistsForCategory(
                $category->category_id,
                $sectorId,
                $tagId
            );
            return $category;
        });

        return [
            'collections' => $collections,
            'categories' => $categories,
            'sector_id' => $sectorId,
            'tag_id' => $tagId,
        ];
    }

    private function getPlaylistsForCategory($categoryId, $sectorId = null, $tagId = null)
    {
        return Playlist::query()
            ->whereHas('categories', fn($q) => $q->where('category_id', $categoryId))
            ->when($sectorId, function($q) use ($sectorId) {
                $q->whereHas('sectors', fn($query) => $query->where('sector_id', $sectorId));
            })
            ->when($tagId, function($q) use ($tagId) {
                $q->whereHas('tags', fn($query) => $query->where('tag_id', $tagId));
            })
            ->where('is_active', true)
            ->limit(20)
            ->get();
    }

    private function checkDisplayRules($collection, $dayOfWeek, $currentTime, $sectorId): bool
    {
        $rules = $collection->display_rules;

        // Time range check
        if (isset($rules['time_range'])) {
            if ($currentTime < $rules['time_range']['start'] ||
                $currentTime > $rules['time_range']['end']) {
                return false;
            }
        }

        // Days check
        if (isset($rules['days']) && !in_array($dayOfWeek, $rules['days'])) {
            return false;
        }

        // Sector check
        if (isset($rules['sectors']) && $sectorId) {
            if (!in_array($sectorId, $rules['sectors'])) {
                return false;
            }
        }

        return true;
    }

    private function checkVisibilityConditions($collection, $user): bool
    {
        $conditions = $collection->visibility_conditions;

        // Auth required
        if (isset($conditions['auth_required']) && $conditions['auth_required']) {
            if (!$user) return false;
        }

        // Subscription type
        if (isset($conditions['subscription_types']) && $user) {
            $activeSubscription = $user->subscriptions()
                ->where('status', 'active')
                ->first();

            if (!$activeSubscription ||
                !in_array($activeSubscription->subscription_type, $conditions['subscription_types'])) {
                return false;
            }
        }

        // User sector
        if (isset($conditions['user_sectors']) && $user) {
            if (!in_array($user->primary_sector_id, $conditions['user_sectors'])) {
                return false;
            }
        }

        return true;
    }
}

HomeController.php

public function index(
    Request $request,
    SmartRecommendationService $service
) {
    $user = auth()->user();
    $sectorId = $request->get('sector_id', $user?->primary_sector_id);
    $tagId = $request->get('tag_id');

    // Get smart recommendations
    $data = $service->getRecommendations($sectorId, $tagId, $user);

    // Get all sectors for selector
    $sectors = Sector::where('is_active', true)->get();

    // Get all tags for filters
    $tags = Tag::where('is_active', true)->get();

    return view('themes.muzibu.home', [
        'collections' => $data['collections'],
        'categories' => $data['categories'],
        'sectors' => $sectors,
        'tags' => $tags,
        'selectedSector' => $sectorId,
        'selectedTag' => $tagId,
    ]);
}

Enhanced Frontend Prototype (Interactive)

Sektör Seçin:
Müzik Tarzı:

Şu Anda Sizin İçin (Saat: )

☕ Kahve Keyfi

Cafe için özel • 07:00-11:00

💪 Workout Energy

Gym için özel • 06:00-12:00

☀️ Güne Başlangıç

Hard Rock Jazz Tüm tarzlar

☕ Öğle Arası

Rahatlatıcı müzikler

🌙 Gece Müzikleri

Atmosferik & Rahatlatıcı
Akıllı Filtreleme Aktif
Sektör:
Saat: (Sabah - Energik içerikler)
Müzik Tarzı:
→ İçerikler otomatik filtrelendi ve en uygun öneriler gösteriliyor!
Bu interaktif demo Alpine.js kullanıyor. Sector ve Tag seçerek farklı içerikleri görebilirsiniz!

Complete Integration Flow (User Journey)

1

Kullanıcı Girişi & Profil

• Kullanıcı sisteme giriş yapar (veya guest olarak devam eder)
• Profilde primary_sector_id set edilir (Cafe, Restaurant, vb.)
• Abonelik durumu kontrol edilir (Free, Premium, Corporate)
2

Anasayfa Yükleme

HomeController@index çalışır
SmartRecommendationService çağrılır
• Parametreler: sector_id, tag_id, user
• Sistem şu anki saati ve günü alır (09:30, Salı)
3

Akıllı Filtreleme (Backend)

3a. Content Collections Filtresi:
display_rules kontrol: Saat 09:30 → Sabah koleksiyonları göster
visibility_conditions kontrol: User premium mi? → Premium koleksiyonlar ekle
• Sector ID kontrol: Cafe (1) → Cafe koleksiyonları göster
3b. Categories Filtresi:
• Cafe sektörüne özel kategoriler getir (sector_id=1)
• Global kategoriler ekle (sector_id=NULL)
• Her kategori için playlist'leri filtrele (Sector + Tag + Category)
4

Frontend Render

Sector Selector: 4 seçenek (Cafe, Restaurant, Gym, SPA)
Tag Filters: Tümü, Hard Rock, Jazz, Acoustic, Chill
Collections: "Kahve Keyfi" koleksiyonu scroll görünümü
Categories: "Güne Başlangıç", "Öğle Arası", "Gece Müzikleri" bölümleri
5

Kullanıcı Etkileşimi

• Kullanıcı Restaurant seçer → Sayfa Ajax ile yenilenir
Jazz tag'i seçilir → Sadece Jazz içerikler gösterilir
• Kategori scroll edilir → "Gece Müzikleri" bölümüne gelinir
• Playlist'e tıklanır → Player başlar
6

Dinamik Güncelleme

• Saat değişir (09:30 → 14:00) → Otomatik yenileme
• "Öğle Arası" koleksiyonu gösterilir, "Sabah Enerjisi" gizlenir
• Admin panel'den yeni koleksiyon eklenir → Anında yansır
• Kullanıcı premium olur → Premium koleksiyonlar unlock olur

Uygulama Planı (Step by Step)

Phase 1: Database & Migrations

Yeni Tablolar:
✓ muzibu_tags
✓ muzibu_playlist_categories
✓ muzibu_content_collections
✓ muzibu_collection_items
Mevcut Tablo Güncellemeleri:
✓ users: primary_sector_id ekle
✓ muzibu_playlistables: Polymorphic pivot (mevcut)
Migration konumu: Modules/Muzibu/database/migrations/tenant/

Phase 2: Models & Relations

Tag model: HasTranslations, polymorphic relations
PlaylistCategory model: Sector relation, polymorphic
ContentCollection model: JSON cast, polymorphic items
Playlist model'e method ekle: tags(), categories()
User model'e ekle: primarySector() relation

Phase 3: Service Classes

SmartRecommendationService: Main logic
ContentCollectionService: Collection filtering
CategoryService: Category & playlist grouping

Phase 4: Admin Panel (Livewire)

Components:
• TagComponent (CRUD)
• CategoryComponent (CRUD)
• ContentCollectionComponent (CRUD + 5 tabs)
Features:
• Drag & drop sorting
• JSON rule builder
• Live preview

Phase 5: Frontend (Blade + Alpine.js)

home.blade.php: Enhanced layout
• Sector selector component
• Tag filter component
• Collection slider (Spotify-style)
• Category sections with horizontal scroll
• Alpine.js for interactivity (tab switching, filtering)

Phase 6: Seeder & Testing

• Tag seeder (Hard Rock, Jazz, Acoustic, Chill, vb.)
• Category seeder (Güne Başlangıç, Öğle Arası, Gece)
• Collection seeder (Kahve Keyfi, Workout Energy, vb.)
• Test senaryoları: Farklı saat/gün/sektör kombinasyonları
🎉

Complete Integration Başarıyla Tasarlandı!

Akıllı Öneri + Sector + Tag + Category = Güçlü Müzik Platformu

Kullanıcı İçin
  • Sektörüne özel içerik
  • Saate göre otomatik öneriler
  • Tarz bazlı kolay filtreleme
  • Spotify seviyesinde UX
Teknik Avantajlar
  • Polymorphic ilişkiler (esnek)
  • JSON rules (sonsuz kombinasyon)
  • Cache edilebilir yapı
  • Tenant-aware database
İş Değeri
  • Kullanıcı memnuniyeti ↑
  • Dinleme süreleri ↑
  • Premium conversion ↑
  • Rakiplerden ayrışma
Gelecek Geliştirmeler:
• AI-powered playlist generation (kullanıcının dinleme geçmişine göre)
• Collaborative filtering (benzer kullanıcılardan öneriler)
• A/B testing admin panel (hangi koleksiyonlar daha çok tıklanıyor?)
• Mood-based dynamic filtering (kullanıcının ruh haline göre)
• Voice-activated sector/tag selection