132 lines
3.6 KiB
PHP
132 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Support\Concerns\DerivesWorkspaceIdFromTenant;
|
|
use App\Support\Concerns\InteractsWithODataTypes;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class Policy extends Model
|
|
{
|
|
use DerivesWorkspaceIdFromTenant;
|
|
use HasFactory;
|
|
use InteractsWithODataTypes;
|
|
|
|
public const VISIBILITY_ACTIVE = 'active';
|
|
|
|
public const VISIBILITY_IGNORED_LOCALLY = 'ignored_locally';
|
|
|
|
public const VISIBILITY_PROVIDER_MISSING = 'provider_missing';
|
|
|
|
public const VISIBILITY_IGNORED_LOCALLY_PROVIDER_MISSING = 'ignored_locally_provider_missing';
|
|
|
|
protected $guarded = [];
|
|
|
|
protected $casts = [
|
|
'metadata' => 'array',
|
|
'last_synced_at' => 'datetime',
|
|
'ignored_at' => 'datetime',
|
|
'missing_from_provider_at' => 'datetime',
|
|
];
|
|
|
|
public function tenant(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Tenant::class);
|
|
}
|
|
|
|
public function versions(): HasMany
|
|
{
|
|
return $this->hasMany(PolicyVersion::class);
|
|
}
|
|
|
|
public function backupItems(): HasMany
|
|
{
|
|
return $this->hasMany(BackupItem::class);
|
|
}
|
|
|
|
public function scopeActive(Builder $query): Builder
|
|
{
|
|
return $query
|
|
->whereNull('ignored_at')
|
|
->whereNull('missing_from_provider_at');
|
|
}
|
|
|
|
public function scopeIgnored(Builder $query): Builder
|
|
{
|
|
return $query->whereNotNull('ignored_at');
|
|
}
|
|
|
|
public function scopeProviderMissing(Builder $query): Builder
|
|
{
|
|
return $query->whereNotNull('missing_from_provider_at');
|
|
}
|
|
|
|
public function scopeCurrentBackupEligible(Builder $query): Builder
|
|
{
|
|
return $query
|
|
->whereNull('ignored_at')
|
|
->whereNull('missing_from_provider_at');
|
|
}
|
|
|
|
public function isIgnoredLocally(): bool
|
|
{
|
|
return $this->ignored_at !== null;
|
|
}
|
|
|
|
public function isProviderMissing(): bool
|
|
{
|
|
return $this->missing_from_provider_at !== null;
|
|
}
|
|
|
|
public function visibilityState(): string
|
|
{
|
|
return match (true) {
|
|
$this->isIgnoredLocally() && $this->isProviderMissing() => self::VISIBILITY_IGNORED_LOCALLY_PROVIDER_MISSING,
|
|
$this->isIgnoredLocally() => self::VISIBILITY_IGNORED_LOCALLY,
|
|
$this->isProviderMissing() => self::VISIBILITY_PROVIDER_MISSING,
|
|
default => self::VISIBILITY_ACTIVE,
|
|
};
|
|
}
|
|
|
|
public function isCurrentBackupEligible(): bool
|
|
{
|
|
return ! $this->isIgnoredLocally() && ! $this->isProviderMissing();
|
|
}
|
|
|
|
public function currentBackupBlockedReason(): ?string
|
|
{
|
|
if ($this->isProviderMissing()) {
|
|
return self::VISIBILITY_PROVIDER_MISSING;
|
|
}
|
|
|
|
if ($this->isIgnoredLocally()) {
|
|
return self::VISIBILITY_IGNORED_LOCALLY;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function currentBackupBlockedReasonLabel(): ?string
|
|
{
|
|
return match ($this->currentBackupBlockedReason()) {
|
|
self::VISIBILITY_PROVIDER_MISSING => 'Provider missing - current provider-backed capture is unavailable.',
|
|
self::VISIBILITY_IGNORED_LOCALLY => 'Ignored locally - restore local visibility before fresh capture.',
|
|
default => null,
|
|
};
|
|
}
|
|
|
|
public function ignore(): void
|
|
{
|
|
$this->update(['ignored_at' => now()]);
|
|
}
|
|
|
|
public function unignore(): void
|
|
{
|
|
$this->update(['ignored_at' => null]);
|
|
}
|
|
}
|