Skip to content
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 @@ -112,7 +112,7 @@ public BaseResponse<OotdRelatedResponse> getRelatedOotds(@PathVariable Long ootd
description = "μ•± μ „μš© μΉ΄λ©”λΌλ‘œ μ΄¬μ˜ν•œ μ°©μž₯ 사진을 OOTD둜 κ²Œμ‹œν•©λ‹ˆλ‹€. "
+ "κ²Œμ‹œ 응닡은 AI νƒœκ·Έ 뢄석을 기닀리지 μ•Šκ³  μ¦‰μ‹œ λ°˜ν™˜ν•˜λ©°, "
+ "κ²Œμ‹œ 직후 λ°±κ·ΈλΌμš΄λ“œμ—μ„œ λΉ„λ™κΈ°λ‘œ 사진 전체에 λŒ€ν•œ AI νƒœκ·Έ 뢄석이 μžλ™μœΌλ‘œ μ§„ν–‰λ©λ‹ˆλ‹€. "
+ "뢄석이 λλ‚˜λ©΄ tagStatusκ°€ ANALYZINGμ—μ„œ AUTO_UNCONFIRMED둜 λ°”λ€λ‹ˆλ‹€."
+ "μžλ™ νƒœκ·ΈλŠ” 별도 확인 단계 없이 μ¦‰μ‹œ ν™•μ •λ˜λ©°, 뢄석이 λλ‚˜λ©΄ tagStatusκ°€ ANALYZINGμ—μ„œ CONFIRMED둜 λ°”λ€λ‹ˆλ‹€."
)
@ApiResponse(
responseCode = "200",
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/tenure/domain/ootd/entity/Ootd.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,13 @@ public static Ootd createArchived(User owner, String imageUrl, String imageObjec
return ootd;
}

// AI μžλ™λΆ„μ„μ΄ 끝났을 λ•Œ ν˜ΈμΆœν•œλ‹€. 이미 μ‚¬μš©μžκ°€ ν™•μΈμ™„λ£Œ(CONFIRMED)ν•œ 뒀라면 λ˜λŒλ¦¬μ§€ μ•ŠλŠ”λ‹€.
// AI μžλ™λΆ„μ„μ΄ 끝났을 λ•Œ ν˜ΈμΆœν•œλ‹€. auto-tag ν”Œλ‘œμš°λŠ” μ‚¬μš©μžκ°€ λ³„λ„λ‘œ ν™•μΈν•˜λŠ” 화면이 μ—†μœΌλ―€λ‘œ
// 뢄석이 λλ‚˜λ©΄ λ°”λ‘œ ν™•μ •(CONFIRMED) μ²˜λ¦¬ν•΄μ„œ, OOTD 상세/κ΄€λ ¨/검색 λ“± CONFIRMED νƒœκ·Έλ§Œ λ…ΈμΆœν•˜λŠ”
// ν™”λ©΄μ—μ„œλ„ μžλ™ νƒœκ·Έκ°€ λ°”λ‘œ 보이게 ν•œλ‹€. 이미 ANALYZING을 λ²—μ–΄λ‚œ μƒνƒœλΌλ©΄ λ˜λŒλ¦¬μ§€ μ•ŠλŠ”λ‹€.
public void markAutoTagsReady() {
if (this.tagStatus == OotdTagStatus.ANALYZING) {
this.tagStatus = OotdTagStatus.AUTO_UNCONFIRMED;
this.tagStatus = OotdTagStatus.CONFIRMED;
this.tagConfirmedAt = LocalDateTime.now();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,17 @@ public void saveAiTags(Long ootdId, List<AiTagResult> results) {
.filter(Objects::nonNull)
.toList();

// auto-tag ν”Œλ‘œμš°λŠ” μ‚¬μš©μžκ°€ νƒœκ·Έλ₯Ό λ”°λ‘œ 확인/ν™•μ •ν•˜λŠ” 화면이 μ—†μœΌλ―€λ‘œ, μ €μž₯κ³Ό λ™μ‹œμ— ν™•μ •(CONFIRMED)
// μ²˜λ¦¬ν•œλ‹€. κ·Έλž˜μ•Ό OOTD 상세/κ΄€λ ¨/검색 λ“± CONFIRMED νƒœκ·Έλ§Œ λ…ΈμΆœν•˜λŠ” ν™”λ©΄κ³Ό 착용 정보 집계에 λ°”λ‘œ λ°˜μ˜λœλ‹€.
tags.forEach(OotdTag::confirm);
ootdTagRepository.saveAll(tags);
ootd.markAutoTagsReady();

tags.stream()
.map(OotdTag::getItem)
.distinct()
.forEach(this::recalculateWearStats);

log.info("AI νƒœκ·Έ μ €μž₯ μ™„λ£Œ - ootdId={}, μ €μž₯된 νƒœκ·Έ 수={}/{} (보유 μ•„μ΄ν…œ λ§€μΉ­ μ‹€νŒ¨λΆ„ μ œμ™Έ)", ootdId, tags.size(), results.size());
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ spring:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: trueaㅝ
format_sql: true
show-sql: false

sql:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ void saveAiTags_filtersOutResultsBelowConfidenceThreshold() {
when(ootdRepository.findById(OOTD_ID)).thenReturn(Optional.of(ootd));
when(itemRepository.findByOwner_IdAndItemStatusOrderByCreatedAtDesc(OWNER_ID, ItemStatus.OWNED))
.thenReturn(List.of(jacket, sneakers));
when(ootdTagRepository.findWearStatsByItemId(anyLong(), eq(TagStatus.CONFIRMED), eq(OotdPublicationStatus.ACTIVE)))
.thenReturn(wearStats(1, LocalDateTime.now()));

List<AiTagResult> results = List.of(
aiTagResult("블루쒅 μžμΌ“", "μ•„μš°ν„°", BigDecimal.valueOf(0.92)),
Expand All @@ -677,12 +679,12 @@ void saveAiTags_filtersOutResultsBelowConfidenceThreshold() {
assertThat(savedTags).hasSize(2);
assertThat(savedTags).allSatisfy(tag -> {
assertThat(tag.getSource()).isEqualTo(TagSource.AI);
assertThat(tag.getStatus()).isEqualTo(TagStatus.AUTO_UNCONFIRMED);
assertThat(tag.getStatus()).isEqualTo(TagStatus.CONFIRMED);
assertThat(tag.getItem()).isNotNull();
});
assertThat(savedTags).extracting(OotdTag::getLabelText)
.containsExactlyInAnyOrder("블루쒅 μžμΌ“", "μš΄λ™ν™”");
assertThat(ootd.getTagStatus()).isEqualTo(OotdTagStatus.AUTO_UNCONFIRMED);
assertThat(ootd.getTagStatus()).isEqualTo(OotdTagStatus.CONFIRMED);
}

@Test
Expand All @@ -694,6 +696,8 @@ void saveAiTags_filtersOutResultsWithOutOfRangeBbox() {
when(ootdRepository.findById(OOTD_ID)).thenReturn(Optional.of(ootd));
when(itemRepository.findByOwner_IdAndItemStatusOrderByCreatedAtDesc(OWNER_ID, ItemStatus.OWNED))
.thenReturn(List.of(jacket));
when(ootdTagRepository.findWearStatsByItemId(anyLong(), eq(TagStatus.CONFIRMED), eq(OotdPublicationStatus.ACTIVE)))
.thenReturn(wearStats(1, LocalDateTime.now()));

AiTagResult validResult = aiTagResult("블루쒅 μžμΌ“", "μ•„μš°ν„°", BigDecimal.valueOf(0.92));
AiTagResult outOfRangeResult = new AiTagResult(
Expand Down Expand Up @@ -738,7 +742,7 @@ void saveAiTags_skipsResultWhenNoOwnedItemMatches() {
verify(ootdTagRepository).saveAll(captor.capture());

assertThat(captor.getValue()).isEmpty();
assertThat(ootd.getTagStatus()).isEqualTo(OotdTagStatus.AUTO_UNCONFIRMED);
assertThat(ootd.getTagStatus()).isEqualTo(OotdTagStatus.CONFIRMED);
}

@Test
Expand Down
Loading