Files
ismysiteup.online/app/Models/HealthCheck.php
T
2026-01-17 16:42:43 +02:00

144 lines
3.1 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class HealthCheck extends Model
{
protected $fillable = [
'site_id',
'endpoint',
'expected_json_keys',
'last_checked_at',
'is_healthy',
'response_data',
'response_time_ms',
'performance_threshold',
'status_code',
'is_active',
];
protected $casts = [
'expected_json_keys' => 'array',
'response_data' => 'array',
'last_checked_at' => 'datetime',
'is_healthy' => 'boolean',
'is_active' => 'boolean',
];
/**
* Get the site that owns the health check.
*/
public function site(): BelongsTo
{
return $this->belongsTo(Site::class);
}
/**
* Scope to filter active health checks.
*/
public function scopeActive($query)
{
return $query->where('is_active', true);
}
/**
* Scope to filter healthy checks.
*/
public function scopeHealthy($query)
{
return $query->where('is_healthy', true);
}
/**
* Scope to filter unhealthy checks.
*/
public function scopeUnhealthy($query)
{
return $query->where('is_healthy', false);
}
/**
* Get the full URL for the health check endpoint.
*/
public function getFullUrlAttribute(): string
{
$siteUrl = rtrim($this->site->url, '/');
$endpoint = ltrim($this->endpoint, '/');
return $siteUrl . '/' . $endpoint;
}
/**
* Get status badge color.
*/
public function getStatusColorAttribute(): string
{
if ($this->is_healthy === null) {
return 'secondary';
}
return $this->is_healthy ? 'success' : 'danger';
}
/**
* Get status text.
*/
public function getStatusTextAttribute(): string
{
if ($this->is_healthy === null) {
return 'Unknown';
}
return $this->is_healthy ? 'Healthy' : 'Unhealthy';
}
/**
* Get display name for the endpoint.
*/
public function getDisplayNameAttribute(): string
{
return $this->endpoint ?: 'Health Check';
}
/**
* Validate if response contains all expected keys.
*/
public function validateResponseKeys(array $responseData): bool
{
if (empty($this->expected_json_keys)) {
return true;
}
foreach ($this->expected_json_keys as $key) {
if (!$this->hasNestedKey($responseData, $key)) {
return false;
}
}
return true;
}
/**
* Check if nested key exists in array using dot notation.
*/
protected function hasNestedKey(array $array, string $key): bool
{
if (array_key_exists($key, $array)) {
return true;
}
foreach (explode('.', $key) as $segment) {
if (!is_array($array) || !array_key_exists($segment, $array)) {
return false;
}
$array = $array[$segment];
}
return true;
}
}