diff --git a/common/src/main/java/com/wypl/common/exception/GlobalErrorCode.java b/common/src/main/java/com/wypl/common/exception/GlobalErrorCode.java new file mode 100644 index 0000000..ab0ded3 --- /dev/null +++ b/common/src/main/java/com/wypl/common/exception/GlobalErrorCode.java @@ -0,0 +1,31 @@ +package com.wypl.common.exception; + +public enum GlobalErrorCode implements ServerErrorCode { + INTERNAL_SERVER_ERROR(500, "GLOBAL_001", "알 수 없는 서버의 오류입니다."), + ; + + private final int statusCode; + private final String errorCode; + private final String message; + + private GlobalErrorCode(int statusCode, String errorCode, String message) { + this.statusCode = statusCode; + this.errorCode = errorCode; + this.message = message; + } + + @Override + public String getErrorCode() { + return errorCode; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public int getStatusCode() { + return statusCode; + } +} diff --git a/domain/jpa-core/build.gradle b/domain/jpa-core/build.gradle index b65f5b6..183958e 100644 --- a/domain/jpa-core/build.gradle +++ b/domain/jpa-core/build.gradle @@ -5,7 +5,9 @@ java { } dependencies { + implementation project(':common') + api('org.springframework.boot:spring-boot-starter-data-jpa') - runtimeOnly 'com.h2database:h2' + runtimeOnly('com.h2database:h2') } diff --git a/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaAuditingConfig.java b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaAuditingConfig.java new file mode 100644 index 0000000..fca6d4e --- /dev/null +++ b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaAuditingConfig.java @@ -0,0 +1,9 @@ +package com.wypl.jpacore; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@EnableJpaAuditing +@Configuration +public class JpaAuditingConfig { +} diff --git a/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaBaseEntity.java b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaBaseEntity.java new file mode 100644 index 0000000..6bd4331 --- /dev/null +++ b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaBaseEntity.java @@ -0,0 +1,56 @@ +package com.wypl.jpacore; + +import java.time.LocalDateTime; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import com.wypl.common.exception.WyplException; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@MappedSuperclass +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EntityListeners(AuditingEntityListener.class) +public abstract class JpaBaseEntity { + + @CreatedDate + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "modified_at", nullable = false) + private LocalDateTime modifiedAt; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + public void delete() { + if (isDeleted()) { + throw new WyplException(JpaErrorCode.ALREADY_DELETED_ENTITY); + } + this.deletedAt = LocalDateTime.now(); + } + + public void restore() { + if (isNotDeleted()) { + throw new WyplException(JpaErrorCode.NON_DELETED_ENTITY); + } + this.deletedAt = null; + } + + public boolean isNotDeleted() { + return deletedAt == null; + } + + public boolean isDeleted() { + return !isNotDeleted(); + } +} diff --git a/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaErrorCode.java b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaErrorCode.java new file mode 100644 index 0000000..5961a1f --- /dev/null +++ b/domain/jpa-core/src/main/java/com/wypl/jpacore/JpaErrorCode.java @@ -0,0 +1,20 @@ +package com.wypl.jpacore; + +import com.wypl.common.exception.ServerErrorCode; + +import lombok.Getter; + +@Getter +public enum JpaErrorCode implements ServerErrorCode { + ALREADY_DELETED_ENTITY(400, "JPA_001", "이미 삭제된 데이터입니다"), + NON_DELETED_ENTITY(400, "JPA_002", "삭제되지 않은 데이터는 복구할 수 없습니다."); + private final int statusCode; + private final String errorCode; + private final String message; + + private JpaErrorCode(int statusCode, String errorCode, String message) { + this.statusCode = statusCode; + this.errorCode = errorCode; + this.message = message; + } +} diff --git a/domain/jpa-core/src/main/resources/application.yml b/domain/jpa-core/src/main/resources/application.yml deleted file mode 100644 index e69de29..0000000 diff --git a/domain/jpamongo-review-domain/build.gradle b/domain/jpamongo-review-domain/build.gradle new file mode 100644 index 0000000..4c56292 --- /dev/null +++ b/domain/jpamongo-review-domain/build.gradle @@ -0,0 +1,13 @@ +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +dependencies { + implementation project(':common') + implementation project(':domain:jpa-core') + implementation project(':domain:jpa-member-domain') + implementation project(':domain:jpa-calendar-domain') + implementation project(':domain:mongo-core') +} diff --git a/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/domain/Review.java b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/domain/Review.java new file mode 100644 index 0000000..4210575 --- /dev/null +++ b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/domain/Review.java @@ -0,0 +1,42 @@ +package com.wypl.jpamongoreviewdomain.review.domain; + +import org.hibernate.annotations.SQLRestriction; + +import com.wypl.jpacore.JpaBaseEntity; +import com.wypl.jpamemberdomain.member.Member; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@Builder +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@SQLRestriction("deleted_at is null") +@Entity +public class Review extends JpaBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "review_id") + private Long reviewId; + + @Column(nullable = false, length = 50) + private String title; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + // TODO: 추후 schedule 와 `@ManyToOne` 관계가 필요 +} diff --git a/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/repository/ReviewRepository.java b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/repository/ReviewRepository.java new file mode 100644 index 0000000..89bffe5 --- /dev/null +++ b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/review/repository/ReviewRepository.java @@ -0,0 +1,8 @@ +package com.wypl.jpamongoreviewdomain.review.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.wypl.jpamongoreviewdomain.review.domain.Review; + +public interface ReviewRepository extends JpaRepository { +} diff --git a/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/domain/ReviewContents.java b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/domain/ReviewContents.java new file mode 100644 index 0000000..d1fc5a3 --- /dev/null +++ b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/domain/ReviewContents.java @@ -0,0 +1,27 @@ +package com.wypl.jpamongoreviewdomain.reviewcontents.domain; + +import java.util.List; +import java.util.Map; + +import org.springframework.data.mongodb.core.mapping.Document; + +import com.wypl.mongocore.MongoBaseEntity; + +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@Builder +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Document(collection = "review_contents") +public class ReviewContents extends MongoBaseEntity { + @Id + private Long reviewId; + + private List> contents; +} diff --git a/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/repository/ReviewContentsRepository.java b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/repository/ReviewContentsRepository.java new file mode 100644 index 0000000..2ef7b09 --- /dev/null +++ b/domain/jpamongo-review-domain/src/main/java/com/wypl/jpamongoreviewdomain/reviewcontents/repository/ReviewContentsRepository.java @@ -0,0 +1,8 @@ +package com.wypl.jpamongoreviewdomain.reviewcontents.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; + +import com.wypl.jpamongoreviewdomain.reviewcontents.domain.ReviewContents; + +public interface ReviewContentsRepository extends MongoRepository { +} diff --git a/domain/jpa-core/src/main/java/com/wypl/jpacore/.gitkeep b/domain/jpamongo-review-domain/src/test/java/com/wypl/jpamongoreviewdomain/.gitkeep similarity index 100% rename from domain/jpa-core/src/main/java/com/wypl/jpacore/.gitkeep rename to domain/jpamongo-review-domain/src/test/java/com/wypl/jpamongoreviewdomain/.gitkeep diff --git a/domain/mongo-core/build.gradle b/domain/mongo-core/build.gradle index 9221ddf..4475f3c 100644 --- a/domain/mongo-core/build.gradle +++ b/domain/mongo-core/build.gradle @@ -5,6 +5,8 @@ java { } dependencies { + implementation project(':common') + /* Database */ api('org.springframework.boot:spring-boot-starter-data-mongodb') implementation('de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring31x:4.11.0') diff --git a/domain/mongo-core/src/main/java/com/wypl/mongocore/.gitkeep b/domain/mongo-core/src/main/java/com/wypl/mongocore/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoAuditingConfig.java b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoAuditingConfig.java new file mode 100644 index 0000000..95f3cf8 --- /dev/null +++ b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoAuditingConfig.java @@ -0,0 +1,9 @@ +package com.wypl.mongocore; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.EnableMongoAuditing; + +@EnableMongoAuditing +@Configuration +public class MongoAuditingConfig { +} diff --git a/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoBaseEntity.java b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoBaseEntity.java new file mode 100644 index 0000000..b9c7ee3 --- /dev/null +++ b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoBaseEntity.java @@ -0,0 +1,50 @@ +package com.wypl.mongocore; + +import java.time.LocalDateTime; + +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.mongodb.core.mapping.Field; + +import com.wypl.common.exception.WyplException; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class MongoBaseEntity { + @CreatedDate + @Field(name = "created_at", write = Field.Write.NON_NULL) + private LocalDateTime createdAt; + + @LastModifiedDate + @Field(name = "modified_at", write = Field.Write.NON_NULL) + private LocalDateTime modifiedAt; + + @Field(name = "deleted_at") + private LocalDateTime deletedAt; + + public void delete() { + if (isDeleted()) { + throw new WyplException(MongoErrorCode.ALREADY_DELETED_ENTITY); + } + this.deletedAt = LocalDateTime.now(); + } + + public void restore() { + if (isNotDeleted()) { + throw new WyplException(MongoErrorCode.NON_DELETED_ENTITY); + } + this.deletedAt = null; + } + + public boolean isNotDeleted() { + return deletedAt == null; + } + + public boolean isDeleted() { + return !isNotDeleted(); + } +} diff --git a/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoErrorCode.java b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoErrorCode.java new file mode 100644 index 0000000..c2eec64 --- /dev/null +++ b/domain/mongo-core/src/main/java/com/wypl/mongocore/MongoErrorCode.java @@ -0,0 +1,20 @@ +package com.wypl.mongocore; + +import com.wypl.common.exception.ServerErrorCode; + +import lombok.Getter; + +@Getter +public enum MongoErrorCode implements ServerErrorCode { + ALREADY_DELETED_ENTITY(400, "JPA_001", "이미 삭제된 요소는 삭제할 수 없습니다."), + NON_DELETED_ENTITY(400, "JPA_002", "삭제되지 않은 요소는 복구할 수 없습니다."); + private final int statusCode; + private final String errorCode; + private final String message; + + private MongoErrorCode(int statusCode, String errorCode, String message) { + this.statusCode = statusCode; + this.errorCode = errorCode; + this.message = message; + } +} diff --git a/domain/mongo-core/src/main/resources/application.yml b/domain/mongo-core/src/main/resources/application.yml deleted file mode 100644 index e69de29..0000000 diff --git a/settings.gradle b/settings.gradle index a52971e..8f812b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -12,6 +12,7 @@ include ':domain' include ':domain:jpa-core' include ':domain:jpa-calendar-domain' include ':domain:jpa-member-domain' +include ':domain:jpamongo-review-domain' include ':domain:mongo-core' /* Client Module */