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] 핀(Pin) 패키지 코드 리팩터링(PinImage 기능 구현 포함) #240

Merged
merged 130 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
8646b1a
[Docs] GitHub Issue 및 PR Template 설정 (#37)
junpakPark Jul 18, 2023
5b153cc
[Docs] GitHub Issue Template 파일명 오류 수정 (#39)
junpakPark Jul 18, 2023
c54a142
Merge branch 'develop' of https://github.com/woowacourse-teams/2023-m…
kpeel5839 Jul 25, 2023
1397964
Merge branch 'develop' of https://github.com/woowacourse-teams/2023-m…
kpeel5839 Jul 25, 2023
4efef6e
Merge branch 'develop' of https://github.com/woowacourse-teams/2023-m…
kpeel5839 Jul 26, 2023
29997b1
feat: member 구현 중
junpakPark Jul 27, 2023
82233e0
Merge branch 'feature/member' of https://github.com/woowacourse-teams…
kpeel5839 Jul 27, 2023
70f351f
feat: 패키지 분리, AuthMember 구현
junpakPark Jul 28, 2023
b98ce02
feat: MemberArgumentResolver 구현
kpeel5839 Jul 28, 2023
bd32df0
Merge branch 'feature/member' of https://github.com/woowacourse-teams…
kpeel5839 Jul 28, 2023
69268ee
feat: AuthTopic 구현
kpeel5839 Jul 28, 2023
f6faad0
Merge branch 'feature/member' of https://github.com/woowacourse-teams…
kpeel5839 Jul 28, 2023
960b9b3
Merge branch 'feature/junepark-member' into feature/junjun
kpeel5839 Jul 28, 2023
68838dc
feat: MemberArgumentResolver 구현
kpeel5839 Jul 28, 2023
5bda12f
refactor: API 명세 수정을 위한 임의 커밋
junpakPark Jul 28, 2023
83f79ff
feat: Publicity, Permission 정적 팩토리 및 Converter 추가
kpeel5839 Jul 28, 2023
27a0738
refactor: Topic 에 Publicity, Permission 추가로 인한 테스트 수정
kpeel5839 Jul 28, 2023
41ee4ef
refactor: 모든 테스트가 통과하도록 수정
kpeel5839 Jul 28, 2023
b0850af
refactor: 모든 테스트가 통과하도록 수정
kpeel5839 Jul 28, 2023
9ffcefd
feat: Topic 에 관한 CRUD 에 권한 적용 완료
kpeel5839 Jul 29, 2023
471a826
fix: Converter 반환값 이상으로 인한 오류 해결
kpeel5839 Jul 29, 2023
5075d4b
feat: Pin 기능에 권한 설정 추가
kpeel5839 Jul 29, 2023
30a97f7
style: 사용하지 않는 import 문 제거 및 접근 제어자 조정
kpeel5839 Jul 29, 2023
470fcb5
refactor: .. 지송;;^^
junpakPark Jul 31, 2023
9b58830
refactor: TopicStatus 로직 오류 수정 LocationController 오타 수정
junpakPark Jul 31, 2023
80d7e9f
refactor: 불필요 상수 제거
junpakPark Jul 31, 2023
939964c
refactor: PinResponse 자료형 변경
junpakPark Jul 31, 2023
12e83b4
feat: Image 클래스 구현
junpakPark Jul 31, 2023
8c869a1
feat: LocationRepository에 하버사인을 이용한 find 메서드 구현
junpakPark Jul 31, 2023
7bdea8a
refactor: LocationController의 메서드명 변경
junpakPark Jul 31, 2023
5cf4318
refactor: getTopicsWithPermission의 반환값 변경
junpakPark Jul 31, 2023
cc4c0c4
style: 불필요 공백 제거
junpakPark Jul 31, 2023
b45f3b1
refactor: 로직 오류 수정 및 테스트 추가
junpakPark Jul 31, 2023
0dec766
test: Topic 패키지 테스트 추가
junpakPark Jul 31, 2023
c451958
refactor: Auth 관련 리팩터링 및 TopicIntegrationTest
junpakPark Aug 1, 2023
2433935
refactor: auth 어노테이션 제거
junpakPark Aug 1, 2023
4383f25
test: AddressTest 추가
junpakPark Aug 1, 2023
209a4e2
test: Pin 관련 테스트 추가
junpakPark Aug 1, 2023
d6e4e7a
refactor: Coordinate BigDecimal -> Double 로 수정
kpeel5839 Aug 1, 2023
712a289
refactor: 모든 테스트가 성공하도록 수정
kpeel5839 Aug 1, 2023
846490a
refactor: LocationRepositoryTest 수정
kpeel5839 Aug 1, 2023
cd57810
refactor: Git Conflict Merge 해결
junpakPark Aug 1, 2023
6626b7e
feat: 멤버 단일 조회 기능 추가
kpeel5839 Aug 1, 2023
02979b3
feat: 멤버 목록 조회 기능 구현
kpeel5839 Aug 1, 2023
be59142
feat : Member 를 Create 하는 기능 추가
kpeel5839 Aug 2, 2023
1d81886
feat : Member 가 만든 Topic 들을 조회하는 기능 추가
kpeel5839 Aug 2, 2023
2dccd5f
feat : Member 가 본인이 만든 Pin 을 조회하는 기능 추가
kpeel5839 Aug 2, 2023
975fffd
feat : 토픽을 생성한 자가 특정 멤버에게 권한을 주는 기능 추가
kpeel5839 Aug 2, 2023
6cc09a4
feat : 토픽을 생성한자가 특정 멤버의 권한을 삭제하는 기능 추가
kpeel5839 Aug 2, 2023
dc90aa5
feat : 해당 토픽에 권한을 가진 모든 유저를 조회
kpeel5839 Aug 2, 2023
a78a348
feat : 권한을 가진 유저를 ID 로 조회하는 기능 추가
kpeel5839 Aug 2, 2023
426ad35
refactor: AuthTopic 객체 제거
junpakPark Aug 2, 2023
53db76c
chore: AuthToic 변경 사항 반영을 위한 merge
yoondgu Aug 2, 2023
008ff66
chore: AuthToic 변경 사항 반영을 위한 merge 추가
yoondgu Aug 2, 2023
f1a32de
refactor: Pin 예외 메시지 수정
yoondgu Aug 1, 2023
92879ef
chore: AuthToic 변경 사항 반영을 위한 merge 추가
yoondgu Aug 2, 2023
1a825b5
feat : Topic, Pin, Member 에 연관관계 편의 메서드 추가
kpeel5839 Aug 2, 2023
f8370c3
refactor: RestDocs를 위한 Interceptor 조건문 추가
junpakPark Aug 2, 2023
52fa017
refactor: 핀 조회 관련 API 문서화에 인증 헤더 추가
yoondgu Aug 2, 2023
d0d56a9
Merge branch 'feature/authenticated' into be-refactor/pin
yoondgu Aug 2, 2023
1520467
test : Permission 추가와 관련된 Domain Test 작성
kpeel5839 Aug 2, 2023
2f48f41
test : 다른 유저에게 권한을 주는 기능 테스트 추가
kpeel5839 Aug 2, 2023
9e97c05
chore : Auth 관련 기능들 Pull 받은 후 충돌 해결
kpeel5839 Aug 2, 2023
b9a18fc
test : 권한 부여 인수테스트 추가
kpeel5839 Aug 2, 2023
d6188c4
docs : 권한 부여 API 명세 작성
kpeel5839 Aug 2, 2023
8ffb1f3
test : 권한 삭제 Service Test 작성
kpeel5839 Aug 2, 2023
9a8a019
test : 권한 삭제 인수테스트 작성
kpeel5839 Aug 2, 2023
fa6d7fe
docs : 권한 삭제 API 명세 작성
kpeel5839 Aug 2, 2023
0dad751
test : memberResponse 정적 팩토리 메서드 테스트 작성
kpeel5839 Aug 2, 2023
bb84223
test : 권한이 있는 멤버 전체를 조회하는 기능 Service Test 작성
kpeel5839 Aug 2, 2023
71e970a
test : 해당 토픽에 권한을 가진 자들을 모두 조회하는 기능 인수테스트 작성
kpeel5839 Aug 2, 2023
d5128c6
docs : 해당 토픽에 권한을 가진 유저의 목록을 조회하는 API 명세 작성
kpeel5839 Aug 2, 2023
c5423ad
test : MemberDetailResponse 생성 테스트 추가
kpeel5839 Aug 3, 2023
37a79a8
test : 권한을 가진 유저를 조회하는 기능 Service Test 추가
kpeel5839 Aug 3, 2023
36ac58e
test : 권한을 가진 유저를 조회하는 기능 인수테스트 추가
kpeel5839 Aug 3, 2023
342f35e
docs : 권한을 가진 유저를 조회하는 기능 API 명세 추가
kpeel5839 Aug 3, 2023
864b851
test : 유저를 저장하는 기능 Service Test 작성
kpeel5839 Aug 3, 2023
3fa28bc
test : 유저를 저장하는 기능 인수테스트 작성
kpeel5839 Aug 3, 2023
6b3696f
docs : 유저를 저장하는 기능 API 명세 작성
kpeel5839 Aug 3, 2023
9192536
test : 유저를 목록 조회하는 기능 Service Test 작성
kpeel5839 Aug 3, 2023
522708f
test : 유저를 목록 조회하는 기능 인수테스트 작성
kpeel5839 Aug 3, 2023
0815ff7
docs : 유저를 목록 조회하는 기능 API 명세 작성
kpeel5839 Aug 3, 2023
7fcc517
refactor : AuthInterceptor mocking 을 RestDocs 에서 실행
kpeel5839 Aug 3, 2023
2ea4a21
test : 유저 단일 조회 Service Test 작성
kpeel5839 Aug 3, 2023
e521b2c
test : 유저 단일 조회 인수테스트 작성
kpeel5839 Aug 3, 2023
e2bb58e
docs : 유저 단일 조회 API 명세 작성
kpeel5839 Aug 3, 2023
9d04afb
test : 유저가 만든 토픽, 핀 조회 Service Test 작성
kpeel5839 Aug 3, 2023
96d3512
test : 유저가 만든 토픽, 핀 조회 인수테스트 작성
kpeel5839 Aug 3, 2023
019f330
docs : 유저가 만든 토픽, 핀 조회 API 명세 작성
kpeel5839 Aug 3, 2023
5bfb799
Merge remote-tracking branch 'origin/feature/member-#161' into be-ref…
yoondgu Aug 5, 2023
e010527
refactor: Pin 생성 시 PinInfo를 묶어서 받도록 수정, 중복 테스트 제거
yoondgu Aug 5, 2023
9d8497f
refactor: Pin 생성 시 권한 예외처리 추가
yoondgu Aug 5, 2023
196f669
test: 테스트 코드 컨벤션 통일, 도메인 계층 간 테스트 내용 분리, fixture 사용
yoondgu Aug 5, 2023
7fee7a8
refactor: PinImage 생성 시 Image 객체를 전달받도록 수정, getter 추가
yoondgu Aug 5, 2023
ca4f77a
chore: member-#161,173 pull 받은 후 충돌 해결
yoondgu Aug 5, 2023
f3350cd
refactor: 회원 조회 로직 권한 확인 후 수행하도록 변경, 상수 처리
yoondgu Aug 5, 2023
b394b0f
test: 테스트 클래스 내 픽스쳐 사용 방식 통일, 메서드 순서 변경
yoondgu Aug 5, 2023
83339d8
test: Pin copy 테스트 추가
yoondgu Aug 5, 2023
9367605
test: Pin 통합테스트 request 객체 멤버변수로 관리
yoondgu Aug 6, 2023
00c83dd
feat: PinImage 추가 API 작성, 기존 Pin 생성 및 수정 명세 변경
yoondgu Aug 7, 2023
413ee7c
test: 중복되는 내용의 PinCommandServiceTest 테스트 삭제
yoondgu Aug 7, 2023
d3ac82e
feat: 핀 삭제 시 핀 이미지 삭제 구현
yoondgu Aug 7, 2023
6459767
test: 핀 삭제 테스트에서 핀 이미지도 삭제되는지 확인하도록 수정
yoondgu Aug 7, 2023
799a264
refactor: 핀 이미지 추가 시 location 응답헤더 반환하도록 수정
yoondgu Aug 7, 2023
7310146
feat: 핀 이미지 삭제 기능 구현
yoondgu Aug 7, 2023
c0bfc7d
feat: 핀 상세 조회 시 이미지 id 반환하도록 수정
yoondgu Aug 7, 2023
dbb4523
docs: RestDocs 문서화 설정에 새 API 추가
yoondgu Aug 7, 2023
1335e0e
feat: 핀 복사 시 핀 이미지도 복사하도록 수정
yoondgu Aug 7, 2023
05293f1
chore: 불필요한 주석 삭제, 코드 리뷰를 위한 주석 추가
yoondgu Aug 7, 2023
8a976a2
chore: 충돌 해결을 위한 develop merge
yoondgu Aug 2, 2023
c6354f3
fix: updatedAt 관련 테스트 실패 해결
yoondgu Aug 8, 2023
b339a33
refactor: 중복 거리 상수 단위 표기
yoondgu Aug 8, 2023
20238ad
fix: 핀 이미지 삭제 메서드명 수정
yoondgu Aug 8, 2023
91307a1
fix: 핀 이미지 관련 핸들러메서드에 LoginRequired 추가
yoondgu Aug 8, 2023
3941aef
refactor: 사용하지 않는 Location 헤더값 전달 삭제
yoondgu Aug 8, 2023
c461d82
feat: 핀 이미지 삭제 hard delete에서 soft delete으로 변경
yoondgu Aug 8, 2023
882b88b
refactor: null 검증 메서드 통일
yoondgu Aug 8, 2023
3e26e65
test: Pin, PinImage RepositoryTest setUp 메서드 처리
yoondgu Aug 8, 2023
e4a7cde
refactor: Pin 서비스 클래스 메서드 분리
yoondgu Aug 8, 2023
4e50b84
test: Pin, PinImage RepositoryTest 픽스쳐 적용
yoondgu Aug 8, 2023
ce0855d
refactor: Pin 조회 서비스 메서드 네이밍 구체화
yoondgu Aug 8, 2023
8ddcabf
refactor: PinQueryServiceTest 픽스쳐 적용
yoondgu Aug 8, 2023
9639360
refactor: Pin 변수명, 개행 수정
yoondgu Aug 8, 2023
5fbd5ac
fix: 864b851e 충돌 해결 시 주석 처리 실수 해제, 테스트 실패 해결
yoondgu Aug 8, 2023
43ca6c2
refactor: PinCommandServiceTest 픽스쳐 적용, 테스트 단순화
yoondgu Aug 8, 2023
27bef77
test: Pin 서비스 계층 권한 관련 테스트 작성
yoondgu Aug 8, 2023
56a13c7
refactor: 핀 이미지 제거 메서드명 구체화
yoondgu Aug 8, 2023
e12532d
test: 불필요한 객체 생성 삭제
yoondgu Aug 9, 2023
c8875b7
refactor: 정적 팩터리 메서드 내부에서 객체 생성하도록 변경
yoondgu Aug 9, 2023
3968a39
chore: 충돌 해결을 위한 merge
yoondgu Aug 9, 2023
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
7 changes: 7 additions & 0 deletions backend/src/docs/asciidoc/pin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ operation::pin-controller-test/update[snippets='http-request,http-response']
=== 핀 삭제

operation::pin-controller-test/delete[snippets='http-request,http-response']

=== 핀 이미지 추가

operation::pin-controller-test/add-image[snippets='http-request,http-response']

=== 핀 이미지 삭제
operation::pin-controller-test/remove-image[snippets='http-request,http-response']
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ protected AuthMember(
public Long getMemberId() {
return memberId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,12 @@ public double getLongitude() {
return coordinate.getLongitude();
}

public String getRoadBaseAddress() {
return address.getRoadBaseAddress();
}

public String getLegalDongCode() {
return address.getLegalDongCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,86 @@
import com.mapbefine.mapbefine.member.domain.MemberRepository;
import com.mapbefine.mapbefine.pin.domain.Pin;
import com.mapbefine.mapbefine.pin.domain.PinImage;
import com.mapbefine.mapbefine.pin.domain.PinImageRepository;
import com.mapbefine.mapbefine.pin.domain.PinRepository;
import com.mapbefine.mapbefine.pin.dto.request.PinCreateRequest;
import com.mapbefine.mapbefine.pin.dto.request.PinImageCreateRequest;
import com.mapbefine.mapbefine.pin.dto.request.PinUpdateRequest;
import com.mapbefine.mapbefine.topic.domain.Topic;
import com.mapbefine.mapbefine.topic.domain.TopicRepository;
import java.util.NoSuchElementException;
import java.util.Objects;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Service
public class PinCommandService {

private static final double DUPLICATE_LOCATION_DISTANCE_METERS = 10.0;

private final PinRepository pinRepository;
private final LocationRepository locationRepository;
private final TopicRepository topicRepository;
private final MemberRepository memberRepository;
private final PinImageRepository pinImageRepository;

public PinCommandService(
PinRepository pinRepository,
LocationRepository locationRepository,
TopicRepository topicRepository,
MemberRepository memberRepository
MemberRepository memberRepository,
PinImageRepository pinImageRepository
) {
this.pinRepository = pinRepository;
this.locationRepository = locationRepository;
this.topicRepository = topicRepository;
this.memberRepository = memberRepository;
this.pinImageRepository = pinImageRepository;
}

public Long save(AuthMember authMember, PinCreateRequest request) {
Coordinate coordinate = Coordinate.of(request.latitude(), request.longitude());
Topic topic = topicRepository.findById(request.topicId())
.orElseThrow(NoSuchElementException::new);
Member member = memberRepository.findById(authMember.getMemberId())
.orElseThrow(NoSuchElementException::new);
authMember.canPinCreateOrUpdate(topic);

Location pinLocation = locationRepository.findAllByCoordinateAndDistanceInMeters(
coordinate, 10.0).stream()
.filter(location -> location.isSameAddress(request.address()))
.findFirst()
.orElseGet(() -> saveLocation(request, coordinate));

public long save(AuthMember authMember, PinCreateRequest request) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

primitive 값으로 반환해주시는 이유가 있을까요 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

앗 제가 잘못 생각한 것 같아요 ㅎㅎㅎ
id값으로는 null을 반환할 일 없는(반환하면 안되는) 메서드이기 때문에
�null일 수도 있는 Wrapper보다 primitive가 이 메서드를 더 믿고 사용할 수 있게 해준다고 생각합니다!

Topic topic = findTopic(request.topicId());
validatePinCreateOrUpdate(authMember, topic);

Member member = findMember(authMember.getMemberId());
Pin pin = Pin.createPinAssociatedWithLocationAndTopicAndMember(
request.name(),
request.description(),
pinLocation,
findDuplicateOrCreatePinLocation(request),
topic,
member
);
pinRepository.save(pin);

return pin.getId();
}

private Topic findTopic(Long topicId) {
if (Objects.isNull(topicId)) {
throw new NoSuchElementException("토픽을 찾을 수 없습니다.");
}
return topicRepository.findById(topicId)
.orElseThrow(() -> new NoSuchElementException("토픽을 찾을 수 없습니다."));
}

for (String pinImage : request.images()) {
PinImage.createPinImageAssociatedWithPin(pinImage, pin);
private Member findMember(Long memberId) {
if (Objects.isNull(memberId)) {
throw new NoSuchElementException("회원 정보를 찾을 수 없습니다.");
}
return memberRepository.findById(memberId)
.orElseThrow(() -> new NoSuchElementException("회원 정보를 찾을 수 없습니다."));
}

private Location findDuplicateOrCreatePinLocation(PinCreateRequest request) {
Coordinate coordinate = Coordinate.of(request.latitude(), request.longitude());

return pinRepository.save(pin).getId();
return locationRepository.findAllByCoordinateAndDistanceInMeters(coordinate, DUPLICATE_LOCATION_DISTANCE_METERS)
.stream()
.filter(location -> location.isSameAddress(request.address()))
.findFirst()
.orElseGet(() -> saveLocation(request, coordinate));
}

private Location saveLocation(PinCreateRequest pinCreateRequest, Coordinate coordinate) {
Expand All @@ -74,31 +97,61 @@ private Location saveLocation(PinCreateRequest pinCreateRequest, Coordinate coor
pinCreateRequest.address(),
pinCreateRequest.legalDongCode()
);

Location location = new Location(address, coordinate);

return locationRepository.save(location);
}

public void update(
AuthMember member,
AuthMember authMember,
Long pinId,
PinUpdateRequest request
) {
Pin pin = pinRepository.findById(pinId)
.orElseThrow(NoSuchElementException::new);
member.canPinCreateOrUpdate(pin.getTopic());
Pin pin = findPin(pinId);
validatePinCreateOrUpdate(authMember, pin.getTopic());

pin.updatePinInfo(request.name(), request.description());
}

pinRepository.save(pin);
private Pin findPin(Long pinId) {
return pinRepository.findById(pinId)
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 핀입니다."));
}

public void removeById(AuthMember member, Long pinId) {
Pin pin = pinRepository.findById(pinId)
.orElseThrow(NoSuchElementException::new);
member.canDelete(pin.getTopic());
public void removeById(AuthMember authMember, Long pinId) {
Pin pin = findPin(pinId);
validatePinCreateOrUpdate(authMember, pin.getTopic());

pinRepository.deleteById(pinId);
pinImageRepository.deleteAllByPinId(pinId);
}

public void addImage(AuthMember authMember, PinImageCreateRequest request) {
Pin pin = findPin(request.pinId());
validatePinCreateOrUpdate(authMember, pin.getTopic());

PinImage pinImage = PinImage.createPinImageAssociatedWithPin(request.imageUrl(), pin);
pinImageRepository.save(pinImage);
}

public void removeImageById(AuthMember authMember, Long pinImageId) {
PinImage pinImage = findPinImage(pinImageId);
Pin pin = pinImage.getPin();
validatePinCreateOrUpdate(authMember, pin.getTopic());

pinImageRepository.deleteById(pinImageId);
}

private PinImage findPinImage(Long pinImageId) {
return pinImageRepository.findById(pinImageId)
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 핀 이미지입니다."));
}

private void validatePinCreateOrUpdate(AuthMember authMember, Topic topic) {
if (authMember.canPinCreateOrUpdate(topic)) {
return;
}

throw new IllegalArgumentException("핀 생성 및 수정 권한이 없습니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.mapbefine.mapbefine.pin.domain.PinRepository;
import com.mapbefine.mapbefine.pin.dto.response.PinDetailResponse;
import com.mapbefine.mapbefine.pin.dto.response.PinResponse;
import com.mapbefine.mapbefine.topic.domain.Topic;
import java.util.List;
import java.util.NoSuchElementException;
import org.springframework.stereotype.Service;
Expand All @@ -13,26 +14,37 @@
@Transactional(readOnly = true)
@Service
public class PinQueryService {

private final PinRepository pinRepository;

public PinQueryService(PinRepository pinRepository) {
this.pinRepository = pinRepository;
}

public List<PinResponse> findAll(AuthMember member) {
// TODO: 2023/08/08 isDeleted 제외하고 조회하기
public List<PinResponse> findAllReadable(AuthMember member) {
return pinRepository.findAll()
.stream()
.filter(pin -> member.canRead(pin.getTopic()))
.map(PinResponse::from)
.toList();
}

public PinDetailResponse findById(AuthMember member, Long pinId) {
// TODO: 2023/08/08 isDeleted 제외하고 조회하기
public PinDetailResponse findDetailById(AuthMember member, Long pinId) {
Pin pin = pinRepository.findById(pinId)
.filter(optionalPin -> member.canRead(optionalPin.getTopic()))
.orElseThrow(NoSuchElementException::new);
.orElseThrow(() -> new NoSuchElementException("존재하지 않는 핀입니다."));
validateReadAuth(member, pin.getTopic());

return PinDetailResponse.from(pin);
}

private void validateReadAuth(AuthMember member, Topic topic) {
if (member.canRead(topic)) {
return;
}

throw new IllegalArgumentException("조회 권한이 없습니다.");
}

}
33 changes: 20 additions & 13 deletions backend/src/main/java/com/mapbefine/mapbefine/pin/domain/Pin.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ public class Pin extends BaseTimeEntity {
@Embedded
private PinInfo pinInfo;

@ManyToOne
@JoinColumn(name = "member_id")
private Member creator;

@OneToMany(mappedBy = "pin", cascade = CascadeType.PERSIST)
private List<PinImage> pinImages = new ArrayList<>();

@ManyToOne
@JoinColumn(name = "location_id", nullable = false)
private Location location;
Expand All @@ -50,10 +43,17 @@ public class Pin extends BaseTimeEntity {
@JoinColumn(name = "topic_id", nullable = false)
private Topic topic;

@ManyToOne
@JoinColumn(name = "member_id")
private Member creator;

@Column(nullable = false)
@ColumnDefault(value = "false")
private boolean isDeleted = false;

@OneToMany(mappedBy = "pin", cascade = CascadeType.PERSIST)
private List<PinImage> pinImages = new ArrayList<>();

private Pin(
PinInfo pinInfo,
Location location,
Expand All @@ -73,33 +73,40 @@ public static Pin createPinAssociatedWithLocationAndTopicAndMember(
Topic topic,
Member creator
) {
PinInfo pinInfo = PinInfo.of(name, description);

Pin pin = new Pin(
pinInfo,
PinInfo.of(name, description),
location,
topic,
creator
);

location.addPin(pin);
topic.addPin(pin);
creator.addPin(pin);

return pin;
Copy link
Collaborator

Choose a reason for hiding this comment

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

저는 개인적으로 return 이전에 개행을 넣어주는게 가독성 측면에서 더 좋다고 생각합니다 !

도이는 어떠신가요 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

앗 공감합니다!! 놓친 부분이라 바로 반영하겠습니다!

}

public void updatePinInfo(String name, String description) {
pinInfo.update(name, description);
pinInfo = PinInfo.of(name, description);
}

public Pin copy(Topic topic, Member creator) {
return Pin.createPinAssociatedWithLocationAndTopicAndMember(
Pin copy = Pin.createPinAssociatedWithLocationAndTopicAndMember(
pinInfo.getName(),
pinInfo.getDescription(),
location,
topic,
creator
);
copyPinImages(copy);

return copy;
}

private void copyPinImages(Pin pin) {
for (PinImage pinImage : pinImages) {
PinImage.createPinImageAssociatedWithPin(pinImage.getImageUrl(), pin);
}
}

public void addPinImage(PinImage pinImage) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.mapbefine.mapbefine.pin.domain;

import com.mapbefine.mapbefine.common.entity.BaseTimeEntity;
import com.mapbefine.mapbefine.common.entity.Image;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand All @@ -11,11 +13,12 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class PinImage {
public class PinImage extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -28,7 +31,10 @@ public class PinImage {
@JoinColumn(name = "pin_id")
private Pin pin;


@Column(nullable = false)
@ColumnDefault(value = "false")
private boolean isDeleted = false;

private PinImage(Image image, Pin pin) {
this.image = image;
this.pin = pin;
Expand All @@ -41,4 +47,8 @@ public static PinImage createPinImageAssociatedWithPin(String imageUrl, Pin pin)
return pinImage;
}

public String getImageUrl() {
return image.getImageUrl();
}

}
Loading
Loading