Skip to content

Commit

Permalink
release: 0.5.6 (#232)
Browse files Browse the repository at this point in the history
* fix: 충돌 해결 (#210)

* fix: 소셜 로그인 에러 긴급 수정 (#214) (#215)

* feat: 기존 회원 리뷰 조회 API 로직 변경 (#218)

* feat: userId 에 해당하는 유저 리뷰 조회 API 로직 변경 (#217)

* test: 통합테스트 수정 (#217)

* test: 단위테스트 수정 (#217)

* docs: readme 작성 (#222)

* docs: readme 작성

* docs: readme 수정

* test: QA용 EndMeetingAlerted를 발행한다

* feat: 유저가 삭제되었을때, 알람토큰도 삭제하도록 수정 (#226)

* feat: 유저가 삭제되었을때, 알람토큰도 삭제하도록 수정한다

* test: ApplicationEventPublisher 바인딩 안되는 테스트 삭제

* refactor: UserDeletedEvent 핸들러 이름 변경

* test: 친구조회 테스트 수정

* refactor: code smell을 제거한다

* fix: 모임 시작, 종료 알림이 모임 참여자가 3명 이상이 아니라면, 발행되지않도록 수정 (#231)

* feat: 리뷰 등록시 모임 참여 유저 조회 API 수정 (#229)

* refactor: MeetingController getCurrentUserId() 메소드로 통일 (#228)

* feat: 리뷰에 자신 포함 확인 로직 추가 (#195)

* feat: 모임 참여자 자신 포함 여부 확인 로직 추가(#228)

* test: 단위 테스트 추가 (#228)

* test: 통합 테스트 수정 및 실패 케이스 추가 (#228)

* refactor: title, body alert data에 추가

---------

Co-authored-by: ddingmin <[email protected]>
Co-authored-by: ChoiDongKuen <[email protected]>
  • Loading branch information
3 people authored Feb 16, 2024
1 parent e6222bc commit b81a396
Show file tree
Hide file tree
Showing 11 changed files with 349 additions and 80 deletions.
2 changes: 2 additions & 0 deletions src/main/java/net/teumteum/alert/infra/FcmAlertPublisher.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ private Message buildMessage(String token, Alert alert, Map<String, String> data
.setToken(token)
.setNotification(buildNotification(alert))
.setAndroidConfig(buildAndroidConfig(alert))
.putData("title", alert.getTitle())
.putData("body", alert.getBody())
.putData("publishedAt", alert.getCreatedAt().toString())
.putData("userId", alert.getUserId().toString())
.putData("type", alert.getType().toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -43,14 +43,14 @@ public class MeetingController {
public MeetingResponse createMeeting(
@RequestPart @Valid CreateMeetingRequest meetingRequest,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.createMeeting(images, meetingRequest, userId);
}

@GetMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public MeetingResponse getMeetingById(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingById(meetingId, userId);
}

Expand All @@ -64,7 +64,7 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
@RequestParam(value = "participantUserId", required = false) Long participantUserId,
@RequestParam(value = "isBookmarked", required = false) Boolean isBookmarked,
@RequestParam(value = "searchWord", required = false) String searchWord) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingsBySpecification(pageable, topic, meetingAreaStreet, participantUserId,
searchWord, isBookmarked, isOpen, userId);
}
Expand All @@ -74,55 +74,56 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
public MeetingResponse updateMeeting(@PathVariable Long meetingId,
@RequestPart @Valid UpdateMeetingRequest request,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.updateMeeting(meetingId, images, request, userId);
}

@DeleteMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public void deleteMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.deleteMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.CREATED)
public MeetingResponse addParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.addParticipant(meetingId, userId);
}

@DeleteMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public void deleteParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelParticipant(meetingId, userId);
}

@GetMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public List<MeetingParticipantsResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
return meetingService.getParticipants(meetingId);
public List<MeetingParticipantResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
Long userId = getCurrentUserId();
return meetingService.getParticipants(meetingId, userId);
}

@PostMapping("/{meetingId}/reports")
@ResponseStatus(HttpStatus.CREATED)
public void reportMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.reportMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.CREATED)
public void addBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.addBookmark(meetingId, userId);
}

@DeleteMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.OK)
public void deleteBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelBookmark(meetingId, userId);
}

Expand All @@ -132,4 +133,8 @@ public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ill
Sentry.captureException(illegalArgumentException);
return ErrorResponse.of(illegalArgumentException);
}

private Long getCurrentUserId() {
return securityService.getCurrentUserId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import net.teumteum.user.domain.User;

public record MeetingParticipantsResponse(
public record MeetingParticipantResponse(
Long id,
Long characterId,
String name,
String job
) {

public static MeetingParticipantsResponse of(
public static MeetingParticipantResponse of(
User user
) {
return new MeetingParticipantsResponse(
return new MeetingParticipantResponse(
user.getId(),
user.getCharacterId(),
user.getName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@Transactional(readOnly = true)
public class MeetingAlertPublisher {

private static final String KR_TIME_ZONE = "Asia/Seoul";
private static final String EVERY_ONE_MINUTES = "0 * * * * *";
private static final String EVERY_12PM = "0 0 12 * * *";

Expand All @@ -24,18 +25,20 @@ public class MeetingAlertPublisher {

@Scheduled(cron = EVERY_ONE_MINUTES)
public void alertBeforeMeeting() {
var alertStart = LocalDateTime.now(ZoneId.of("Asia/Seoul")).plusMinutes(5).withNano(0).withSecond(0);
var alertStart = LocalDateTime.now(ZoneId.of(KR_TIME_ZONE)).plusMinutes(5).withNano(0).withSecond(0);
var alertEnd = alertStart.plusMinutes(1).withNano(0).withSecond(0);
var alertTargets = meetingRepository.findAlertMeetings(alertStart, alertEnd);
alertTargets.forEach(meeting -> eventPublisher.publishEvent(
new BeforeMeetingAlerted(meeting.getParticipantUserIds())
)
);
alertTargets.stream()
.filter(alertTarget -> alertTarget.getParticipantUserIds().size() > 2)
.forEach(meeting -> eventPublisher.publishEvent(
new BeforeMeetingAlerted(meeting.getParticipantUserIds())
)
);
}

@Scheduled(cron = EVERY_12PM)
public void alertEndMeeting() {
var today = LocalDateTime.now(ZoneId.of("Asia/Seoul"))
var today = LocalDateTime.now(ZoneId.of(KR_TIME_ZONE))
.withNano(0)
.withSecond(0)
.withMinute(0)
Expand All @@ -44,14 +47,16 @@ public void alertEndMeeting() {
var yesterday = today.minusDays(1);

var alertTargets = meetingRepository.findAlertMeetings(yesterday, today);
alertTargets.forEach(meeting -> eventPublisher.publishEvent(
new EndMeetingAlerted(meeting.getId(), meeting.getTitle(), meeting.getParticipantUserIds())
));
alertTargets.stream()
.filter(alertTarget -> alertTarget.getParticipantUserIds().size() > 2)
.forEach(meeting -> eventPublisher.publishEvent(
new EndMeetingAlerted(meeting.getId(), meeting.getTitle(), meeting.getParticipantUserIds())
));
}

@Scheduled(cron = EVERY_ONE_MINUTES)
public void alertEndMeetingForQa() {
var today = LocalDateTime.now(ZoneId.of("Asia/Seoul"))
var today = LocalDateTime.now(ZoneId.of(KR_TIME_ZONE))
.withNano(0)
.withSecond(0)
.withMinute(0)
Expand All @@ -61,8 +66,10 @@ public void alertEndMeetingForQa() {
var yesterday = today.minusDays(365);

var alertTargets = meetingRepository.findAlertMeetings(yesterday, future);
alertTargets.forEach(meeting -> eventPublisher.publishEvent(
new EndMeetingAlerted(meeting.getId(), meeting.getTitle(), meeting.getParticipantUserIds())
));
alertTargets.stream()
.filter(alertTarget -> alertTarget.getParticipantUserIds().size() > 2)
.forEach(meeting -> eventPublisher.publishEvent(
new EndMeetingAlerted(meeting.getId(), meeting.getTitle(), meeting.getParticipantUserIds())
));
}
}
18 changes: 14 additions & 4 deletions src/main/java/net/teumteum/meeting/service/MeetingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -94,7 +94,8 @@ public void deleteMeeting(Long meetingId, Long userId) {
}

@Transactional(readOnly = true)
public PageDto<MeetingsResponse> getMeetingsBySpecification(Pageable pageable, Topic topic, String meetingAreaStreet,
public PageDto<MeetingsResponse> getMeetingsBySpecification(Pageable pageable, Topic topic,
String meetingAreaStreet,
Long participantUserId, String searchWord, Boolean isBookmarked, Boolean isOpen, Long userId) {

Specification<Meeting> spec = MeetingSpecification.withIsOpen(isOpen);
Expand Down Expand Up @@ -153,13 +154,16 @@ public void cancelParticipant(Long meetingId, Long userId) {
}

@Transactional(readOnly = true)
public List<MeetingParticipantsResponse> getParticipants(Long meetingId) {
public List<MeetingParticipantResponse> getParticipants(Long meetingId, Long userId) {
var existMeeting = getMeeting(meetingId);

checkMeetingContainUser(existMeeting, userId);

return existMeeting.getParticipantUserIds().stream()
.filter(id -> !id.equals(userId))
.map(userConnector::findUserById)
.flatMap(Optional::stream)
.map(MeetingParticipantsResponse::of)
.map(MeetingParticipantResponse::of)
.toList();
}

Expand Down Expand Up @@ -207,4 +211,10 @@ public void reportMeeting(Long meetingId, Long userId) {
throw new IllegalArgumentException("모임 개설자는 모임을 신고할 수 없습니다.");
}
}

private void checkMeetingContainUser(Meeting meeting, Long userId) {
if (!meeting.getParticipantUserIds().contains(userId)) {
throw new IllegalArgumentException("모임에 참여하지 않은 회원입니다.");
}
}
}
Loading

0 comments on commit b81a396

Please sign in to comment.