Skip to content

[Feat] #16 - 미션 생성 API, presigned-url 발급 API 구현 및 기존 엔티티 수정 - #20

Merged
sae2say merged 17 commits into
mainfrom
feat/#16
Aug 31, 2026
Merged

[Feat] #16 - 미션 생성 API, presigned-url 발급 API 구현 및 기존 엔티티 수정#20
sae2say merged 17 commits into
mainfrom
feat/#16

Conversation

@sae2say

@sae2say sae2say commented Aug 16, 2026

Copy link
Copy Markdown
Collaborator

Related issue 🛠

Work Description ✏️

미션 이미지 presigned URL 발급 API 구현

  • 미션 이미지 업로드를 위한 presigned PUT URL을 발급하는 로직 구현.
  • 이미지 파일 형식(jpeg, jpg, png, gif, webp)만 허용하도록 검증.

미션 생성 API 구현

  • 제목, 설명, 난이도, 이미지 URL, 태그(선택)를 입력받아 새로운 미션을 생성하는 로직 구현.
  • RestClient로 runyour.ai를 직접 호출해 미션의 제목, 설명, 태그를 바탕으로 카테고리를 자동 분류. Spring AI는 Boot 4.x 호환 문제로 사용하지 않음.
  • 모델은 claude의 haiku 사용.

미션 찜 추가 / 해제 API 구현

  • 특정 미션을 원하는 여행 일정에 추가하는 로직 구현. 본인 소유의 일정에만 추가 가능.
  • 이미 추가된 일정은 중복 저장 없이 기존 항목을 그대로 반환(멱등).
  • 추가했던 미션을 일정에서 제거하는 로직 구현. 이미 없는 경우 무시(멱등).

미션-일정 데이터 구조 설계

  • 미션 상태(완료 여부 등)가 일정별로 독립적으로 관리되어야 하는 기획을 반영해, 기존 UserMission을 (일정, 미션) 단위로 재설계.
  • 같은 미션이 여러 일정에 각각 담길 수 있으며, 한 일정에서의 완료 처리가 다른 일정에 영향을 주지 않음.
  • 회원별 미션 전체 조회와 특정 일정 내 미션 조회를 모두 지원할 수 있는 구조.

Mission 엔티티 정리

  • 더 이상 사용되지 않는 region, recommended 필드 제거.

CI 개선

  • 테스트 코드 없이도 CI가 통과하도록 수정. 불필요한 DB 서비스 컨테이너 제거로 빌드 시간 단축.

일정별 미션 찜 여부 조회 API 구현

  • 특정 미션에 대해 나의 모든 여행 일정별로 찜 여부를 조회하는 로직 구현.
  • 일정 목록과 찜 데이터를 각각 한 번씩만 조회한 뒤 매핑해 N+1 없이 처리.
  • 찜이 된 일정은 likeId를 함께 반환하고, 안 된 일정은 null로 반환. 일정 생성일 최신순 정렬.

미션 검색 피드에 소스 필터 추가

  • source 쿼리 파라미터(ALL / OFFICIAL / HOT / ADDED, 기본값 ALL)를 추가해 미션 검색 피드를 필터링할 수 있도록 구현.
  • OFFICIAL: 공식 미션만 필터링.
  • HOT: 현재 핫 미션 스냅샷에서 미션 목록을 조회해 카드 형태로 반환.
  • ADDED: 내가 일정에 추가한 미션만 반환(중복 제거, ACTIVE 상태만)

Trouble Shooting ⚽️

Clock이 UTC 기준으로 동작해 핫 미션 집계 윈도우가 UTC로 계산되고, addedAt은 JVM 기본 타임존(KST)으로 저장되어 타임존이 혼용되는 버그 수정. Clock을 Asia/Seoul 기준으로 변경해 집계 윈도우와 저장 시각의 타임존을 일치시킴.

Related ScreenShot 📷

presigned-url 발급 API

image

미션 생성 API

image

미션 찜 설정 API

image

미션 찜 해제 API

image

Uncompleted Tasks 😅

To Reviewers 📢

openAI 사용방식
제가 학교에서 종설할 때 지원받았던 LLM 호출 서드파티 서비스 runyourai의 토큰이 꽤 남아있어서, 이걸 사용해서 LLM 호출하려구요! (18만원 정도 남아있습니다.)
나중에 일정 추천 관련해서도 호출 막 하다보면 어느정도로 토큰이 소비될 진 잘 모르겠는데, 부족하면 그 때 가서 openai 다시 설정할게요!

마이그레이션
userMission의 제약이랑 인덱스를 수정해서, 로컬에서 마이그레이션이 필요할 수 있어요! userMission 테이블 드롭하고 다시 애플리케이션 실행하시거나, 마이그레이션 코드 첨부할게요! 그냥 이 쿼리 실행하면 됩니다

-- 1. 기존 unique 제약 삭제
ALTER TABLE user_mission DROP INDEX uk_user_mission_member_mission;

-- 2. travel_plan_id 컬럼 추가
ALTER TABLE user_mission
    ADD COLUMN travel_plan_id BIGINT NOT NULL,
    ADD CONSTRAINT fk_user_mission_travel_plan
        FOREIGN KEY (travel_plan_id) REFERENCES travel_plan(id);

-- 3. 새 unique 제약 추가
ALTER TABLE user_mission
    ADD CONSTRAINT uk_user_mission_plan_mission UNIQUE (travel_plan_id, mission_id);

-- 4. 인덱스 추가
CREATE INDEX idx_user_mission_travel_plan_id ON user_mission (travel_plan_id);

@laura-jung laura-jung left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

presignedUrl부터 AI 연결까지... 역시 대세희네요...
꼼꼼하게 작업해주셔서 감사합니다. 항상 많이 배워갑니다....

AI 때문에 변경된 yml도 있을 것 같아서 노션에 공유 부탁드릴게요!

코멘트 남긴것도 확인부탁드립니다!

Comment on lines +87 to +93
if (source == MissionSourceTypeOption.HOT) {
return buildHotMissionsResponse(memberId);
}
if (source == MissionSourceTypeOption.ADDED) {
return buildAddedMissionsResponse(memberId);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

HOT이나 ADDED인 경우 여기 if 문에서 바로 반환되어 keyword,sort, page, size와 같은 다른 파라미터들이 적용되지 않을 것 같습니다.
source도 기존 검색 조건과 조합해서 필터링·페이징해야 다른 조건들도 함께 적용될 것 같아요! 아니면 의도적으로 반영되지 않게 기획하신 건지 궁금합니다!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

HOT 미션은 계산 로직에서 top 5개로 자르고 있길래 바로 반환했는데, ADDED는 제가 놓쳤네요! ADDED에 적용해두겠습니다!

Comment on lines +235 to +236
List<TravelPlan> plans = travelPlanRepository.findByMemberIdOrderByCreatedAtDesc(memberId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

이곳에서도 미션 존재 여부를 확인하는 로직이 필요할 것 같아요! 미션이 삭제되어 비활성화된 missionId도 모든 일정이 isLiked=false인 정상 응답을 반환할 것 같습니다!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

앗 그러네요 반영했습니다!

@sae2say
sae2say merged commit c8e6692 into main Aug 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 미션 추가(찜) 기능 구현 [feat] 새로운 미션 생성 기능 구현

2 participants