a
Kurumsal Muzik Streaming Platformu - Ultimate Master Plan
v1 + v2 + v3 + v4 + v5 + v6 + v7 = Ultimate Birlesik Versiyon
Temel altyapi hazir, B2B ozellikleri bekleniyor
Modules/Muzibu/
├── app/
│ ├── Http/Controllers/
│ │ ├── Api/
│ │ │ ├── AlbumController.php
│ │ │ ├── GenreController.php
│ │ │ ├── PlaylistController.php
│ │ │ ├── SectorController.php
│ │ │ ├── SongController.php
│ │ │ └── SongStreamController.php
│ │ ├── Admin/
│ │ │ └── CorporateAccountController.php
│ │ └── Front/
│ │ └── (Home, Album, Playlist, Genre, Sector, Search)
│ ├── Livewire/Admin/
│ │ └── CorporateAccountComponent.php
│ ├── Jobs/
│ │ ├── ConvertToHLSJob.php
│ │ ├── ProcessBulkSongHLSJob.php
│ │ ├── TranslateMuzibuJob.php
│ │ └── BulkDeleteMuzibusJob.php
│ ├── Models/
│ │ ├── Album.php
│ │ ├── Artist.php
│ │ ├── Genre.php
│ │ ├── Playlist.php
│ │ ├── Radio.php
│ │ ├── Sector.php
│ │ ├── Song.php (14,321 bytes)
│ │ ├── SongPlay.php
│ │ └── MuzibuCorporateAccount.php (✅ GÜNCEL)
│ └── Repositories/ (7 repository)
├── database/migrations/
│ ├── central/
│ │ └── 2025_11_26_000001_add_branch_name_to_muzibu_corporate_accounts.php
│ └── tenant/
│ ├── 2025_11_24_000001_create_muzibu_corporate_accounts_table.php
│ └── 2025_11_26_000001_add_branch_name_to_muzibu_corporate_accounts.php
├── resources/views/
│ ├── admin/
│ │ ├── corporate-index.blade.php
│ │ ├── corporate-manage.blade.php
│ │ └── livewire/
│ │ └── corporate-account-component.blade.php
│ └── themes/muzibu/
│ └── (Frontend views)
├── lang/ (tr, en, de)
└── routes/
├── admin.php
├── api.php
└── web.php
Monolitik 2,685 satirlik dosya. Icerigi:
| Katman | Durum | Aciklama |
|---|---|---|
| Rate Limiting | YOK | API sinirsiz erisime acik |
| Bearer Token | KISMI | Login var ama stream'de zorunlu degil |
| Subscription Check | YOK | Premium kontrol yapilmiyor |
| Signed URL | YOK | URL'ler sifreli degil |
| HLS + AES-128 | YOK | HLS var ama sifresiz |
| Device Fingerprint | YOK | Cihaz tespiti yok |
| CSRF Protection | VAR | X-CSRF-TOKEN kullaniliyor |
| Tur | Sure | Neden? |
|---|---|---|
| 🎸 Rock / Metal | 2-3 saniye | Keskin gecisler, enerji kaybi olmasin |
| 🎹 Caz / Blues | 4-6 saniye | Yumusak, dogal gecis |
| 🎧 Elektronik | 6-10 saniye | Beat matching, DJ tarzi mix |
| 🎻 Klasik | 5-8 saniye | Sessiz finaller, zarif gecis |
| 🎤 Pop | 3-4 saniye | Dengeli, standart gecis |
| ☕ Ambient | 8-12 saniye | Atmosfer koruma |
Sarkilar arasi ses farkini ortadan kaldirmak icin kritik ozellik!
Spotify, Apple Music, YouTube Music gibi buyuk platformlarin kullandigi etkileyici ozellik!
| Frekans | Band | Etki |
|---|---|---|
| 32 Hz | Sub Bass | Derin bas, titresim |
| 64 Hz | Bass | Davul kick, bas gitar |
| 125 Hz | Low Mid | Vokal sicakligi |
| 250 Hz | Mid | Enstruman govdesi |
| 500 Hz | Mid | Vokal netligi |
| 1 kHz | Upper Mid | Ses presence |
| 2 kHz | Upper Mid | Vokal artikulasyonu |
| 4 kHz | Presence | Clarity, detay |
| 8 kHz | Brilliance | Parlaklik |
| 16 kHz | Air | Ultra high, sparkle |
| Kalite | Bitrate | Paket | Kullanim |
|---|---|---|---|
| 📱 Normal | 96 kbps AAC | Ucretsiz/Onizleme | Mobil veri tasarrufu |
| 🎧 Yuksek | 192 kbps AAC | Starter | Gunluk dinleme |
| 🔊 Cok Yuksek | 320 kbps AAC | Professional | Kaliteli hoparlor |
| 💎 Lossless | FLAC 16-bit/44.1kHz | Premium | Hi-Fi sistem |
| 👑 Hi-Res | FLAC 24-bit/96kHz | Enterprise | Studyo kalitesi |
Gelecekte @persist direktifi ile daha temiz cozum:
Muzibu'da bir dinlenme sayilmasi icin sarki en az 60 saniye dinlenmeli.
| Alan | Aciklama | Kullanim |
|---|---|---|
| user_id | Dinleyici kimligi | Kisisel oneri |
| song_id | Sarki kimligi | Populerlik analizi |
| branch_id | Sube kimligi | Sube raporlari |
| duration_seconds | Dinleme suresi | Engagement olcumu |
| completed | Sarki bitti mi? | Skip analizi |
| ip_address | IP adresi (hashed) | Guvenlik |
| device_type | Cihaz turu | Platform analizi |
| quality | Ses kalitesi | Bandwidth analizi |
Maliyet: 26K sarki × $0.01 = $260 (Leonardo.ai)
Temel Prensipler:
| ID | User ID | Parent ID | Company Name | Branch Name | Durum |
|---|---|---|---|---|---|
| 1 | 100 | NULL | Starbucks | NULL | 🏢 Ana Firma |
| 2 | 200 | 1 | NULL | Kadıköy Şubesi | 🏪 Alt Şube |
| 3 | 201 | 1 | NULL | Beşiktaş Şubesi | 🏪 Alt Şube |
| 4 | 202 | 1 | NULL | Şişli Şubesi | 🏪 Alt Şube |
Kadıköy Bağımsızlaşırsa:
| Alan | Tip | Açıklama |
|---|---|---|
| id | bigint | Primary key |
| user_id | bigint | Her şube = Ayrı user (premium) |
| parent_id | bigint (nullable) | NULL = Ana, VALUE = Alt şube |
| company_name | string | Ana firma adı |
| branch_name | string (nullable) | ✅ YENİ: Alt şube adı |
| corporate_code | string (unique) | Sadece ana firmada |
| is_active | boolean | Aktif/Pasif |
✅ İyi Yönler:
❌ Eksikler:
| Öncelik | İşlem | Dosya |
|---|---|---|
| 1️⃣ YÜKSEK | View'de branch_name kullan | corporate-account-component.blade.php |
| 2️⃣ YÜKSEK | detachBranch() method ekle | CorporateAccountComponent.php |
| 3️⃣ ORTA | canViewBranchStats() yetki kontrolü | MuzibuCorporateAccount.php |
| 4️⃣ ORTA | Ana/Alt şube badge'leri | corporate-account-component.blade.php |
| 5️⃣ DÜŞÜK | İstatistik raporu sayfası | Yeni route + view |
Muzibu Corporate sistemi, çoklu şubeli işletmelerin müzik yayını yapmasını sağlar. Ancak ÖNEMLI: Bu klasik bir hiyerarşik sistem değildir!
-- Ana Firma
INSERT INTO muzibu_corporate_accounts (user_id, parent_id, company_name, branch_name, corporate_code)
VALUES (100, NULL, 'Starbucks', NULL, 'STB-X8K2M');
-- Alt Şube (farklı user!)
INSERT INTO muzibu_corporate_accounts (user_id, parent_id, company_name, branch_name, corporate_code)
VALUES (200, 1, NULL, 'Kadıköy Şubesi', NULL);
-- Şube Bağımsızlaşma
UPDATE muzibu_corporate_accounts
SET parent_id = NULL, company_name = 'Kadıköy Coffee', corporate_code = 'KDK-P9L3X'
WHERE id = 2;
// Ana şube mi?
public function isMainBranch(): bool
{
return $this->parent_id === null;
}
// Alt şubeleri getir
public function getSubBranches()
{
return $this->children()->get();
}
// Şirket adını döndür (ana şubeyse kendi, alt şubeyse parent'tan)
public function getCompanyName(): ?string
{
if ($this->isMainBranch()) {
return $this->company_name;
}
return $this->parent ? $this->parent->company_name : null;
}
// Yetki kontrolü
public function canViewBranchStats($branchId): bool
{
if ($this->isMainBranch()) {
return $this->children()->where('id', $branchId)->exists();
}
return $this->id === $branchId;
}
Ana işlemler:
1. User A (id: 100) → Ana firma oluştur: "Starbucks"
2. User B (id: 200) → Alt şube olarak ekle: "Kadıköy Şubesi" (parent_id: 1)
3. User C (id: 201) → Alt şube olarak ekle: "Beşiktaş Şubesi" (parent_id: 1)
4. User A → Tüm şubelerin istatistiklerini görebilir (Kadıköy + Beşiktaş)
5. User B → Sadece Kadıköy'ün istatistiklerini görebilir
6. User B → Bağımsızlaşma talep eder
7. Admin → User B'nin parent_id'sini NULL yapar
8. User B → Artık ana firma! Kendi corporate_code'u var
| İşlem | Durum | Yapan |
|---|---|---|
| Migration: branch_name alan ekleme (central) | ✅ TAMAM | Claude |
| Migration: branch_name alan ekleme (tenant) | ✅ TAMAM | Claude |
| Model: branch_name fillable + helper methodlar | ✅ TAMAM | Claude |
| Migration çalıştırma (central + tüm tenant'lar) | ✅ TAMAM | Claude |
| Sistem mimarisi dokümantasyonu | ✅ TAMAM | Claude |
| View'de branch_name kullanımı | ✅ TAMAM | Claude |
| detachBranch() method ekleme | ✅ TAMAM | Claude |
| Ana Şube / Alt Şube badge'leri | ✅ TAMAM | Claude |
| Bağımsızlaştır butonu (rocket icon) | ✅ TAMAM | Claude |
| Öncelik | İşlem | Dosya | Yapacak |
|---|---|---|---|
| 1️⃣ YÜK | FRONTEND: Şube seçici UI | themes/muzibu/layouts/app.blade.php | Frontend yapay zekası |
| 2️⃣ YÜK | FRONTEND: Player şube bilgisi | themes/muzibu/components/player.blade.php | Frontend yapay zekası |
| 3️⃣ ORT | FRONTEND: Şube istatistik widget'ı | Yeni component | Frontend yapay zekası |
| ❄️ İLERİ | ADMIN: İstatistik sistem (canViewBranchStats + rapor) | Çok daha sonra yapılacak | İleri tarihte |
MuzibuCorporateAccount tablosundan gelir| Yontem | Aciklama | Oneri |
|---|---|---|
| ⏰ Sabit Saat | 09:00, 12:00, 18:00 | Onemli duyurular |
| 🎵 X Sarki Sonra | Her 5 sarkida bir | Reklam icin |
| ⏱️ X Dakika Sonra | Her 30 dakikada | Duzenli hatirlatma |
| 🎼 Sarki Bitiminde | Dogal bitiste anons | ✅ EN IYI UX! |
Musteriyi etkileyecek, rakiplerden ayiracak ozellikler
Problem: Eski muzibu-player.js monolithic (2026 satır), bakım zor, duplicate code
Çözüm: Feature-based modüler yapı
player/
├── core/
│ ├── safe-storage.js (localStorage wrapper)
│ └── player-core.js (muzibuApp main)
├── features/
│ ├── favorites.js (like/favorite system)
│ └── auth.js (authentication)
└── muzibu-player.BACKUP... (eski - kullanılmıyor)
safe-storage.js → Utility öncemuzibu-store.js → Alpine storefavorites.js → Feature modülleriauth.js → Feature modülleriplayer-core.js → Core (features'ı spread eder)muzibu-cache/toast/theme.js → Utils/UIfunction muzibuApp() {
return {
...muzibuFavorites(), // features/favorites.js
...muzibuAuth(), // features/auth.js
// ... core player functions
}
}
Problem: DB::table() kullanımı tenant bypass ediyordu → Yanlış tenant'tan data geliyordu (song ID 54, 87 gibi)
Çözüm: TÜM controller'lar Eloquent'e çevrildi
$songs = DB::table('muzibu_songs')
->where('is_active', 1)
->get();
// ❌ Farklı tenant'lardan gelir!
$songs = Song::where('is_active', 1)
->with('album.artist')
->get();
// ✅ Sadece mevcut tenant!
Mimari: Frontend (Alpine.js) + Backend (Laravel API)
Frontend (SPA) Backend (API)
───────────── ─────────────
Alpine.js Components → Laravel API Endpoints
├─ Player (JS) ─→ ├─ /api/muzibu/songs/*
├─ Queue Management ─→ ├─ /api/muzibu/playlists/*
├─ Search ─→ ├─ /api/muzibu/albums/*
├─ Favorites ─→ ├─ /api/muzibu/genres/*
└─ Auth ─→ └─ /api/muzibu/sectors/*
23. Sosyal Ozellikler
❤️ Begeni & Kaydetme
📤 Paylasim