76 lines
3.1 KiB
PHP
76 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class Workspace extends Model
|
|
{
|
|
use HasFactory, HasUuids;
|
|
|
|
protected $fillable = [
|
|
'name', 'slug', 'owner_user_id', 'plan',
|
|
'trial_ends_at', 'logo_url', 'billing_email', 'region',
|
|
'quotas_override',
|
|
];
|
|
|
|
protected $casts = [
|
|
'trial_ends_at' => 'datetime',
|
|
'quotas_override' => 'array',
|
|
];
|
|
|
|
/** Plan-defaults (quotas before any override). */
|
|
public const PLAN_QUOTAS = [
|
|
'free' => ['sites' => 1, 'servers' => 0, 'team' => 1, 'storage_gb' => 5, 'features' => []],
|
|
'starter' => ['sites' => 10, 'servers' => 1, 'team' => 3, 'storage_gb' => 50, 'features' => ['staging', 'daily_backups']],
|
|
'pro' => ['sites' => 100, 'servers' => 5, 'team' => 10, 'storage_gb' => 500, 'features' => ['staging', 'hourly_backups', 'audit', 'monitoring', 'email_relay']],
|
|
'agency' => ['sites' => 1000, 'servers' => 999, 'team' => 25, 'storage_gb' => 5000, 'features' => ['staging', 'hourly_backups', 'audit', 'monitoring', 'email_relay', 'multi_workspace', 'white_label', 'reports', 'sso']],
|
|
'enterprise' => ['sites' => 99999,'servers' => 9999,'team' => 9999,'storage_gb' => 50000, 'features' => ['*']],
|
|
];
|
|
|
|
public function owner(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'owner_user_id');
|
|
}
|
|
|
|
public function sites(): HasMany { return $this->hasMany(Site::class); }
|
|
public function servers(): HasMany { return $this->hasMany(Server::class); }
|
|
public function clusters(): HasMany { return $this->hasMany(Cluster::class); }
|
|
public function backups(): HasMany { return $this->hasMany(Backup::class); }
|
|
public function members(): HasMany { return $this->hasMany(TeamMember::class); }
|
|
public function invitations(): HasMany { return $this->hasMany(Invitation::class); }
|
|
public function activities(): HasMany { return $this->hasMany(Activity::class); }
|
|
|
|
public function getQuotasAttribute(): array
|
|
{
|
|
$base = self::PLAN_QUOTAS[$this->plan] ?? self::PLAN_QUOTAS['free'];
|
|
return array_merge($base, $this->quotas_override ?? []);
|
|
}
|
|
|
|
public function hasFeature(string $feature): bool
|
|
{
|
|
$features = $this->quotas['features'] ?? [];
|
|
return in_array('*', $features, true) || in_array($feature, $features, true);
|
|
}
|
|
|
|
public function isOverQuota(string $resource): bool
|
|
{
|
|
$count = match ($resource) {
|
|
'sites' => $this->sites()->count(),
|
|
'servers' => $this->servers()->count(),
|
|
'team' => $this->members()->count(),
|
|
default => 0,
|
|
};
|
|
return $count >= ($this->quotas[$resource] ?? 0);
|
|
}
|
|
|
|
public function isOnTrial(): bool
|
|
{
|
|
return $this->trial_ends_at && $this->trial_ends_at->isFuture();
|
|
}
|
|
}
|