Skip to content

Commit

Permalink
Merge pull request #309 from Team-Sopetit/feature/#308-get-daily-rout…
Browse files Browse the repository at this point in the history
…ines

[FEAT] Daily Routine 목록 조회(in add view) 기능 구현
  • Loading branch information
thguss authored Jul 24, 2024
2 parents dc52bff + d4880a9 commit 3be3ffe
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.soptie.server.memberroutine.repository.dto.MemberChallengeResponse;
import com.soptie.server.memberroutine.repository.dto.MemberRoutineResponse;
import com.soptie.server.routine.entity.Routine;
import com.soptie.server.routine.entity.RoutineType;
import com.soptie.server.routine.exception.RoutineException;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -47,4 +48,8 @@ public boolean existMemberChallenge(Member member) {
public Optional<MemberChallengeResponse> findChallengeByMember(Member member) {
return memberRoutineRepository.findChallengeByMember(member);
}

public List<MemberRoutine> findAllByMemberAndType(Member member, RoutineType type) {
return memberRoutineRepository.findByMemberAndType(member, type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ public interface MemberRoutineRepository extends JpaRepository<MemberRoutine, Lo
void deleteByMember(Member member);

boolean existsByMemberAndType(Member member, RoutineType type);

List<MemberRoutine> findByMemberAndType(Member member, RoutineType type);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public List<Routine> findChallengeRoutinesByTheme(Long themeId) {
return routineRepository.findByTypeAndThemeId(RoutineType.CHALLENGE, themeId);
}

public List<RoutineVO> findAllByTypeAndThemeId(RoutineType type, Long themeId) {
return routineRepository.findByTypeAndThemeId(type, themeId).stream().map(RoutineVO::from).toList();
public List<Routine> findAllByTypeAndThemeId(RoutineType type, Long themeId) {
return routineRepository.findByTypeAndThemeId(type, themeId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.List;
import java.util.Objects;

import com.soptie.server.routine.service.vo.RoutineVO;
import com.soptie.server.routine.entity.Routine;

import lombok.AccessLevel;
import lombok.Builder;
Expand All @@ -14,7 +14,7 @@ public record HappinessRoutineListAcquireResponse(
List<HappinessRoutineResponse> routines
) {

public static HappinessRoutineListAcquireResponse from(List<RoutineVO> routines) {
public static HappinessRoutineListAcquireResponse from(List<Routine> routines) {
return HappinessRoutineListAcquireResponse.builder()
.routines(routines.stream().map(HappinessRoutineResponse::from).toList())
.build();
Expand All @@ -29,13 +29,13 @@ private record HappinessRoutineResponse(
@NonNull String iconImageUrl
) {

private static HappinessRoutineResponse from(RoutineVO routine) {
private static HappinessRoutineResponse from(Routine routine) {
return HappinessRoutineResponse.builder()
.routineId(routine.routineId())
.name(Objects.nonNull(routine.theme()) ? routine.theme().name() : "알 수 없는 테마")
.nameColor(Objects.nonNull(routine.theme()) ? routine.theme().color() : "#FFFFFF")
.title(routine.content())
.iconImageUrl(Objects.nonNull(routine.theme()) ? routine.theme().imageLinks().iconImageUrl() : "")
.routineId(routine.getId())
.name(Objects.nonNull(routine.getTheme()) ? routine.getTheme().getName() : "알 수 없는 테마")
.nameColor(Objects.nonNull(routine.getTheme()) ? routine.getTheme().getColor() : "#FFFFFF")
.title(routine.getContent())
.iconImageUrl(routine.getTheme() != null ? routine.getTheme().getImageLinks().getIconImageUrl() : "")
.build();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package com.soptie.server.routine.controller.v2;

import java.security.Principal;
import java.util.LinkedHashSet;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.soptie.server.common.dto.SuccessResponse;
import com.soptie.server.routine.controller.v2.docs.DailyRoutineControllerV2Docs;
import com.soptie.server.routine.controller.v2.dto.response.DailyRoutineListAcquireResponseV2;
import com.soptie.server.routine.controller.v2.dto.response.DailyRoutinesAcquireResponseV2;
import com.soptie.server.routine.message.RoutineSuccessMessage;
import com.soptie.server.routine.service.RoutineService;

Expand All @@ -34,4 +39,16 @@ public ResponseEntity<SuccessResponse<DailyRoutineListAcquireResponseV2>> acquir
DailyRoutineListAcquireResponseV2.from(response)));
}

@ResponseStatus(HttpStatus.OK)
@GetMapping("/theme/{themeId}")
public SuccessResponse<DailyRoutinesAcquireResponseV2> acquireAllByThemeAndMember(
Principal principal,
@PathVariable long themeId
) {
val memberId = Long.parseLong(principal.getName());
val response = routineService.acquireAllInDailyByThemeAndMember(memberId, themeId);
return SuccessResponse.success(
RoutineSuccessMessage.SUCCESS_GET_ROUTINE.getMessage(),
DailyRoutinesAcquireResponseV2.from(response));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,60 @@
package com.soptie.server.routine.controller.v2.docs;

import java.security.Principal;
import java.util.LinkedHashSet;

import org.springframework.http.ResponseEntity;

import com.soptie.server.common.dto.SuccessResponse;
import com.soptie.server.routine.controller.v2.dto.response.DailyRoutineListAcquireResponseV2;
import com.soptie.server.routine.controller.v2.dto.response.DailyRoutinesAcquireResponseV2;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

@Tag(name = "DailyRoutineApiV2", description = "데일리 루틴 API (version2)")
public interface DailyRoutineControllerV2Docs {

@Operation(
summary = "데일리 루틴 목록 조회",
description = "특정 테마 id 목록에 속하는 데일리 루틴 목록을 조회합니다."
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "OK Success",
content = @Content(schema = @Schema(implementation = DailyRoutineListAcquireResponseV2.class)))})
ResponseEntity<SuccessResponse<DailyRoutineListAcquireResponseV2>> acquireAllByThemes(
@Parameter(name = "themeIds", description = "조회할 테마 id 목록") LinkedHashSet<Long> themeIds
@Parameter(
name = "themeIds",
description = "조회할 테마 id 목록",
required = true,
in = ParameterIn.QUERY
) LinkedHashSet<Long> themeIds
);

@Operation(
summary = "데일리 루틴 목록 조회",
description = "특정 테마에 속하는 데일리 루틴 목록을 조회합니다. 회원이 가진 유무를 함께 확인할 수 있습니다."
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "OK Success",
content = @Content(schema = @Schema(implementation = DailyRoutinesAcquireResponseV2.class)))})
SuccessResponse<DailyRoutinesAcquireResponseV2> acquireAllByThemeAndMember(
@Parameter(hidden = true) Principal principal,
@Parameter(
name = "themeId",
description = "조회하려는 루틴의 테마 id",
required = true,
in = ParameterIn.PATH
) long themeId
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.List;
import java.util.Map;

import com.soptie.server.routine.service.vo.RoutineVO;
import com.soptie.server.routine.entity.Routine;

import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
Expand All @@ -14,7 +14,7 @@ public record DailyRoutineListAcquireResponseV2(
List<ThemeResponse> themes
) {

public static DailyRoutineListAcquireResponseV2 from(Map<Long, List<RoutineVO>> routinesMap) {
public static DailyRoutineListAcquireResponseV2 from(Map<Long, List<Routine>> routinesMap) {
return DailyRoutineListAcquireResponseV2.builder()
.themes(routinesMap.keySet().stream().map(key -> ThemeResponse.from(key, routinesMap.get(key))).toList())
.build();
Expand All @@ -26,7 +26,7 @@ private record ThemeResponse(
List<RoutineResponse> routines
) {

private static ThemeResponse from(long themeId, List<RoutineVO> routines) {
private static ThemeResponse from(long themeId, List<Routine> routines) {
return ThemeResponse.builder()
.themeId(themeId)
.routines(routines.stream().map(RoutineResponse::from).toList())
Expand All @@ -40,10 +40,10 @@ private record RoutineResponse(
@NotNull String content
) {

private static RoutineResponse from(RoutineVO routine) {
private static RoutineResponse from(Routine routine) {
return RoutineResponse.builder()
.routineId(routine.routineId())
.content(routine.content())
.routineId(routine.getId())
.content(routine.getContent())
.build();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.soptie.server.routine.controller.v2.dto.response;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.soptie.server.routine.entity.Routine;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.val;

@Builder(access = AccessLevel.PRIVATE)
public record DailyRoutinesAcquireResponseV2(
@Schema(description = "조회하려는 루틴 목록")
@NotNull
List<DailyRoutineResponse> routines
) {

public static DailyRoutinesAcquireResponseV2 from(Map<Boolean, List<Routine>> routineToMember) {
val routines = new ArrayList<DailyRoutineResponse>();
for (val key : routineToMember.keySet()) {
routines.addAll(routineToMember.get(key).stream()
.map(routine -> DailyRoutineResponse.of(routine, key))
.toList());
}
return DailyRoutinesAcquireResponseV2.builder()
.routines(routines)
.build();
}

@Builder(access = AccessLevel.PRIVATE)
private record DailyRoutineResponse(
@Schema(description = "루틴 id")
long id,
@Schema(description = "루틴 내용")
@NotNull
String content,
@Schema(description = "회원이 가지고 있는 루틴 유무")
boolean existedInMember
) {

private static DailyRoutineResponse of(Routine routine, boolean existedInMember) {
return DailyRoutineResponse.builder()
.id(routine.getId())
.content(routine.getContent())
.existedInMember(existedInMember)
.build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static com.soptie.server.common.config.ValueConfig.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -13,9 +15,11 @@
import com.soptie.server.member.adapter.MemberFinder;
import com.soptie.server.member.entity.Member;
import com.soptie.server.memberroutine.adapter.MemberRoutineFinder;
import com.soptie.server.memberroutine.entity.MemberRoutine;
import com.soptie.server.memberroutine.repository.dto.MemberChallengeResponse;
import com.soptie.server.routine.adapter.ChallengeFinder;
import com.soptie.server.routine.adapter.RoutineFinder;
import com.soptie.server.routine.entity.Routine;
import com.soptie.server.routine.entity.RoutineType;
import com.soptie.server.routine.service.dto.request.HappinessSubRoutineListGetServiceRequest;
import com.soptie.server.routine.service.dto.response.ChallengeRoutineListAcquireServiceResponse;
Expand Down Expand Up @@ -45,7 +49,7 @@ public List<RoutineVO> acquireAllInDailyNotInMemberByThemeId(long memberId, long
return routineFinder.findAllNotInMemberByTypeAndThemeId(memberId, RoutineType.DAILY, themeId);
}

public List<RoutineVO> acquireAllInHappinessByThemeId(Long themeId) {
public List<Routine> acquireAllInHappinessByThemeId(Long themeId) {
return routineFinder.findAllByTypeAndThemeId(RoutineType.CHALLENGE, themeId);
}

Expand All @@ -57,8 +61,8 @@ public HappinessSubRoutineListGetServiceResponse getHappinessSubRoutines(
return HappinessSubRoutineListGetServiceResponse.of(routine, subRoutines);
}

public Map<Long, List<RoutineVO>> acquireAllInDailyWithThemeId(Set<Long> themeIds) {
val themeToRoutine = new LinkedHashMap<Long, List<RoutineVO>>();
public Map<Long, List<Routine>> acquireAllInDailyWithThemeId(Set<Long> themeIds) {
val themeToRoutine = new LinkedHashMap<Long, List<Routine>>();
for (val themeId : themeIds) {
val routines = routineFinder.findAllByTypeAndThemeId(RoutineType.DAILY, themeId);
themeToRoutine.put(themeId, routines);
Expand All @@ -83,6 +87,26 @@ public Map<String, ChallengeRoutineListAcquireServiceResponse> acquireAllInChall
return themeToChallenge;
}

public Map<Boolean, List<Routine>> acquireAllInDailyByThemeAndMember(long memberId, long themeId) {
val routines = routineFinder.findAllByTypeAndThemeId(RoutineType.DAILY, themeId);
val member = memberFinder.findById(memberId);
val memberRoutineIds = memberRoutineFinder.findAllByMemberAndType(member, RoutineType.DAILY).stream()
.map(MemberRoutine::getRoutineId)
.toList();
return getRoutineToMember(routines, memberRoutineIds);
}

private Map<Boolean, List<Routine>> getRoutineToMember(List<Routine> routines, List<Long> memberRoutineIds) {
val routineToMember = new HashMap<Boolean, List<Routine>>();
routineToMember.put(true, new ArrayList<>());
routineToMember.put(false, new ArrayList<>());
for (val routine : routines) {
val isMemberRoutine = memberRoutineIds.contains(routine.getId());
routineToMember.get(isMemberRoutine).add(routine);
}
return routineToMember;
}

private long getChallengeIdByMember(Member member) {
val challengeByMember = memberRoutineFinder.findChallengeByMember(member);
return challengeByMember.map(MemberChallengeResponse::challengeId).orElse(MEMBER_HAS_NOT_CHALLENGE);
Expand Down
Loading

0 comments on commit 3be3ffe

Please sign in to comment.