From b70d79a8d54e0611234499b62cc482dff87c5c6e Mon Sep 17 00:00:00 2001 From: hskwon Date: Thu, 27 Nov 2025 18:49:09 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20API=20Flow=20Tester=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - admin_api_flows: 플로우 정의 저장 테이블 - admin_api_flow_runs: 실행 이력 및 로그 테이블 --- ...27_100000_create_admin_api_flow_tables.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 database/migrations/2025_11_27_100000_create_admin_api_flow_tables.php diff --git a/database/migrations/2025_11_27_100000_create_admin_api_flow_tables.php b/database/migrations/2025_11_27_100000_create_admin_api_flow_tables.php new file mode 100644 index 0000000..d9f347d --- /dev/null +++ b/database/migrations/2025_11_27_100000_create_admin_api_flow_tables.php @@ -0,0 +1,70 @@ +id()->comment('ID'); + $table->string('name', 100)->comment('플로우 이름'); + $table->text('description')->nullable()->comment('설명'); + $table->string('category', 50)->nullable()->comment('카테고리'); + $table->json('flow_definition')->comment('플로우 정의 (JSON)'); + $table->boolean('is_active')->default(true)->comment('활성화 여부'); + $table->foreignId('created_by')->nullable()->comment('생성자 ID'); + $table->foreignId('updated_by')->nullable()->comment('수정자 ID'); + $table->timestamps(); + + // 인덱스 + $table->index('category', 'idx_admin_api_flows_category'); + $table->index('is_active', 'idx_admin_api_flows_is_active'); + $table->index('name', 'idx_admin_api_flows_name'); + }); + + // admin_api_flow_runs: 실행 이력 테이블 + Schema::create('admin_api_flow_runs', function (Blueprint $table) { + $table->id()->comment('ID'); + $table->foreignId('flow_id')->comment('플로우 ID') + ->constrained('admin_api_flows') + ->onDelete('cascade'); + $table->string('status', 20)->default('PENDING')->comment('상태: PENDING, RUNNING, SUCCESS, FAILED, PARTIAL'); + $table->timestamp('started_at')->nullable()->comment('시작 시간'); + $table->timestamp('completed_at')->nullable()->comment('완료 시간'); + $table->unsignedInteger('duration_ms')->nullable()->comment('실행 시간 (ms)'); + $table->unsignedSmallInteger('total_steps')->nullable()->comment('총 단계 수'); + $table->unsignedSmallInteger('completed_steps')->default(0)->comment('완료된 단계 수'); + $table->unsignedSmallInteger('failed_step')->nullable()->comment('실패한 단계'); + $table->json('execution_log')->nullable()->comment('실행 로그 (단계별 결과)'); + $table->json('input_variables')->nullable()->comment('입력 변수'); + $table->text('error_message')->nullable()->comment('에러 메시지'); + $table->foreignId('executed_by')->nullable()->comment('실행자 ID'); + $table->timestamp('created_at')->useCurrent()->comment('생성 시간'); + + // 인덱스 + $table->index('flow_id', 'idx_admin_api_flow_runs_flow_id'); + $table->index('status', 'idx_admin_api_flow_runs_status'); + $table->index('created_at', 'idx_admin_api_flow_runs_created_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('admin_api_flow_runs'); + Schema::dropIfExists('admin_api_flows'); + } +};