Skip to content

fix: [NDGL-141] 컨텐츠 등록 및 구독 API 수정#76

Merged
WooJJam merged 6 commits into
developfrom
feature/NDGL-141-Server-컨텐츠-등록-및-구독-API-수정
May 14, 2026

Hidden character warning

The head ref may contain hidden characters: "feature/NDGL-141-Server-\ucee8\ud150\uce20-\ub4f1\ub85d-\ubc0f-\uad6c\ub3c5-API-\uc218\uc815"
Merged

fix: [NDGL-141] 컨텐츠 등록 및 구독 API 수정#76
WooJJam merged 6 commits into
developfrom
feature/NDGL-141-Server-컨텐츠-등록-및-구독-API-수정

Conversation

@WooJJam
Copy link
Copy Markdown
Member

@WooJJam WooJJam commented May 14, 2026

🤖 이 PR은 AI를 사용하여 자동 생성되었습니다.

요약

사용자 제안 템플릿에서 여행 카테고리를 복수 선택으로 전환하고 DomesticRegion을 제거하여 API·도메인·이벤트·알림을 일관되게 업데이트합니다.
이로써 카테고리가 리스트로 영속화되고 입력 검증 및 알림 표현이 개선됩니다.

변경 내용

  • 여행 카테고리를 단일값에서 복수 선택(리스트)으로 변경
  • DomesticRegion 타입 및 관련 필드를 제거
  • API/도메인/이벤트/퍼블리셔/서비스/엔티티를 복수 카테고리 대응으로 변경
  • TravelCategory enum 항목을 확장하여 추가

참고 사항

  • 카테고리 저장 방식 변경으로 데이터 마이그레이션 및 호환성 점검이 필요합니다.

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 여행 템플릿 카테고리 확장: 맛집, 카페/디저트, 힐링/풍경, 명소, 로컬, 쇼핑, 액티비티/체험, 가성비 등 8가지 카테고리 추가
    • 여행 템플릿에 여러 카테고리 동시 선택 지원
  • Changes

    • 여행 템플릿에서 지역(Region) 필드 제거

전달사항 (클라이언트)

1. POST /api/v1/suggested-templates (제안 템플릿 등록)

변경된 내용

  • 요청 본문 키 표기 변경: video_linkvideoLink, recommend_reasonrecommendReason (모두 camelCase로 통일)
  • recommendReason필수 → 선택 (생략 가능)
  • category단일 enum 값 → 배열로 변경되고 필수가 됨 (최소 1개)
  • region 필드 제거
  • category 허용 값(8개로 확정): FOOD(맛집), CAFE(카페/디저트), HEALING(힐링/풍경), ATTRACTION(명소), LOCAL(로컬), SHOPPING(쇼핑), ACTIVITY(액티비티/체험), BUDGET(가성비). 기존 UNCATEGORIZED 사용 불가

대응 방안

  • 요청 본문을 다음 형태로 보낼 것:
    {
      "videoLink": "https://youtu.be/abc12345678",
      "recommendReason": "선택 입력값",
      "category": ["FOOD", "CAFE"]
    }
  • 카테고리 선택 UI를 다중 선택 가능하게 변경. 기존 UNCATEGORIZED 보내고 있었다면 새 값 중 적절한 것으로 매핑

2. 구독 API: 경로/요청 본문 모두 변경

변경 전: POST /api/v1/suggested-templates/{id}/subscribe
변경 후: POST /api/v1/suggested-templates/subscribe

변경된 내용

  • 경로에서 {id} 제거. 대신 요청 본문으로 영상 링크 전달
    { "videoLink": "https://youtu.be/abc12345678" }
  • 서버가 영상 링크에서 videoId 추출 → PENDING 상태인 제안을 찾아 구독 등록
  • 해당 영상에 PENDING 상태의 제안이 없으면(거절되었거나 이미 처리됨) 404 TRAVEL-02-003 반환

대응 방안

  • 제안 등록 API에서 409 TRAVEL-03-003(다른 사용자가 이미 PENDING 요청 중) 받았을 때, 방금 보냈던 동일 videoLink를 그대로 구독 API 본문에 담아 호출하면 됨. templateId를 알 필요 없음
  • 흐름 예시:
    1. POST /api/v1/suggested-templates 호출 → 409 TRAVEL-03-003
    2. POST /api/v1/suggested-templates/subscribe 호출, body: { "videoLink": "(1번과 동일)" }200
  • 404 응답 처리 추가 필요 (PENDING이 사라진 경우 = 사실상 구독할 영상이 없음)

카테고리 코드 / 라벨 매핑

코드 라벨
FOOD 맛집
CAFE 카페/디저트
HEALING 힐링/풍경
ATTRACTION 명소
LOCAL 로컬
SHOPPING 쇼핑
ACTIVITY 액티비티/체험
BUDGET 가성비

@WooJJam WooJJam self-assigned this May 14, 2026
@WooJJam WooJJam added fix 버그 또는 오류 수정 ai-generated AI로 생성한 PR labels May 14, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Warning

Rate limit exceeded

@WooJJam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 34 minutes and 51 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 200df0a2-6d50-47a5-b941-da2c7ba24b63

📥 Commits

Reviewing files that changed from the base of the PR and between 02d0f02 and 1c02f33.

📒 Files selected for processing (5)
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/UserSuggestedTemplateApi.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/UserSuggestedTemplateController.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/SubscribeUserSuggestedTemplateRequest.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/facade/UserSuggestedTemplateFacade.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/service/UserSuggestedTemplateService.java

요약

제안된 템플릿 카테고리 저장 방식을 단일 값에서 목록 기반으로 변경하고 DomesticRegion 필드를 제거하며, 관련된 API 계약, 이벤트 파이프라인, 데이터 매핑을 함께 업데이트합니다.

변경 사항

카테고리 도메인 모델 리팩토링

계층 / 파일(들) 요약
카테고리 열거형 확장 및 지역 제거
common/src/main/java/com/yapp/ndgl/common/type/TravelCategory.java, common/src/main/java/com/yapp/ndgl/common/type/DomesticRegion.java
TravelCategory 열거형은 UNCATEGORIZED 하나에서 FOOD, CAFE, HEALING, ATTRACTION, LOCAL, SHOPPING, ACTIVITY, BUDGET 등 8개의 명시적 카테고리로 확장되었습니다. DomesticRegion 열거형은 완전히 제거되었습니다.
도메인 및 엔티티 모델 타입 변경
domain/domain-service/src/main/java/com/yapp/ndgl/domain/travel/UserSuggestedTemplate.java, domain/domain-rdb/src/main/java/com/yapp/ndgl/domain/travel/entity/UserSuggestedTemplateEntity.java
category 필드가 TravelCategory에서 List<TravelCategory>로 변경되었고, 엔티티는 JSON 컬럼 매핑(@JdbcTypeCode(SqlTypes.JSON))을 사용하여 데이터베이스에 카테고리 목록을 저장합니다. 두 모델에서 DomesticRegion region 필드가 제거되었습니다.
매퍼 업데이트
domain/domain-service/src/main/java/com/yapp/ndgl/domain/travel/mapper/UserSuggestedTemplateMapper.java
엔티티-도메인 매핑에서 region 설정이 제거되고, 카테고리 목록 변환 로직은 유지됩니다.

API 계약 및 검증 업데이트

계층 / 파일(들) 요약
요청 DTO 구조 변경
application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/CreateUserSuggestedTemplateRequest.java
category 필드가 TravelCategory에서 List<TravelCategory>로 변경되고 @NotEmpty 검증이 추가됩니다. recommendReason 필드는 필수에서 선택사항으로 변경되며, Jackson @JsonProperty 어노테이션이 제거되고 DomesticRegion region 필드가 삭제됩니다.
응답 DTO 및 Swagger 문서
application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/AdminUserSuggestedTemplateResponse.java, application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/UserSuggestedTemplateApi.java
AdminUserSuggestedTemplateResponsecategoryList<String>으로 표현하며, 도메인의 카테고리 목록에서 라벨을 추출하여 매핑합니다. region 필드가 제거됩니다. Swagger 요청 예시는 camelCase 필드명과 카테고리 배열로 업데이트됩니다.
응답 DTO 제거
application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/UserSuggestedTemplateResponse.java
공개 UserSuggestedTemplateResponse 레코드와 from(...) 팩토리 메서드가 완전히 제거되었습니다.

이벤트 파이프라인 및 알림 업데이트

계층 / 파일(들) 요약
이벤트 및 발행자 리팩토링
application/src/main/java/com/yapp/ndgl/application/domains/travel/event/UserSuggestedTemplateCreatedEvent.java, application/src/main/java/com/yapp/ndgl/application/domains/travel/event/publisher/UserSuggestedTemplateEventPublisher.java
UserSuggestedTemplateCreatedEventcategory 필드가 String에서 List<String>으로 변경되고 region 필드가 제거됩니다. 이벤트 발행자는 요청의 category() 목록에서 카테고리 라벨 스트림을 구성하여 이벤트에 전달합니다.
알림 생성 및 텍스트 유틸리티
application/src/main/java/com/yapp/ndgl/application/domains/travel/event/UserSuggestedTemplateNotification.java, common/src/main/java/com/yapp/ndgl/common/util/TextUtils.java
알림의 createEmbeds() 메서드에서 "지역" 필드가 제거되고, 새로운 TextUtils.joinOrDefault(...)TextUtils.defaultIfBlank(...) 메서드를 사용하여 카테고리를 구분자로 결합하고 기본값을 처리합니다.

통합 및 지원 변경

계층 / 파일(들) 요약
서비스 및 테스트 업데이트
application/src/main/java/com/yapp/ndgl/application/domains/travel/service/UserSuggestedTemplateService.java, application/src/test/java/com/yapp/ndgl/application/domains/travel/UserSuggestedTemplateConcurrencyTest.java
서비스의 UserSuggestedTemplate.of(...) 호출에서 request.category()를 전달하고 request.region()은 제거합니다. 동시성 테스트는 CreateUserSuggestedTemplateRequestList.of(TravelCategory.FOOD)를 사용하도록 업데이트됩니다.
로깅 설정
application/src/main/resources/logback-spring.xml
LOG_PATH 설정이 Spring 프로퍼티 바인딩에서 직접 Logback XML <property> 정의로 변경됩니다.

예상 코드 리뷰 노력

🎯 4 (복잡함) | ⏱️ ~45분

관련 PR

  • YAPP-Github/NDGL-BE#75: 이 PR의 관리자 응답 DTO 리팩토링이 #75의 초기 AdminUserSuggestedTemplateResponse 도입과 직접 연계되어 있으며, TravelCategory + DomesticRegion에서 List<String> 카테고리로 변경합니다.
  • YAPP-Github/NDGL-BE#74: 이 PR의 UserSuggestedTemplateCreatedEventList<String> category 변경 및 region 제거와 이벤트/발행자/알림 파이프라인 업데이트가 #74의 초기 구현과 직접 겹칩니다.

제안 라벨

feat


🐰 카테고리 정렬하고 지역은 빠져나가고,
목록 담아 데이터베이스로 날아가고,
이벤트는 새로이 알림을 부르네,
한 뭉텅이에서 여럿으로 피어나며,
템플릿의 옷을 갈아입도다! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 컨텐츠 등록 및 구독 API 수정에 대한 변경 사항과 일치하며, 주요 변경점인 카테고리 구조 개선과 지역 필드 제거를 포괄적으로 설명합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/NDGL-141-Server-컨텐츠-등록-및-구독-API-수정

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@WooJJam WooJJam changed the title feat: [NDGL-141] server 컨텐츠 등록 및 구독 api 수정 feat: [NDGL-141] 컨텐츠 등록 및 구독 API 수정 May 14, 2026
@WooJJam WooJJam changed the title feat: [NDGL-141] 컨텐츠 등록 및 구독 API 수정 fix: [NDGL-141] 컨텐츠 등록 및 구독 API 수정 May 14, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/CreateUserSuggestedTemplateRequest.java`:
- Around line 21-23: The category list in CreateUserSuggestedTemplateRequest can
contain null elements causing NPEs when UserSuggestedTemplateEventPublisher does
request.category().stream().map(TravelCategory::name); add element-level
validation by annotating the List<TravelCategory> category with `@NotNull` on its
elements (e.g., `@NotEmpty` on the list + `@NotNull` for items), import the
appropriate javax/jakarta.validation.constraints.NotNull, and re-run validation
so requests like category: [null] are rejected before reaching
UserSuggestedTemplateEventPublisher.

In
`@application/src/main/java/com/yapp/ndgl/application/domains/travel/event/publisher/UserSuggestedTemplateEventPublisher.java`:
- Around line 26-28: In UserSuggestedTemplateEventPublisher change the mapping
of request.category() from TravelCategory::name to TravelCategory::getLabel so
the event carries the enum's Korean label rather than the constant name; locate
the stream in the method where List<String> category is built and replace
.map(TravelCategory::name) with .map(TravelCategory::getLabel) so Discord
notifications show the user-facing label.

In `@application/src/main/resources/logback-spring.xml`:
- Line 4: 현재 logback 설정에서 <property name="LOG_PATH" value="${LOG_PATH:-logs}"/>는
Logback 변수 치환만 수행해 Spring 환경변수(LOG_PATH)를 읽지 못하므로 배포 환경의 LOG_PATH가 무시됩니다; 변경하려면
해당 <property ...> 항목을 <springProperty scope="context" name="LOG_PATH"
source="LOG_PATH" defaultValue="logs"/>로 되돌려 Spring Environment에서 값을 읽게 하고, 참조하는
코드(예: pattern이나 appender에서 사용하는 LOG_PATH 변수 이름)를 그대로 유지해 환경변수 기반 경로가 정상적으로 적용되도록
하세요.

In
`@domain/domain-rdb/src/main/java/com/yapp/ndgl/domain/travel/entity/UserSuggestedTemplateEntity.java`:
- Around line 41-43: The category field in UserSuggestedTemplateEntity was
changed from a single VARCHAR enum to a JSON List<TravelCategory> (field:
category, type: List<TravelCategory>, enum: TravelCategory), so existing rows
with values like "FOOD" will break; add a migration that converts existing
varchar enum values into JSON arrays (e.g. "FOOD" -> '["FOOD"]') and update the
column DDL if needed (or add an explicit Flyway/Liquibase migration script) to
perform the conversion atomically; alternatively/additionally, add a
backward-compatible read fallback in the repository/service layer that detects
plain string values and wraps them into a single-element JSON array before
deserialization (refer to UserSuggestedTemplateEntity.category and any
repository methods that read/write it).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 97e7cce1-9e8b-42ab-b668-018fd9135502

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab3fb3 and 02d0f02.

📒 Files selected for processing (16)
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/UserSuggestedTemplateApi.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/AdminUserSuggestedTemplateResponse.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/CreateUserSuggestedTemplateRequest.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/UserSuggestedTemplateResponse.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/event/UserSuggestedTemplateCreatedEvent.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/event/UserSuggestedTemplateNotification.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/event/publisher/UserSuggestedTemplateEventPublisher.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/service/UserSuggestedTemplateService.java
  • application/src/main/resources/logback-spring.xml
  • application/src/test/java/com/yapp/ndgl/application/domains/travel/UserSuggestedTemplateConcurrencyTest.java
  • common/src/main/java/com/yapp/ndgl/common/type/DomesticRegion.java
  • common/src/main/java/com/yapp/ndgl/common/type/TravelCategory.java
  • common/src/main/java/com/yapp/ndgl/common/util/TextUtils.java
  • domain/domain-rdb/src/main/java/com/yapp/ndgl/domain/travel/entity/UserSuggestedTemplateEntity.java
  • domain/domain-service/src/main/java/com/yapp/ndgl/domain/travel/UserSuggestedTemplate.java
  • domain/domain-service/src/main/java/com/yapp/ndgl/domain/travel/mapper/UserSuggestedTemplateMapper.java
💤 Files with no reviewable changes (3)
  • common/src/main/java/com/yapp/ndgl/common/type/DomesticRegion.java
  • application/src/main/java/com/yapp/ndgl/application/domains/travel/controller/dto/UserSuggestedTemplateResponse.java
  • domain/domain-service/src/main/java/com/yapp/ndgl/domain/travel/mapper/UserSuggestedTemplateMapper.java

Comment thread application/src/main/resources/logback-spring.xml
@WooJJam WooJJam merged commit b215b3a into develop May 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated AI로 생성한 PR fix 버그 또는 오류 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant