Skip to content

Commit

Permalink
[BE] 확정 약속 조회 시 hostName 정보 추가 (#281)
Browse files Browse the repository at this point in the history
* refactor: 확정 약속 조회할 때 hostName 정보 추가

* refactor: 반복문 -> stream

* refactor: HOST_NOT_FOUND 에러 메시지 수정

* docs: swagger 에러 코드 추가

- ApiErrorResponse.InternalServerError 추가

* refactor: availableAttendeesOf 메서드 반환값 AttendeeGroup으로 변경
  • Loading branch information
seunghye218 authored Aug 22, 2024
1 parent 9a7f81a commit 01f92d5
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,18 @@
@interface NotFound {
@AliasFor(annotation = ApiResponse.class, attribute = "description") String value() default "";
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Operation
@ApiResponse(
responseCode = "500",
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = CustomProblemDetail.class)
)
)
@interface InternalServerError {
@AliasFor(annotation = ApiResponse.class, attribute = "description") String value() default "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ ResponseEntity<MomoApiResponse<MeetingConfirmResponse>> confirm(
| NOT_FOUND_MEETING | 존재하지 않는 약속 정보 입니다. |
| NOT_CONFIRMED | 아직 확정되지 않은 약속입니다. |
""")
@ApiErrorResponse.InternalServerError(ERROR_CODE_TABLE_HEADER + """
| HOST_NOT_FOUND | 약속의 주최자 정보를 찾을 수 없습니다. 관리자에게 문의하세요. |
""")
MomoApiResponse<ConfirmedMeetingResponse> findConfirmedMeeting(
@PathVariable @Schema(description = "약속 UUID") String uuid
);
Expand Down
13 changes: 13 additions & 0 deletions backend/src/main/java/kr/momo/domain/attendee/AttendeeGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.IntStream;
import kr.momo.exception.MomoException;
Expand Down Expand Up @@ -79,6 +80,18 @@ public boolean isSameSize(AttendeeGroup attendeeGroup) {
return attendees.size() == attendeeGroup.size();
}

public Optional<Attendee> findHost() {
return attendees.stream()
.dropWhile(attendee -> !attendee.isHost())
.findFirst();
}

public List<String> names() {
return attendees.stream()
.map(Attendee::name)
.toList();
}

@Override
public boolean equals(Object object) {
if (this == object) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Map;
import kr.momo.domain.BaseEntity;
import kr.momo.domain.attendee.Attendee;
import kr.momo.domain.attendee.AttendeeGroup;
import kr.momo.domain.schedule.Schedule;
import lombok.AccessLevel;
import lombok.Getter;
Expand Down Expand Up @@ -51,15 +52,16 @@ public ConfirmedMeeting(Meeting meeting, LocalDateTime startDateTime, LocalDateT
this.endDateTime = endDateTime;
}

public List<Attendee> availableAttendeesOf(List<Schedule> schedules) {
public AttendeeGroup availableAttendeesOf(List<Schedule> schedules) {
Map<Attendee, Long> groupAttendeeByScheduleCount = schedules.stream()
.filter(this::isScheduleWithinDateTimeRange)
.collect(groupingBy(Schedule::getAttendee, counting()));

long confirmedTimeSlotCount = countTimeSlotOfConfirmedMeeting();
return groupAttendeeByScheduleCount.keySet().stream()
List<Attendee> availableAttendees = groupAttendeeByScheduleCount.keySet().stream()
.filter(key -> groupAttendeeByScheduleCount.get(key) == confirmedTimeSlotCount)
.toList();
return new AttendeeGroup(availableAttendees);
}

private boolean isScheduleWithinDateTimeRange(Schedule schedule) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public enum AttendeeErrorCode implements ErrorCodeType {
NOT_FOUND_ATTENDEE(HttpStatus.NOT_FOUND, "해당 약속에 참여하는 참가자 정보가 없습니다."),
ACCESS_DENIED(HttpStatus.FORBIDDEN, "접근이 거부되었습니다."),
DUPLICATED_ATTENDEE_NAME(HttpStatus.BAD_REQUEST, "참여자의 이름이 중복됩니다."),
INVALID_ATTENDEE_SIZE(HttpStatus.BAD_REQUEST, "참여자의 수는 최소 1명입니다.");
INVALID_ATTENDEE_SIZE(HttpStatus.BAD_REQUEST, "참여자의 수는 최소 1명입니다."),
HOST_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR, "약속의 주최자 정보를 찾을 수 없습니다. 관리자에게 문의하세요."),;

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.time.LocalDateTime;
import java.util.List;
import kr.momo.domain.attendee.Attendee;
import kr.momo.domain.attendee.AttendeeGroup;
import kr.momo.domain.attendee.AttendeeRepository;
import kr.momo.domain.availabledate.AvailableDateRepository;
import kr.momo.domain.availabledate.AvailableDates;
Expand Down Expand Up @@ -107,12 +108,13 @@ public ConfirmedMeetingResponse findByUuid(String uuid) {
ConfirmedMeeting confirmedMeeting = confirmedMeetingRepository.findByMeeting(meeting)
.orElseThrow(() -> new MomoException(MeetingErrorCode.NOT_CONFIRMED));

List<Attendee> attendees = attendeeRepository.findAllByMeeting(meeting);
List<Schedule> schedules = scheduleRepository.findAllByAttendeeIn(attendees);
AttendeeGroup attendees = new AttendeeGroup(attendeeRepository.findAllByMeeting(meeting));
Attendee host = attendees.findHost()
.orElseThrow(() -> new MomoException(AttendeeErrorCode.HOST_NOT_FOUND));
List<Schedule> schedules = scheduleRepository.findAllByAttendeeIn(attendees.getAttendees());
AttendeeGroup availableAttendees = confirmedMeeting.availableAttendeesOf(schedules);

attendees = confirmedMeeting.availableAttendeesOf(schedules);

return ConfirmedMeetingResponse.from(meeting, attendees, confirmedMeeting);
return ConfirmedMeetingResponse.from(meeting, host, availableAttendees, confirmedMeeting);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import java.util.List;
import java.util.Locale;
import kr.momo.domain.attendee.Attendee;
import kr.momo.domain.attendee.AttendeeGroup;
import kr.momo.domain.meeting.ConfirmedMeeting;
import kr.momo.domain.meeting.Meeting;

public record ConfirmedMeetingResponse(
String meetingName,
String hostName,
List<String> availableAttendeeNames,
@JsonFormat(pattern = "yyyy-MM-dd", shape = Shape.STRING)
LocalDate startDate,
Expand All @@ -27,11 +29,12 @@ public record ConfirmedMeetingResponse(
) {

public static ConfirmedMeetingResponse from(
Meeting meeting, List<Attendee> attendees, ConfirmedMeeting confirmedMeeting
Meeting meeting, Attendee host, AttendeeGroup attendees, ConfirmedMeeting confirmedMeeting
) {
return new ConfirmedMeetingResponse(
meeting.getName(),
attendees.stream().map(Attendee::name).toList(),
host.name(),
attendees.names(),
confirmedMeeting.getStartDateTime().toLocalDate(),
confirmedMeeting.getStartDateTime().toLocalTime(),
confirmedMeeting.getStartDateTime().getDayOfWeek().getDisplayName(TextStyle.NARROW, Locale.KOREAN),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ void confirmScheduleUnlock() {
@Test
void confirmInvalidRequest() {
Meeting meeting = createLockedMovieMeeting();
AvailableDate availableDate = availableDateRepository.save(new AvailableDate(LocalDate.now().plusDays(1), meeting));
AvailableDate availableDate = availableDateRepository.save(
new AvailableDate(LocalDate.now().plusDays(1), meeting));
String tomorrow = availableDate.getDate().format(DateTimeFormatter.ISO_DATE);
Attendee guest = attendeeRepository.save(AttendeeFixture.GUEST_MARK.create(meeting));
String token = getToken(guest, meeting);
Expand Down Expand Up @@ -490,6 +491,7 @@ void findConfirmedMeeting() {
Meeting meeting = MeetingFixture.MOVIE.create();
meeting.lock();
meeting = meetingRepository.save(meeting);
attendeeRepository.save(AttendeeFixture.HOST_JAZZ.create(meeting));
confirmedMeetingRepository.save(ConfirmedMeetingFixture.MOVIE.create(meeting));

RestAssured.given().log().all()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.time.LocalTime;
import java.util.List;
import kr.momo.domain.attendee.Attendee;
import kr.momo.domain.attendee.AttendeeGroup;
import kr.momo.domain.availabledate.AvailableDate;
import kr.momo.domain.schedule.Schedule;
import kr.momo.domain.timeslot.Timeslot;
Expand Down Expand Up @@ -37,7 +38,8 @@ void availableAttendeesOf() {
new Schedule(attendee2, new AvailableDate(today, meeting), Timeslot.TIME_0000)
);

List<Attendee> attendees = confirmedMeeting.availableAttendeesOf(schedules);
AttendeeGroup availableAttendees = confirmedMeeting.availableAttendeesOf(schedules);
List<Attendee> attendees = availableAttendees.getAttendees();

assertAll(
() -> assertThat(attendees).hasSize(1),
Expand Down

0 comments on commit 01f92d5

Please sign in to comment.