diff --git a/build.gradle b/build.gradle index 64bcdc6..dc782e0 100644 --- a/build.gradle +++ b/build.gradle @@ -19,10 +19,20 @@ repositories { } dependencies { - // ✅ 웹서버 실행 위해 Web 스타터 추가 (CI 확인용 간단 서버) + // 기본 웹 서버 implementation 'org.springframework.boot:spring-boot-starter-web' - // ✅ 테스트 관련 + // JPA (DB 매핑용) + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // MySQL 드라이버 + runtimeOnly 'com.mysql:mysql-connector-j' + + // Lombok (getter/setter, builder, etc.) + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + // 테스트 관련 testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } diff --git a/src/main/java/com/example/UMC/UmcApplication.java b/src/main/java/com/example/UMC/UmcApplication.java index d92a392..226d1b0 100644 --- a/src/main/java/com/example/UMC/UmcApplication.java +++ b/src/main/java/com/example/UMC/UmcApplication.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +@EnableJpaAuditing @SpringBootApplication public class UmcApplication { diff --git a/src/main/java/com/example/UMC/domain/BaseEntity.java b/src/main/java/com/example/UMC/domain/BaseEntity.java new file mode 100644 index 0000000..a19a4a1 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/BaseEntity.java @@ -0,0 +1,24 @@ +package com.example.UMC.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { + @CreationTimestamp + @Column(name = "created_at", nullable = false) + private LocalDateTime createdAt; + + @UpdateTimestamp + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; +} diff --git a/src/main/java/com/example/UMC/domain/enums/Gender.java b/src/main/java/com/example/UMC/domain/enums/Gender.java new file mode 100644 index 0000000..e74dfb1 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/enums/Gender.java @@ -0,0 +1,5 @@ +package com.example.UMC.domain.enums; + +public enum Gender { + M, F, UNKNOWN +} diff --git a/src/main/java/com/example/UMC/domain/enums/MissionStatus.java b/src/main/java/com/example/UMC/domain/enums/MissionStatus.java new file mode 100644 index 0000000..ad644c3 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/enums/MissionStatus.java @@ -0,0 +1,5 @@ +package com.example.UMC.domain.enums; + +public enum MissionStatus { + NOT_STARTED, CANCEL, PROCESS, COMPLETE +} diff --git a/src/main/java/com/example/UMC/domain/enums/Status.java b/src/main/java/com/example/UMC/domain/enums/Status.java new file mode 100644 index 0000000..47dd735 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/enums/Status.java @@ -0,0 +1,5 @@ +package com.example.UMC.domain.enums; + +public enum Status { + ACTIVE, LOCK +} diff --git a/src/main/java/com/example/UMC/domain/likes/LikeCategory.java b/src/main/java/com/example/UMC/domain/likes/LikeCategory.java new file mode 100644 index 0000000..bc8a533 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/likes/LikeCategory.java @@ -0,0 +1,21 @@ +package com.example.UMC.domain.likes; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "like_category") +public class LikeCategory { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "category_id") + private Long id; + + @Column(name = "category_name", nullable = false, length = 20) + private String name; +} diff --git a/src/main/java/com/example/UMC/domain/likes/UserLikeFood.java b/src/main/java/com/example/UMC/domain/likes/UserLikeFood.java new file mode 100644 index 0000000..a0dcc75 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/likes/UserLikeFood.java @@ -0,0 +1,27 @@ +package com.example.UMC.domain.likes; + +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "user_like_food") +public class UserLikeFood { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_like_food_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id", nullable = false) + private LikeCategory category; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; +} diff --git a/src/main/java/com/example/UMC/domain/mission/Mission.java b/src/main/java/com/example/UMC/domain/mission/Mission.java new file mode 100644 index 0000000..fe3025a --- /dev/null +++ b/src/main/java/com/example/UMC/domain/mission/Mission.java @@ -0,0 +1,47 @@ +package com.example.UMC.domain.mission; + +import com.example.UMC.domain.store.Store; +import com.example.UMC.domain.store.Region; +import jakarta.persistence.*; +import lombok.*; +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "misson") +public class Mission { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "misson_id") + private Long id; + + @Column(name = "title", nullable = false, length = 120) + private String title; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Column(name = "min_spend") + private Integer minSpend; + + @Column(name = "point") + private Integer point; + + @Column(name = "starts_at") + private LocalDateTime startsAt; + + @Column(name = "ends_at") + private LocalDateTime endsAt; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id", nullable = false) + private Store store; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; +} diff --git a/src/main/java/com/example/UMC/domain/mission/UserMission.java b/src/main/java/com/example/UMC/domain/mission/UserMission.java new file mode 100644 index 0000000..614b43b --- /dev/null +++ b/src/main/java/com/example/UMC/domain/mission/UserMission.java @@ -0,0 +1,47 @@ +package com.example.UMC.domain.mission; + +import com.example.UMC.domain.enums.MissionStatus; +import com.example.UMC.domain.store.Region; +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "user_misson") +public class UserMission { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_misson_id") + private Long id; + + @Column(name = "verrification_code", length = 16) + private String verificationCode; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false, length = 20) + private MissionStatus status; + + @Column(name = "challenge_at") + private LocalDateTime challengeAt; + + @Column(name = "completed_at") + private LocalDateTime completedAt; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "misson_id", nullable = false) + private Mission mission; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; +} diff --git a/src/main/java/com/example/UMC/domain/notification/Notification.java b/src/main/java/com/example/UMC/domain/notification/Notification.java new file mode 100644 index 0000000..fcfea87 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/notification/Notification.java @@ -0,0 +1,32 @@ +package com.example.UMC.domain.notification; + + +import com.example.UMC.domain.BaseEntity; +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "notification") +public class Notification extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "notification_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @Column(name = "is_notification", nullable = false) + private Boolean isNotification; + + @Column(name = "is_read", nullable = false) + private Boolean isRead; +} + diff --git a/src/main/java/com/example/UMC/domain/review/Review.java b/src/main/java/com/example/UMC/domain/review/Review.java new file mode 100644 index 0000000..badf891 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/Review.java @@ -0,0 +1,40 @@ +package com.example.UMC.domain.review; + +import com.example.UMC.domain.BaseEntity; +import com.example.UMC.domain.store.Region; +import com.example.UMC.domain.store.Store; +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "review") +public class Review extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "review_id") + private Long id; + + @Column(name = "rating", nullable = false) + private Integer rating; + + @Column(name = "content", columnDefinition = "TEXT") + private String content; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id", nullable = false) + private Store store; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; +} diff --git a/src/main/java/com/example/UMC/domain/review/ReviewImage.java b/src/main/java/com/example/UMC/domain/review/ReviewImage.java new file mode 100644 index 0000000..9944bf6 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/ReviewImage.java @@ -0,0 +1,31 @@ +package com.example.UMC.domain.review; + +import com.example.UMC.domain.store.Region; +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "review_img") +public class ReviewImage { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "review_img_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "review_id", nullable = false) + private Review review; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; + + @Column(name = "review_img_url", nullable = false, length = 255) + private String imageUrl; +} diff --git a/src/main/java/com/example/UMC/domain/review/ReviewReply.java b/src/main/java/com/example/UMC/domain/review/ReviewReply.java new file mode 100644 index 0000000..682f990 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/ReviewReply.java @@ -0,0 +1,35 @@ +package com.example.UMC.domain.review; + +import com.example.UMC.domain.store.Region; +import com.example.UMC.domain.user.User; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "review_replies") +public class ReviewReply { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "review_reply_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "review_id", nullable = false) + private Review review; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; + + @Column(name = "review_reply_text", columnDefinition = "TEXT") + private String text; +} diff --git a/src/main/java/com/example/UMC/domain/store/Region.java b/src/main/java/com/example/UMC/domain/store/Region.java new file mode 100644 index 0000000..d2e87f2 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/store/Region.java @@ -0,0 +1,21 @@ +package com.example.UMC.domain.store; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "resion") +public class Region { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "resion_id") + private Long id; + + @Column(name = "resion_name", nullable = false, length = 255) + private String name; +} diff --git a/src/main/java/com/example/UMC/domain/store/Store.java b/src/main/java/com/example/UMC/domain/store/Store.java new file mode 100644 index 0000000..e7cb049 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/store/Store.java @@ -0,0 +1,33 @@ +package com.example.UMC.domain.store; + +import com.example.UMC.domain.BaseEntity; +import jakarta.persistence.*; +import lombok.*; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "store") +public class Store extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "store_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "resion_id", nullable = false) + private Region region; + + @Column(name = "name", nullable = false, length = 100) + private String name; + + @Column(name = "address", length = 255) + private String address; + + @Column(name = "food_category", length = 50) + private String foodCategory; +} diff --git a/src/main/java/com/example/UMC/domain/user/Agreement.java b/src/main/java/com/example/UMC/domain/user/Agreement.java new file mode 100644 index 0000000..415a535 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/user/Agreement.java @@ -0,0 +1,29 @@ +package com.example.UMC.domain.user; + +import com.example.UMC.domain.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "agreement") +public class Agreement extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "agreement_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @Column(name = "is_privacy", nullable = false) + private Boolean isPrivacy; + + @Column(name = "is_service", nullable = false) + private Boolean isService; +} diff --git a/src/main/java/com/example/UMC/domain/user/User.java b/src/main/java/com/example/UMC/domain/user/User.java new file mode 100644 index 0000000..87ee8bd --- /dev/null +++ b/src/main/java/com/example/UMC/domain/user/User.java @@ -0,0 +1,87 @@ +package com.example.UMC.domain.user; + +import com.example.UMC.domain.BaseEntity; +import com.example.UMC.domain.mission.UserMission; +import com.example.UMC.domain.notification.Notification; +import com.example.UMC.domain.review.Review; +import com.example.UMC.domain.review.ReviewReply; +import com.example.UMC.domain.enums.*; +import com.example.UMC.domain.likes.UserLikeFood; +import jakarta.persistence.*; +import lombok.*; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Table(name = "user") +public class User extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long id; + + @Column(name = "name", nullable = false, length = 50) + private String name; + + @Enumerated(EnumType.STRING) + @Column(name = "gender", nullable = false, length = 10) + private Gender gender; + + @Column(name = "email", nullable = false, length = 255, unique = true) + private String email; + + @Column(name = "phone_number", length = 20) + private String phoneNumber; + + @Column(name = "birth", length = 20) + private String birth; + + @Column(name = "address", length = 255) + private String address; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false, length = 10) + private Status status; + + @Column(name = "privacy_agree", nullable = false) + private Boolean privacyAgree; + + @Column(name = "id", nullable = false, length = 100) + private String loginId; + + @Column(name = "password", nullable = false, length = 100) + private String password; + + @Column(name = "point", nullable = false) + private Integer point; + + //연관관계 + + // 약관 동의 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List agreements; + + // 알림 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List notifications; + + // 리뷰 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List reviews; + + // 리뷰 답글 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List reviewReplies; + + // 선호 음식 (User_Like_Food) 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List likeFoods; + + // 유저 미션 (User_Mission) 1:N + @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE) + private List missions; +}