Skip to content

Commit

Permalink
Merge pull request #602 from woowacourse-teams/develop
Browse files Browse the repository at this point in the history
Release v.1.4.0
  • Loading branch information
InKyoJeong authored Oct 5, 2022
2 parents a764166 + 6b34271 commit a566cd6
Show file tree
Hide file tree
Showing 74 changed files with 1,275 additions and 275 deletions.
34 changes: 34 additions & 0 deletions .github/release-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name-template: "v$RESOLVED_VERSION"
tag-template: "v$RESOLVED_VERSION"
categories:
- title: "🚀 Features"
labels:
- "🌟기능"
- ":star2:기능"
- title: "🐛 Bug Fixes"
labels:
- "🐞수정"
- ":lady_beetle:수정"
- title: "🪃 Trouble Shooting"
labels:
- "🪃트러블슈팅"
- ":boomerang:트러블슈팅"
change-template: "- $TITLE (#$NUMBER)"
change-title-escapes: '\<*_&'
version-resolver:
major:
labels:
- "major"
minor:
labels:
- "minor"
patch:
labels:
- "patch"
default: patch
template: |
$CHANGES
<br>
$CONTRIBUTORS
21 changes: 21 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: 티타임 릴리즈 자동화

on:
push:
branches: [main]

permissions:
contents: read

jobs:
update_release_draft:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@v5
with:
config-name: release-config.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public ResponseEntity<List<ScheduleFindResponse>> findOwnSchedules(@CoachAuthent

@PutMapping("/me/schedules")
public ResponseEntity<Void> updateSchedules(@CoachAuthenticationPrincipal Long coachId,
@RequestBody ScheduleUpdateRequest request) {
scheduleService.update(coachId, request);
@RequestBody List<ScheduleUpdateRequest> requests) {
scheduleService.update(coachId, requests);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.woowacourse.teatime.teatime.controller.dto.response;

import com.woowacourse.teatime.teatime.domain.Coach;
import com.woowacourse.teatime.teatime.repository.dto.CoachWithPossible;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -15,8 +18,16 @@ public class CoachFindResponse {
private String name;
private String description;
private String image;
private Boolean isPossible;

public CoachFindResponse(Coach coach) {
this(coach.getId(), coach.getName(), coach.getDescription(), coach.getImage());
public CoachFindResponse(Coach coach, boolean isPossible) {
this(coach.getId(), coach.getName(), coach.getDescription(), coach.getImage(), isPossible);
}

public static List<CoachFindResponse> of(List<CoachWithPossible> coachWithPossibles) {
return coachWithPossibles.stream()
.map(c -> new CoachFindResponse(c.getId(), c.getName(), c.getDescription(), c.getImage(),
c.getPossible()))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,43 @@
package com.woowacourse.teatime.teatime.domain;

import com.woowacourse.teatime.teatime.exception.InvalidProfileInfoException;
import com.woowacourse.teatime.teatime.repository.dto.CoachWithPossible;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.ColumnResult;
import javax.persistence.ConstructorResult;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedNativeQuery;
import javax.persistence.SqlResultSetMapping;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
@SqlResultSetMapping(
name = "CoachWithPossibleMapping",
classes = @ConstructorResult(
targetClass = CoachWithPossible.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "name", type = String.class),
@ColumnResult(name = "description", type = String.class),
@ColumnResult(name = "image", type = String.class),
@ColumnResult(name = "possible", type = Boolean.class),
}
)
)
@NamedNativeQuery(
name = "findCoaches",
query = "SELECT c.id AS id, c.name AS name, c.description AS description, c.image AS image, EXISTS ("
+ "SELECT * FROM schedule s2 WHERE s2.coach_id = c.id AND s2.local_date_time > NOW() AND s2.is_possible = TRUE ) AS possible "
+ "FROM coach c",
resultSetMapping = "CoachWithPossibleMapping")
public class Coach {

public static final String PREFIX_DESCRIPTION = "안녕하세요~ ";
Expand All @@ -32,7 +55,7 @@ public class Coach {
@Column(nullable = false)
private String email;

@Lob
@Column(nullable = false, length = 60)
private String description;

private String image;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.woowacourse.teatime.teatime.repository;

import com.woowacourse.teatime.teatime.domain.Coach;
import com.woowacourse.teatime.teatime.repository.dto.CoachWithPossible;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface CoachRepository extends JpaRepository<Coach, Long> {

Optional<Coach> findByEmail(String email);

@Query(name = "findCoaches", nativeQuery = true)
List<CoachWithPossible> findCoaches();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ public interface ReservationRepository extends JpaRepository<Reservation, Long>
List<Reservation> findAllByCrewIdLatestOrder(Long crewId);

@Query("SELECT r FROM Reservation AS r "
+ "INNER JOIN r.schedule AS s "
+ "INNER JOIN s.coach AS c "
+ "ON c.id = :coachId "
+ "JOIN FETCH r.schedule AS s "
+ "JOIN FETCH r.crew AS cr "
+ "INNER JOIN s.coach AS co "
+ "ON co.id = :coachId "
+ "WHERE r.reservationStatus NOT IN :status")
List<Reservation> findAllByCoachIdAndStatusNot(Long coachId, ReservationStatus status);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.woowacourse.teatime.teatime.repository.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CoachWithPossible {

private Long id;
private String name;
private String description;
private String image;
private Boolean possible;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,18 @@ public void remindReservation() {
List<Reservation> reservations = reservationRepository.findAllApprovedReservationsBetween(findFirstTime(date),
findLastTime(date));
for (Reservation reservation : reservations) {
requestAlarm(SlackAlarmDto.remindCoach(reservation));
requestAlarm(SlackAlarmDto.remindCrew(reservation));
requestAlarm(SlackAlarmDto.alarmToCoach(reservation, AlarmTitle.REMIND_COACH));
requestAlarm(SlackAlarmDto.alarmToCrew(reservation, AlarmTitle.REMIND_CREW));
}
}

public void alertSheetSubmitted(Reservation reservation) {
SlackAlarmDto crewAlarmDto = SlackAlarmDto.alarmToCrew(reservation, AlarmTitle.SUBMIT_SHEET_TO_CREW);
requestAlarm(crewAlarmDto);
SlackAlarmDto coachAlarmDto = SlackAlarmDto.alarmToCoach(reservation, AlarmTitle.SUBMIT_SHEET_TO_COACH);
requestAlarm(coachAlarmDto);
}

private void requestAlarm(SlackAlarmDto alarmDto) {
try {
botClient.post()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

public enum AlarmTitle {

APPLY("☕️티타임이 신청되었습니다.", "#CCE6BA"),
CONFIRM("✅티타임이 확정되었습니다.", "#B4E0FF"),
CANCEL("🥹아이쿠...! 티타임이 취소되었습니다..", "#E6ACA8"),
REMIND_CREW("⏰내일 티타임이 있습니다. 시트를 잊지 말고 제출해주세요!!", "#FFE594"),
REMIND_COACH("⏰내일 티타임이 있습니다.", "#FF2594");
APPLY("☕️ 티타임이 신청되었습니다.", "#CCE6BA"),
CONFIRM("✅ 티타임이 확정되었습니다.", "#B4E0FF"),
SUBMIT_SHEET_TO_CREW("📝 시트가 제출되었습니다.", "#9498FF"),
SUBMIT_SHEET_TO_COACH("📝 방금 크루가 시트를 제출했어요! 한번 확인하러 가볼까요?", "#9498FF"),
CANCEL("🥹 아이쿠...! 티타임이 취소되었습니다..", "#E6ACA8"),
REMIND_CREW("⏰ 내일 티타임이 있습니다. 시트를 잊지 말고 제출해주세요!!", "#FFE594"),
REMIND_COACH("⏰ 내일 티타임이 있습니다.", "#FFE594");

private final String message;
private final String barColor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import com.woowacourse.teatime.teatime.domain.Coach;
import com.woowacourse.teatime.teatime.exception.NotFoundCoachException;
import com.woowacourse.teatime.teatime.repository.CoachRepository;
import com.woowacourse.teatime.teatime.repository.ScheduleRepository;
import com.woowacourse.teatime.teatime.repository.dto.CoachWithPossible;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -19,13 +20,12 @@
public class CoachService {

private final CoachRepository coachRepository;
private final ScheduleRepository scheduleRepository;

@Transactional(readOnly = true)
public List<CoachFindResponse> findAll() {
List<Coach> coaches = coachRepository.findAll();
return coaches.stream()
.map(CoachFindResponse::new)
.collect(Collectors.toList());
List<CoachWithPossible> coachWithPossibles = coachRepository.findCoaches();
return CoachFindResponse.of(coachWithPossibles);
}

public Long save(CoachSaveRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,13 @@ public List<CoachFindCrewHistoryResponse> findCrewHistoryByCoach(Long crewId) {
public void updateSheetStatusToSubmitted(Long crewId, Long reservationId, SheetStatus status) {
Reservation reservation = reservationRepository.findById(reservationId)
.orElseThrow(NotFoundReservationException::new);
validateCrewAuthorization(crewId, reservation);
Crew crew = crewRepository.findById(crewId)
.orElseThrow(NotFoundCrewException::new);
validateCrewAuthorization(crew.getId(), reservation);

if (SUBMITTED.equals(status)) {
reservation.updateSheetStatusToSubmitted();
alarmService.alertSheetSubmitted(reservation);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ public List<ScheduleFindResponse> find(Long coachId, ScheduleFindRequest request
return ScheduleFindResponse.from(schedules);
}

public void update(Long coachId, ScheduleUpdateRequest request) {
deleteAllByCoachAndDate(coachId, request);
saveAllByCoachAndDate(coachId, request);
public void update(Long coachId, List<ScheduleUpdateRequest> requests) {
for (ScheduleUpdateRequest request : requests) {
deleteAllByCoachAndDate(coachId, request);
saveAllByCoachAndDate(coachId, request);
}
}

private void deleteAllByCoachAndDate(Long coachId, ScheduleUpdateRequest request) {
Expand All @@ -60,8 +62,7 @@ private void deleteAllByCoachAndDate(Long coachId, ScheduleUpdateRequest request

private void validateDeletable(Long coachId, ScheduleUpdateRequest request, LocalDateTime start,
LocalDateTime end) {
Coach coach = findCoach(coachId);
List<Schedule> newSchedules = toSchedules(request, coach);
List<Schedule> newSchedules = toSchedules(request, findCoach(coachId));
List<Schedule> oldSchedules = scheduleRepository
.findAllByCoachIdBetween(coachId, start, end);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.woowacourse.teatime.teatime.service.dto;

import static com.woowacourse.teatime.teatime.service.AlarmTitle.REMIND_COACH;
import static com.woowacourse.teatime.teatime.service.AlarmTitle.REMIND_CREW;

import com.woowacourse.teatime.teatime.domain.Coach;
import com.woowacourse.teatime.teatime.domain.Crew;
import com.woowacourse.teatime.teatime.domain.Reservation;
Expand All @@ -20,6 +17,8 @@
@AllArgsConstructor
public class SlackAlarmDto {

private static final String DIRECT_LINK = "<https://teatime.pe.kr/|티타임 바로가기>";

private String channel;
private String text;
private List<AttachmentDto> attachments;
Expand All @@ -32,24 +31,25 @@ public static List<SlackAlarmDto> of(AlarmInfoDto alarmInfoDto, AlarmTitle alarm
new SlackAlarmDto(alarmInfoDto.getCrewSlackId(), alarmTitle.getMessage(), List.of(attachmentDto)));
}

public static SlackAlarmDto remindCoach(Reservation reservation) {
public static SlackAlarmDto alarmToCoach(Reservation reservation, AlarmTitle alarmTitle) {
Crew crew = reservation.getCrew();
Coach coach = reservation.getCoach();
String message = getMessage(crew.getName(), coach.getName(), reservation.getScheduleDateTime());
AttachmentDto attachmentDto = new AttachmentDto(REMIND_COACH.getBarColor(), message);
return new SlackAlarmDto(coach.getSlackId(), REMIND_COACH.getMessage(), List.of(attachmentDto));
AttachmentDto attachmentDto = new AttachmentDto(alarmTitle.getBarColor(), message);
return new SlackAlarmDto(coach.getSlackId(), alarmTitle.getMessage(), List.of(attachmentDto));
}

public static SlackAlarmDto remindCrew(Reservation reservation) {
public static SlackAlarmDto alarmToCrew(Reservation reservation, AlarmTitle alarmTitle) {
Crew crew = reservation.getCrew();
Coach coach = reservation.getCoach();
String message = getMessage(crew.getName(), coach.getName(), reservation.getScheduleDateTime());
AttachmentDto attachmentDto = new AttachmentDto(REMIND_CREW.getBarColor(), message);
return new SlackAlarmDto(crew.getSlackId(), REMIND_CREW.getMessage(), List.of(attachmentDto));
AttachmentDto attachmentDto = new AttachmentDto(alarmTitle.getBarColor(), message);
return new SlackAlarmDto(crew.getSlackId(), alarmTitle.getMessage(), List.of(attachmentDto));
}

private static String getMessage(String crewName, String coachName, LocalDateTime dateTime) {
return String.join("\r\n",
DIRECT_LINK,
"크루: " + crewName,
"코치: " + coachName,
"티타임: " + Date.formatDate("yyyy-MM-dd HH:mm", dateTime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ void updateByCoachAndDate() {
ExtractableResponse<Response> updateResponse = RestAssured.given(super.spec).log().all()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.header("Authorization", "Bearer " + coachToken)
.body(request)
.body(List.of(request))
.filter(document("update-schedule", requestFields(
fieldWithPath("date").description("날짜"),
fieldWithPath("schedules").description("스케줄")
fieldWithPath("[].date").description("날짜"),
fieldWithPath("[].schedules").description("스케줄")
)))
.when().put("/api/v2/coaches/me/schedules")
.then().log().all()
Expand All @@ -140,7 +140,7 @@ void updateByCoachAndDate() {

if (IS_LAST_DAY_OF_MONTH) {
assertAll(
() -> assertThat(updateResponse.statusCode()).isEqualTo(HttpStatus.OK.value()),
() -> assertThat(updateResponse.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()),
() -> assertThat(result).hasSize(1)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ void findCoaches() throws Exception {

given(coachService.findAll())
.willReturn(List.of(
new CoachFindResponse(COACH_BROWN),
new CoachFindResponse(COACH_JASON)
new CoachFindResponse(COACH_BROWN, true),
new CoachFindResponse(COACH_JASON, false)
));

//when
Expand Down
Loading

0 comments on commit a566cd6

Please sign in to comment.