Skip to content

Commit d867bcf

Browse files
authored
Merge branch 'develop' into develop
2 parents d8462a5 + 714c779 commit d867bcf

34 files changed

Lines changed: 689 additions & 142 deletions

.github/workflows/dev-cd.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ jobs:
125125
export CLOTH_INFERENCE_PATH=${{ secrets.CLOTH_INFERENCE_PATH }}
126126
export STYLE_INFERENCE_PATH=${{ secrets.STYLE_INFERENCE_PATH }}
127127
export HISTORY_CLOTH_DETECT_PATH=${{ secrets.HISTORY_CLOTH_DETECT_PATH }}
128+
export DEFAULT_PROFILE_IMAGE_URL=${{ secrets.DEFAULT_PROFILE_IMAGE_URL }}
129+
export TODAY_TEMPERATURE_IMAGE_URL=${{ secrets.TODAY_TEMPERATURE_IMAGE_URL }}
128130
129131
mkdir -p /home/ubuntu/secrets
130132
echo "${{ secrets.FIREBASE_SA_JSON_B64 }}" | base64 -d | tee /home/ubuntu/secrets/firebase-sa.json > /dev/null

.github/workflows/prod-cd.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ jobs:
131131
export CLOTH_INFERENCE_PATH=${{ secrets.CLOTH_INFERENCE_PATH }}
132132
export STYLE_INFERENCE_PATH=${{ secrets.STYLE_INFERENCE_PATH }}
133133
export HISTORY_CLOTH_DETECT_PATH=${{ secrets.HISTORY_CLOTH_DETECT_PATH }}
134+
export DEFAULT_PROFILE_IMAGE_URL=${{ secrets.DEFAULT_PROFILE_IMAGE_URL }}
135+
export TODAY_TEMPERATURE_IMAGE_URL=${{ secrets.TODAY_TEMPERATURE_IMAGE_URL }}
134136
135137
mkdir -p /home/ubuntu/secrets
136138
echo "${{ secrets.FIREBASE_SA_JSON_B64 }}" | base64 -d | tee /home/ubuntu/secrets/firebase-sa.json > /dev/null

.github/workflows/prod-openapi.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ concurrency:
1616
jobs:
1717
sync:
1818
runs-on: ubuntu-latest
19-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
19+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
2020

2121
env:
2222
CODIVEAPI_BRANCH: main
2323
PROD_OPENAPI_URL: "${{ secrets.CODIVE_PROD_BASE_URL }}/v3/api-docs"
2424
TARGET_PATH: Sources/CodiveAPI/openapi.yaml
25+
SWAGGER_USERNAME: ${{ secrets.SWAGGER_USERNAME }}
26+
SWAGGER_PASSWORD: ${{ secrets.SWAGGER_PASSWORD }}
2527

2628
steps:
2729
- name: Checkout backend repo (for context only)
@@ -35,7 +37,9 @@ jobs:
3537
echo "Waiting for production OpenAPI to be ready..."
3638
3739
for i in {1..30}; do
38-
if curl -fsS --connect-timeout 5 "$PROD_OPENAPI_URL" > /dev/null; then
40+
if curl -fsS --connect-timeout 5 \
41+
-u "$SWAGGER_USERNAME:$SWAGGER_PASSWORD" \
42+
"$PROD_OPENAPI_URL" > /dev/null; then
3943
echo "Server is ready."
4044
exit 0
4145
fi
@@ -52,6 +56,7 @@ jobs:
5256
set -euo pipefail
5357
echo "Fetching OpenAPI from: $PROD_OPENAPI_URL"
5458
curl -fsSL --retry 5 --retry-delay 2 --connect-timeout 10 --max-time 30 \
59+
-u "$SWAGGER_USERNAME:$SWAGGER_PASSWORD" \
5560
"$PROD_OPENAPI_URL" -o openapi.json
5661
test -s openapi.json
5762
head -c 1 openapi.json | grep -q '{'

clokey-api/dev-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ services:
5555

5656
# Firebase
5757
FIREBASE_CREDENTIALS_PATH: /run/secrets/firebase-sa.json
58+
DEFAULT_PROFILE_IMAGE_URL: ${DEFAULT_PROFILE_IMAGE_URL}
59+
TODAY_TEMPERATURE_IMAGE_URL: ${TODAY_TEMPERATURE_IMAGE_URL}
5860

5961
# JWT
6062
JWT_ACCESS_TOKEN_SECRET: ${JWT_ACCESS_TOKEN_SECRET}

clokey-api/prod-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ services:
5555

5656
# Firebase
5757
FIREBASE_CREDENTIALS_PATH: /run/secrets/firebase-sa.json
58+
DEFAULT_PROFILE_IMAGE_URL: ${DEFAULT_PROFILE_IMAGE_URL}
59+
TODAY_TEMPERATURE_IMAGE_URL: ${TODAY_TEMPERATURE_IMAGE_URL}
5860

5961
# JWT
6062
JWT_ACCESS_TOKEN_SECRET: ${JWT_ACCESS_TOKEN_SECRET}

clokey-api/src/main/java/org/clokey/domain/cloth/dto/response/ClothListResponse.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,22 @@ public record ClothListResponse(
88
@Schema(description = "옷 브랜드 이름", example = "나이키") String brand,
99
@Schema(description = "옷 이름", example = "파란색 후드") String name,
1010
@Schema(description = "상위 카테고리 이름", example = "상의") String parentCategory,
11-
@Schema(description = "하위 카테고리 이름", example = "후드티") String category) {}
11+
@Schema(description = "하위 카테고리 이름", example = "후드티") String category,
12+
@Schema(description = "오늘의 코디에 포함된 옷인지 여부", example = "true")
13+
boolean isTodayCoordinateCloth) {
14+
15+
public ClothListResponse(
16+
Long clothId,
17+
String ImageUrl,
18+
String brand,
19+
String name,
20+
String parentCategory,
21+
String category) {
22+
this(clothId, ImageUrl, brand, name, parentCategory, category, false);
23+
}
24+
25+
public ClothListResponse withTodayCoordinateCloth(boolean isTodayCoordinateCloth) {
26+
return new ClothListResponse(
27+
clothId, ImageUrl, brand, name, parentCategory, category, isTodayCoordinateCloth);
28+
}
29+
}

clokey-api/src/main/java/org/clokey/domain/cloth/service/ClothServiceImpl.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.clokey.domain.cloth.service;
22

3+
import java.time.LocalDate;
4+
import java.time.ZoneId;
35
import java.util.List;
46
import java.util.Map;
57
import java.util.Set;
@@ -17,6 +19,7 @@
1719
import org.clokey.domain.cloth.exception.ClothErrorCode;
1820
import org.clokey.domain.cloth.repository.ClothRepository;
1921
import org.clokey.domain.coordinate.repository.CoordinateClothRepository;
22+
import org.clokey.domain.coordinate.repository.CoordinateRepository;
2023
import org.clokey.domain.history.repository.HistoryClothTagRepository;
2124
import org.clokey.domain.image.event.ImageDeleteEvent;
2225
import org.clokey.domain.search.event.ClothDeleteEvent;
@@ -28,19 +31,24 @@
2831
import org.clokey.response.SliceResponse;
2932
import org.clokey.util.StorageUtil;
3033
import org.springframework.context.ApplicationEventPublisher;
34+
import org.springframework.data.domain.PageRequest;
3135
import org.springframework.data.domain.Slice;
36+
import org.springframework.data.domain.SliceImpl;
3237
import org.springframework.stereotype.Service;
3338
import org.springframework.transaction.annotation.Transactional;
3439

3540
@Service
3641
@RequiredArgsConstructor
3742
public class ClothServiceImpl implements ClothService {
3843

44+
private static final ZoneId KST = ZoneId.of("Asia/Seoul");
45+
3946
private final MemberUtil memberUtil;
4047

4148
private final ClothRepository clothRepository;
4249
private final CategoryRepository categoryRepository;
4350
private final HistoryClothTagRepository historyClothTagRepository;
51+
private final CoordinateRepository coordinateRepository;
4452

4553
private final ApplicationEventPublisher eventPublisher;
4654
private final CoordinateClothRepository coordinateClothRepository;
@@ -115,7 +123,27 @@ public SliceResponse<ClothListResponse> getClothes(
115123
clothRepository.findAllMemberClothesByCategoriesAndSeasons(
116124
lastClothId, size, direction, categoryIds, currentMember.getId(), seasons);
117125

118-
return SliceResponse.from(result);
126+
Set<Long> todayCoordinateClothIds =
127+
coordinateRepository
128+
.findDailyCoordinateByDateAndMemberId(
129+
LocalDate.now(KST), currentMember.getId())
130+
.map(
131+
coordinate ->
132+
coordinate.getCoordinateClothes().stream()
133+
.map(cc -> cc.getCloth().getId())
134+
.collect(Collectors.toSet()))
135+
.orElse(Set.of());
136+
137+
List<ClothListResponse> content =
138+
result.getContent().stream()
139+
.map(
140+
cloth ->
141+
cloth.withTodayCoordinateCloth(
142+
todayCoordinateClothIds.contains(cloth.clothId())))
143+
.toList();
144+
145+
return SliceResponse.from(
146+
new SliceImpl<>(content, PageRequest.of(0, size), result.hasNext()));
119147
}
120148

121149
@Override

clokey-api/src/main/java/org/clokey/domain/history/controller/HistoryController.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.clokey.domain.history.dto.response.MonthlyHistoryResponse;
1717
import org.clokey.domain.history.dto.response.SituationListResponse;
1818
import org.clokey.domain.history.dto.response.StyleListResponse;
19+
import org.clokey.domain.history.dto.response.TodayHistoryExistenceResponse;
1920
import org.clokey.domain.history.service.HistoryService;
2021
import org.clokey.response.BaseResponse;
2122
import org.springframework.validation.annotation.Validated;
@@ -127,6 +128,16 @@ public BaseResponse<HistoryOwnershipCheckResponse> checkHistoryOwnership(
127128
return BaseResponse.onSuccess(GlobalBaseSuccessCode.OK, response);
128129
}
129130

131+
@GetMapping("/today/existence")
132+
@Operation(
133+
operationId = "History_checkTodayHistoryExistence",
134+
summary = "오늘 기록 존재 여부 확인",
135+
description = "현재 사용자가 오늘 작성한 기록이 존재하는지 확인합니다.")
136+
public BaseResponse<TodayHistoryExistenceResponse> checkTodayHistoryExistence() {
137+
TodayHistoryExistenceResponse response = historyService.checkTodayHistoryExistence();
138+
return BaseResponse.onSuccess(GlobalBaseSuccessCode.OK, response);
139+
}
140+
130141
@DeleteMapping("/{historyId}")
131142
@Operation(
132143
operationId = "History_deleteHistory",

clokey-api/src/main/java/org/clokey/domain/history/dto/request/HistoryCreateRequest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.swagger.v3.oas.annotations.media.Schema;
55
import jakarta.validation.Valid;
66
import jakarta.validation.constraints.*;
7+
import java.time.LocalDate;
78
import java.util.List;
89

910
@Schema(description = "기록 생성 요청")
@@ -13,6 +14,9 @@ public record HistoryCreateRequest(
1314
description = "기록의 내용",
1415
example = "안녕 오늘 오지게 덥다 ㄷㄷ;; 근데 한달 뒤면 가을임 벌써 가을 기대 만발ㅋ")
1516
String content,
17+
@NotNull(message = "기록 작성 날짜는 비워둘 수 없습니다.")
18+
@Schema(description = "기록 작성 날짜", example = "2026-04-12")
19+
LocalDate historyDate,
1620
@NotNull(message = "상황 ID는 비워둘 수 없습니다.") @Schema(description = "상황 ID", example = "7")
1721
Long situationId,
1822
@NotNull(message = "스타일 목록은 비워둘 수 없습니다.")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.clokey.domain.history.dto.response;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
public record TodayHistoryExistenceResponse(
6+
@Schema(description = "오늘 기록 존재 여부", example = "true") boolean exists) {
7+
public static TodayHistoryExistenceResponse of(boolean exists) {
8+
return new TodayHistoryExistenceResponse(exists);
9+
}
10+
}

0 commit comments

Comments
 (0)