Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] feat: 발자국 삭제 및 발자국 상태 수동 변경 구현 #460

Merged
merged 3 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

public enum ErrorCode {

// TODO: 추가 필요
DEFAULT_ERROR_CODE,
FAILED_LOAD_SERVER_FIREBASE_CREDENTIALS,
INVALID_FIREBASE_CREDENTIALS,
FILE_SIZE_EXCEED,
NOT_ALLOW_OTHER_FOOTPRINT_CHANGE,
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
import com.happy.friendogly.common.ApiResponse;
import com.happy.friendogly.footprint.dto.request.FindNearFootprintRequest;
import com.happy.friendogly.footprint.dto.request.SaveFootprintRequest;
import com.happy.friendogly.footprint.dto.request.UpdateWalkStatusRequest;
import com.happy.friendogly.footprint.dto.request.UpdateWalkStatusAutoRequest;
import com.happy.friendogly.footprint.dto.response.FindMyLatestFootprintTimeAndPetExistenceResponse;
import com.happy.friendogly.footprint.dto.response.FindNearFootprintResponse;
import com.happy.friendogly.footprint.dto.response.FindOneFootprintResponse;
import com.happy.friendogly.footprint.dto.response.SaveFootprintResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusAutoResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusManualResponse;
import com.happy.friendogly.footprint.service.FootprintCommandService;
import com.happy.friendogly.footprint.service.FootprintQueryService;
import jakarta.validation.Valid;
import java.net.URI;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -54,7 +56,6 @@ public ApiResponse<FindOneFootprintResponse> findOne(
@Auth Long memberId,
@PathVariable Long footprintId
) {
// TODO: 추후 토큰에서 memberId를 가져오도록 변경
FindOneFootprintResponse response = footprintQueryService.findOne(memberId, footprintId);
return ApiResponse.ofSuccess(response);
}
Expand All @@ -64,7 +65,6 @@ public ApiResponse<List<FindNearFootprintResponse>> findNear(
@Auth Long memberId,
@Valid FindNearFootprintRequest request
) {
// TODO: 추후 토큰에서 memberId를 가져오도록 변경
List<FindNearFootprintResponse> response = footprintQueryService.findNear(memberId, request);
return ApiResponse.ofSuccess(response);
}
Expand All @@ -73,18 +73,34 @@ public ApiResponse<List<FindNearFootprintResponse>> findNear(
public ApiResponse<FindMyLatestFootprintTimeAndPetExistenceResponse> findMyLatestFootprintTimeAndPetExistence(
@Auth Long memberId
) {
// TODO: 추후 토큰에서 memberId를 가져오도록 변경
FindMyLatestFootprintTimeAndPetExistenceResponse response
= footprintQueryService.findMyLatestFootprintTimeAndPetExistence(memberId);
return ApiResponse.ofSuccess(response);
}

@PatchMapping("/walk-status")
public ApiResponse<UpdateWalkStatusResponse> updateWalkStatus(
@PatchMapping("/recent/walk-status/auto")
public ApiResponse<UpdateWalkStatusAutoResponse> updateWalkStatusAuto(
@Auth Long memberId,
@Valid @RequestBody UpdateWalkStatusRequest request
@Valid @RequestBody UpdateWalkStatusAutoRequest request
) {
UpdateWalkStatusResponse walkStatusResponse = footprintCommandService.updateWalkStatus(memberId, request);
return ApiResponse.ofSuccess(walkStatusResponse);
UpdateWalkStatusAutoResponse response = footprintCommandService.updateWalkStatusAuto(memberId, request);
return ApiResponse.ofSuccess(response);
}

@PatchMapping("/recent/walk-status/manual")
public ApiResponse<UpdateWalkStatusManualResponse> updateWalkStatusManual(
@Auth Long memberId
) {
UpdateWalkStatusManualResponse response = footprintCommandService.updateWalkStatusManual(memberId);
return ApiResponse.ofSuccess(response);
}

@DeleteMapping("/{footprintId}")
public ResponseEntity<Void> delete(
@Auth Long memberId,
@PathVariable Long footprintId
) {
footprintCommandService.delete(memberId, footprintId);
return ResponseEntity.noContent().build();
}
Comment on lines +98 to 105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

footprintId 를 입력받지 않고도 로그인한 memberId 로 조회할 수 있지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최신 발자국을 삭제하는 것이 아닌 특정발자국을 삭제하는 api라 id를 받았습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수동삭제가 가능해져서 api가 다채로워졌네요~. 고생 많으십니다. ㅠㅠ

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.happy.friendogly.footprint.domain.WalkStatus.AFTER;
import static com.happy.friendogly.footprint.domain.WalkStatus.ONGOING;

import com.happy.friendogly.exception.FriendoglyException;
import com.happy.friendogly.member.domain.Member;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
Expand Down Expand Up @@ -126,6 +127,13 @@ public void updateWalkStatusWithCurrentLocation(Location currentLocation) {
}
}

public void finishWalkingManual() {
if (walkStatus.isBefore() || walkStatus.isAfter()) {
throw new FriendoglyException("산책 중에서 산책 후로의 변경만 가능합니다.");
}
endWalk();
}

private void startWalk() {
walkStatus = ONGOING;
startWalkTime = LocalDateTime.now();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotNull;

public record UpdateWalkStatusRequest(
public record UpdateWalkStatusAutoRequest(

@NotNull
@DecimalMin(value = "-90.0", message = "위도는 -90도 이상 90도 이하로 입력해 주세요.")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.happy.friendogly.footprint.dto.request;

import jakarta.validation.constraints.NotBlank;

public record UpdateWalkStatusManualRequest(

@NotBlank(message = "walkStatus는 빈 문자열이나 null을 입력할 수 없습니다.")
String walkStatus
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.happy.friendogly.footprint.dto.response;

import com.happy.friendogly.footprint.domain.WalkStatus;
import java.time.LocalDateTime;

public record UpdateWalkStatusAutoResponse(
WalkStatus walkStatus,
LocalDateTime changedWalkStatusTime
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.happy.friendogly.footprint.dto.response;

import com.happy.friendogly.footprint.domain.WalkStatus;
import java.time.LocalDateTime;

public record UpdateWalkStatusManualResponse(
WalkStatus walkStatus,
LocalDateTime changedWalkStatusTime
) {

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ default Footprint getTopOneByMemberIdOrderByCreatedAtDesc(Long memberId) {
}

List<Footprint> findAllByIsDeletedFalse();

default Footprint getById(Long id) {
return findById(id)
.orElseThrow(() -> new FriendoglyException("발자국이 존재하지 않습니다."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import com.happy.friendogly.footprint.domain.Location;
import com.happy.friendogly.footprint.domain.WalkStatus;
import com.happy.friendogly.footprint.dto.request.SaveFootprintRequest;
import com.happy.friendogly.footprint.dto.request.UpdateWalkStatusRequest;
import com.happy.friendogly.footprint.dto.request.UpdateWalkStatusAutoRequest;
import com.happy.friendogly.footprint.dto.response.SaveFootprintResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusAutoResponse;
import com.happy.friendogly.footprint.dto.response.UpdateWalkStatusManualResponse;
import com.happy.friendogly.footprint.repository.FootprintRepository;
import com.happy.friendogly.member.domain.Member;
import com.happy.friendogly.member.repository.MemberRepository;
Expand Down Expand Up @@ -103,7 +104,7 @@ private void sendWalkComingNotification(String memberName, List<String> nearDevi
);
}

public UpdateWalkStatusResponse updateWalkStatus(Long memberId, UpdateWalkStatusRequest request) {
public UpdateWalkStatusAutoResponse updateWalkStatusAuto(Long memberId, UpdateWalkStatusAutoRequest request) {
Footprint footprint = footprintRepository.getTopOneByMemberIdOrderByCreatedAtDesc(memberId);
if (footprint.isDeleted()) {
throw new FriendoglyException("가장 최근 발자국이 삭제된 상태입니다.");
Expand All @@ -112,14 +113,15 @@ public UpdateWalkStatusResponse updateWalkStatus(Long memberId, UpdateWalkStatus
WalkStatus beforeWalkStatus = footprint.getWalkStatus();

footprint.updateWalkStatusWithCurrentLocation(new Location(request.latitude(), request.longitude()));

if (beforeWalkStatus.isBefore() && footprint.getWalkStatus().isOngoing()) {
Member startWalkMember = memberRepository.getById(memberId);
List<String> nearDeviceTokens = findNearDeviceTokensWithoutMine(footprint, startWalkMember);
String memberName = footprint.getMember().getName().getValue();
sendWalkStartNotification(memberName, nearDeviceTokens);
}

return new UpdateWalkStatusResponse(footprint.getWalkStatus());
return new UpdateWalkStatusAutoResponse(footprint.getWalkStatus(), footprint.findChangedWalkStatusTime());
}

private void sendWalkStartNotification(String startMemberName, List<String> nearDeviceTokens) {
Expand All @@ -130,6 +132,20 @@ private void sendWalkStartNotification(String startMemberName, List<String> near
);
}

public UpdateWalkStatusManualResponse updateWalkStatusManual(Long memberId) {
Comment on lines 134 to +135
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

산책 상태를 AFTER로 변경한다는 것을 네이밍에 더 드러내는 것은 어떨까요?

Footprint footprint = footprintRepository.getTopOneByMemberIdOrderByCreatedAtDesc(memberId);
footprint.finishWalkingManual();
Comment on lines +136 to +137
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

footprint.finishWalkingManual() 과 같은 새로운 메서드를 생성하지 않고, 기존의 footprint.endWalk() 메서드에 검증 로직만 추가해서 재사용하는건 어떤가요?

return new UpdateWalkStatusManualResponse(footprint.getWalkStatus(), footprint.findChangedWalkStatusTime());
}

public void delete(Long memberId, Long footprintId) {
Footprint footprint = footprintRepository.getById(footprintId);
if (!footprint.isCreatedBy(memberId)) {
throw new FriendoglyException("본인의 발자국만 삭제 가능합니다.");
}
Comment on lines +143 to +145
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 인가에 관한 예외라고 생각합니다.! 상태코드로 구체화 하면 어떨까요?

footprint.updateToDeleted();
}

private List<String> findNearDeviceTokensWithoutMine(Footprint standardFootprint, Member member) {
List<Footprint> footprints = footprintRepository.findAllByIsDeletedFalse();

Expand Down
Loading
Loading