Skip to content

Commit 3affe29

Browse files
committed
feat: 컬렉션에 위치 마스커 추가, 컬렉션 응답이 가는 도메인들에 isMine 필드 추가 및 마스커 적용, 테스트 추가
1 parent f8a7496 commit 3affe29

8 files changed

Lines changed: 287 additions & 12 deletions

File tree

src/main/java/org/devkor/apu/saerok_server/domain/collection/application/CollectionQueryService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ public GetNearbyCollectionsResponse getNearbyCollections(GetNearbyCollectionsCom
214214
boolean isLikedByMe = command.userId() != null && myLikeMap.getOrDefault(c.getId(), false);
215215
String userProfileImageUrl = profileImageMap.get(c.getUser().getId());
216216
String thumbnailProfileImageUrl = thumbnailProfileImageMap.get(c.getUser().getId());
217+
boolean isMine = command.userId() != null && command.userId().equals(c.getUser().getId());
217218

218219
return collectionWebMapper.toGetNearbyCollectionsResponseItem(
219220
c,
@@ -223,7 +224,8 @@ public GetNearbyCollectionsResponse getNearbyCollections(GetNearbyCollectionsCom
223224
thumbnailProfileImageUrl,
224225
likeCount,
225226
commentCount,
226-
isLikedByMe
227+
isLikedByMe,
228+
isMine
227229
);
228230
})
229231
.toList();

src/main/java/org/devkor/apu/saerok_server/domain/collection/core/repository/CollectionRepository.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,16 @@ public List<UserBirdCollection> findNearby(Point ref, double radiusMeters, Long
5555

5656
if (isMineOnly && userId != null) {
5757
String sqlMineOnly = """
58-
SELECT *
58+
SELECT c.*
5959
FROM user_bird_collection c
60+
LEFT JOIN bird b ON b.id = c.bird_id
6061
WHERE ST_DWithin(
6162
c.location::geography,
6263
CAST(:refPoint AS geography),
6364
:radius
6465
)
6566
AND c.user_id = :userId
67+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
6668
ORDER BY ST_Distance(
6769
c.location::geography,
6870
CAST(:refPoint AS geography)
@@ -79,8 +81,9 @@ ORDER BY ST_Distance(
7981
}
8082

8183
String sqlAll = """
82-
SELECT *
84+
SELECT c.*
8385
FROM user_bird_collection c
86+
LEFT JOIN bird b ON b.id = c.bird_id
8487
WHERE ST_DWithin(
8588
c.location::geography,
8689
CAST(:refPoint AS geography),
@@ -90,6 +93,7 @@ WHERE ST_DWithin(
9093
c.access_level = 'PUBLIC'
9194
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
9295
)
96+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
9397
ORDER BY ST_Distance(
9498
c.location::geography,
9599
CAST(:refPoint AS geography)
@@ -111,12 +115,14 @@ public long countNearbyCandidates(Point ref, double radiusMeters, Long userId, b
111115
String sql = """
112116
SELECT COUNT(*)
113117
FROM user_bird_collection c
118+
LEFT JOIN bird b ON b.id = c.bird_id
114119
WHERE ST_DWithin(
115120
c.location::geography,
116121
CAST(:refPoint AS geography),
117122
:radius
118123
)
119124
AND c.user_id = :userId
125+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
120126
""";
121127

122128
var query = em.createNativeQuery(sql)
@@ -130,6 +136,7 @@ WHERE ST_DWithin(
130136
String sql = """
131137
SELECT COUNT(*)
132138
FROM user_bird_collection c
139+
LEFT JOIN bird b ON b.id = c.bird_id
133140
WHERE ST_DWithin(
134141
c.location::geography,
135142
CAST(:refPoint AS geography),
@@ -139,6 +146,7 @@ WHERE ST_DWithin(
139146
c.access_level = 'PUBLIC'
140147
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
141148
)
149+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
142150
""";
143151

144152
var query = em.createNativeQuery(sql)
@@ -169,12 +177,14 @@ WITH candidates AS (
169177
ST_Distance(c.location::geography, CAST(:refPoint AS geography)) AS dist,
170178
ST_SnapToGrid(ST_Transform(c.location, 3857), :gridSize, :gridSize) AS cell_id
171179
FROM user_bird_collection c
180+
LEFT JOIN bird b ON b.id = c.bird_id
172181
WHERE ST_DWithin(
173182
c.location::geography,
174183
CAST(:refPoint AS geography),
175184
:radius
176185
)
177186
AND c.user_id = :userId
187+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
178188
), ranked AS (
179189
SELECT id,
180190
dist,
@@ -203,6 +213,7 @@ WITH candidates AS (
203213
ST_Distance(c.location::geography, CAST(:refPoint AS geography)) AS dist,
204214
ST_SnapToGrid(ST_Transform(c.location, 3857), :gridSize, :gridSize) AS cell_id
205215
FROM user_bird_collection c
216+
LEFT JOIN bird b ON b.id = c.bird_id
206217
WHERE ST_DWithin(
207218
c.location::geography,
208219
CAST(:refPoint AS geography),
@@ -212,6 +223,7 @@ WHERE ST_DWithin(
212223
c.access_level = 'PUBLIC'
213224
OR (CAST(:userId AS bigint) IS NOT NULL AND c.user_id = :userId)
214225
)
226+
AND (c.bird_id IS NULL OR b.conservation_grade = 'NONE')
215227
), ranked AS (
216228
SELECT id,
217229
dist,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.devkor.apu.saerok_server.domain.collection.core.service;
2+
3+
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
4+
import org.devkor.apu.saerok_server.domain.dex.bird.core.entity.Bird;
5+
import org.devkor.apu.saerok_server.domain.dex.bird.core.enums.ConservationGrade;
6+
7+
public final class CollectionLocationMasker {
8+
9+
private CollectionLocationMasker() {
10+
}
11+
12+
public static Double latitude(UserBirdCollection collection, boolean isOwner) {
13+
if (shouldMaskLocation(collection, isOwner) || collection == null || collection.getLocation() == null) {
14+
return null;
15+
}
16+
return collection.getLatitude();
17+
}
18+
19+
public static Double longitude(UserBirdCollection collection, boolean isOwner) {
20+
if (shouldMaskLocation(collection, isOwner) || collection == null || collection.getLocation() == null) {
21+
return null;
22+
}
23+
return collection.getLongitude();
24+
}
25+
26+
public static String locationAlias(UserBirdCollection collection, boolean isOwner) {
27+
if (shouldMaskLocation(collection, isOwner) || collection == null) {
28+
return null;
29+
}
30+
return collection.getLocationAlias();
31+
}
32+
33+
public static String address(UserBirdCollection collection, boolean isOwner) {
34+
if (shouldMaskLocation(collection, isOwner) || collection == null) {
35+
return null;
36+
}
37+
return collection.getAddress();
38+
}
39+
40+
public static boolean shouldMaskLocation(UserBirdCollection collection, boolean isOwner) {
41+
if (isOwner || collection == null) {
42+
return false;
43+
}
44+
45+
Bird bird = collection.getBird();
46+
if (bird == null) {
47+
return false;
48+
}
49+
50+
ConservationGrade grade = bird.getConservationGrade();
51+
return grade != null && grade.shouldHideLocation();
52+
}
53+
}

src/main/java/org/devkor/apu/saerok_server/domain/collection/mapper/CollectionWebMapper.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import org.devkor.apu.saerok_server.domain.collection.application.dto.DeleteCollectionCommand;
1010
import org.devkor.apu.saerok_server.domain.collection.application.dto.*;
1111
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
12+
import org.devkor.apu.saerok_server.domain.collection.core.service.CollectionLocationMasker;
1213
import org.mapstruct.Mapper;
1314
import org.mapstruct.Mapping;
1415
import org.mapstruct.MappingConstants;
1516
import org.mapstruct.Named;
1617

1718
@Mapper(
18-
componentModel = MappingConstants.ComponentModel.SPRING
19+
componentModel = MappingConstants.ComponentModel.SPRING,
20+
imports = CollectionLocationMasker.class
1921
)
2022
public interface CollectionWebMapper {
2123

@@ -58,6 +60,10 @@ public interface CollectionWebMapper {
5860
@Mapping(target = "commentCount", source = "commentCount")
5961
@Mapping(target = "isLiked", source = "isLiked")
6062
@Mapping(target = "isMine", source = "isMine")
63+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
64+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
65+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
66+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
6167
GetCollectionDetailResponse toGetCollectionDetailResponse(UserBirdCollection collection, String imageUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked, boolean isMine);
6268

6369
@Mapping(target = "collectionId", source = "collection.id")
@@ -71,7 +77,11 @@ public interface CollectionWebMapper {
7177
@Mapping(target = "user.nickname", source = "collection.user.nickname")
7278
@Mapping(target = "user.profileImageUrl", source = "userProfileImageUrl")
7379
@Mapping(target = "user.thumbnailProfileImageUrl", source = "thumbnailProfileImageUrl")
74-
GetNearbyCollectionsResponse.Item toGetNearbyCollectionsResponseItem(UserBirdCollection collection, String imageUrl, String thumbnailUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked);
80+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
81+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
82+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
83+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
84+
GetNearbyCollectionsResponse.Item toGetNearbyCollectionsResponseItem(UserBirdCollection collection, String imageUrl, String thumbnailUrl, String userProfileImageUrl, String thumbnailProfileImageUrl, long likeCount, long commentCount, boolean isLiked, boolean isMine);
7585

7686
@Named("getBirdId")
7787
default Long getBirdId(UserBirdCollection collection) {

src/main/java/org/devkor/apu/saerok_server/domain/community/application/CommunityDataAssembler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ public List<CommunityCollectionInfo> toCollectionInfos(List<UserBirdCollection>
6060
long commentCount = collectionCommentRepository.countByCollectionId(collection.getId());
6161
boolean isLiked = userId != null && collectionLikeRepository.existsByUserIdAndCollectionId(userId, collection.getId());
6262
boolean isPopular = popularStatusMap.getOrDefault(collection.getId(), false);
63+
boolean isMine = userId != null && userId.equals(collection.getUser().getId());
6364

6465
Long suggestionUserCount = collection.getBird() == null
6566
? suggestionUserCounts.getOrDefault(collection.getId(), 0L)
6667
: null;
6768

6869
return communityWebMapper.toCommunityCollectionInfo(
69-
collection, imageUrl, thumbnailImageUrl, userProfileImageUrl, thumbnailProfileImageUrl, likeCount, commentCount, isLiked, isPopular, suggestionUserCount
70+
collection, imageUrl, thumbnailImageUrl, userProfileImageUrl, thumbnailProfileImageUrl, likeCount, commentCount, isLiked, isPopular, suggestionUserCount, isMine
7071
);
7172
})
7273
.toList();

src/main/java/org/devkor/apu/saerok_server/domain/community/mapper/CommunityWebMapper.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.devkor.apu.saerok_server.domain.community.mapper;
22

33
import org.devkor.apu.saerok_server.domain.collection.core.entity.UserBirdCollection;
4+
import org.devkor.apu.saerok_server.domain.collection.core.service.CollectionLocationMasker;
45
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityCollectionInfo;
56
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityFreeBoardPostInfo;
67
import org.devkor.apu.saerok_server.domain.community.api.dto.common.CommunityUserInfo;
@@ -11,18 +12,18 @@
1112
import org.mapstruct.Mapping;
1213
import org.mapstruct.MappingConstants;
1314

14-
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, imports = OffsetDateTimeLocalizer.class)
15+
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, imports = {OffsetDateTimeLocalizer.class, CollectionLocationMasker.class})
1516
public interface CommunityWebMapper {
1617

1718
@Mapping(target = "collectionId", source = "collection.id")
1819
@Mapping(target = "imageUrl", source = "imageUrl")
1920
@Mapping(target = "thumbnailImageUrl", source = "thumbnailImageUrl")
2021
@Mapping(target = "discoveredDate", source = "collection.discoveredDate")
2122
@Mapping(target = "createdAt", expression = "java(OffsetDateTimeLocalizer.toSeoulLocalDateTime(collection.getCreatedAt()))")
22-
@Mapping(target = "latitude", source = "collection.latitude")
23-
@Mapping(target = "longitude", source = "collection.longitude")
24-
@Mapping(target = "locationAlias", source = "collection.locationAlias")
25-
@Mapping(target = "address", source = "collection.address")
23+
@Mapping(target = "latitude", expression = "java(CollectionLocationMasker.latitude(collection, isMine))")
24+
@Mapping(target = "longitude", expression = "java(CollectionLocationMasker.longitude(collection, isMine))")
25+
@Mapping(target = "locationAlias", expression = "java(CollectionLocationMasker.locationAlias(collection, isMine))")
26+
@Mapping(target = "address", expression = "java(CollectionLocationMasker.address(collection, isMine))")
2627
@Mapping(target = "note", source = "collection.note")
2728
@Mapping(target = "likeCount", source = "likeCount")
2829
@Mapping(target = "commentCount", source = "commentCount")
@@ -41,7 +42,8 @@ CommunityCollectionInfo toCommunityCollectionInfo(
4142
Long commentCount,
4243
Boolean isLiked,
4344
Boolean isPopular,
44-
Long suggestionUserCount
45+
Long suggestionUserCount,
46+
boolean isMine
4547
);
4648

4749
@Mapping(target = "userId", source = "user.id")

0 commit comments

Comments
 (0)