diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/job/BlogContentJobConfig.java b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/job/BlogContentJobConfig.java similarity index 90% rename from apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/job/BlogContentJobConfig.java rename to apps/user-service/src/main/java/com/gltkorea/icebang/batch/job/BlogContentJobConfig.java index 6646c9dc..61626411 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/job/BlogContentJobConfig.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/job/BlogContentJobConfig.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.domain.batch.job; +package com.gltkorea.icebang.batch.job; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; @@ -9,8 +9,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.transaction.PlatformTransactionManager; -import com.gltkorea.icebang.domain.batch.tasklet.ContentGenerationTasklet; -import com.gltkorea.icebang.domain.batch.tasklet.KeywordExtractionTasklet; +import com.gltkorea.icebang.batch.tasklet.ContentGenerationTasklet; +import com.gltkorea.icebang.batch.tasklet.KeywordExtractionTasklet; import lombok.RequiredArgsConstructor; diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/ContentGenerationTasklet.java b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/ContentGenerationTasklet.java similarity index 97% rename from apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/ContentGenerationTasklet.java rename to apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/ContentGenerationTasklet.java index c445cc21..5cc8918a 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/ContentGenerationTasklet.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/ContentGenerationTasklet.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.domain.batch.tasklet; +package com.gltkorea.icebang.batch.tasklet; import java.util.List; diff --git a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/KeywordExtractionTasklet.java b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/KeywordExtractionTasklet.java similarity index 97% rename from apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/KeywordExtractionTasklet.java rename to apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/KeywordExtractionTasklet.java index 4dc544b9..520403b3 100644 --- a/apps/user-service/src/main/java/com/gltkorea/icebang/domain/batch/tasklet/KeywordExtractionTasklet.java +++ b/apps/user-service/src/main/java/com/gltkorea/icebang/batch/tasklet/KeywordExtractionTasklet.java @@ -1,4 +1,4 @@ -package com.gltkorea.icebang.domain.batch.tasklet; +package com.gltkorea.icebang.batch.tasklet; import java.util.List; diff --git a/apps/user-service/src/main/resources/application-test-e2e.yml b/apps/user-service/src/main/resources/application-test-e2e.yml index e41568fb..7703f4a3 100644 --- a/apps/user-service/src/main/resources/application-test-e2e.yml +++ b/apps/user-service/src/main/resources/application-test-e2e.yml @@ -3,6 +3,12 @@ spring: activate: on-profile: test-e2e + sql: + init: + mode: always + schema-locations: classpath:sql/schema.sql + encoding: UTF-8 + mybatis: mapper-locations: classpath:mybatis/mapper/**/*.xml type-aliases-package: com.gltkorea.icebang.dto diff --git a/apps/user-service/src/main/resources/application-test-unit.yml b/apps/user-service/src/main/resources/application-test-unit.yml index df3f9cba..fec65f43 100644 --- a/apps/user-service/src/main/resources/application-test-unit.yml +++ b/apps/user-service/src/main/resources/application-test-unit.yml @@ -36,7 +36,9 @@ spring: # SQL 스크립트 초기화 설정 sql: init: - mode: embedded + mode: always + schema-locations: classpath:sql/schema.sql + encoding: UTF-8 mybatis: mapper-locations: classpath:mybatis/mapper/**/*.xml diff --git a/apps/user-service/src/main/resources/mybatis/mapper/ScheduleMapper.xml b/apps/user-service/src/main/resources/mybatis/mapper/ScheduleMapper.xml index f85de8b5..4a40fe49 100644 --- a/apps/user-service/src/main/resources/mybatis/mapper/ScheduleMapper.xml +++ b/apps/user-service/src/main/resources/mybatis/mapper/ScheduleMapper.xml @@ -4,12 +4,12 @@ diff --git a/apps/user-service/src/main/resources/sql/schema.sql b/apps/user-service/src/main/resources/sql/schema.sql index e36805fc..e2a9a917 100644 --- a/apps/user-service/src/main/resources/sql/schema.sql +++ b/apps/user-service/src/main/resources/sql/schema.sql @@ -110,4 +110,147 @@ CREATE INDEX IF NOT EXISTS CREATE INDEX IF NOT EXISTS `idx_permissions_resource` ON `permissions` (`resource`); CREATE INDEX IF NOT EXISTS - `idx_permissions_active` ON `permissions` (`is_active`); \ No newline at end of file + `idx_permissions_active` ON `permissions` (`is_active`); + + + +CREATE TABLE IF NOT EXISTS `workflows` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL UNIQUE, + `description` text NULL, + `is_enabled` boolean DEFAULT TRUE, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint unsigned NULL, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated_by` bigint unsigned NULL, + PRIMARY KEY (`id`) + ); + +CREATE TABLE IF NOT EXISTS `schedules` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `workflow_id` bigint unsigned NOT NULL, + `cron_expression` varchar(50) NULL, + `parameters` json NULL, + `is_active` boolean DEFAULT TRUE, + `last_run_status` varchar(20) NULL, + `last_run_at` timestamp NULL, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint unsigned NULL, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated_by` bigint unsigned NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_schedules_to_workflows` FOREIGN KEY (`workflow_id`) REFERENCES `workflows` (`id`) + ); + +CREATE TABLE IF NOT EXISTS `jobs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL UNIQUE, + `description` text NULL, + `is_enabled` boolean DEFAULT TRUE, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint unsigned NULL, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `updated_by` bigint unsigned NULL, + PRIMARY KEY (`id`) + ); + +CREATE TABLE IF NOT EXISTS `tasks` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL UNIQUE, + `type` varchar(50) NULL, + `parameters` json NULL, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) + ); + +CREATE TABLE IF NOT EXISTS `workflow_jobs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `workflow_id` bigint unsigned NOT NULL, + `job_id` bigint unsigned NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_workflow_jobs_to_workflows` FOREIGN KEY (`workflow_id`) REFERENCES `workflows` (`id`), + CONSTRAINT `fk_workflow_jobs_to_jobs` FOREIGN KEY (`job_id`) REFERENCES `jobs` (`id`), + UNIQUE KEY `uk_workflow_job` (`workflow_id`, `job_id`) + ); + +CREATE TABLE IF NOT EXISTS `job_tasks` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `job_id` bigint unsigned NOT NULL, + `task_id` bigint unsigned NOT NULL, + `execution_order` int NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_job_tasks_to_jobs` FOREIGN KEY (`job_id`) REFERENCES `jobs` (`id`), + CONSTRAINT `fk_job_tasks_to_tasks` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`), + UNIQUE KEY `uk_job_task` (`job_id`, `task_id`) + ); + +CREATE TABLE IF NOT EXISTS `execution_logs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `execution_type` varchar(20) NULL COMMENT 'task, schedule, job, workflow', + `source_id` bigint unsigned NULL COMMENT '모든 데이터에 대한 ID ex: job_id, schedule_id, task_id, ...', + `log_level` varchar(20) NULL, + `executed_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `log_message` text NULL, + `trace_id` char(36) NULL, + `config_snapshot` json NULL, + PRIMARY KEY (`id`), + INDEX `idx_source_id_type` (`source_id`, `execution_type`) + ); + +CREATE TABLE IF NOT EXISTS `task_io_data` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `trace_id` char(36) NULL, + `io_type` varchar(10) NULL COMMENT 'INPUT, OUTPUT', + `name` varchar(100) NULL, + `data_type` varchar(50) NULL, + `data_value` json NULL, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + INDEX `idx_trace_id` (`trace_id`) + ); + +CREATE TABLE IF NOT EXISTS `configs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `target_type` varchar(50) NULL COMMENT 'user, job, workflow', + `target_id` bigint unsigned NULL, + `version` int NULL, + `json` json NULL, + `is_active` boolean DEFAULT TRUE, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `created_by` bigint unsigned NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_config_target` (`target_type`, `target_id`) + ); + +CREATE TABLE IF NOT EXISTS `categories` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(100) NULL, + `description` text NULL, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) + ); + +CREATE TABLE IF NOT EXISTS `user_configs` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint unsigned NOT NULL, + `type` varchar(50) NULL, + `name` varchar(100) NULL, + `json` json NULL, + `is_active` boolean DEFAULT TRUE, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) + ); + +-- 인덱스 추가 (성능 최적화) +CREATE INDEX IF NOT EXISTS `idx_schedules_workflow` ON `schedules` (`workflow_id`); +CREATE INDEX IF NOT EXISTS `idx_jobs_enabled` ON `jobs` (`is_enabled`); +CREATE INDEX IF NOT EXISTS `idx_tasks_type` ON `tasks` (`type`); +CREATE INDEX IF NOT EXISTS `idx_workflows_enabled` ON `workflows` (`is_enabled`); +CREATE UNIQUE INDEX IF NOT EXISTS `uk_schedules_workflow` ON `schedules` (`workflow_id`); +CREATE UNIQUE INDEX IF NOT EXISTS `uk_job_name` ON `jobs` (`name`); +CREATE UNIQUE INDEX IF NOT EXISTS `uk_task_name` ON `tasks` (`name`); +CREATE UNIQUE INDEX IF NOT EXISTS `uk_workflows_name` ON `workflows` (`name`); +CREATE INDEX IF NOT EXISTS `idx_user_configs_user` ON `user_configs` (`user_id`); \ No newline at end of file diff --git a/apps/user-service/src/test/java/com/gltkorea/icebang/support/E2eTestSupportTest.java b/apps/user-service/src/test/java/com/gltkorea/icebang/support/E2eTestSupportTest.java index 7fd2deff..bad5a2ba 100644 --- a/apps/user-service/src/test/java/com/gltkorea/icebang/support/E2eTestSupportTest.java +++ b/apps/user-service/src/test/java/com/gltkorea/icebang/support/E2eTestSupportTest.java @@ -3,9 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; -import org.springframework.test.context.jdbc.Sql; -@Sql(scripts = "classpath:sql/schema.sql") class E2eTestSupportTest extends E2eTestSupport { @Test diff --git a/docker/local/docker-compose.yml b/docker/local/docker-compose.yml index b02dd2eb..67f7ecbf 100644 --- a/docker/local/docker-compose.yml +++ b/docker/local/docker-compose.yml @@ -33,18 +33,18 @@ services: depends_on: - mariadb - pre-processing-service: - build: - context: ../../apps/pre-processing-service # 프로젝트 루트 (Dockerfile이 루트에 없으면 맞게 조정) - dockerfile: Dockerfile # Dockerfile 경로 (루트에 없다면 상대경로로 수정) - image: pre-processing-service:latest - container_name: pre-processing-service - restart: always - ports: - - "8000:8000" - env_file: - - ../../apps/pre-processing-service/.env # 공통 - - ../../apps/pre-processing-service/dev.env # 개발 +# pre-processing-service: +# build: +# context: ../../apps/pre-processing-service # 프로젝트 루트 (Dockerfile이 루트에 없으면 맞게 조정) +# dockerfile: Dockerfile # Dockerfile 경로 (루트에 없다면 상대경로로 수정) +# image: pre-processing-service:latest +# container_name: pre-processing-service +# restart: always +# ports: +# - "8000:8000" +# env_file: +# - ../../apps/pre-processing-service/.env # 공통 +# - ../../apps/pre-processing-service/dev.env # 개발 volumes: mariadb_data: \ No newline at end of file