Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
@Table(name = "member_mission")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class MemberMission {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberMissionId;

@Builder.Default
private Boolean isComplete = false;

@ManyToOne(fetch = FetchType.LAZY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.umc.prac.domain.member.repository;

import com.umc.prac.domain.member.entity.Member;
import com.umc.prac.domain.member.entity.MemberMission;
import com.umc.prac.domain.mission.entity.Mission;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberMissionRepository extends JpaRepository<MemberMission, Long> {

boolean existsByMemberAndMission(Member member, Mission mission);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.umc.prac.domain.member.repository;

import com.umc.prac.domain.member.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MemberRepository extends JpaRepository<Member, Long> {
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@Table(name = "mission")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class Mission {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -26,12 +27,14 @@ public class Mission {

private Integer point;

@Builder.Default
private LocalDateTime createdAt = LocalDateTime.now();

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "store_id")
private Store store;

@Builder.Default
@OneToMany(mappedBy = "mission", cascade = CascadeType.ALL, orphanRemoval = true)
private List<MemberMission> memberMissions = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.umc.prac.domain.mission.repository;

import com.umc.prac.domain.mission.entity.Mission;
import org.springframework.data.jpa.repository.JpaRepository;

public interface MissionRepository extends JpaRepository<Mission, Long> {
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@Table(name = "review")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class Review {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -24,6 +25,7 @@ public class Review {
// 리뷰 별점 (예: 4.5)
private Double star;

@Builder.Default
private LocalDateTime createdAt = LocalDateTime.now();

@ManyToOne(fetch = FetchType.LAZY)
Expand All @@ -34,9 +36,11 @@ public class Review {
@JoinColumn(name = "store_id")
private Store store;

@Builder.Default
@OneToMany(mappedBy = "review", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ReviewPhoto> reviewPhotos = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "review", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reply> replies = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.umc.prac.domain.store.controller;

import com.umc.prac.domain.store.dto.request.MissionChallengeRequest;
import com.umc.prac.domain.store.dto.request.StoreCreateRequest;
import com.umc.prac.domain.store.dto.request.StoreMissionCreateRequest;
import com.umc.prac.domain.store.dto.request.StoreReviewCreateRequest;
import com.umc.prac.domain.store.dto.response.MemberMissionResponse;
import com.umc.prac.domain.store.dto.response.MissionResponse;
import com.umc.prac.domain.store.dto.response.ReviewResponse;
import com.umc.prac.domain.store.dto.response.StoreResponse;
import com.umc.prac.domain.store.service.StoreCommandService;
import com.umc.prac.global.apiPayload.ApiResponse;
import com.umc.prac.global.apiPayload.code.SuccessCode;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1")
public class StoreCommandController {

private final StoreCommandService storeCommandService;

public StoreCommandController(StoreCommandService storeCommandService) {
this.storeCommandService = storeCommandService;
}

@PostMapping("/locations/{locationId}/stores")
public ApiResponse<StoreResponse> createStore(@PathVariable Long locationId,
@Valid @RequestBody StoreCreateRequest request) {
StoreResponse response = storeCommandService.createStore(locationId, request);
return ApiResponse.onSuccess(SuccessCode.STORE_CREATE_SUCCESS, response);
}

@PostMapping("/stores/{storeId}/reviews")
public ApiResponse<ReviewResponse> createReview(@PathVariable Long storeId,
@Valid @RequestBody StoreReviewCreateRequest request) {
ReviewResponse response = storeCommandService.createReview(storeId, request);
return ApiResponse.onSuccess(SuccessCode.REVIEW_CREATE_SUCCESS, response);
}

@PostMapping("/stores/{storeId}/missions")
public ApiResponse<MissionResponse> createMission(@PathVariable Long storeId,
@Valid @RequestBody StoreMissionCreateRequest request) {
MissionResponse response = storeCommandService.createMission(storeId, request);
return ApiResponse.onSuccess(SuccessCode.MISSION_CREATE_SUCCESS, response);
}

@PostMapping("/missions/{missionId}/challenge")
public ApiResponse<MemberMissionResponse> challengeMission(@PathVariable Long missionId,
@Valid @RequestBody MissionChallengeRequest request) {
MemberMissionResponse response = storeCommandService.challengeMission(missionId, request);
return ApiResponse.onSuccess(SuccessCode.MISSION_CHALLENGE_SUCCESS, response);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.prac.domain.store.dto.request;

import jakarta.validation.constraints.NotNull;

public record MissionChallengeRequest(
@NotNull(message = "회원 ID는 필수입니다.")
Long memberId
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.umc.prac.domain.store.dto.request;

import jakarta.validation.constraints.NotBlank;

public record StoreCreateRequest(
@NotBlank(message = "가게 이름은 필수입니다.")
String name,

@NotBlank(message = "가게 연락처는 필수입니다.")
String managerNumber
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.umc.prac.domain.store.dto.request;

import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;

import java.time.LocalDate;

public record StoreMissionCreateRequest(
@NotNull(message = "마감일은 필수입니다.")
@FutureOrPresent(message = "마감일은 오늘 또는 미래여야 합니다.")
LocalDate deadline,

@NotBlank(message = "미션 조건은 필수입니다.")
String conditional,

@NotNull(message = "포인트는 필수입니다.")
@Positive(message = "포인트는 양수여야 합니다.")
Integer point
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.umc.prac.domain.store.dto.request;

import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public record StoreReviewCreateRequest(
@NotNull(message = "회원 ID는 필수입니다.")
Long memberId,

@NotBlank(message = "리뷰 내용은 필수입니다.")
String content,

@NotNull(message = "별점은 필수입니다.")
@DecimalMin(value = "0.0", message = "별점은 0 이상이어야 합니다.")
@DecimalMax(value = "5.0", message = "별점은 5 이하이어야 합니다.")
Double star
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.prac.domain.store.dto.response;

public record MemberMissionResponse(
Long memberMissionId,
Long memberId,
Long missionId,
Boolean isComplete
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.umc.prac.domain.store.dto.response;

import java.time.LocalDate;
import java.time.LocalDateTime;

public record MissionResponse(
Long missionId,
Long storeId,
String conditional,
Integer point,
LocalDate deadline,
LocalDateTime createdAt
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.umc.prac.domain.store.dto.response;

import java.time.LocalDateTime;

public record ReviewResponse(
Long reviewId,
Long memberId,
Long storeId,
Double star,
String content,
LocalDateTime createdAt
) {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.umc.prac.domain.store.dto.response;

public record StoreResponse(
Long storeId,
String name,
Long locationId,
String managerNumber
) {
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@Table(name = "store")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class Store {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -25,9 +26,11 @@ public class Store {
@JoinColumn(name = "location_id")
private Location location;

@Builder.Default
@OneToMany(mappedBy = "store", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Mission> missions = new ArrayList<>();

@Builder.Default
@OneToMany(mappedBy = "store", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Review> reviews = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.umc.prac.domain.store.repository;

import com.umc.prac.domain.store.entity.Location;
import org.springframework.data.jpa.repository.JpaRepository;

public interface LocationRepository extends JpaRepository<Location, Long> {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.umc.prac.domain.store.repository;

import com.umc.prac.domain.store.entity.Store;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StoreRepository extends JpaRepository<Store, Long> {
}

Loading