Files
sam-manage/app/Models/Admin/AdminApiFlowRun.php
김보곤 e272f16357 feat: [database] codebridge DB connection 적용 (merge 후 재적용)
- 78개 MNG 전용 모델에 $connection = 'codebridge' 재적용
- config/database.php codebridge connection 포함
2026-03-07 11:28:47 +09:00

206 lines
5.0 KiB
PHP

<?php
namespace App\Models\Admin;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* API Flow Tester - 실행 이력 모델
*
* @property int $id
* @property int $flow_id
* @property string $status
* @property \Carbon\Carbon|null $started_at
* @property \Carbon\Carbon|null $completed_at
* @property int|null $duration_ms
* @property int|null $total_steps
* @property int $completed_steps
* @property int|null $failed_step
* @property array|null $execution_log
* @property array|null $input_variables
* @property string|null $error_message
* @property int|null $executed_by
* @property \Carbon\Carbon $created_at
*/
class AdminApiFlowRun extends Model
{
// 상태 상수
public const STATUS_PENDING = 'PENDING';
public const STATUS_RUNNING = 'RUNNING';
public const STATUS_SUCCESS = 'SUCCESS';
public const STATUS_FAILED = 'FAILED';
public const STATUS_PARTIAL = 'PARTIAL';
protected $table = 'admin_api_flow_runs';
public $timestamps = false; // created_at만 사용
protected $fillable = [
'flow_id',
'status',
'started_at',
'completed_at',
'duration_ms',
'total_steps',
'completed_steps',
'failed_step',
'execution_log',
'input_variables',
'error_message',
'api_logs',
'executed_by',
];
protected $casts = [
'flow_id' => 'integer',
'created_at' => 'datetime',
'started_at' => 'datetime',
'completed_at' => 'datetime',
'duration_ms' => 'integer',
'total_steps' => 'integer',
'completed_steps' => 'integer',
'failed_step' => 'integer',
'execution_log' => 'array',
'input_variables' => 'array',
'api_logs' => 'array',
'executed_by' => 'integer',
];
/**
* 상태별 필터링
*/
public function scopeStatus($query, string $status)
{
return $query->where('status', $status);
}
/**
* 성공한 실행만 조회
*/
public function scopeSuccessful($query)
{
return $query->where('status', self::STATUS_SUCCESS);
}
/**
* 실패한 실행만 조회
*/
public function scopeFailed($query)
{
return $query->where('status', self::STATUS_FAILED);
}
/**
* 관계: 플로우
*/
public function flow(): BelongsTo
{
return $this->belongsTo(AdminApiFlow::class, 'flow_id');
}
/**
* 관계: 실행자
*/
public function executor(): BelongsTo
{
return $this->belongsTo(User::class, 'executed_by');
}
/**
* 실행 중인지 확인
*/
public function isRunning(): bool
{
return $this->status === self::STATUS_RUNNING;
}
/**
* 완료되었는지 확인 (성공/실패/부분 포함)
*/
public function isCompleted(): bool
{
return in_array($this->status, [
self::STATUS_SUCCESS,
self::STATUS_FAILED,
self::STATUS_PARTIAL,
]);
}
/**
* 진행률 반환 (0-100)
*/
public function getProgressAttribute(): int
{
if (! $this->total_steps || $this->total_steps === 0) {
return 0;
}
return (int) round(($this->completed_steps / $this->total_steps) * 100);
}
/**
* 상태 라벨 반환 (한글)
*/
public function getStatusLabelAttribute(): string
{
return match ($this->status) {
self::STATUS_PENDING => '대기 중',
self::STATUS_RUNNING => '실행 중',
self::STATUS_SUCCESS => '성공',
self::STATUS_FAILED => '실패',
self::STATUS_PARTIAL => '부분 성공',
default => $this->status,
};
}
/**
* 상태 색상 반환 (Tailwind CSS class)
*/
public function getStatusColorAttribute(): string
{
return match ($this->status) {
self::STATUS_PENDING => 'bg-gray-100 text-gray-600',
self::STATUS_RUNNING => 'bg-blue-100 text-blue-700',
self::STATUS_SUCCESS => 'bg-green-100 text-green-700',
self::STATUS_FAILED => 'bg-red-100 text-red-700',
self::STATUS_PARTIAL => 'bg-yellow-100 text-yellow-700',
default => 'bg-gray-100 text-gray-600',
};
}
/**
* API 로그 개수 반환
*/
public function getApiLogCountAttribute(): int
{
return is_array($this->api_logs) ? count($this->api_logs) : 0;
}
/**
* API 로그에 오류가 있는지 확인
*/
public function hasApiErrors(): bool
{
if (! is_array($this->api_logs)) {
return false;
}
foreach ($this->api_logs as $log) {
if (isset($log['type']) && $log['type'] === 'response') {
$status = $log['status'] ?? 0;
if ($status >= 400) {
return true;
}
}
}
return false;
}
}