Skip to content

Commit

Permalink
Merge pull request #173 from Team-HMH/develop
Browse files Browse the repository at this point in the history
deploy: main <- develop
  • Loading branch information
kseysh authored Jul 13, 2024
2 parents 8d8a750 + a489c9a commit 420ae4a
Show file tree
Hide file tree
Showing 71 changed files with 911 additions and 409 deletions.
24 changes: 24 additions & 0 deletions src/main/java/sopt/org/hmh/domain/admin/controller/AdminApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package sopt.org.hmh.domain.admin.controller;

import io.swagger.v3.oas.annotations.Operation;
import org.springframework.http.ResponseEntity;
import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest;
import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse;
import sopt.org.hmh.global.common.response.BaseResponse;

public interface AdminApi {
@Operation(summary = "κ΄€λ¦¬μž 둜그인")
ResponseEntity<BaseResponse<AdminTokenResponse>> orderAdminLogin(AdminLoginRequest request);

@Operation(summary = "κ΄€λ¦¬μž κΆŒν•œμœΌλ‘œ μœ μ € μ¦‰μ‹œ μ‚­μ œ")
ResponseEntity<Void> orderAdminWithdrawImmediately(AdminUserIdRequest request);

@Operation(summary = "κ΄€λ¦¬μž κΆŒν•œμœΌλ‘œ μœ μ € 정보 λ³€κ²½")
ResponseEntity<Void> orderAdminChangeUserInfo(AdminUserInfoRequest request);

@Operation(summary = "κ΄€λ¦¬μž κΆŒν•œμœΌλ‘œ μœ μ € μ±Œλ¦°μ§€ 정보 λ³€κ²½")
ResponseEntity<Void> orderAdminChangeDailyChallengeInfo(AdminDailyChallengeRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package sopt.org.hmh.domain.admin.controller;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
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;
import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminLoginRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminUserIdRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest;
import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse;
import sopt.org.hmh.domain.admin.exception.AdminSuccess;
import sopt.org.hmh.domain.admin.service.AdminFacade;
import sopt.org.hmh.global.common.response.BaseResponse;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/admin")
public class AdminController implements AdminApi {

private final AdminFacade adminFacade;

@Override
@PostMapping("/login")
public ResponseEntity<BaseResponse<AdminTokenResponse>> orderAdminLogin(
@RequestBody final AdminLoginRequest request) {
return ResponseEntity
.status(AdminSuccess.ADMIN_LOGIN_SUCCESS.getHttpStatus())
.body(BaseResponse.success(AdminSuccess.ADMIN_LOGIN_SUCCESS,
adminFacade.adminLogin(request.authCode())));
}

@Override
@DeleteMapping("/user")
public ResponseEntity<Void> orderAdminWithdrawImmediately(
@RequestBody @Valid final AdminUserIdRequest request) {
adminFacade.withdrawImmediately(request.userId());
return ResponseEntity
.noContent()
.build();
}

@Override
@PatchMapping("/user")
public ResponseEntity<Void> orderAdminChangeUserInfo(
@RequestBody @Valid final AdminUserInfoRequest request) {
adminFacade.changeUserInfo(request);
return ResponseEntity
.noContent()
.build();
}

@Override
@PatchMapping("/challenge/daily")
public ResponseEntity<Void> orderAdminChangeDailyChallengeInfo(
@RequestBody @Valid final AdminDailyChallengeRequest request) {
adminFacade.changeDailyChallengeInfo(request);
return ResponseEntity
.noContent()
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package sopt.org.hmh.domain.admin.dto.request;

import java.time.LocalDate;
import java.util.List;
import sopt.org.hmh.domain.dailychallenge.domain.Status;

public record AdminDailyChallengeRequest(
Long userId,
LocalDate startDate,
List<Status> statuses
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package sopt.org.hmh.domain.admin.dto.request;

public record AdminLoginRequest(
String authCode
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package sopt.org.hmh.domain.admin.dto.request;

public record AdminUserIdRequest(
Long userId
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package sopt.org.hmh.domain.admin.dto.request;

public record AdminUserInfoRequest(
Long userId,
String name,
Integer point
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package sopt.org.hmh.domain.admin.dto.response;

public record AdminTokenResponse(
String accessToken
) {
}
31 changes: 31 additions & 0 deletions src/main/java/sopt/org/hmh/domain/admin/exception/AdminError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package sopt.org.hmh.domain.admin.exception;

import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import sopt.org.hmh.global.common.exception.base.ErrorBase;

@AllArgsConstructor
public enum AdminError implements ErrorBase {

// 401 UNAUTHORIZED
INVALID_ADMIN_AUTH_CODE(HttpStatus.UNAUTHORIZED, "κ΄€λ¦¬μž 인증 λ²ˆν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."),
;

private final HttpStatus status;
private final String errorMessage;

@Override
public int getHttpStatusCode() {
return this.status.value();
}

@Override
public HttpStatus getHttpStatus() {
return this.status;
}

@Override
public String getErrorMessage() {
return this.errorMessage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package sopt.org.hmh.domain.admin.exception;

import sopt.org.hmh.global.common.exception.base.ExceptionBase;

public class AdminException extends ExceptionBase {

public AdminException(AdminError errorBase) {
super(errorBase);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package sopt.org.hmh.domain.admin.exception;

import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import sopt.org.hmh.global.common.exception.base.SuccessBase;

@AllArgsConstructor
public enum AdminSuccess implements SuccessBase {

// 200 OK
ADMIN_LOGIN_SUCCESS(HttpStatus.OK, "κ΄€λ¦¬μž λ‘œκ·ΈμΈμ— μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€."),

// 204 NO CONTENT
ADMIN_WITHDRAW_IMMEDIATELY_SUCCESS(HttpStatus.NO_CONTENT, "κ΄€λ¦¬μž κΆŒν•œμœΌλ‘œ μœ μ € μ¦‰μ‹œ μ‚­μ œμ— μ„±κ³΅ν–ˆμŠ΅λ‹ˆλ‹€."),
;

private final HttpStatus status;
private final String successMessage;

@Override
public int getHttpStatusCode() {
return this.status.value();
}

@Override
public HttpStatus getHttpStatus() {
return this.status;
}

@Override
public String getSuccessMessage() {
return this.successMessage;
}
}
81 changes: 81 additions & 0 deletions src/main/java/sopt/org/hmh/domain/admin/service/AdminFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package sopt.org.hmh.domain.admin.service;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sopt.org.hmh.domain.admin.dto.request.AdminDailyChallengeRequest;
import sopt.org.hmh.domain.admin.dto.request.AdminUserInfoRequest;
import sopt.org.hmh.domain.admin.dto.response.AdminTokenResponse;
import sopt.org.hmh.domain.admin.exception.AdminError;
import sopt.org.hmh.domain.admin.exception.AdminException;
import sopt.org.hmh.domain.challenge.domain.exception.ChallengeError;
import sopt.org.hmh.domain.challenge.domain.exception.ChallengeException;
import sopt.org.hmh.domain.challenge.service.ChallengeService;
import sopt.org.hmh.domain.dailychallenge.domain.Status;
import sopt.org.hmh.domain.dailychallenge.service.DailyChallengeService;
import sopt.org.hmh.domain.user.domain.User;
import sopt.org.hmh.domain.user.service.UserService;
import sopt.org.hmh.global.auth.jwt.TokenService;

@Service
@RequiredArgsConstructor
public class AdminFacade {

@Value("${jwt.admin-auth-code}")
private String adminAuthCode;

private final UserService userService;
private final TokenService tokenService;
private final ChallengeService challengeService;
private final DailyChallengeService dailyChallengeService;

public AdminTokenResponse adminLogin(String authCode) {
validateAdminAuthCode(authCode);
return new AdminTokenResponse(tokenService.issueAdminToken());
}

private void validateAdminAuthCode(String authCode) {
if (!adminAuthCode.equals(authCode)) {
throw new AdminException(AdminError.INVALID_ADMIN_AUTH_CODE);
}
}

@Transactional
public void withdrawImmediately(Long userId) {
userService.checkIsExistUserId(userId);
challengeService.deleteChallengeRelatedByUserId(userId);
userService.withdrawImmediately(userId);
}

@Transactional
public void changeUserInfo(AdminUserInfoRequest request) {
User user = userService.findByIdOrThrowException(request.userId());
if (Objects.nonNull(request.point())) {
user.changePoint(request.point());
}
if (Objects.nonNull(request.name())) {
user.changeName(request.name());
}
}

@Transactional
public void changeDailyChallengeInfo(AdminDailyChallengeRequest request) {
Long currentChallengeId = userService.getCurrentChallengeIdByUserId(request.userId());
List<Status> statuses = request.statuses();
LocalDate challengeDate = request.startDate();

validateStatusesPeriod(currentChallengeId, statuses);
dailyChallengeService.changeInfoOfDailyChallenges(currentChallengeId, statuses, challengeDate);
}

private void validateStatusesPeriod(Long challengeId, List<Status> statuses) {
Integer challengePeriod = challengeService.getChallengePeriod(challengeId);
if (challengePeriod != statuses.size()) {
throw new ChallengeException(ChallengeError.INVALID_PERIOD_NUMERIC);
}
}
}
3 changes: 3 additions & 0 deletions src/main/java/sopt/org/hmh/domain/app/domain/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;

@Getter
Expand All @@ -14,7 +15,9 @@ public abstract class App {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull(message = "osλŠ” null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
protected String os;

@NotNull(message = "appCodeλŠ” null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
protected String appCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public abstract class AppConstants {
public static final Long MINIMUM_APP_TIME = 0L;
public static final Long MAXIMUM_APP_TIME = 21_600_000L; // 6μ‹œκ°„
public static final Long MAXIMUM_APP_TIME = 7_200_000L; // 2μ‹œκ°„
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sopt.org.hmh.domain.app.domain;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -16,6 +17,7 @@ public class ChallengeApp extends App {
@JoinColumn(name = "challenge_id")
private Challenge challenge;

@NotNull(message = "λͺ©ν‘œ μ‹œκ°„μ€ null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
private Long goalTime;

@Builder
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/sopt/org/hmh/domain/app/domain/HistoryApp.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sopt.org.hmh.domain.app.domain;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -16,7 +17,10 @@ public class HistoryApp extends App {
@JoinColumn(name = "daily_challenge_id")
private DailyChallenge dailyChallenge;

@NotNull(message = "μ‚¬μš© μ‹œκ°„μ€ null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
private Long usageTime;

@NotNull(message = "λͺ©ν‘œ μ‹œκ°„μ€ null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
private Long goalTime;

@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ public enum AppError implements ErrorBase {

APP_NOT_FOUND(HttpStatus.NOT_FOUND, "앱을 찾을 수 μ—†μŠ΅λ‹ˆλ‹€."),
APP_EXIST_ALREADY(HttpStatus.CONFLICT, "이미 μΆ”κ°€λœ μ•±μž…λ‹ˆλ‹€."),
INVALID_APP_CODE_NULL(HttpStatus.BAD_REQUEST, "μ•± μ½”λ“œ 값이 λΉ„μ–΄μžˆμŠ΅λ‹ˆλ‹€"),
INVALID_TIME_RANGE(HttpStatus.BAD_REQUEST, "μ•± μ‹œκ°„μ˜ λ²”μœ„κ°€ μœ νš¨ν•œμ§€ ν™•μΈν•΄μ£Όμ„Έμš”"),
INVALID_TIME_NULL(HttpStatus.BAD_REQUEST, "μ•± μ‹œκ°„μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”"),
INVALID_GOAL_TIME(HttpStatus.BAD_REQUEST, "μ•± λͺ©ν‘œ μ‹œκ°„μ΄ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€."),
;

private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sopt.org.hmh.domain.app.dto.request;

import jakarta.validation.constraints.NotNull;

public record AppRemoveRequest(
@NotNull(message = "μ•± μ½”λ“œλŠ” null일 수 μ—†μŠ΅λ‹ˆλ‹€.")
String appCode
) {
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package sopt.org.hmh.domain.app.dto.request;

import jakarta.validation.Valid;
import java.util.List;

public record ChallengeAppArrayRequest(
List<ChallengeAppRequest> apps
List<@Valid ChallengeAppRequest> apps
) {
}
Loading

0 comments on commit 420ae4a

Please sign in to comment.