Skip to content

Commit

Permalink
[BSVR-180] 레벨업 테이블 조회 API (#101)
Browse files Browse the repository at this point in the history
* feat : level 테이블 내의 모든 정보를 가져오는 기능 추가

* feat : 레벨업 테이블 API 구현

* feat : 레벨업 테이블 API JWT 필터 예외 추가

* refactor : 해당 레벨의 minimum Review는 not null임을 명시하도록 원시타입으로 변경

* refactor : 상수 레벨 테이블을 사용해서 레벨 계산하도록 변경

* refactor : 상수 레벨 테이블을 사용해서 레벨업에 필요한 리뷰 수 계산하도록 변경

* fix : 레벨 계산 오류 수정

* build : ImmutableMap 사용을 위한 의존성 추가

* refactor : ImmutableMap을 사용해 레벨 최소/최대 조건 구현

* refactor : rest api 명명 규칙에 맞도록 복수형으로 변경

* refactor : ResponseStatus, summary 추가

* refactor : 레벨업 조건 테이블 조회 api 변경으로 인한 필터 조건 변경
  • Loading branch information
wjdwnsdnjs13 authored Aug 3, 2024
1 parent aeba0e5 commit 7564cb1
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
"/api-docs",
"/swagger-ui.html",
"/favicon.ico",
"/api/v1/members"
"/api/v1/members",
"/api/v1/levelUpConditions",
};

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.depromeet.spot.application.member.controller;

import java.util.List;

import org.depromeet.spot.application.member.dto.response.LevelUpTableResponse;
import org.depromeet.spot.usecase.port.in.member.LevelUsecase;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@Tag(name = "레벨")
@RequestMapping("/api/v1/levelUpConditions")
public class LevelUpTableController {

private final LevelUsecase levelUsecase;

@GetMapping
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "레벨업 조건 테이블 조회 API")
public List<LevelUpTableResponse> getLevelUpTable() {
return levelUsecase.findAllLevels().stream().map(LevelUpTableResponse::from).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.depromeet.spot.application.member.dto.response;

import org.depromeet.spot.domain.member.Level;

import lombok.Builder;

@Builder
public record LevelUpTableResponse(Integer level, String title, int minimum, Integer maximum) {
public static LevelUpTableResponse from(Level level) {
LevelUpTableResponse levelUpTableResponse =
LevelUpTableResponse.builder()
.level(level.getValue())
.title(level.getTitle())
.minimum(level.getMinimum())
.maximum(level.getMaximum())
.build();

return levelUpTableResponse;
}
}
3 changes: 3 additions & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
dependencies {
implementation(project(":common"))

// ImmutableMap을 위한 구아바 사용
implementation("com.google.guava:guava:31.0.1-jre")
}

tasks.jar { enabled = true }
Expand Down
81 changes: 49 additions & 32 deletions domain/src/main/java/org/depromeet/spot/domain/member/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,35 @@

import java.time.LocalDateTime;

import com.google.common.collect.ImmutableMap;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class Level {

private static final ImmutableMap<Integer, Integer> LEVEL_MINIMUM_CONDITIONS =
ImmutableMap.<Integer, Integer>builder()
.put(0, 0)
.put(1, 1)
.put(2, 3)
.put(3, 5)
.put(4, 8)
.put(5, 14)
.put(6, 21)
.build();

private static final ImmutableMap<Integer, Integer> LEVEL_MAXIMUM_CONDITIONS =
ImmutableMap.<Integer, Integer>builder()
.put(0, 0)
.put(1, 2)
.put(2, 4)
.put(3, 7)
.put(4, 13)
.put(5, 20)
.build();
private final Long id;
private final int value;
private final String title;
Expand All @@ -18,42 +40,37 @@ public class Level {
private final LocalDateTime deletedAt;

public static int calculateLevel(final long reviewCnt) {
if (reviewCnt == 0) {
return 0;
}
if (reviewCnt <= 2) {
return 1;
}
if (2 < reviewCnt && reviewCnt <= 4) {
return 2;
}
if (4 < reviewCnt && reviewCnt <= 7) {
return 3;
}
if (7 < reviewCnt && reviewCnt <= 13) {
return 4;
}
if (13 < reviewCnt && reviewCnt <= 20) {
if (reviewCnt > LEVEL_MINIMUM_CONDITIONS.get(6)) {
return 6;
} else if (reviewCnt > LEVEL_MAXIMUM_CONDITIONS.get(5)) {
return 5;
} else if (reviewCnt > LEVEL_MAXIMUM_CONDITIONS.get(4)) {
return 4;
} else if (reviewCnt > LEVEL_MAXIMUM_CONDITIONS.get(3)) {
return 3;
} else if (reviewCnt > LEVEL_MAXIMUM_CONDITIONS.get(2)) {
return 2;
} else if (reviewCnt > LEVEL_MAXIMUM_CONDITIONS.get(1)) {
return 1;
}
return 6;
return 0;
}

public static long calculateReviewCntToLevelUp(long reviewCnt) {
int nextLevelMinimumReview;
if (reviewCnt == 0) {
nextLevelMinimumReview = 1;
} else if (reviewCnt <= 2) {
nextLevelMinimumReview = 3;
} else if (2 < reviewCnt && reviewCnt <= 4) {
nextLevelMinimumReview = 5;
} else if (4 < reviewCnt && reviewCnt <= 7) {
nextLevelMinimumReview = 8;
} else if (7 < reviewCnt && reviewCnt <= 13) {
nextLevelMinimumReview = 14;
} else if (13 < reviewCnt && reviewCnt <= 20) {
nextLevelMinimumReview = 21;
} else return 0;
return nextLevelMinimumReview - reviewCnt;
int level = calculateLevel(reviewCnt);
if (level > 5) {
return 0;
}
// (다음 레벨의 최소 리뷰 조건) - (현재 작성한 리뷰 수)
return LEVEL_MINIMUM_CONDITIONS.get(level + 1) - reviewCnt;
}

public int getMinimum() {
return LEVEL_MINIMUM_CONDITIONS.get(value);
}

public Integer getMaximum() {
if (value > 5) return null;
return LEVEL_MAXIMUM_CONDITIONS.get(value);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.depromeet.spot.jpa.member.repository;

import java.util.List;

import org.depromeet.spot.domain.member.Level;
import org.depromeet.spot.jpa.member.entity.LevelEntity;
import org.depromeet.spot.usecase.port.out.member.LevelRepository;
import org.springframework.stereotype.Repository;

Expand All @@ -16,4 +19,9 @@ public class LevelRepositoryImpl implements LevelRepository {
public Level findByValue(final int value) {
return levelJpaRepository.findByValue(value).toDomain();
}

@Override
public List<Level> findAll() {
return levelJpaRepository.findAll().stream().map(LevelEntity::toDomain).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.depromeet.spot.usecase.port.in.member;

import java.util.List;

import org.depromeet.spot.domain.member.Level;

public interface LevelUsecase {
List<Level> findAllLevels();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.depromeet.spot.usecase.port.out.member;

import java.util.List;

import org.depromeet.spot.domain.member.Level;

public interface LevelRepository {

Level findByValue(int value);

List<Level> findAll();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.depromeet.spot.usecase.service.level;

import java.util.List;

import org.depromeet.spot.domain.member.Level;
import org.depromeet.spot.usecase.port.in.member.LevelUsecase;
import org.depromeet.spot.usecase.port.out.member.LevelRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LevelService implements LevelUsecase {

private final LevelRepository levelRepository;

@Override
public List<Level> findAllLevels() {
return levelRepository.findAll();
}
}

0 comments on commit 7564cb1

Please sign in to comment.