clupilot/app/app/Models/Workspace.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();
}
}