start project

This commit is contained in:
2026-05-15 16:33:34 +03:30
parent 553238b0fb
commit d756661b45
50 changed files with 3523 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Fillable(['admin_user_id', 'subject_type', 'subject_id', 'action', 'metadata', 'created_at'])]
class AdminAuditLog extends Model
{
public $timestamps = false;
protected function casts(): array
{
return [
'metadata' => 'array',
'created_at' => 'datetime',
];
}
public function admin(): BelongsTo
{
return $this->belongsTo(User::class, 'admin_user_id');
}
}

54
app/Models/Broadcast.php Normal file
View File

@@ -0,0 +1,54 @@
<?php
namespace App\Models;
use Database\Factories\BroadcastFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
#[Fillable([
'channel_id',
'title',
'status',
'recording_enabled',
'mediamtx_path',
'source_type',
'source_id',
'hls_url',
'viewer_peak',
'started_at',
'ended_at',
])]
class Broadcast extends Model
{
/** @use HasFactory<BroadcastFactory> */
use HasFactory;
public const STATUS_PENDING = 'pending';
public const STATUS_LIVE = 'live';
public const STATUS_ENDED = 'ended';
protected function casts(): array
{
return [
'recording_enabled' => 'boolean',
'started_at' => 'datetime',
'ended_at' => 'datetime',
];
}
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
public function vod(): HasOne
{
return $this->hasOne(Vod::class);
}
}

21
app/Models/Category.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Database\Factories\CategoryFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable(['name', 'slug', 'description'])]
class Category extends Model
{
/** @use HasFactory<CategoryFactory> */
use HasFactory;
public function channels(): HasMany
{
return $this->hasMany(Channel::class);
}
}

89
app/Models/Channel.php Normal file
View File

@@ -0,0 +1,89 @@
<?php
namespace App\Models;
use Database\Factories\ChannelFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
#[Fillable([
'user_id',
'category_id',
'live_broadcast_id',
'slug',
'display_name',
'description',
'avatar_path',
'banner_path',
'thumbnail_path',
'is_live',
'viewer_count',
'suspended_at',
])]
class Channel extends Model
{
/** @use HasFactory<ChannelFactory> */
use HasFactory;
protected function casts(): array
{
return [
'is_live' => 'boolean',
'suspended_at' => 'datetime',
];
}
public function getRouteKeyName(): string
{
return 'slug';
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function streamKey(): HasOne
{
return $this->hasOne(StreamKey::class);
}
public function broadcasts(): HasMany
{
return $this->hasMany(Broadcast::class);
}
public function liveBroadcast(): BelongsTo
{
return $this->belongsTo(Broadcast::class, 'live_broadcast_id');
}
public function vods(): HasMany
{
return $this->hasMany(Vod::class);
}
public function follows(): HasMany
{
return $this->hasMany(Follow::class);
}
public function chatMessages(): HasMany
{
return $this->hasMany(ChatMessage::class);
}
public function isSuspended(): bool
{
return $this->suspended_at !== null || $this->user?->suspended_at !== null;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Fillable(['channel_id', 'broadcast_id', 'user_id', 'body'])]
class ChatMessage extends Model
{
use SoftDeletes;
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
public function broadcast(): BelongsTo
{
return $this->belongsTo(Broadcast::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

21
app/Models/Follow.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Fillable(['channel_id', 'user_id'])]
class Follow extends Model
{
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

24
app/Models/StreamKey.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Fillable(['channel_id', 'key_hash', 'last_used_at', 'revoked_at'])]
class StreamKey extends Model
{
protected function casts(): array
{
return [
'last_used_at' => 'datetime',
'revoked_at' => 'datetime',
];
}
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
}

42
app/Models/Vod.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Fillable([
'broadcast_id',
'channel_id',
'title',
'storage_path',
'playback_url',
'duration_seconds',
'size_bytes',
'published_at',
'expires_at',
])]
class Vod extends Model
{
use SoftDeletes;
protected function casts(): array
{
return [
'published_at' => 'datetime',
'expires_at' => 'datetime',
];
}
public function broadcast(): BelongsTo
{
return $this->belongsTo(Broadcast::class);
}
public function channel(): BelongsTo
{
return $this->belongsTo(Channel::class);
}
}