diff --git a/build.gradle.kts b/build.gradle.kts index 5ce78d0c..a544683b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -90,8 +90,8 @@ project(":entity") { dependencies { api("org.springframework.boot:spring-boot-starter-data-jpa") - api("com.mysql:mysql-connector-j:${properties["mysqlConnectorVersion"]}") - runtimeOnly("com.h2database:h2:${properties["h2DatabaseVersion"]}") // todo : fade out + runtimeOnly("com.mysql:mysql-connector-j:${properties["mysqlConnectorVersion"]}") + // runtimeOnly("com.h2database:h2:${properties["h2DatabaseVersion"]}") // todo : fade out // Jasypt implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:${properties["jasyptSpringBootStarterVersion"]}") @@ -106,6 +106,16 @@ project(":entity") { // query 값 정렬 implementation("com.github.gavlyukovskiy:p6spy-spring-boot-starter:${properties["p6spyVersion"]}") } + + allOpen { + annotation("jakarta.persistence.Entity") + annotation("jakarta.persistence.Embeddable") + annotation("jakarta.persistence.MappedSuperclass") + } + + noArg { + annotation("jakarta.persistence.Entity") + } } project(":common") { diff --git a/entity/src/main/kotlin/com/mashup/dojo/ImageRepository.kt b/entity/src/main/kotlin/com/mashup/dojo/ImageRepository.kt index 55f4869b..68fc1d36 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/ImageRepository.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/ImageRepository.kt @@ -3,12 +3,14 @@ package com.mashup.dojo import com.mashup.dojo.base.BaseEntity import jakarta.persistence.Entity import jakarta.persistence.Id +import jakarta.persistence.Table import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository @Repository interface ImageRepository : JpaRepository +@Table(name = "image") @Entity class ImageEntity( @Id diff --git a/entity/src/main/kotlin/com/mashup/dojo/MemberEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/MemberEntity.kt new file mode 100644 index 00000000..a483348c --- /dev/null +++ b/entity/src/main/kotlin/com/mashup/dojo/MemberEntity.kt @@ -0,0 +1,86 @@ +package com.mashup.dojo + +import com.mashup.dojo.base.BaseTimeEntity +import jakarta.persistence.CascadeType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.Id +import jakarta.persistence.OneToMany +import jakarta.persistence.Table + +private const val DEFAULT_POINT = 200 + +@Entity +@Table(name = "member") +class MemberEntity( + @Id + val id: String, + @Column(name = "full_name", nullable = false) + val fullName: String, + @Column(name = "second_initial_name", nullable = false) + val secondInitialName: String, + val profileImageId: String?, + @Column(name = "platform", nullable = false) + @Enumerated(EnumType.STRING) + val platform: Platform, + val ordinal: Int, + @Column(name = "gender", nullable = false) + @Enumerated(EnumType.STRING) + val gender: Gender, + point: Int = DEFAULT_POINT, + @OneToMany(mappedBy = "picker", cascade = [CascadeType.ALL], orphanRemoval = true) + val pickers: MutableList = mutableListOf(), + @OneToMany(mappedBy = "picked", cascade = [CascadeType.ALL], orphanRemoval = true) + val picked: MutableList = mutableListOf(), + @OneToMany(mappedBy = "from", cascade = [CascadeType.ALL], orphanRemoval = true) + val fromRelations: MutableList = mutableListOf(), + @OneToMany(mappedBy = "to", cascade = [CascadeType.ALL], orphanRemoval = true) + val toRelations: MutableList = mutableListOf(), + + ) : BaseTimeEntity() { + @Column(name = "point", nullable = false) + var point: Int = point + protected set + + fun updatePoint(newPoint: Int) { + this.point = newPoint + } + + companion object { + fun createMemberEntity( + id: String, + fullName: String, + secondInitialName: String, + profileImageId: String?, + platform: Platform, + gender: Gender, + ordinal: Int, + ): MemberEntity { + return MemberEntity( + id = id, + fullName = fullName, + secondInitialName = secondInitialName, + profileImageId = profileImageId, + platform = platform, + ordinal = ordinal, + gender = gender, + DEFAULT_POINT + ) + } + } +} + +enum class Platform { + PRODUCT_DESIGN, + WEB, + IOS, + ANDROID, + SPRING, +} + +enum class Gender { + MALE, + FEMALE, +} diff --git a/entity/src/main/kotlin/com/mashup/dojo/MemberRelationEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/MemberRelationEntity.kt new file mode 100644 index 00000000..7de96a96 --- /dev/null +++ b/entity/src/main/kotlin/com/mashup/dojo/MemberRelationEntity.kt @@ -0,0 +1,25 @@ +package com.mashup.dojo + +import com.mashup.dojo.base.BaseTimeEntity +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.Id +import jakarta.persistence.ManyToOne + +@Entity +class MemberRelationEntity( + @Id + val id: String, + @ManyToOne + val from: MemberEntity, + @ManyToOne + val to: MemberEntity, + @Enumerated(EnumType.STRING) + val relationType: RelationType, +) : BaseTimeEntity() + +enum class RelationType { + FRIEND, + ACCOMPANY, +} diff --git a/entity/src/main/kotlin/com/mashup/dojo/MemberRepository.kt b/entity/src/main/kotlin/com/mashup/dojo/MemberRepository.kt index 4be4c775..9e77bee0 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/MemberRepository.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/MemberRepository.kt @@ -1,21 +1,5 @@ package com.mashup.dojo -import com.mashup.dojo.base.BaseEntity -import jakarta.persistence.Entity -import jakarta.persistence.Id import org.springframework.data.jpa.repository.JpaRepository interface MemberRepository : JpaRepository - -@Entity -class MemberEntity( - @Id - val id: String, - val fullName: String, - val secondInitialName: String, - val profileImageId: String?, - val platform: String, - val ordinal: Int, - val gender: String, - val point: Int, -) : BaseEntity() diff --git a/entity/src/main/kotlin/com/mashup/dojo/PickEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/PickEntity.kt new file mode 100644 index 00000000..47bee7cb --- /dev/null +++ b/entity/src/main/kotlin/com/mashup/dojo/PickEntity.kt @@ -0,0 +1,35 @@ +package com.mashup.dojo + +import com.mashup.dojo.base.BaseTimeEntity +import com.mashup.dojo.question.QuestionEntity +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.Id +import jakarta.persistence.JoinColumn +import jakarta.persistence.ManyToOne +import jakarta.persistence.Table + +@Entity +@Table(name = "pick") +class PickEntity( + @Id + val id: String, + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "question_id") + val questionEntity: QuestionEntity, + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "picker_id", referencedColumnName = "id") + val picker: MemberEntity, + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "picked_id", referencedColumnName = "id") + val picked: MemberEntity, + @Column(name = "is_gender_open") + val isGenderOpen: Boolean, + @Column(name = "is_platform_open") + val isPlatformOpen: Boolean, + @Column(name = "is_mid_initial_name_open") + val isMidInitialNameOpen: Boolean, + @Column(name = "is_full_name_open") + val isFullNameOpen: Boolean, +) : BaseTimeEntity() diff --git a/entity/src/main/kotlin/com/mashup/dojo/base/BaseEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/base/BaseEntity.kt index 83f015a2..46a15649 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/base/BaseEntity.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/base/BaseEntity.kt @@ -12,16 +12,16 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener abstract class BaseEntity : BaseTimeEntity() { @CreatedBy @Column(updatable = false) - var createdBy: String? = null - private set + lateinit var createdBy: String + protected set @LastModifiedBy - var lastModifiedBy: String? = null - private set + lateinit var lastModifiedBy: String + protected set @Column(nullable = false) var isDeleted: Boolean = false - private set + protected set // 재활성화 - soft delete fun activate() { diff --git a/entity/src/main/kotlin/com/mashup/dojo/base/BaseTimeEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/base/BaseTimeEntity.kt index fb8ef6cc..71d0f884 100644 --- a/entity/src/main/kotlin/com/mashup/dojo/base/BaseTimeEntity.kt +++ b/entity/src/main/kotlin/com/mashup/dojo/base/BaseTimeEntity.kt @@ -14,10 +14,10 @@ abstract class BaseTimeEntity { @CreatedDate @Column(name = "created_at", nullable = false, updatable = false) lateinit var createdAt: LocalDateTime - private set + protected set @LastModifiedDate @Column(name = "updated_at", nullable = false) lateinit var updatedAt: LocalDateTime - private set + protected set } diff --git a/entity/src/main/kotlin/com/mashup/dojo/notification/Notification.kt b/entity/src/main/kotlin/com/mashup/dojo/notification/Notification.kt new file mode 100644 index 00000000..77fdc33e --- /dev/null +++ b/entity/src/main/kotlin/com/mashup/dojo/notification/Notification.kt @@ -0,0 +1,22 @@ +package com.mashup.dojo.notification + +import com.mashup.dojo.base.BaseTimeEntity +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.Id +import jakarta.persistence.Table + +@Entity +@Table(name = "notification") +class Notification( + @Id + val id: String, + @Column(name = "title", nullable = false) + val title: String, + @Column(name = "content", nullable = false) + val content: String, + @Column(name = "topic", nullable = false) + val topic: String, + @Column(name = "send_status", nullable = false) + var sendStatus: Boolean, +) : BaseTimeEntity() diff --git a/entity/src/main/kotlin/com/mashup/dojo/question/QuestionEntity.kt b/entity/src/main/kotlin/com/mashup/dojo/question/QuestionEntity.kt new file mode 100644 index 00000000..90294a7a --- /dev/null +++ b/entity/src/main/kotlin/com/mashup/dojo/question/QuestionEntity.kt @@ -0,0 +1,81 @@ +package com.mashup.dojo.question + +import com.mashup.dojo.PickEntity +import com.mashup.dojo.base.BaseTimeEntity +import jakarta.persistence.CascadeType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import jakarta.persistence.Id +import jakarta.persistence.OneToMany +import jakarta.persistence.Table +import java.lang.RuntimeException + +@Entity +@Table(name = "question") +class QuestionEntity( + @Id + val id: String, + @Column(name = "content", nullable = false) + var content: String, + @Enumerated(EnumType.STRING) + val type: QuestionType, + @Enumerated(EnumType.STRING) + val category: QuestionCategory, + val emojiImageId: String, + @OneToMany(mappedBy = "questionEntity", cascade = [CascadeType.ALL], orphanRemoval = true) + var pickEntities: MutableList = mutableListOf(), +) : BaseTimeEntity() { + companion object { + fun createQuestion( + id: String, + content: String, + questionTypeString: String, + categoryString: String, + emojiImageId: String, + ): QuestionEntity { + val questionType = QuestionType.findByValue(questionTypeString) + val category = QuestionCategory.findByValue(categoryString) + + return QuestionEntity(id, content, questionType, category, emojiImageId) + } + } +} + +enum class QuestionType { + FRIEND, + ACCOMPANY, + ; + + companion object { + fun findByValue(value: String): QuestionType { + return entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw RuntimeException("ToDo change to DoJoException") + // ToDo + // DojoException.of(DojoExceptionType.INVALID_MEMBER_PLATFORM) + } + } +} + +enum class QuestionCategory { + LOVE, + ENTERTAINMENT, // 유흥 + APPEARANCE, + FLIRTING, // 작업 + PERSONALITY, + GET_TO_KNOW, + JOKE, + STRENGTH, + OTHER, + ; + + companion object { + fun findByValue(value: String): QuestionCategory { + return entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw RuntimeException("ToDo change to DoJoException") + // ToDo + // DojoException.of(DojoExceptionType.INVALID_MEMBER_PLATFORM) + } + } +} diff --git a/entity/src/main/resources/application-entity-local.yml b/entity/src/main/resources/application-entity-local.yml new file mode 100644 index 00000000..3242e2a9 --- /dev/null +++ b/entity/src/main/resources/application-entity-local.yml @@ -0,0 +1,19 @@ +spring: + datasource: + url: ENC(i+u914ZiotX9OZ2gFuRg+4+CpIK142QN/KuzoMmvPz8wHrvSO9ow1F8hwlD9WY1O29WITufUjEL2zAKZJv0wTNk8+19/cJgYj4F7b0H4bjVlNVuslh7FMMIJ/zgZst5o) + username: ENC(WS0DuwNzN19hZCDcpeK0ptXS6Gv3CowQNfwGQ4A3byU=) + password: ENC(ozxs8iZBHjljszbq6/y3cVt5Xt1Z8Nj6qh6gPobhs9A=) + driver-class-name: com.mysql.cj.jdbc.Driver + jpa: + show-sql: true + hibernate: + ddl-auto: validate + properties: + hibernate: + default_batch_fetch_size: 200 + dialect: org.hibernate.dialect.MySQL8Dialect + format_sql: true + +jasypt: + encryptor: + password: ${JASYPT_ENCRYPTOR_PASSWORD} diff --git a/entity/src/main/resources/application-entity-prod.yml b/entity/src/main/resources/application-entity-prod.yml new file mode 100644 index 00000000..b56e0c92 --- /dev/null +++ b/entity/src/main/resources/application-entity-prod.yml @@ -0,0 +1,19 @@ +spring: + datasource: + url: ENC(CptY28rV7YQickOOUYd5VOkKCv3ZMixjof2NFt51FtNrW+jmXEnpZDA/wv+f+RxdjmQK4zaN8QEOzkLh0/jloIOCGaTZ76tn+4yt5Tco4IKAtEa1esVaA9je39bWdWyj) + username: ENC(WS0DuwNzN19hZCDcpeK0ptXS6Gv3CowQNfwGQ4A3byU=) + password: ENC(ozxs8iZBHjljszbq6/y3cVt5Xt1Z8Nj6qh6gPobhs9A=) + driver-class-name: com.mysql.cj.jdbc.Driver + jpa: + show-sql: true + hibernate: + ddl-auto: validate + properties: + hibernate: + default_batch_fetch_size: 200 + dialect: org.hibernate.dialect.MySQL8Dialect + format_sql: true + +jasypt: + encryptor: + password: ${JASYPT_ENCRYPTOR_PASSWORD} diff --git a/entity/src/main/resources/application-entity.yaml b/entity/src/main/resources/application-entity.yaml deleted file mode 100644 index 507cea7b..00000000 --- a/entity/src/main/resources/application-entity.yaml +++ /dev/null @@ -1,16 +0,0 @@ -spring: - datasource: # todo mysql - url: ENC(GPT8CR78IymrQCJ/ui4FKpW3y+eOb99E9Neh0AqVsGe4wR4+llYdbISGgFUaJB1RKBc99SK1pJ/Y2yE3MpOVH/30rdTmQ4qD+VNoC6B42wBzr2aiqlYE4x8hF8XvtdmT) - username: ENC(WS0DuwNzN19hZCDcpeK0ptXS6Gv3CowQNfwGQ4A3byU=) - password: ENC(ozxs8iZBHjljszbq6/y3cVt5Xt1Z8Nj6qh6gPobhs9A=) - driver-class-name: com.mysql.cj.jdbc.Driver - jpa: - properties: - hibernate: - ddl-auto: none - dialect: org.hibernate.dialect.MySQLDialect - show_sql: true - -jasypt: - encryptor: - password: ${JASYPT_ENCRYPTOR_PASSWORD} diff --git a/entity/src/main/resources/ddl/V1ddl-dev.sql b/entity/src/main/resources/ddl/V1ddl-dev.sql new file mode 100644 index 00000000..f1fc7076 --- /dev/null +++ b/entity/src/main/resources/ddl/V1ddl-dev.sql @@ -0,0 +1,58 @@ +CREATE TABLE dojo_dev.question +( + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + content VARCHAR(255) NOT NULL, + target ENUM('EITHER','FRIEND','STRANGER') NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_dev.profile +( + is_deleted BIT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + member_id BIGINT, + updated_at DATETIME(6) NOT NULL, + created_by VARCHAR(255), + image_url VARCHAR(255) NOT NULL, + last_modified_by VARCHAR(255), + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_dev.pick +( + created_at DATETIME(6) NOT NULL, + from_member_id BIGINT, + id BIGINT NOT NULL AUTO_INCREMENT, + question_id BIGINT, + to_member_id BIGINT, + updated_at DATETIME(6) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_dev.notification +( + send_status BIT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + content VARCHAR(255) NOT NULL, + title VARCHAR(255) NOT NULL, + topic VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_dev.member +( + generation INT NOT NULL, + point INT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + name VARCHAR(255) NOT NULL, + gender ENUM('FEMALE','MALE') NOT NULL, + platform ENUM('ANDROID','IOS','PRODUCT_DESIGN','SPRING','WEB') NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; diff --git a/entity/src/main/resources/ddl/V1ddl-prod.sql b/entity/src/main/resources/ddl/V1ddl-prod.sql new file mode 100644 index 00000000..f8655a25 --- /dev/null +++ b/entity/src/main/resources/ddl/V1ddl-prod.sql @@ -0,0 +1,58 @@ +CREATE TABLE dojo_prod.question +( + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + content VARCHAR(255) NOT NULL, + target ENUM('EITHER','FRIEND','STRANGER') NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_prod.profile +( + is_deleted BIT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + member_id BIGINT, + updated_at DATETIME(6) NOT NULL, + created_by VARCHAR(255), + image_url VARCHAR(255) NOT NULL, + last_modified_by VARCHAR(255), + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_prod.pick +( + created_at DATETIME(6) NOT NULL, + from_member_id BIGINT, + id BIGINT NOT NULL AUTO_INCREMENT, + question_id BIGINT, + to_member_id BIGINT, + updated_at DATETIME(6) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_prod.notification +( + send_status BIT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + content VARCHAR(255) NOT NULL, + title VARCHAR(255) NOT NULL, + topic VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE dojo_prod.member +( + generation INT NOT NULL, + point INT NOT NULL, + created_at DATETIME(6) NOT NULL, + id BIGINT NOT NULL AUTO_INCREMENT, + updated_at DATETIME(6) NOT NULL, + name VARCHAR(255) NOT NULL, + gender ENUM('FEMALE','MALE') NOT NULL, + platform ENUM('ANDROID','IOS','PRODUCT_DESIGN','SPRING','WEB') NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB; diff --git a/service/src/main/kotlin/com/mashup/dojo/domain/Member.kt b/service/src/main/kotlin/com/mashup/dojo/domain/Member.kt index 3630093d..feff1355 100644 --- a/service/src/main/kotlin/com/mashup/dojo/domain/Member.kt +++ b/service/src/main/kotlin/com/mashup/dojo/domain/Member.kt @@ -1,6 +1,9 @@ package com.mashup.dojo.domain +import com.mashup.dojo.Gender +import com.mashup.dojo.Platform import com.mashup.dojo.UUIDGenerator +import java.lang.RuntimeException import java.time.LocalDateTime /** @@ -72,6 +75,16 @@ data class Member( enum class MemberGender { MALE, FEMALE, + ; + + companion object { + fun findByValue(value: String): Gender { + return Gender.entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw RuntimeException("ToDo change to DoJoException") + // ToDo + // DojoException.of(DojoExceptionType.INVALID_MEMBER_PLATFORM) + } + } } enum class MemberPlatform { @@ -81,4 +94,14 @@ enum class MemberPlatform { ANDROID, IOS, DESIGN, + ; + + companion object { + fun findByValue(value: String): Platform { + return Platform.entries.find { it.name.equals(value, ignoreCase = true) } + ?: throw RuntimeException("ToDo change to DoJoException") + // ToDo + // DojoException.of(DojoExceptionType.INVALID_MEMBER_PLATFORM) + } + } } diff --git a/service/src/main/kotlin/com/mashup/dojo/service/MemberService.kt b/service/src/main/kotlin/com/mashup/dojo/service/MemberService.kt index df6b8a03..62131284 100644 --- a/service/src/main/kotlin/com/mashup/dojo/service/MemberService.kt +++ b/service/src/main/kotlin/com/mashup/dojo/service/MemberService.kt @@ -97,14 +97,16 @@ class DefaultMemberService( } private fun Member.toEntity(): MemberEntity { - return MemberEntity( + val platform = MemberPlatform.findByValue(platform.name) + val gender = MemberGender.findByValue(gender.name) + + return MemberEntity.createMemberEntity( id = id.value, fullName = fullName, secondInitialName = secondInitialName, profileImageId = profileImageId?.value, - platform = platform.name, - ordinal = ordinal, - gender = gender.name, - point = point + platform = platform, + gender = gender, + ordinal = ordinal ) }