diff --git a/build.gradle b/build.gradle
index 864f84b5..836600a8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,6 +30,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
+ // flyway
+ implementation 'org.springframework.boot:spring-boot-starter-flyway'
+ implementation 'org.flywaydb:flyway-mysql'
+
// S3
implementation platform('io.awspring.cloud:spring-cloud-aws-dependencies:4.0.2')
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'
@@ -65,10 +69,11 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// test
- testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
testImplementation 'org.springframework.security:spring-security-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
- testImplementation 'com.h2database:h2'
+ testImplementation 'org.springframework.boot:spring-boot-testcontainers'
+ testImplementation 'org.testcontainers:testcontainers-mysql'
}
// CheckStyle
diff --git a/src/main/java/ditda/backend/domain/commission/category/textbook/entity/TextbookPage.java b/src/main/java/ditda/backend/domain/commission/category/textbook/entity/TextbookPage.java
index fd396110..f4d65ba5 100644
--- a/src/main/java/ditda/backend/domain/commission/category/textbook/entity/TextbookPage.java
+++ b/src/main/java/ditda/backend/domain/commission/category/textbook/entity/TextbookPage.java
@@ -26,7 +26,7 @@
name = "textbook_pages",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_commission_required_page_type",
+ name = "uk_textbook_pages_commission_id_page_type",
columnNames = {"commission_id", "page_type"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/core/entity/CommissionColor.java b/src/main/java/ditda/backend/domain/commission/core/entity/CommissionColor.java
index 7623c298..b1c1ab9f 100644
--- a/src/main/java/ditda/backend/domain/commission/core/entity/CommissionColor.java
+++ b/src/main/java/ditda/backend/domain/commission/core/entity/CommissionColor.java
@@ -25,7 +25,7 @@
name = "commission_colors",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_commission_color_role",
+ name = "uk_commission_colors_commission_id_role",
columnNames = {"commission_id", "role"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/core/entity/CommissionConcept.java b/src/main/java/ditda/backend/domain/commission/core/entity/CommissionConcept.java
index ac7663c4..41df5965 100644
--- a/src/main/java/ditda/backend/domain/commission/core/entity/CommissionConcept.java
+++ b/src/main/java/ditda/backend/domain/commission/core/entity/CommissionConcept.java
@@ -25,7 +25,7 @@
name = "commission_concepts",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_commission_concept",
+ name = "uk_commission_concepts_commission_id_concept",
columnNames = {"commission_id", "concept"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraft.java b/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraft.java
index 33bc7710..90a2594d 100644
--- a/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraft.java
+++ b/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraft.java
@@ -24,7 +24,7 @@
name = "commission_drafts",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_commission_draft_round",
+ name = "uk_commission_drafts_commission_application_id_round",
columnNames = {"commission_application_id", "round"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraftFile.java b/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraftFile.java
index f6ab301b..cf81b670 100644
--- a/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraftFile.java
+++ b/src/main/java/ditda/backend/domain/commission/draft/entity/CommissionDraftFile.java
@@ -26,7 +26,7 @@
name = "commission_draft_files",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_commission_draft_file_order",
+ name = "uk_commission_draft_files_commission_draft_id_file_order",
columnNames = {"commission_draft_id", "file_order"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionRequest.java b/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionRequest.java
index ba928d98..238bc1c2 100644
--- a/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionRequest.java
+++ b/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionRequest.java
@@ -25,7 +25,7 @@
name = "revision_requests",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_revision_request_target_draft",
+ name = "uk_revision_requests_target_draft_id",
columnNames = {"target_draft_id"}
)
}
diff --git a/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionResponse.java b/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionResponse.java
index 7c3678e9..95ce0a35 100644
--- a/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionResponse.java
+++ b/src/main/java/ditda/backend/domain/commission/revision/entity/RevisionResponse.java
@@ -22,7 +22,7 @@
name = "revision_responses",
uniqueConstraints = {
@UniqueConstraint(
- name = "uk_revision_response_produced_draft",
+ name = "uk_revision_responses_produced_draft_id",
columnNames = {"produced_draft_id"}
)
}
diff --git a/src/main/java/ditda/backend/domain/settlement/entity/Settlement.java b/src/main/java/ditda/backend/domain/settlement/entity/Settlement.java
index 6c57a8d1..feb261a3 100644
--- a/src/main/java/ditda/backend/domain/settlement/entity/Settlement.java
+++ b/src/main/java/ditda/backend/domain/settlement/entity/Settlement.java
@@ -28,7 +28,7 @@
@Entity
@Table(name = "settlements",
uniqueConstraints = @UniqueConstraint(
- name = "uk_settlements_designer_commission_type",
+ name = "uk_settlements_designer_id_commission_id_settlement_type",
columnNames = {"designer_id", "commission_id", "settlement_type"}
))
@Getter
diff --git a/src/main/java/ditda/backend/domain/user/entity/User.java b/src/main/java/ditda/backend/domain/user/entity/User.java
index b9303660..087c728d 100644
--- a/src/main/java/ditda/backend/domain/user/entity/User.java
+++ b/src/main/java/ditda/backend/domain/user/entity/User.java
@@ -50,7 +50,7 @@ public class User extends BaseEntity {
private String phone;
@Enumerated(EnumType.STRING)
- @Column(name = "role", nullable = false)
+ @Column(name = "role", nullable = false, length = 20)
private UserRole role;
@Column(name = "email_verified_at")
diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml
index 63b2736a..56e27ec4 100644
--- a/src/main/resources/application-local.yaml
+++ b/src/main/resources/application-local.yaml
@@ -1,7 +1,7 @@
spring:
jpa:
hibernate:
- ddl-auto: update
+ ddl-auto: validate
properties:
hibernate:
format_sql: true
diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml
index 49ed592f..3707eb3d 100644
--- a/src/main/resources/application-prod.yaml
+++ b/src/main/resources/application-prod.yaml
@@ -1,7 +1,7 @@
spring:
jpa:
hibernate:
- ddl-auto: update # TODO: validate로 변경
+ ddl-auto: validate
properties:
hibernate:
format_sql: false
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index 1e32ee5a..cae3fb2b 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -13,6 +13,13 @@ spring:
password: ${DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
+ flyway:
+ enabled: true
+ locations: classpath:db/migration
+ baseline-on-migrate: true
+ baseline-version: 1
+ out-of-order: true
+
data:
redis:
host: ${REDIS_HOST}
diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql
new file mode 100644
index 00000000..46c88059
--- /dev/null
+++ b/src/main/resources/db/migration/V1__init.sql
@@ -0,0 +1,391 @@
+-- =========================================================
+-- V1__init.sql
+-- Ditda 초기 schema
+--
+-- 정책:
+-- - Enum: VARCHAR + @Enumerated(EnumType.STRING) 매핑
+-- - Timestamp: DATETIME(6) 사용
+-- - BaseEntity(@MappedSuperclass): 각 테이블에 인라인으로 전개
+-- - 제약 네이밍 : Hibernate 자동 생성 난수 이름 대신 명시적 이름 사용
+-- (PK 컬럼 기본, uk_
_ / idx__ / fk__)
+-- =========================================================
+
+
+-- =========================================================
+-- ADMIN
+-- =========================================================
+
+CREATE TABLE admins
+(
+ admin_id BIGINT NOT NULL AUTO_INCREMENT,
+ username VARCHAR(20) NOT NULL,
+ password VARCHAR(255) NOT NULL,
+ name VARCHAR(50) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (admin_id),
+ UNIQUE KEY uk_admins_username (username)
+);
+
+-- =========================================================
+-- USER
+-- =========================================================
+
+CREATE TABLE users
+(
+ user_id BIGINT NOT NULL AUTO_INCREMENT,
+ username VARCHAR(20) NOT NULL,
+ password VARCHAR(255) NOT NULL,
+ name VARCHAR(50) NOT NULL,
+ email VARCHAR(100) NOT NULL,
+ profile_image_url VARCHAR(255) NOT NULL,
+ phone VARCHAR(20) NOT NULL,
+ role VARCHAR(20) NOT NULL,
+ email_verified_at DATETIME(6) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (user_id),
+ UNIQUE KEY uk_users_email (email),
+ UNIQUE KEY uk_users_username (username)
+);
+
+CREATE TABLE designers
+(
+ designer_id BIGINT NOT NULL,
+ level VARCHAR(20) NOT NULL,
+ exp INT NOT NULL,
+ bank_name VARCHAR(50) NOT NULL,
+ account_number VARCHAR(255) NOT NULL,
+ account_holder VARCHAR(50) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (designer_id),
+ CONSTRAINT fk_designers_user_id FOREIGN KEY (designer_id) REFERENCES users (user_id)
+);
+
+CREATE TABLE instructors
+(
+ instructor_id BIGINT NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (instructor_id),
+ CONSTRAINT fk_instructors_user_id FOREIGN KEY (instructor_id) REFERENCES users (user_id)
+);
+
+CREATE TABLE portfolios
+(
+ portfolio_id BIGINT NOT NULL AUTO_INCREMENT,
+ designer_id BIGINT NOT NULL,
+ portfolio_url VARCHAR(255) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (portfolio_id),
+ KEY idx_portfolios_designer_id (designer_id),
+ CONSTRAINT fk_portfolios_designer_id FOREIGN KEY (designer_id) REFERENCES designers (designer_id)
+);
+
+-- =========================================================
+-- AUTH
+-- =========================================================
+
+CREATE TABLE refresh_tokens
+(
+ session_id VARCHAR(36) NOT NULL,
+ user_id BIGINT NOT NULL,
+ refresh_token_hash VARCHAR(128) NOT NULL,
+ expires_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (session_id),
+ KEY idx_refresh_tokens_user_id (user_id),
+ CONSTRAINT fk_refresh_tokens_user_id FOREIGN KEY (user_id) REFERENCES users (user_id)
+);
+
+-- =========================================================
+-- COMMISSION
+-- =========================================================
+
+CREATE TABLE commissions
+(
+ commission_id BIGINT NOT NULL AUTO_INCREMENT,
+ instructor_id BIGINT NOT NULL,
+ assigned_designer_id BIGINT DEFAULT NULL,
+ plan_code VARCHAR(10) NOT NULL,
+ title VARCHAR(50) NOT NULL,
+ category_type VARCHAR(50) NOT NULL,
+ size VARCHAR(10) NOT NULL,
+ additional_concept VARCHAR(300) DEFAULT NULL,
+ color_selection_mode VARCHAR(30) NOT NULL,
+ first_draft_deadline DATE NOT NULL,
+ application_deadline DATE NOT NULL,
+ final_deadline DATE NOT NULL,
+ status VARCHAR(30) NOT NULL,
+ max_revision INT NOT NULL,
+ selected_at DATETIME(6) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (commission_id),
+ KEY idx_commissions_assigned_designer_id (assigned_designer_id),
+ KEY idx_commissions_instructor_id (instructor_id),
+ CONSTRAINT fk_commissions_assigned_designer_id FOREIGN KEY (assigned_designer_id) REFERENCES designers (designer_id),
+ CONSTRAINT fk_commissions_instructor_id FOREIGN KEY (instructor_id) REFERENCES instructors (instructor_id)
+);
+
+
+CREATE TABLE commission_colors
+(
+ commission_color_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ color_code VARCHAR(7) NOT NULL,
+ role VARCHAR(10) NOT NULL,
+ PRIMARY KEY (commission_color_id),
+ UNIQUE KEY uk_commission_colors_commission_id_role (commission_id, role),
+ CONSTRAINT fk_commission_colors_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+CREATE TABLE commission_concepts
+(
+ commission_concept_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ concept VARCHAR(30) NOT NULL,
+ PRIMARY KEY (commission_concept_id),
+ UNIQUE KEY uk_commission_concepts_commission_id_concept (commission_id, concept),
+ CONSTRAINT fk_commission_concepts_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+CREATE TABLE commission_files
+(
+ commission_file_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ file_kind VARCHAR(20) NOT NULL,
+ file_url VARCHAR(255) NOT NULL,
+ description VARCHAR(300) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (commission_file_id),
+ KEY idx_commission_files_commission_id (commission_id),
+ CONSTRAINT fk_commission_files_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+
+-- =========================================================
+-- APPLICATION
+-- =========================================================
+
+CREATE TABLE commission_applications
+(
+ commission_application_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ designer_id BIGINT NOT NULL,
+ status VARCHAR(20) NOT NULL,
+ active_key VARCHAR(64) GENERATED ALWAYS AS (
+ CASE
+ WHEN status <> 'CANCELLED'
+ THEN CONCAT(commission_id, '-', designer_id) END
+ ) VIRTUAL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (commission_application_id),
+ UNIQUE KEY uk_commission_applications_active_key (active_key),
+ KEY idx_commission_applications_commission_id (commission_id),
+ KEY idx_commission_applications_designer_id (designer_id),
+ CONSTRAINT fk_commission_applications_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id),
+ CONSTRAINT fk_commission_applications_designer_id FOREIGN KEY (designer_id) REFERENCES designers (designer_id)
+);
+
+-- =========================================================
+-- DRAFT
+-- =========================================================
+
+CREATE TABLE commission_drafts
+(
+ commission_draft_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_application_id BIGINT NOT NULL,
+ round INT NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (commission_draft_id),
+ UNIQUE KEY uk_commission_drafts_commission_application_id_round (commission_application_id, round),
+ CONSTRAINT fk_commission_drafts_commission_application_id FOREIGN KEY (commission_application_id) REFERENCES commission_applications (commission_application_id)
+);
+
+
+CREATE TABLE commission_draft_files
+(
+ commission_draft_file_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_draft_id BIGINT NOT NULL,
+ file_order INT NOT NULL,
+ file_url VARCHAR(255) NOT NULL,
+ watermarked_file_url VARCHAR(255) DEFAULT NULL,
+ watermark_status VARCHAR(20) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (commission_draft_file_id),
+ UNIQUE KEY uk_commission_draft_files_commission_draft_id_file_order (commission_draft_id, file_order),
+ CONSTRAINT fk_commission_draft_files_commission_draft_id FOREIGN KEY (commission_draft_id) REFERENCES commission_drafts (commission_draft_id)
+);
+
+-- =========================================================
+-- REVISION
+-- =========================================================
+
+CREATE TABLE revision_requests
+(
+ revision_request_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ target_draft_id BIGINT NOT NULL,
+ checked BIT(1) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (revision_request_id),
+ UNIQUE KEY uk_revision_requests_target_draft_id (target_draft_id),
+ KEY idx_revision_requests_commission_id (commission_id),
+ CONSTRAINT fk_revision_requests_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id),
+ CONSTRAINT fk_revision_requests_target_draft_id FOREIGN KEY (target_draft_id) REFERENCES commission_drafts (commission_draft_id)
+);
+
+CREATE TABLE revision_responses
+(
+ revision_request_id BIGINT NOT NULL,
+ produced_draft_id BIGINT NOT NULL,
+ designer_comment VARCHAR(300) DEFAULT NULL,
+ checked BIT(1) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (revision_request_id),
+ UNIQUE KEY uk_revision_responses_produced_draft_id (produced_draft_id),
+ CONSTRAINT fk_revision_responses_produced_draft_id FOREIGN KEY (produced_draft_id) REFERENCES commission_drafts (commission_draft_id),
+ CONSTRAINT fk_revision_responses_revision_request_id FOREIGN KEY (revision_request_id) REFERENCES revision_requests (revision_request_id)
+);
+
+CREATE TABLE revision_details
+(
+ revision_detail_id BIGINT NOT NULL AUTO_INCREMENT,
+ revision_request_id BIGINT NOT NULL,
+ category VARCHAR(20) NOT NULL,
+ comment VARCHAR(300) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (revision_detail_id),
+ KEY idx_revision_details_revision_request_id (revision_request_id),
+ CONSTRAINT fk_revision_details_revision_request_id FOREIGN KEY (revision_request_id) REFERENCES revision_requests (revision_request_id)
+);
+
+-- =========================================================
+-- TEXTBOOK
+-- =========================================================
+
+CREATE TABLE textbooks
+(
+ commission_id BIGINT NOT NULL,
+ title VARCHAR(50) NOT NULL,
+ instructor_name VARCHAR(50) NOT NULL,
+ subject VARCHAR(50) NOT NULL,
+ PRIMARY KEY (commission_id),
+ CONSTRAINT fk_textbooks_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+CREATE TABLE textbook_pages
+(
+ textbook_page_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ page_type VARCHAR(30) NOT NULL,
+ page_description VARCHAR(150) DEFAULT NULL,
+ PRIMARY KEY (textbook_page_id),
+ UNIQUE KEY uk_textbook_pages_commission_id_page_type (commission_id, page_type),
+ CONSTRAINT fk_textbook_pages_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+-- =========================================================
+-- PAYMENT
+-- =========================================================
+
+CREATE TABLE payments
+(
+ payment_id BIGINT NOT NULL AUTO_INCREMENT,
+ commission_id BIGINT NOT NULL,
+ amount INT NOT NULL,
+ depositor_name VARCHAR(50) DEFAULT NULL,
+ status VARCHAR(30) NOT NULL,
+ paid_at DATETIME(6) DEFAULT NULL,
+ deposit_notified_at DATETIME(6) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (payment_id),
+ KEY idx_payments_commission_id (commission_id),
+ CONSTRAINT fk_payments_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id)
+);
+
+-- =========================================================
+-- SETTLEMENT
+-- =========================================================
+
+CREATE TABLE settlements
+(
+ settlement_id BIGINT NOT NULL AUTO_INCREMENT,
+ designer_id BIGINT NOT NULL,
+ commission_id BIGINT NOT NULL,
+ settlement_type VARCHAR(20) NOT NULL,
+ amount INT NOT NULL,
+ status VARCHAR(20) NOT NULL,
+ settled_at DATETIME(6) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (settlement_id),
+ UNIQUE KEY uk_settlements_designer_id_commission_id_settlement_type (designer_id, commission_id, settlement_type),
+ KEY idx_settlements_commission_id (commission_id),
+ CONSTRAINT fk_settlements_commission_id FOREIGN KEY (commission_id) REFERENCES commissions (commission_id),
+ CONSTRAINT fk_settlements_designer_id FOREIGN KEY (designer_id) REFERENCES designers (designer_id)
+);
+
+-- =========================================================
+-- OUTBOX
+-- =========================================================
+
+CREATE TABLE notification_outboxes
+(
+ notification_outbox_id BIGINT NOT NULL AUTO_INCREMENT,
+ recipient_email VARCHAR(100) NOT NULL,
+ subject VARCHAR(150) NOT NULL,
+ template_name VARCHAR(100) NOT NULL,
+ template_variables TEXT NOT NULL,
+ status VARCHAR(20) NOT NULL,
+ scheduled_at DATETIME(6) NOT NULL,
+ retry_count INT NOT NULL,
+ error_message TEXT,
+ sent_at DATETIME(6) DEFAULT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (notification_outbox_id),
+ KEY idx_notification_outboxes_status_scheduled_at (status, scheduled_at)
+);
+
+-- =========================================================
+-- TERM
+-- =========================================================
+
+CREATE TABLE user_terms
+(
+ user_term_id BIGINT NOT NULL AUTO_INCREMENT,
+ user_id BIGINT NOT NULL,
+ term_type VARCHAR(50) NOT NULL,
+ version VARCHAR(20) NOT NULL,
+ is_agreed BIT(1) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (user_term_id),
+ KEY idx_user_terms_user_id (user_id),
+ CONSTRAINT fk_user_terms_user_id FOREIGN KEY (user_id) REFERENCES users (user_id)
+);
+
+CREATE TABLE payment_terms
+(
+ payment_term_id BIGINT NOT NULL AUTO_INCREMENT,
+ payment_id BIGINT NOT NULL,
+ term_type VARCHAR(50) NOT NULL,
+ version VARCHAR(20) NOT NULL,
+ is_agreed BIT(1) NOT NULL,
+ created_at DATETIME(6) NOT NULL,
+ updated_at DATETIME(6) NOT NULL,
+ PRIMARY KEY (payment_term_id),
+ KEY idx_payment_terms_payment_id (payment_id),
+ CONSTRAINT fk_payment_terms_payment_id FOREIGN KEY (payment_id) REFERENCES payments (payment_id)
+);
diff --git a/src/test/java/ditda/backend/BackendApplicationTests.java b/src/test/java/ditda/backend/BackendApplicationTests.java
index 0e14068a..acfab744 100644
--- a/src/test/java/ditda/backend/BackendApplicationTests.java
+++ b/src/test/java/ditda/backend/BackendApplicationTests.java
@@ -1,17 +1,10 @@
package ditda.backend;
import org.junit.jupiter.api.Test;
-import org.redisson.api.RedissonClient;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.bean.override.mockito.MockitoBean;
-@SpringBootTest
-@ActiveProfiles("test")
-class BackendApplicationTests {
+import ditda.backend.support.IntegrationTestSupport;
- @MockitoBean
- private RedissonClient redissonClient;
+class BackendApplicationTests extends IntegrationTestSupport {
@Test
void contextLoads() {
diff --git a/src/test/java/ditda/backend/support/IntegrationTestSupport.java b/src/test/java/ditda/backend/support/IntegrationTestSupport.java
new file mode 100644
index 00000000..7e78caa0
--- /dev/null
+++ b/src/test/java/ditda/backend/support/IntegrationTestSupport.java
@@ -0,0 +1,16 @@
+package ditda.backend.support;
+
+import org.redisson.api.RedissonClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+
+@SpringBootTest
+@ActiveProfiles("test")
+@Import(TestcontainersConfiguration.class)
+public abstract class IntegrationTestSupport {
+
+ @MockitoBean
+ protected RedissonClient redissonClient;
+}
diff --git a/src/test/java/ditda/backend/support/TestcontainersConfiguration.java b/src/test/java/ditda/backend/support/TestcontainersConfiguration.java
new file mode 100644
index 00000000..e31cbcc4
--- /dev/null
+++ b/src/test/java/ditda/backend/support/TestcontainersConfiguration.java
@@ -0,0 +1,23 @@
+package ditda.backend.support;
+
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.context.annotation.Bean;
+import org.testcontainers.mysql.MySQLContainer;
+
+@TestConfiguration(proxyBeanMethods = false)
+public class TestcontainersConfiguration {
+
+ @Bean
+ @ServiceConnection
+ MySQLContainer mysqlContainer() {
+ MySQLContainer container = new MySQLContainer("mysql:8.4")
+ .withDatabaseName("ditda");
+
+ container.setCommand(
+ "--character-set-server=utf8mb4",
+ "--collation-server=utf8mb4_unicode_ci"
+ );
+ return container;
+ }
+}
diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml
index a1a37820..2b9cd51d 100644
--- a/src/test/resources/application-test.yaml
+++ b/src/test/resources/application-test.yaml
@@ -1,13 +1,10 @@
spring:
- datasource:
- url: jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1
- username: sa
- password:
- driver-class-name: org.h2.Driver
-
jpa:
hibernate:
- ddl-auto: create-drop
+ ddl-auto: validate
+ properties:
+ hibernate:
+ default_batch_fetch_size: 100
data:
redis: