Skip to content

Commit 9ef1185

Browse files
committed
feat: 스프린트 수정
1 parent d1f3a4a commit 9ef1185

34 files changed

Lines changed: 239 additions & 201 deletions

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ dependencies {
8282

8383
//validation
8484
implementation ("org.springframework.boot:spring-boot-starter-validation")
85-
85+
implementation("com.ibm.icu:icu4j:75.1")
8686
}
8787

8888
kotlin {

src/main/java/com/official/memento/global/handler/GlobalExceptionHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.official.memento.global.exception.*;
77
import io.jsonwebtoken.ExpiredJwtException;
88
import io.jsonwebtoken.io.DecodingException;
9+
import jakarta.servlet.http.HttpServletRequest;
910
import org.slf4j.Logger;
1011
import org.slf4j.LoggerFactory;
1112
import org.springframework.http.HttpStatus;
@@ -86,7 +87,7 @@ public ResponseEntity<ErrorResponse> mementoException(final MementoException exc
8687
}
8788

8889
@ExceptionHandler(RuntimeException.class)
89-
public ResponseEntity<ErrorResponse> runtimeException(final RuntimeException exception) {
90+
public ResponseEntity<ErrorResponse> runtimeException(final RuntimeException exception, final HttpServletRequest request) {
9091
logger.error("Runtime exception occurred ", exception);
9192
alarmSendUseCase.sendException(new AlarmExceptionCommand(exception));
9293
return ErrorResponse.of(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCode.INTERNAL_SERVER_ERROR);

src/main/java/com/official/memento/global/util/Validator.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,28 @@
22

33
import static com.official.memento.global.exception.ErrorCode.INVALID_JSON_FORMAT;
44

5+
import com.ibm.icu.text.BreakIterator;
6+
import com.ibm.icu.util.ULocale;
57
import com.official.memento.global.exception.InvalidRequestBodyException;
6-
import java.text.BreakIterator;
8+
79

810
public class Validator {
911

1012
public static void validateLengthContainEmoji(final String text, final int maxLength) {
11-
BreakIterator iterator = BreakIterator.getCharacterInstance();
13+
if (text == null) {
14+
return;
15+
}
16+
17+
// ICU4J BreakIterator: "character" = grapheme cluster
18+
BreakIterator iterator = BreakIterator.getCharacterInstance(ULocale.ROOT);
1219
iterator.setText(text);
1320

1421
int count = 0;
15-
while (BreakIterator.DONE != iterator.next()) {
22+
int boundary = iterator.first();
23+
while ((boundary = iterator.next()) != BreakIterator.DONE) {
1624
count++;
1725
}
26+
1827
if (count > maxLength) {
1928
throw new InvalidRequestBodyException(INVALID_JSON_FORMAT);
2029
}

src/main/java/com/official/memento/member/controller/MemberPersonalInfoApiController.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
import com.official.memento.member.controller.dto.MemberTimeZoneUpdateRequest;
88
import com.official.memento.member.controller.dto.MemberUptimeDto;
99
import com.official.memento.member.controller.dto.MemberUptimeUpdateRequest;
10+
import com.official.memento.member.controller.dto.MemberWindDownUpdateRequest;
1011
import com.official.memento.member.domain.MemberPersonalInfo;
1112
import com.official.memento.member.service.command.MemberPersonalInfoCommand;
1213
import com.official.memento.member.service.command.MemberTimeZoneUpdateCommand;
1314
import com.official.memento.member.service.command.MemberUpTimeUpdateCommand;
15+
import com.official.memento.member.service.command.MemberWindDownUpdateCommand;
1416
import com.official.memento.member.service.usecase.MemberPersonalInfoGetUseCase;
1517
import com.official.memento.member.service.usecase.MemberPersonalInfoUpdateUseCase;
18+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
1619
import lombok.RequiredArgsConstructor;
1720
import org.springframework.http.HttpStatus;
1821
import org.springframework.http.ResponseEntity;
@@ -50,8 +53,8 @@ public ResponseEntity<SuccessResponse<MemberUptimeDto>> getUpTime(
5053
@Authorization final AuthorizationUser authorizationUser) {
5154
final MemberPersonalInfo personalInfo = memberPersonalInfoGetUseCase.retrieveUptime(authorizationUser.memberId());
5255
final MemberUptimeDto response = MemberUptimeDto.of(
53-
personalInfo.getWakeUpTime().toString(),
54-
personalInfo.getWindDownTime().toString()
56+
personalInfo.getWakeUpTime(),
57+
personalInfo.getWindDownTime()
5558
);
5659
return SuccessResponse.of(HttpStatus.OK, "사용자 업타임 조회 성공", response);
5760
}
@@ -77,4 +80,15 @@ public ResponseEntity<SuccessResponse<?>> updateUpTime(
7780
));
7881
return SuccessResponse.of(HttpStatus.OK, "사용자 기상 시간 업데이트 성공");
7982
}
83+
84+
@PatchMapping("/wind-down")
85+
public ResponseEntity<SuccessResponse<?>> updateWindDown(
86+
@Authorization AuthorizationUser authorizationUser,
87+
@RequestBody final MemberWindDownUpdateRequest request) {
88+
memberPersonalInfoUpdateUseCase.updateWindDown(MemberWindDownUpdateCommand.of(
89+
authorizationUser.memberId(),
90+
request.windDownTime()
91+
));
92+
return SuccessResponse.of(HttpStatus.OK, "사용자 취침 시간 업데이트 성공");
93+
}
8094
}

src/main/java/com/official/memento/member/controller/MemberPersonalInfoApiDocs.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.official.memento.member.controller.dto.MemberPersonalInfoRequest;
77
import com.official.memento.member.controller.dto.MemberUptimeDto;
88
import com.official.memento.member.controller.dto.MemberUptimeUpdateRequest;
9+
import com.official.memento.member.controller.dto.MemberWindDownUpdateRequest;
910
import io.swagger.v3.oas.annotations.Operation;
1011
import io.swagger.v3.oas.annotations.Parameter;
1112
import io.swagger.v3.oas.annotations.enums.ParameterIn;
@@ -45,16 +46,30 @@ ResponseEntity<SuccessResponse<MemberUptimeDto>> getUpTime(
4546
@Parameter(name = "Authorization", in = ParameterIn.HEADER, description = "Bearer Token", required = true, example = "Bearer access_token")
4647
@Authorization final AuthorizationUser authorizationUser);
4748

48-
@Operation(summary = "사용자 업타임 업데이트")
49+
@Operation(summary = "사용자 기상 시간 업데이트")
4950
@ApiResponses(
5051
value = {
51-
@ApiResponse(responseCode = "200", description = "회원 업타임 업데이트 성공"),
52-
@ApiResponse(responseCode = "400", description = "회원 업타임 업데이트 실패", content = @Content),
52+
@ApiResponse(responseCode = "200", description = "회원 기상 시간 업데이트 성공"),
53+
@ApiResponse(responseCode = "400", description = "회원 기상 시간 업데이트 실패", content = @Content),
5354
@ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", content = @Content)
5455
}
5556
)
5657
ResponseEntity<SuccessResponse<?>> updateUpTime(
5758
@Parameter(name = "Authorization", in = ParameterIn.HEADER, description = "Bearer Token", required = true, example = "Bearer access_token")
5859
@Authorization final AuthorizationUser authorizationUser,
5960
@RequestBody final MemberUptimeUpdateRequest request);
61+
62+
@Operation(summary = "사용자 취침 시간 업데이트")
63+
@ApiResponses(
64+
value = {
65+
@ApiResponse(responseCode = "200", description = "회원 취침 시간 업데이트 성공"),
66+
@ApiResponse(responseCode = "400", description = "회원 취침 시간 업데이트 실패", content = @Content),
67+
@ApiResponse(responseCode = "500", description = "INTERNAL SERVER ERROR", content = @Content)
68+
}
69+
)
70+
ResponseEntity<SuccessResponse<?>> updateWindDown(
71+
@Parameter(name = "Authorization", in = ParameterIn.HEADER, description = "Bearer Token", required = true, example = "Bearer access_token")
72+
@Authorization final AuthorizationUser authorizationUser,
73+
@RequestBody final MemberWindDownUpdateRequest request);
6074
}
75+
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.official.memento.member.controller.dto;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4+
import java.time.LocalTime;
5+
import java.time.format.DateTimeFormatter;
46

57
@Schema(name = "사용자 업타임 조회 응답")
68
public record MemberUptimeDto(
@@ -9,7 +11,8 @@ public record MemberUptimeDto(
911
@Schema(description = "일정 마무리 시간", example = "22:30")
1012
String windDownTime
1113
) {
12-
public static MemberUptimeDto of(String wakeUpTime, String windDownTime) {
13-
return new MemberUptimeDto(wakeUpTime, windDownTime);
14+
public static MemberUptimeDto of(LocalTime wakeUpTime, LocalTime windDownTime) {
15+
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("HH:mm");
16+
return new MemberUptimeDto(wakeUpTime.format(f1), windDownTime.format(f1));
1417
}
1518
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.official.memento.member.controller.dto;
2+
3+
public record MemberWindDownUpdateRequest(
4+
String windDownTime
5+
) {
6+
}

src/main/java/com/official/memento/member/domain/MemberPersonalInfo.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,19 @@ public MemberPersonalInfo updateUpTime(final LocalTime wakeUpTime) {
130130
this.isPreferReminder,
131131
this.isImportantBreaks);
132132
}
133+
134+
public MemberPersonalInfo updateWindDownTime(final LocalTime windDownTime) {
135+
return MemberPersonalInfo.withId(
136+
this.id,
137+
this.memberId,
138+
this.wakeUpTime,
139+
windDownTime,
140+
this.timeZoneOffset,
141+
this.job,
142+
this.jobOtherDetail,
143+
this.isStressedUnorganizedSchedule,
144+
this.isForgetImportantThings,
145+
this.isPreferReminder,
146+
this.isImportantBreaks);
147+
}
133148
}

src/main/java/com/official/memento/member/service/MemberPersonalInfoService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.official.memento.member.service.command.MemberPersonalInfoCreateCommand;
99
import com.official.memento.member.service.command.MemberTimeZoneUpdateCommand;
1010
import com.official.memento.member.service.command.MemberUpTimeUpdateCommand;
11+
import com.official.memento.member.service.command.MemberWindDownUpdateCommand;
1112
import com.official.memento.member.service.result.MemberPersonalInfoResult;
1213
import com.official.memento.member.service.usecase.MemberPersonalInfoCreateUseCase;
1314
import com.official.memento.member.service.usecase.MemberPersonalInfoDeleteUseCase;
@@ -69,6 +70,12 @@ public void updateUpTime(final MemberUpTimeUpdateCommand command){
6970
memberPersonalInfoRepository.update(memberPersonalInfo.updateUpTime(command.wakeUpTime()));
7071
}
7172

73+
@Override
74+
public void updateWindDown(final MemberWindDownUpdateCommand command){
75+
MemberPersonalInfo memberPersonalInfo = memberPersonalInfoRepository.findByMemberId(command.memberId());
76+
memberPersonalInfoRepository.update(memberPersonalInfo.updateWindDownTime(command.windDownTime()));
77+
}
78+
7279
@Override
7380
@Transactional(readOnly = true)
7481
public MemberPersonalInfo retrieveUptime(final long memberId) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.official.memento.member.service.command;
2+
3+
import java.time.LocalTime;
4+
5+
public record MemberWindDownUpdateCommand(
6+
long memberId,
7+
LocalTime windDownTime
8+
) {
9+
public static MemberWindDownUpdateCommand of(
10+
final long memberId,
11+
final String windDownTime
12+
){
13+
return new MemberWindDownUpdateCommand(
14+
memberId,
15+
LocalTime.parse(windDownTime)
16+
);
17+
}
18+
}

0 commit comments

Comments
 (0)