- 모델: AdminApiFlow, AdminApiFlowRun - 컨트롤러: FlowTesterController - 뷰: index, create, edit, history, run-detail - 사이드바 메뉴에 "개발 도구" 그룹 추가 - 라우트 설정
174 lines
4.2 KiB
PHP
174 lines
4.2 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',
|
|
'executed_by',
|
|
];
|
|
|
|
protected $casts = [
|
|
'flow_id' => 'integer',
|
|
'started_at' => 'datetime',
|
|
'completed_at' => 'datetime',
|
|
'duration_ms' => 'integer',
|
|
'total_steps' => 'integer',
|
|
'completed_steps' => 'integer',
|
|
'failed_step' => 'integer',
|
|
'execution_log' => 'array',
|
|
'input_variables' => '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 => 'badge-ghost',
|
|
self::STATUS_RUNNING => 'badge-info',
|
|
self::STATUS_SUCCESS => 'badge-success',
|
|
self::STATUS_FAILED => 'badge-error',
|
|
self::STATUS_PARTIAL => 'badge-warning',
|
|
default => 'badge-ghost',
|
|
};
|
|
}
|
|
}
|