Skip to content

Commit

Permalink
Merge pull request #205 from ku-ring/develop
Browse files Browse the repository at this point in the history
version 2.8.0
  • Loading branch information
zbqmgldjfh authored Aug 4, 2024
2 parents 935c6bd + e5c1d67 commit b65837d
Show file tree
Hide file tree
Showing 40 changed files with 1,046 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
package com.kustacks.kuring.admin.adapter.in.web;

import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.ADMIN_REAL_NOTICE_CREATE_SUCCESS;
import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.ADMIN_TEST_NOTICE_CREATE_SUCCESS;

import com.google.firebase.database.annotations.NotNull;
import com.kustacks.kuring.admin.adapter.in.web.dto.RealNotificationRequest;
import com.kustacks.kuring.admin.adapter.in.web.dto.TestNotificationRequest;
import com.kustacks.kuring.admin.application.port.in.AdminCommandUseCase;
import com.kustacks.kuring.admin.application.port.in.dto.RealNotificationCommand;
import com.kustacks.kuring.admin.domain.AdminRole;
import com.kustacks.kuring.alert.adapter.in.web.dto.AlertCreateRequest;
import com.kustacks.kuring.alert.application.port.in.dto.AlertCreateCommand;
import com.kustacks.kuring.auth.authorization.AuthenticationPrincipal;
import com.kustacks.kuring.auth.context.Authentication;
import com.kustacks.kuring.auth.secured.Secured;
import com.kustacks.kuring.common.dto.BaseResponse;
import com.kustacks.kuring.common.utils.converter.StringToDateTimeConverter;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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 org.springframework.web.bind.annotation.*;

import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.ADMIN_REAL_NOTICE_CREATE_SUCCESS;
import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.ADMIN_TEST_NOTICE_CREATE_SUCCESS;

@Tag(name = "Admin-Command", description = "관리자가 주체가 되는 정보 수정")
@Validated
Expand Down Expand Up @@ -59,6 +61,33 @@ public ResponseEntity<BaseResponse<String>> createRealNotice(
return ResponseEntity.ok().body(new BaseResponse<>(ADMIN_REAL_NOTICE_CREATE_SUCCESS, null));
}

@Operation(summary = "예약 알림 등록", description = "서버에 예약 알림을 등록한다")
@SecurityRequirement(name = "JWT")
@Secured(AdminRole.ROLE_ROOT)
@PostMapping("/alerts")
public ResponseEntity<BaseResponse<String>> createAlert(
@RequestBody AlertCreateRequest request
) {
AlertCreateCommand command = new AlertCreateCommand(
request.title(), request.content(),
StringToDateTimeConverter.convert(request.alertTime())
);

adminCommandUseCase.addAlertSchedule(command);
return ResponseEntity.ok().body(new BaseResponse<>(ADMIN_REAL_NOTICE_CREATE_SUCCESS, null));
}

@Operation(summary = "예약 알림 삭제", description = "서버에 예약되어 있는 특정 알림을 삭제한다")
@SecurityRequirement(name = "JWT")
@Secured(AdminRole.ROLE_ROOT)
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/alerts/{id}")
public void cancelAlert(
@Parameter(description = "알림 아이디") @NotNull @PathVariable("id") Long id
) {
adminCommandUseCase.cancelAlertSchedule(id);
}

@Hidden
@Secured(AdminRole.ROLE_ROOT)
@GetMapping("/subscribe/all")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.kustacks.kuring.admin.adapter.in.web;

import com.kustacks.kuring.admin.adapter.in.web.dto.AdminAlertResponse;
import com.kustacks.kuring.admin.application.port.in.AdminQueryUseCase;
import com.kustacks.kuring.admin.domain.AdminRole;
import com.kustacks.kuring.auth.authorization.AuthenticationPrincipal;
Expand All @@ -25,8 +26,7 @@

import java.util.List;

import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.AUTH_AUTHENTICATION_SUCCESS;
import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.FEEDBACK_SEARCH_SUCCESS;
import static com.kustacks.kuring.common.dto.ResponseCodeAndMessages.*;

@Tag(name = "Admin-Query", description = "관리자가 주체가 되는 정보 조회")
@Validated
Expand All @@ -43,11 +43,24 @@ public class AdminQueryApiV2 {
@GetMapping("/feedbacks")
public ResponseEntity<BaseResponse<List<AdminFeedbacksResult>>> getFeedbacks(
@Parameter(description = "페이지") @RequestParam(name = "page") @Min(0) int page,
@Parameter(description = "단일 페이지의 사이즈, 1 ~ 30까지 허용") @RequestParam(name = "size") @Min(1) @Max(30) int size) {
@Parameter(description = "단일 페이지의 사이즈, 1 ~ 30까지 허용") @RequestParam(name = "size") @Min(1) @Max(30) int size
) {
List<AdminFeedbacksResult> feedbacks = adminQueryUseCase.lookupFeedbacks(page, size);
return ResponseEntity.ok().body(new BaseResponse<>(FEEDBACK_SEARCH_SUCCESS, feedbacks));
}

@Operation(summary = "예약 알림 조회", description = "어드민이 등록한 모든 예약 알림을 조회한다")
@SecurityRequirement(name = "JWT")
@Secured(AdminRole.ROLE_ROOT)
@GetMapping("/alerts")
public ResponseEntity<BaseResponse<List<AdminAlertResponse>>> getAlerts(
@Parameter(description = "페이지") @RequestParam(name = "page") @Min(0) int page,
@Parameter(description = "단일 페이지의 사이즈, 1 ~ 30까지 허용") @RequestParam(name = "size") @Min(1) @Max(30) int size
) {
List<AdminAlertResponse> alerts = adminQueryUseCase.lookupAlerts(page, size);
return ResponseEntity.ok().body(new BaseResponse<>(ALERT_SEARCH_SUCCESS, alerts));
}

/**
* Root 이상만 호출 가능한 테스트 API
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.kustacks.kuring.admin.adapter.in.web.dto;

import com.kustacks.kuring.alert.domain.AlertStatus;

import java.time.LocalDateTime;

public record AdminAlertResponse(
Long id,
String title,
String content,
AlertStatus status,
LocalDateTime wakeTime
) {
public static AdminAlertResponse of(
Long id, String title, String content,
AlertStatus status, LocalDateTime alertTime
) {
return new AdminAlertResponse(id, title, content, status, alertTime);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.kustacks.kuring.admin.adapter.out.event;

import com.kustacks.kuring.admin.application.port.out.AdminAlertEventPort;
import com.kustacks.kuring.alert.adapter.in.event.dto.AlertCreateEvent;
import com.kustacks.kuring.alert.adapter.in.event.dto.AlertDeleteEvent;
import com.kustacks.kuring.common.domain.Events;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
public class AdminAdminAlertEventAdapter implements AdminAlertEventPort {

@Override
public void addAlertSchedule(String title, String content, LocalDateTime alertTime) {
Events.raise(new AlertCreateEvent(title, content, alertTime));
}

@Override
public void cancelAlertSchedule(Long id) {
Events.raise(new AlertDeleteEvent(id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

import com.kustacks.kuring.admin.application.port.in.dto.RealNotificationCommand;
import com.kustacks.kuring.admin.application.port.in.dto.TestNotificationCommand;
import com.kustacks.kuring.alert.application.port.in.dto.AlertCreateCommand;

public interface AdminCommandUseCase {
void createTestNotice(TestNotificationCommand command);
void createRealNoticeForAllUser(RealNotificationCommand command);
void subscribeAllUserSameTopic();

void addAlertSchedule(AlertCreateCommand command);

void cancelAlertSchedule(Long id);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.kustacks.kuring.admin.application.port.in;

import com.kustacks.kuring.admin.adapter.in.web.dto.AdminAlertResponse;
import com.kustacks.kuring.user.application.port.in.dto.AdminFeedbacksResult;

import java.util.List;

public interface AdminQueryUseCase {
List<AdminFeedbacksResult> lookupFeedbacks(int page, int size);

List<AdminAlertResponse> lookupAlerts(int page, int size);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.kustacks.kuring.admin.application.port.out;

import java.time.LocalDateTime;

public interface AdminAlertEventPort {
void addAlertSchedule(String title, String content, LocalDateTime alertTime);

void cancelAlertSchedule(Long id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.kustacks.kuring.admin.application.port.out;

import com.kustacks.kuring.alert.domain.Alert;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface AdminAlertQueryPort {
Page<Alert> findAllAlertByPageRequest(Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import com.kustacks.kuring.admin.application.port.in.AdminCommandUseCase;
import com.kustacks.kuring.admin.application.port.in.dto.RealNotificationCommand;
import com.kustacks.kuring.admin.application.port.in.dto.TestNotificationCommand;
import com.kustacks.kuring.admin.application.port.out.AdminAlertEventPort;
import com.kustacks.kuring.admin.application.port.out.AdminEventPort;
import com.kustacks.kuring.admin.application.port.out.AdminUserFeedbackPort;
import com.kustacks.kuring.admin.domain.Admin;
import com.kustacks.kuring.alert.application.port.in.dto.AlertCreateCommand;
import com.kustacks.kuring.auth.userdetails.UserDetailsServicePort;
import com.kustacks.kuring.common.annotation.UseCase;
import com.kustacks.kuring.common.properties.ServerProperties;
Expand All @@ -29,6 +31,7 @@ public class AdminCommandService implements AdminCommandUseCase {

private final UserDetailsServicePort userDetailsServicePort;
private final AdminUserFeedbackPort adminUserFeedbackPort;
private final AdminAlertEventPort adminAlertEventPort;
private final AdminEventPort adminEventPort;
private final NoticeProperties noticeProperties;
private final ServerProperties serverProperties;
Expand Down Expand Up @@ -66,6 +69,16 @@ public void createRealNoticeForAllUser(RealNotificationCommand command) {
adminEventPort.sendNotificationByAdmin(command.title(), command.body(), command.url());
}

@Override
public void addAlertSchedule(AlertCreateCommand command) {
adminAlertEventPort.addAlertSchedule(command.title(), command.content(), command.alertTime());
}

@Override
public void cancelAlertSchedule(Long id) {
adminAlertEventPort.cancelAlertSchedule(id);
}

/**
* TODO : 1회성 API - client v2 배포 후, 단 한번 모든 사용자를 공통 topic에 구독시킨 후 제거 예정
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.kustacks.kuring.admin.application.service;

import com.kustacks.kuring.admin.adapter.in.web.dto.AdminAlertResponse;
import com.kustacks.kuring.admin.application.port.in.AdminQueryUseCase;
import com.kustacks.kuring.admin.application.port.out.AdminAlertQueryPort;
import com.kustacks.kuring.admin.application.port.out.AdminUserFeedbackPort;
import com.kustacks.kuring.common.annotation.UseCase;
import com.kustacks.kuring.user.application.port.in.dto.AdminFeedbacksResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
Expand All @@ -17,6 +20,7 @@
public class AdminQueryService implements AdminQueryUseCase {

private final AdminUserFeedbackPort adminUserFeedbackPort;
private final AdminAlertQueryPort adminAlertQueryPort;

@Transactional(readOnly = true)
@Override
Expand All @@ -31,4 +35,19 @@ public List<AdminFeedbacksResult> lookupFeedbacks(int page, int size) {
))
.toList();
}

@Override
public List<AdminAlertResponse> lookupAlerts(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Order.desc("createdAt")));
return adminAlertQueryPort.findAllAlertByPageRequest(pageRequest)
.stream()
.map(alert -> AdminAlertResponse.of(
alert.getId(),
alert.getTitle(),
alert.getContent(),
alert.getStatus(),
alert.getAlertTime()
))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.kustacks.kuring.alert.adapter.in.event;

import com.kustacks.kuring.alert.adapter.in.event.dto.AlertCreateEvent;
import com.kustacks.kuring.alert.adapter.in.event.dto.AlertDeleteEvent;
import com.kustacks.kuring.alert.application.port.in.AlertCommandUseCase;
import com.kustacks.kuring.alert.application.port.in.dto.AlertCreateCommand;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class AlertCommandEventListener {

private final AlertCommandUseCase alertCommandUseCase;

@EventListener
public void createAlert(
AlertCreateEvent event
) {
AlertCreateCommand command = new AlertCreateCommand(
event.title(), event.content(), event.alertTime()
);

alertCommandUseCase.addAlertSchedule(command);
}

@EventListener
public void cancelAlert(
AlertDeleteEvent event
) {
alertCommandUseCase.cancelAlertSchedule(event.id());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.kustacks.kuring.alert.adapter.in.event.dto;

import java.time.LocalDateTime;

public record AlertCreateEvent(
String title,
String content,
LocalDateTime alertTime
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.kustacks.kuring.alert.adapter.in.event.dto;

public record AlertDeleteEvent(
Long id
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.kustacks.kuring.alert.adapter.in.web;

import com.google.firebase.database.annotations.NotNull;
import com.kustacks.kuring.alert.adapter.in.web.dto.AlertCreateRequest;
import com.kustacks.kuring.alert.application.port.in.AlertCommandUseCase;
import com.kustacks.kuring.alert.application.port.in.dto.AlertCreateCommand;
import com.kustacks.kuring.common.annotation.RestWebAdapter;
import com.kustacks.kuring.common.utils.converter.StringToDateTimeConverter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@Tag(name = "Alert-Command", description = "알림 에약")
@Validated
@RequiredArgsConstructor
@RestWebAdapter(path = "/api/v2/alerts")
public class AlertCommandApiV2 {

private final AlertCommandUseCase alertCommandUseCase;

@Operation(summary = "예약 알림 등록", description = "서버에 예약 알림을 등록한다")
@PostMapping
public void createAlert(
@RequestBody AlertCreateRequest request
) {
AlertCreateCommand command = new AlertCreateCommand(
request.title(), request.content(),
StringToDateTimeConverter.convert(request.alertTime())
);

alertCommandUseCase.addAlertSchedule(command);
}

@Operation(summary = "예약 알림 삭제", description = "서버에 예약되어 있는 특정 알림을 삭제한다")
@DeleteMapping("/{id}")
public void cancelAlert(
@Parameter(description = "알림 아이디") @NotNull @PathVariable Long id
) {
alertCommandUseCase.cancelAlertSchedule(id);
}
}
Loading

0 comments on commit b65837d

Please sign in to comment.