Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/resources/application.properties
  • Loading branch information
ChoiWonYu committed Oct 7, 2024
2 parents 9fd2842 + f26fbd7 commit 30bbd60
Show file tree
Hide file tree
Showing 19 changed files with 240 additions and 102 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ dependencies {
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

// Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.first.flash.climbing.problem.application;

import static com.first.flash.climbing.problem.infrastructure.paging.SortBy.DIFFICULTY;
import static com.first.flash.climbing.problem.infrastructure.paging.SortBy.VIEWS;
import static com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy.DIFFICULTY;
import static com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy.VIEWS;

import com.first.flash.climbing.gym.domian.ClimbingGymIdConfirmRequestedEvent;
import com.first.flash.climbing.problem.application.dto.ProblemDetailResponseDto;
Expand All @@ -13,8 +13,8 @@
import com.first.flash.climbing.problem.exception.exceptions.ProblemNotFoundException;
import com.first.flash.climbing.problem.exception.exceptions.QueryProblemExpiredException;
import com.first.flash.climbing.problem.exception.exceptions.QueryProblemNotFoundException;
import com.first.flash.climbing.problem.infrastructure.paging.Cursor;
import com.first.flash.climbing.problem.infrastructure.paging.SortBy;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemCursor;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy;
import com.first.flash.global.event.Events;
import java.util.List;
import java.util.UUID;
Expand All @@ -33,14 +33,15 @@ public class ProblemReadService {
public ProblemsResponseDto findAll(final Long gymId, final String cursor,
final String sortByRequest, final Integer size,
final List<String> difficulty, final List<String> sector, final Boolean hasSolution) {
Cursor prevCursor = Cursor.decode(cursor);
SortBy sortBy = SortBy.from(sortByRequest);
ProblemCursor prevProblemCursor = ProblemCursor.decode(cursor);
ProblemSortBy problemSortBy = ProblemSortBy.from(sortByRequest);

Events.raise(ClimbingGymIdConfirmRequestedEvent.of(gymId));

List<QueryProblem> queryProblems = queryProblemRepository.findAll(prevCursor, sortBy, size,
List<QueryProblem> queryProblems = queryProblemRepository.findAll(prevProblemCursor,
problemSortBy, size,
gymId, difficulty, sector, hasSolution);
String nextCursor = getNextCursor(sortBy, size, queryProblems);
String nextCursor = getNextCursor(problemSortBy, size, queryProblems);
return ProblemsResponseDto.of(queryProblems, nextCursor);
}

Expand Down Expand Up @@ -71,25 +72,25 @@ private void validateExpiration(final Problem problem, final QueryProblem queryP
}
}

private String getNextCursor(final SortBy sortBy, final Integer size,
private String getNextCursor(final ProblemSortBy problemSortBy, final Integer size,
final List<QueryProblem> queryProblems) {
if (hasNextCursor(size, queryProblems)) {
return null;
}
QueryProblem lastProblem = queryProblems.get(size - 1);
return new Cursor(sortBy, getLastSortValue(lastProblem, sortBy), lastProblem.getId())
return new ProblemCursor(problemSortBy, getLastSortValue(lastProblem, problemSortBy), lastProblem.getId())
.encode();
}

private boolean hasNextCursor(final Integer size, final List<QueryProblem> queryProblems) {
return queryProblems.size() != size;
}

private String getLastSortValue(final QueryProblem lastProblem, final SortBy sortBy) {
if (sortBy.equals(DIFFICULTY)) {
private String getLastSortValue(final QueryProblem lastProblem, final ProblemSortBy problemSortBy) {
if (problemSortBy.equals(DIFFICULTY)) {
return lastProblem.getDifficultyLevel().toString();
}
if (sortBy.equals(VIEWS)) {
if (problemSortBy.equals(VIEWS)) {
return lastProblem.getViews().toString();
}
return lastProblem.getRecommendationValue().toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.first.flash.climbing.problem.application.dto;

import com.first.flash.climbing.problem.domain.QueryProblem;
import com.first.flash.global.paging.Meta;
import java.util.List;

public record ProblemsResponseDto(List<ProblemResponseDto> problems, Meta meta) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.first.flash.climbing.problem.domain;

import com.first.flash.climbing.problem.infrastructure.paging.Cursor;
import com.first.flash.climbing.problem.infrastructure.paging.SortBy;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemCursor;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
Expand All @@ -13,7 +13,7 @@ public interface QueryProblemRepository {

Optional<QueryProblem> findById(final UUID id);

List<QueryProblem> findAll(final Cursor preCursor, final SortBy sortBy, final int size,
List<QueryProblem> findAll(final ProblemCursor preProblemCursor, final ProblemSortBy problemSortBy, final int size,
final Long gymId, final List<String> difficulty, final List<String> sector,
final Boolean hasSolution);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.first.flash.climbing.problem.infrastructure;

import static com.first.flash.climbing.problem.domain.QQueryProblem.queryProblem;
import static com.first.flash.climbing.problem.infrastructure.paging.SortBy.DIFFICULTY;
import static com.first.flash.climbing.problem.infrastructure.paging.SortBy.VIEWS;
import static com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy.DIFFICULTY;
import static com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy.VIEWS;

import com.first.flash.climbing.problem.domain.QueryProblem;
import com.first.flash.climbing.problem.infrastructure.paging.Cursor;
import com.first.flash.climbing.problem.infrastructure.paging.SortBy;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemCursor;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
Expand All @@ -23,14 +23,14 @@ public class QueryProblemQueryDslRepository {

private final JPAQueryFactory queryFactory;

public List<QueryProblem> findAll(final Cursor prevCursor, final SortBy sortBy, final int size,
public List<QueryProblem> findAll(final ProblemCursor prevProblemCursor, final ProblemSortBy problemSortBy, final int size,
final Long gymId, final List<String> difficulty, final List<String> sector,
final Boolean hasSolution) {
return queryFactory
.selectFrom(queryProblem)
.where(notExpired(), cursorCondition(prevCursor), inGym(gymId), inSectors(sector),
.where(notExpired(), cursorCondition(prevProblemCursor), inGym(gymId), inSectors(sector),
inDifficulties(difficulty), hasSolution(hasSolution))
.orderBy(sortItem(sortBy), queryProblem.id.desc())
.orderBy(sortItem(problemSortBy), queryProblem.id.desc())
.limit(size)
.fetch();
}
Expand Down Expand Up @@ -63,25 +63,25 @@ private BooleanExpression inGym(final Long gymId) {
return queryProblem.gymId.eq(gymId);
}

private BooleanExpression cursorCondition(final Cursor prevCursor) {
if (Objects.isNull(prevCursor) || Objects.isNull(prevCursor.cursorValue())) {
private BooleanExpression cursorCondition(final ProblemCursor prevProblemCursor) {
if (Objects.isNull(prevProblemCursor) || Objects.isNull(prevProblemCursor.cursorValue())) {
return null;
}
SortBy sortBy = prevCursor.sortBy();
String cursorValue = prevCursor.cursorValue();
UUID cursorId = prevCursor.lastId();
return getExpressionBySortColumn(sortBy, cursorValue, cursorId);
ProblemSortBy problemSortBy = prevProblemCursor.problemSortBy();
String cursorValue = prevProblemCursor.cursorValue();
UUID cursorId = prevProblemCursor.lastId();
return getExpressionBySortColumn(problemSortBy, cursorValue, cursorId);
}

private BooleanExpression getExpressionBySortColumn(
final SortBy sortBy, final String cursorValue, final UUID cursorId) {
if (sortBy.equals(DIFFICULTY)) {
final ProblemSortBy problemSortBy, final String cursorValue, final UUID cursorId) {
if (problemSortBy.equals(DIFFICULTY)) {
return queryProblem.difficultyLevel.gt(Integer.parseInt(cursorValue))
.or(queryProblem.difficultyLevel
.eq(Integer.parseInt(cursorValue))
.and(queryProblem.id.lt(cursorId)));
}
if (sortBy.equals(VIEWS)) {
if (problemSortBy.equals(VIEWS)) {
return queryProblem.views.lt(Integer.parseInt(cursorValue))
.or(queryProblem.views.eq(Integer.parseInt(cursorValue))
.and(queryProblem.id.lt(cursorId)));
Expand All @@ -96,11 +96,11 @@ private BooleanExpression notExpired() {
return queryProblem.isExpired.isFalse();
}

private OrderSpecifier<?> sortItem(final SortBy sortBy) {
if (sortBy.equals(DIFFICULTY)) {
private OrderSpecifier<?> sortItem(final ProblemSortBy problemSortBy) {
if (problemSortBy.equals(DIFFICULTY)) {
return queryProblem.difficultyLevel.asc();
}
if (sortBy.equals(VIEWS)) {
if (problemSortBy.equals(VIEWS)) {
return queryProblem.views.desc();
}
return queryProblem.recommendationValue.desc();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.first.flash.climbing.problem.domain.QueryProblem;
import com.first.flash.climbing.problem.domain.QueryProblemRepository;
import com.first.flash.climbing.problem.infrastructure.paging.Cursor;
import com.first.flash.climbing.problem.infrastructure.paging.SortBy;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemCursor;
import com.first.flash.climbing.problem.infrastructure.paging.ProblemSortBy;
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
Expand All @@ -29,10 +29,10 @@ public Optional<QueryProblem> findById(final UUID id) {
}

@Override
public List<QueryProblem> findAll(final Cursor prevCursor, final SortBy sortBy, final int size,
public List<QueryProblem> findAll(final ProblemCursor prevProblemCursor, final ProblemSortBy problemSortBy, final int size,
final Long gymId, final List<String> difficulty, final List<String> sector,
final Boolean hasSolution) {
return queryProblemQueryDslRepository.findAll(prevCursor, sortBy, size,
return queryProblemQueryDslRepository.findAll(prevProblemCursor, problemSortBy, size,
gymId, difficulty, sector, hasSolution);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.Objects;
import java.util.UUID;

public record Cursor(SortBy sortBy, String cursorValue, UUID lastId) {
public record ProblemCursor(ProblemSortBy problemSortBy, String cursorValue, UUID lastId) {

private static final String DEFAULT_SEPARATOR = ":";
private static final int SORT_BY_INDEX = 0;
Expand All @@ -19,7 +19,7 @@ public String encode() {
.encodeToString(combined.getBytes());
}

public static Cursor decode(final String encoded) {
public static ProblemCursor decode(final String encoded) {
if (Objects.isNull(encoded) || encoded.isEmpty()) {
return null;
}
Expand All @@ -32,7 +32,7 @@ public static Cursor decode(final String encoded) {
throw new IllegalArgumentException();
}

return new Cursor(SortBy.from(parts[SORT_BY_INDEX]), parts[CURSOR_VALUE_INDEX],
return new ProblemCursor(ProblemSortBy.from(parts[SORT_BY_INDEX]), parts[CURSOR_VALUE_INDEX],
UUID.fromString(parts[LAST_ID_INDEX]));
} catch (RuntimeException exception) {
throw new InvalidCursorException();
Expand All @@ -41,7 +41,7 @@ public static Cursor decode(final String encoded) {

private String combineValues() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(sortBy.getValue())
stringBuilder.append(problemSortBy.getValue())
.append(DEFAULT_SEPARATOR)
.append(cursorValue)
.append(DEFAULT_SEPARATOR)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.first.flash.climbing.problem.infrastructure.paging;

public enum ProblemSortBy {

VIEWS("views"),
DIFFICULTY("difficulty"),
RECOMMEND("recommend");

private static final ProblemSortBy DEFAULT_SORT_BY = RECOMMEND;
private final String value;

ProblemSortBy(String value) {
this.value = value;
}

public String getValue() {
return value;
}

public static ProblemSortBy from(final String value) {
for (ProblemSortBy problemSortBy : ProblemSortBy.values()) {
if (problemSortBy.value.equalsIgnoreCase(value)) {
return problemSortBy;
}
}
return DEFAULT_SORT_BY;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.first.flash.climbing.solution.application;

import com.first.flash.account.member.application.BlockService;
import com.first.flash.climbing.gym.domian.ClimbingGymIdConfirmRequestedEvent;
import com.first.flash.climbing.problem.domain.ProblemIdConfirmRequestedEvent;
import com.first.flash.climbing.solution.application.dto.MySolutionsResponseDto;
import com.first.flash.climbing.solution.application.dto.SolutionResponseDto;
import com.first.flash.climbing.solution.application.dto.SolutionUpdateRequestDto;
import com.first.flash.climbing.solution.application.dto.SolutionsPageResponseDto;
import com.first.flash.climbing.solution.application.dto.SolutionsResponseDto;
import com.first.flash.climbing.solution.domain.Solution;
import com.first.flash.climbing.solution.domain.SolutionDeletedEvent;
Expand All @@ -13,9 +15,11 @@
import com.first.flash.climbing.solution.exception.exceptions.SolutionNotFoundException;
import com.first.flash.climbing.solution.infrastructure.dto.DetailSolutionDto;
import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto;
import com.first.flash.climbing.solution.infrastructure.paging.SolutionCursor;
import com.first.flash.global.event.Events;
import com.first.flash.global.util.AuthUtil;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -50,14 +54,17 @@ public SolutionsResponseDto findAllSolutionsByProblemId(final UUID problemId) {
return SolutionsResponseDto.of(solutions);
}

public MySolutionsResponseDto findMySolutions() {
public SolutionsPageResponseDto findMySolutions(final String cursor, final int size,
final Long gymId, final List<String> difficulty) {
UUID myId = AuthUtil.getId();
return findAllSolutionsByMemberId(myId);
}

public MySolutionsResponseDto findAllSolutionsByMemberId(final UUID memberId) {
List<MySolutionDto> solutions = solutionRepository.findAllByUploaderId(memberId);
return MySolutionsResponseDto.of(solutions);
if (!Objects.isNull(gymId)) {
Events.raise(ClimbingGymIdConfirmRequestedEvent.of(gymId));
}
SolutionCursor prevSolutionCursor = SolutionCursor.decode(cursor);
List<MySolutionDto> solutions = solutionRepository.findMySolutions(myId, prevSolutionCursor,
size, gymId, difficulty);
String nextCursor = getNextCursor(size, solutions);
return SolutionsPageResponseDto.of(solutions, nextCursor);
}

@Transactional
Expand Down Expand Up @@ -90,6 +97,19 @@ public void deleteByUploaderId(final UUID memberId) {
solutionRepository.deleteByUploaderId(memberId);
}

private String getNextCursor(final int size, final List<MySolutionDto> solutions) {
if (hasNextCursor(size, solutions)) {
return null;
}
MySolutionDto lastSolution = solutions.get(solutions.size() - 1);
return new SolutionCursor(lastSolution.uploadedAt().toString(),
lastSolution.solutionId()).encode();
}

private boolean hasNextCursor(final int size, final List<MySolutionDto> solutions) {
return solutions.size() != size;
}

private void validateUploader(final UUID uploaderId) {
if (!AuthUtil.isSameId(uploaderId)) {
throw new SolutionAccessDeniedException();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.first.flash.climbing.solution.application.dto;

import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto;
import com.first.flash.global.paging.Meta;
import java.util.List;

public record SolutionsPageResponseDto(List<MySolutionDto> mySolutions, Meta meta) {

public static SolutionsPageResponseDto of(
final List<MySolutionDto> solutions, final String nextCursor) {
if (solutions.isEmpty()) {
return new SolutionsPageResponseDto(List.of(), null);
}
return new SolutionsPageResponseDto(solutions, Meta.from(nextCursor));
}
}
Loading

0 comments on commit 30bbd60

Please sign in to comment.