Skip to content

Commit

Permalink
πŸš€ :: Api-v0.1.3
Browse files Browse the repository at this point in the history
πŸš€ :: Api-v0.1.3
  • Loading branch information
ImNM authored Feb 8, 2023
2 parents 674d99a + 9d34dfa commit 747aec9
Show file tree
Hide file tree
Showing 43 changed files with 413 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import band.gosrock.domain.domains.user.adaptor.UserAdaptor;
import band.gosrock.domain.domains.user.domain.RefreshTokenEntity;
import band.gosrock.domain.domains.user.domain.User;
import band.gosrock.domain.domains.user.service.UserDomainService;
import lombok.RequiredArgsConstructor;

@UseCase
Expand All @@ -17,6 +18,7 @@ public class RefreshUseCase {
private final UserAdaptor userAdaptor;
private final JwtTokenProvider jwtTokenProvider;

private final UserDomainService userDomainService;
private final RefreshTokenAdaptor refreshTokenAdaptor;

private final TokenGenerateHelper tokenGenerateHelper;
Expand All @@ -29,7 +31,8 @@ public TokenAndUserResponse execute(String refreshToken) {
jwtTokenProvider.parseRefreshToken(savedRefreshTokenEntity.getRefreshToken());

User user = userAdaptor.queryUser(refreshUserId);

// λ¦¬ν”„λ ˆμ‰¬ μ‹œμ—λ„ last둜그인 정보 μ—…λ°μ΄νŠΈ
userDomainService.loginUser(user.getOauthInfo());
return tokenGenerateHelper.execute(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import band.gosrock.domain.domains.user.domain.RefreshTokenEntity;
import band.gosrock.domain.domains.user.domain.User;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@Helper
@RequiredArgsConstructor
Expand All @@ -18,6 +19,7 @@ public class TokenGenerateHelper {

private final RefreshTokenAdaptor refreshTokenAdaptor;

@Transactional
public TokenAndUserResponse execute(User user) {
String newAccessToken =
jwtTokenProvider.generateAccessToken(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,31 @@
import band.gosrock.api.comment.service.RetrieveCommentUseCase;
import band.gosrock.api.comment.service.RetrieveRandomCommentUseCase;
import band.gosrock.api.common.slice.SliceResponse;
import band.gosrock.common.annotation.DisableSwaggerSecurity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SecurityRequirement(name = "access-token")
@Tag(name = "응원톑 컨트둀러")
@RestController
@RequestMapping("/v1/events/{eventId}/comments")
@Validated
@RequiredArgsConstructor
public class CommentController {

Expand All @@ -53,6 +58,7 @@ public CreateCommentResponse postComment(
return createCommentUseCase.execute(eventId, createCommentRequest);
}

@DisableSwaggerSecurity
@Operation(summary = "응원글을 μ‘°νšŒν•©λ‹ˆλ‹€.")
@GetMapping
public SliceResponse<RetrieveCommentDTO> getComments(
Expand All @@ -67,15 +73,19 @@ public void deleteComment(@PathVariable Long eventId, @PathVariable Long comment
deleteCommentUseCase.execute(eventId, commentId);
}

@DisableSwaggerSecurity
@Operation(summary = "응원글 개수λ₯Ό μΉ΄μš΄νŒ…ν•©λ‹ˆλ‹€.")
@GetMapping(value = "/counts")
public RetrieveCommentCountResponse getCommentCounts(@PathVariable Long eventId) {
return retrieveCommentCountUseCase.execute(eventId);
}

@DisableSwaggerSecurity
@Operation(summary = "응원글을 랜덀으둜 λ½‘μ•„μ˜΅λ‹ˆλ‹€.")
@GetMapping(value = "/random")
public RetrieveRandomCommentResponse getRandomComment(@PathVariable Long eventId) {
return retrieveRandomCommentUseCase.execute(eventId);
public RetrieveRandomCommentResponse getRandomComment(
@PathVariable Long eventId,
@RequestParam @Min(value = 1L, message = "limit 값은 0보닀 컀야 ν•©λ‹ˆλ‹€.") Long limit) {
return retrieveRandomCommentUseCase.execute(eventId, limit);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import band.gosrock.domain.domains.comment.dto.condition.CommentCondition;
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.user.domain.User;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Slice;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -49,8 +50,8 @@ public RetrieveCommentCountResponse toRetrieveCommentCountResponse(Long commentC
return RetrieveCommentCountResponse.of(commentCount);
}

public RetrieveRandomCommentResponse toRetrieveRandomCommentResponse(Comment comment) {
return RetrieveRandomCommentResponse.of(comment);
public RetrieveRandomCommentResponse toRetrieveRandomCommentResponse(List<Comment> comments) {
return RetrieveRandomCommentResponse.of(comments);
}

private RetrieveCommentDTO toRetrieveCommentDTO(Comment comment, Long currentUserId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@

import band.gosrock.domain.common.vo.CommentInfoVo;
import band.gosrock.domain.domains.comment.domain.Comment;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class RetrieveRandomCommentResponse {

private final CommentInfoVo commentInfo;
private final List<CommentInfoVo> commentInfos;

public static RetrieveRandomCommentResponse of(Comment comment) {
public static RetrieveRandomCommentResponse of(List<Comment> comments) {
return RetrieveRandomCommentResponse.builder()
.commentInfo(comment.toCommentInfoVo())
.commentInfos(comments.stream().map(Comment::toCommentInfoVo).toList())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import band.gosrock.domain.domains.comment.domain.Comment;
import band.gosrock.domain.domains.event.adaptor.EventAdaptor;
import band.gosrock.domain.domains.event.domain.Event;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -22,9 +23,9 @@ public class RetrieveRandomCommentUseCase {
private final EventAdaptor eventAdaptor;

@Transactional(readOnly = true)
public RetrieveRandomCommentResponse execute(Long eventId) {
public RetrieveRandomCommentResponse execute(Long eventId, Long limit) {
Event event = eventAdaptor.findById(eventId);
Comment comment = commentAdaptor.queryRandomComment(event.getId());
return commentMapper.toRetrieveRandomCommentResponse(comment);
List<Comment> comments = commentAdaptor.queryRandomComment(event.getId(), limit);
return commentMapper.toRetrieveRandomCommentResponse(comments);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


import band.gosrock.api.config.security.SecurityUtils;
import band.gosrock.api.config.slack.SlackApiProvider;
import band.gosrock.api.slack.sender.SlackInternalErrorSender;
import band.gosrock.common.dto.ErrorReason;
import band.gosrock.common.dto.ErrorResponse;
import band.gosrock.common.exception.BaseErrorCode;
Expand Down Expand Up @@ -39,7 +39,7 @@
@RequiredArgsConstructor
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

private final SlackApiProvider slackApiProvider;
private final SlackInternalErrorSender slackInternalErrorSender;
// /** Json λ‚ μ§œ ν˜•μ‹ νŒŒμ‹±μ— λŒ€ν•œ μ—λŸ¬ ν•Έλ“€λŸ¬ */
// @ExceptionHandler({ InvalidFormatException.class, DateTimeParseException.class})
// public ResponseEntity<ErrorResponse> JsonParseExceptionHandler(
Expand Down Expand Up @@ -181,7 +181,7 @@ protected ResponseEntity<ErrorResponse> handleException(Exception e, HttpServlet
internalServerError.getReason(),
url);

slackApiProvider.sendError(cachingRequest, e, userId);
slackInternalErrorSender.execute(cachingRequest, e, userId);
return ResponseEntity.status(HttpStatus.valueOf(internalServerError.getStatus()))
.body(errorResponse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.permitAll()
.mvcMatchers(HttpMethod.GET, "/v1/events/{eventId:[\\d+]}/ticketItems")
.permitAll()
.mvcMatchers(HttpMethod.GET, "/v1/events/{eventId:[\\d+]}/comments/**")
.permitAll()
.mvcMatchers(HttpMethod.POST, "/v1/coupons/campaigns")
.hasRole("SUPER_ADMIN")
.anyRequest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class EventController {
private final UpdateEventBasicUseCase updateEventBasicUseCase;
private final UpdateEventDetailUseCase updateEventDetailUseCase;
private final UpdateEventStatusUseCase updateEventStatusUseCase;
private final OpenEventUseCase openEventStatusUseCase;

@Operation(summary = "μžμ‹ μ΄ 관리 쀑인 이벀트 리슀트λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.")
@GetMapping
Expand Down Expand Up @@ -79,7 +80,13 @@ public EventResponse updateEventDetail(
return updateEventDetailUseCase.execute(eventId, updateEventDetailRequest);
}

@Operation(summary = "곡연 μƒνƒœλ₯Ό λ³€κ²½ν•©λ‹ˆλ‹€.")
@Operation(summary = "곡연을 μ˜€ν”ˆ μƒνƒœλ‘œ λ³€κ²½ν•©λ‹ˆλ‹€. λͺ¨λ“  체크리슀트λ₯Ό 달성해야 ν•©λ‹ˆλ‹€.")
@PatchMapping("/{eventId}/open")
public EventResponse updateEventStatus(@PathVariable Long eventId) {
return openEventStatusUseCase.execute(eventId);
}

@Operation(summary = "곡연 μƒνƒœλ₯Ό λ³€κ²½ν•©λ‹ˆλ‹€. (OPEN μ œμ™Έ)")
@PatchMapping("/{eventId}/status")
public EventResponse updateEventStatus(
@PathVariable Long eventId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javax.validation.constraints.Positive;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.hibernate.validator.constraints.Length;

@Getter
@RequiredArgsConstructor
Expand All @@ -19,6 +20,7 @@ public class CreateEventRequest {

@Schema(defaultValue = "고슀락 제 22회 정기곡연", description = "곡연 이름")
@NotBlank(message = "곡연 이름을 μž…λ ₯ν•˜μ„Έμš”")
@Length(max = 25)
private String name;

@Schema(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import javax.validation.constraints.Positive;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.hibernate.validator.constraints.Length;

@Getter
@RequiredArgsConstructor
public class UpdateEventBasicRequest {
@Schema(defaultValue = "고슀락 제 22회 정기곡연", description = "곡연 이름")
@NotBlank(message = "곡연 이름을 μž…λ ₯ν•˜μ„Έμš”")
@Length(max = 25)
private String name;

@Schema(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package band.gosrock.api.event.service;

import static band.gosrock.api.common.aop.hostRole.FindHostFrom.EVENT_ID;
import static band.gosrock.api.common.aop.hostRole.HostQualification.MANAGER;

import band.gosrock.api.common.aop.hostRole.HostRolesAllowed;
import band.gosrock.api.event.model.dto.response.EventResponse;
import band.gosrock.common.annotation.UseCase;
import band.gosrock.domain.domains.event.adaptor.EventAdaptor;
import band.gosrock.domain.domains.event.domain.Event;
import band.gosrock.domain.domains.event.service.EventService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class OpenEventUseCase {
private final EventService eventService;
private final EventAdaptor eventAdaptor;

@Transactional
@HostRolesAllowed(role = MANAGER, findHostFrom = EVENT_ID)
public EventResponse execute(Long eventId) {
final Event event = eventAdaptor.findById(eventId);
return EventResponse.of(eventService.openEvent(event));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
import band.gosrock.common.annotation.Phone;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.hibernate.validator.constraints.Length;

/** 호슀트 κ°„νŽΈ 생성 μš”μ²­ DTO */
@Getter
@RequiredArgsConstructor
public class CreateHostRequest {
@Schema(defaultValue = "고슀락", description = "호슀트 이름")
@NotEmpty(message = "호슀트 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”")
@NotBlank(message = "호슀트 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”")
@Length(max = 15)
private String name;

@Schema(defaultValue = "[email protected]", description = "λ§ˆμŠ€ν„° 이메일")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,68 +1,40 @@
package band.gosrock.api.config.slack;
package band.gosrock.api.slack.sender;

import static com.slack.api.model.block.Blocks.divider;
import static com.slack.api.model.block.Blocks.section;
import static com.slack.api.model.block.composition.BlockCompositions.plainText;

import band.gosrock.infrastructure.config.slack.SlackProvider;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.SlackApiException;
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
import com.slack.api.model.block.Blocks;
import com.slack.api.model.block.LayoutBlock;
import com.slack.api.model.block.composition.MarkdownTextObject;
import com.slack.api.model.block.composition.TextObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;

@Component
@RequiredArgsConstructor
@Slf4j
public class SlackApiProvider {
private final MethodsClient methodsClient;
public class SlackInternalErrorSender {
private final ObjectMapper objectMapper;

private final Environment env;
private final SlackProvider slackProvider;

private final List<String> sendAlarmProfiles = List.of("staging", "prod");

@Value("${slack.webhook.id}")
private String CHANNEL_ID;

private final int MAX_LEN = 500;

@Async
public void sendError(ContentCachingRequestWrapper cachingRequest, Exception e, Long userId)
throws IOException {
String[] activeProfiles = env.getActiveProfiles();
List<String> currentProfile = Arrays.stream(activeProfiles).toList();
if (CollectionUtils.containsAny(sendAlarmProfiles, currentProfile)) {
executeSendError(cachingRequest, e, userId);
}
}

private void executeSendError(
ContentCachingRequestWrapper cachingRequest, Exception e, Long userId)
public void execute(ContentCachingRequestWrapper cachingRequest, Exception e, Long userId)
throws IOException {
final String url = cachingRequest.getRequestURL().toString();
final String method = cachingRequest.getMethod();
final String body =
objectMapper.readTree(cachingRequest.getContentAsByteArray()).toString();
final String exceptionAsString = Arrays.toString(e.getStackTrace());
final int cutLength = Math.min(exceptionAsString.length(), MAX_LEN);

final String errorMessage = e.getMessage();
final String errorStack = exceptionAsString.substring(0, cutLength);
String errorStack = slackProvider.getErrorStack(e);
final String errorUserIP = cachingRequest.getRemoteAddr();

List<LayoutBlock> layoutBlocks = new ArrayList<>();
Expand Down Expand Up @@ -99,16 +71,6 @@ private void executeSendError(
layoutBlocks.add(
section(section -> section.fields(List.of(errorNameMarkdown, errorStackMarkdown))));

ChatPostMessageRequest chatPostMessageRequest =
ChatPostMessageRequest.builder()
.channel(CHANNEL_ID)
.text("")
.blocks(layoutBlocks)
.build();
try {
methodsClient.chatPostMessage(chatPostMessageRequest);
} catch (SlackApiException slackApiException) {
log.error(slackApiException.toString());
}
slackProvider.sendNotification(layoutBlocks);
}
}
Loading

0 comments on commit 747aec9

Please sign in to comment.