Skip to content

Commit 890a414

Browse files
committed
feat: 도감 등록 기능 구현
1 parent 51b68d7 commit 890a414

22 files changed

Lines changed: 2531 additions & 386 deletions
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package apu.saerok_admin.infra.dex;
2+
3+
import apu.saerok_admin.infra.SaerokApiProps;
4+
import apu.saerok_admin.infra.dex.dto.AdminBirdDetailResponse;
5+
import apu.saerok_admin.infra.dex.dto.AdminBirdImagePresignRequest;
6+
import apu.saerok_admin.infra.dex.dto.AdminBirdImagePresignResponse;
7+
import apu.saerok_admin.infra.dex.dto.AdminBirdListResponse;
8+
import apu.saerok_admin.infra.dex.dto.AdminBirdUpsertRequest;
9+
import java.net.URI;
10+
import java.util.List;
11+
import org.springframework.http.HttpMethod;
12+
import org.springframework.stereotype.Component;
13+
import org.springframework.util.StringUtils;
14+
import org.springframework.web.client.RestClient;
15+
import org.springframework.web.util.UriBuilder;
16+
17+
@Component
18+
public class AdminDexClient {
19+
20+
private static final String[] ADMIN_DEX_BIRD_SEGMENTS = {"admin", "dex", "birds"};
21+
22+
private final RestClient saerokRestClient;
23+
private final String[] missingPrefixSegments;
24+
25+
public AdminDexClient(RestClient saerokRestClient, SaerokApiProps saerokApiProps) {
26+
this.saerokRestClient = saerokRestClient;
27+
List<String> missing = saerokApiProps.missingPrefixSegments();
28+
this.missingPrefixSegments = missing.toArray(new String[0]);
29+
}
30+
31+
public AdminBirdListResponse listBirds(String query, int page, int size) {
32+
AdminBirdListResponse response = saerokRestClient.get()
33+
.uri(uriBuilder -> {
34+
UriBuilder builder = buildBaseUri(uriBuilder);
35+
if (StringUtils.hasText(query)) {
36+
builder.queryParam("q", query.trim());
37+
}
38+
builder.queryParam("page", page);
39+
builder.queryParam("size", size);
40+
return builder.build();
41+
})
42+
.retrieve()
43+
.body(AdminBirdListResponse.class);
44+
if (response == null) {
45+
throw new IllegalStateException("Empty response from admin dex API");
46+
}
47+
return response;
48+
}
49+
50+
public AdminBirdDetailResponse getBird(Long birdId) {
51+
AdminBirdDetailResponse response = saerokRestClient.get()
52+
.uri(uriBuilder -> buildUri(uriBuilder, birdId.toString()))
53+
.retrieve()
54+
.body(AdminBirdDetailResponse.class);
55+
if (response == null) {
56+
throw new IllegalStateException("Empty response from admin dex API");
57+
}
58+
return response;
59+
}
60+
61+
public AdminBirdDetailResponse createBird(AdminBirdUpsertRequest request) {
62+
AdminBirdDetailResponse response = saerokRestClient.post()
63+
.uri(uriBuilder -> buildUri(uriBuilder))
64+
.body(request)
65+
.retrieve()
66+
.body(AdminBirdDetailResponse.class);
67+
if (response == null) {
68+
throw new IllegalStateException("Empty response from admin dex API");
69+
}
70+
return response;
71+
}
72+
73+
public AdminBirdDetailResponse updateBird(Long birdId, AdminBirdUpsertRequest request) {
74+
AdminBirdDetailResponse response = saerokRestClient.method(HttpMethod.PUT)
75+
.uri(uriBuilder -> buildUri(uriBuilder, birdId.toString()))
76+
.body(request)
77+
.retrieve()
78+
.body(AdminBirdDetailResponse.class);
79+
if (response == null) {
80+
throw new IllegalStateException("Empty response from admin dex API");
81+
}
82+
return response;
83+
}
84+
85+
public AdminBirdImagePresignResponse generateImagePresignUrl(AdminBirdImagePresignRequest request) {
86+
AdminBirdImagePresignResponse response = saerokRestClient.post()
87+
.uri(uriBuilder -> buildUri(uriBuilder, "image", "presign"))
88+
.body(request)
89+
.retrieve()
90+
.body(AdminBirdImagePresignResponse.class);
91+
if (response == null) {
92+
throw new IllegalStateException("Empty response from admin dex image API");
93+
}
94+
return response;
95+
}
96+
97+
private URI buildUri(UriBuilder builder, String... segments) {
98+
UriBuilder base = buildBaseUri(builder);
99+
if (segments != null && segments.length > 0) {
100+
base.pathSegment(segments);
101+
}
102+
return base.build();
103+
}
104+
105+
private UriBuilder buildBaseUri(UriBuilder builder) {
106+
if (missingPrefixSegments.length > 0) {
107+
builder.pathSegment(missingPrefixSegments);
108+
}
109+
return builder.pathSegment(ADMIN_DEX_BIRD_SEGMENTS);
110+
}
111+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package apu.saerok_admin.infra.dex.dto;
2+
3+
import java.time.OffsetDateTime;
4+
import java.util.List;
5+
6+
public record AdminBirdDetailResponse(
7+
Long id,
8+
BirdName name,
9+
BirdTaxonomy taxonomy,
10+
BirdDescription description,
11+
Double bodyLengthCm,
12+
String nibrUrl,
13+
String conservationGrade,
14+
List<String> habitats,
15+
List<Residency> residencies,
16+
List<SeasonWithRarity> seasonsWithRarity,
17+
List<Image> images,
18+
OffsetDateTime createdAt,
19+
OffsetDateTime updatedAt
20+
) {
21+
public record BirdName(
22+
String koreanName,
23+
String scientificName,
24+
String scientificAuthor,
25+
Integer scientificYear
26+
) {
27+
}
28+
29+
public record BirdTaxonomy(
30+
String phylumEng,
31+
String phylumKor,
32+
String classEng,
33+
String classKor,
34+
String orderEng,
35+
String orderKor,
36+
String familyEng,
37+
String familyKor,
38+
String genusEng,
39+
String genusKor,
40+
String speciesEng,
41+
String speciesKor
42+
) {
43+
}
44+
45+
public record BirdDescription(
46+
String description,
47+
String source,
48+
Boolean isAiGenerated
49+
) {
50+
}
51+
52+
public record SeasonWithRarity(
53+
String season,
54+
String rarity,
55+
Integer priority
56+
) {
57+
}
58+
59+
public record Residency(
60+
String residencyType,
61+
String rarity,
62+
Integer monthBitmask,
63+
Integer effectiveMonthBitmask
64+
) {
65+
}
66+
67+
public record Image(
68+
String objectKey,
69+
String imageUrl,
70+
String originalUrl,
71+
Integer orderIndex,
72+
Boolean isThumb
73+
) {
74+
}
75+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package apu.saerok_admin.infra.dex.dto;
2+
3+
public record AdminBirdImagePresignRequest(String contentType) {
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package apu.saerok_admin.infra.dex.dto;
2+
3+
public record AdminBirdImagePresignResponse(
4+
String presignedUrl,
5+
String objectKey
6+
) {
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package apu.saerok_admin.infra.dex.dto;
2+
3+
import java.time.OffsetDateTime;
4+
import java.util.List;
5+
6+
public record AdminBirdListResponse(
7+
List<Item> birds,
8+
int page,
9+
int size,
10+
long totalElements,
11+
int totalPages
12+
) {
13+
public record Item(
14+
Long id,
15+
String koreanName,
16+
String scientificName,
17+
String conservationGrade,
18+
Double bodyLengthCm,
19+
List<String> habitats,
20+
String thumbImageUrl,
21+
OffsetDateTime updatedAt
22+
) {
23+
}
24+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package apu.saerok_admin.infra.dex.dto;
2+
3+
import java.util.List;
4+
5+
public record AdminBirdUpsertRequest(
6+
Name name,
7+
Taxonomy taxonomy,
8+
Description description,
9+
Double bodyLengthCm,
10+
String nibrUrl,
11+
String conservationGrade,
12+
List<String> habitats,
13+
List<Residency> residencies,
14+
List<Image> images
15+
) {
16+
public record Name(
17+
String koreanName,
18+
String scientificName,
19+
String scientificAuthor,
20+
Integer scientificYear
21+
) {
22+
}
23+
24+
public record Taxonomy(
25+
String phylumEng,
26+
String phylumKor,
27+
String classEng,
28+
String classKor,
29+
String orderEng,
30+
String orderKor,
31+
String familyEng,
32+
String familyKor,
33+
String genusEng,
34+
String genusKor,
35+
String speciesEng,
36+
String speciesKor
37+
) {
38+
}
39+
40+
public record Description(
41+
String description,
42+
String source,
43+
Boolean isAiGenerated
44+
) {
45+
}
46+
47+
public record Residency(
48+
String residencyType,
49+
String rarity,
50+
Integer monthBitmask
51+
) {
52+
}
53+
54+
public record Image(
55+
String objectKey,
56+
String originalUrl
57+
) {
58+
}
59+
}

0 commit comments

Comments
 (0)