Skip to content

[Release] 4.0.0 변경사항 배포 - #223

Merged
KiSeungMin merged 72 commits into
mainfrom
develop
Jun 30, 2026
Merged

KiSeungMin merged 72 commits into
mainfrom
develop

Conversation

@KiSeungMin

Copy link
Copy Markdown
Contributor

📝 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요

  • 소셜 스터디룸 백엔드 도메인과 API를 추가했습니다.
    • 스터디룸 생성, 목록/상세 조회, 이름/썸네일 수정, 삭제, 초대 코드 발급, 초대 코드 참여, 탈퇴, 멤버 강퇴, 개인 주간 목표 설정을 지원합니다.
    • 피드 조회와 피드 반응 API를 추가하고, 문제 등록/풀이 완료 등 기존 학습 활동과 스터디룸 활동 피드를 연동했습니다.
    • 공유 문제 등록, 목록 조회, 삭제, 반응, 댓글 CRUD, 댓글 반응 API를 추가했습니다.
    • 공유 문제 중복 공유를 방지하고, 삭제 시 댓글/반응 잔여 데이터가 남지 않도록 정리 로직을 보강했습니다.
  • 스터디룸 챌린지 기능을 추가하고 진행률 집계를 확장했습니다.
    • 개인/그룹 챌린지, 측정 지표, DAILY/WEEKLY/MONTHLY 기간 기준 집계를 지원합니다.
    • periodDays 기반 임의 주기 챌린지를 지원합니다.
    • 주기형 챌린지는 현재 구간 기준으로 진행률을 계산하고, 기간 종료 전 조기 완료 처리되지 않도록 조정했습니다.
    • 챌린지 삭제 권한, 진행 상태, 히스토리 조회, 완료 시각 기록을 보강했습니다.
  • 스터디룸 주간 리포트 기능을 추가했습니다.
    • 주간 리포트 생성, 조회, 읽음 처리, 상위 멤버/최장 스트릭/총 문제 수/완료 챌린지 정보를 제공합니다.
    • 리포트 응답에 대표 멤버 프로필 이미지 URL을 포함했습니다.
  • 스터디룸 FCM 알림을 추가했습니다.
    • 챌린지 기간 50% 경과, 마감 D-1, 챌린지 달성 완료, 공유 문제 등록, 공유 문제 반응, 공유 문제 댓글 작성 알림을 추가했습니다.
    • Quartz 기반으로 챌린지 예약 알림을 등록/취소하고, 챌린지 완료 시 룸 전체에 즉시 알림을 발송합니다.
  • 커스텀 이모지 기반 감정/반응 기능을 추가했습니다.
    • 공통 CustomEmojiValidator와 에러 케이스를 추가했습니다.
    • 복습 완료 시 소감 이모지를 저장하고, 복습노트 상세/썸네일 응답에 노출합니다.
    • 학습 캘린더 날짜별 감정 이모지 등록/수정 API와 응답 필드를 추가했습니다.
    • 스터디룸 피드/공유 문제/댓글 반응 이모지 검증을 커스텀 이모지 키 기반으로 전환했습니다.
  • 이미지 업로드 흐름을 Presigned URL 방식으로 확장했습니다.
    • S3 Presigned URL 발급 API를 추가했습니다.
    • 문제 이미지, 풀이 이미지, 스터디룸 썸네일, 사용자 프로필 이미지를 URL 등록 방식으로 저장할 수 있도록 API를 추가했습니다.
    • 기존 멀티파트 업로드는 유지하면서 image/jpg, application/octet-stream 등 업로드 MIME 허용 범위를 보강했습니다.
  • 사용자 프로필 이미지 기능을 추가했습니다.
    • 사용자 정보 응답에 프로필 이미지 URL을 포함했습니다.
    • 프로필 이미지 멀티파트 업로드, Presigned URL 등록, 삭제 API를 추가했습니다.
    • 스터디룸 멤버/댓글/챌린지/리포트 응답에 프로필 이미지 URL을 포함했습니다.
  • 폴더/썸네일 응답을 보강했습니다.
    • 폴더 썸네일 응답에 problemCount를 추가했습니다.
    • 스터디룸 목록 응답에 멤버 프로필 이미지와 오늘 연습 여부를 추가했습니다.
  • 운영 안정성 개선을 반영했습니다.
    • AI 분석 처리 트랜잭션을 분리해 deadlock 및 self-invocation 문제를 완화했습니다.
    • ProblemAnalysis DLQ 처리 시 PROCESSING 상태 고착을 방지했습니다.
    • getUserInfo의 사용자 조회와 last active 갱신 트랜잭션을 통합했습니다.
    • Discord Webhook 전송을 RabbitMQ 비동기 처리로 전환했습니다.
    • Sentry 4xx ApplicationException 노이즈 필터링을 추가했습니다.
    • 오답노트 여러 장 등록 시 Hibernate JDBC batch 설정을 추가했습니다.
    • refresh_token 컬럼 인덱스를 추가했습니다.
  • 랜딩 페이지에 스터디룸 섹션과 스크린샷 이미지를 추가하고, 간격/갤러리 배치를 개선했습니다.
  • 에이전트 작업 문서와 PR/이슈 자동화 가이드를 갱신했습니다.

👤 사용자 영향

  • 사용자는 스터디룸을 만들고 초대 코드로 멤버를 초대해 함께 학습 활동을 공유할 수 있습니다.
  • 스터디룸 안에서 목표, 챌린지, 피드, 공유 문제, 댓글, 반응, 주간 리포트를 사용할 수 있습니다.
  • 챌린지와 공유 문제 활동에 대한 FCM 알림을 받을 수 있습니다.
  • 학습 캘린더와 복습노트에 커스텀 이모지 기반 감정 기록이 표시됩니다.
  • 프로필 이미지가 사용자 정보, 스터디룸 멤버, 댓글, 리포트 등에 표시됩니다.
  • 기존 문제/풀이/스터디룸/프로필 이미지 업로드는 Presigned URL 방식으로 확장되어 모바일 앱에서 대용량 이미지 업로드 부담을 줄일 수 있습니다.
  • 기존 Flutter 앱에는 응답 필드 추가가 포함되므로, 구버전 앱이 unknown field를 무시하는 구조인지 최종 확인이 필요합니다.

🔌 API 호환성

  • 요청/응답 DTO 변경 없음

  • 기존 Flutter 앱 버전과 호환 확인

  • breaking change 있음

  • 신규 API가 다수 추가되었습니다.

    • /api/study-room, /api/study-rooms
    • /api/study-room/{roomId}/feed
    • /api/study-room/{roomId}/challenges
    • /api/study-room/{roomId}/shared-problems, /api/study-rooms/{roomId}/shared-problems
    • /api/study-room/{roomId}/weekly-reports
    • /api/fileUpload/presigned-urls
    • /api/learning-calendar/mood
    • /api/users/me/profile-image, /api/users/me/profile-image-url
    • /api/problems/{problemId}/imageData/urls
    • /api/problem-solves/{problemSolveId}/image-urls
  • 기존 API 응답에 필드가 추가되었습니다.

    • 사용자 응답: profileImageUrl
    • 학습 캘린더 응답: moodEmojiKey
    • 복습노트 응답: lastSessionMoodEmojiKey
    • 폴더/썸네일 응답: problemCount
    • 스터디룸 관련 응답: 멤버 프로필 이미지, 오늘 연습 여부, 통계/리포트 정보
  • 기존 계약에 대한 주의사항

    • 요청/응답 DTO 변경은 있으나 대부분 신규 필드 추가와 신규 API 추가입니다.
    • Flutter 구버전에서 추가 응답 필드 무시가 가능한지 확인이 필요합니다.
    • 스터디룸 공유 문제 중복 등록은 409 ALREADY_SHARED_PROBLEM으로 응답합니다.

🗄️ DB migration

  • 없음

  • 있음: migration 파일과 기존 데이터 호환성 확인

  • 추가된 migration

    • V6__add_study_room_schema.sql
    • V7__add_custom_emoji_fields.sql
    • V8__add_study_room_challenge_period.sql
    • V9__widen_study_room_reaction_emoji.sql
    • V10__add_shared_problem_comment.sql
    • V11__add_comment_reactions_and_user_profile_image.sql
    • V12__add_challenge_period_days.sql
    • V13__drop_study_session.sql
    • V14__delete_session_started_feeds.sql
    • V15__add_challenge_completed_at.sql
    • V16__add_weekly_report_profile_image_urls.sql
    • V17__add_refresh_token_index.sql
  • 주요 schema 영향

    • 스터디룸, 멤버, 초대 코드, 피드, 반응, 챌린지, 공유 문제, 댓글, 주간 리포트 테이블이 추가됩니다.
    • practice_note.last_session_mood_emoji_key, user.profile_image_url, study_room_challenge.period, study_room_challenge.period_days, study_room_challenge.completed_at, 주간 리포트 프로필 이미지 컬럼이 추가됩니다.
    • 스터디룸 반응 이모지 컬럼 길이가 VARCHAR(80)으로 확장됩니다.
    • study_session 테이블은 제거되고, 기존 SESSION_STARTED 피드는 삭제됩니다.
    • refresh_token.refresh_token(255) 인덱스가 추가됩니다.
  • 배포 전 확인 필요

    • 운영 DB에 study_session 테이블 또는 SESSION_STARTED 피드가 의미 있는 데이터로 사용 중인지 확인해야 합니다.
    • Flyway migration 순서가 운영 DB의 현재 version과 충돌하지 않는지 확인해야 합니다.
    • refresh_token 인덱스 생성 시간이 운영 DB 크기에서 허용 가능한지 확인해야 합니다.

🔐 인증/권한

  • 영향 없음

  • 사용자별 데이터 소유권 검증 확인

  • 관리자/특수 권한 영향 확인

  • 스터디룸 API는 멤버 여부, 방장 권한, 작성자 권한을 기준으로 접근을 제한합니다.

  • 스터디룸 이름/썸네일 수정, 삭제, 멤버 강퇴 등은 방장 권한 검증이 필요합니다.

  • 공유 문제 댓글 수정/삭제, 공유 문제 삭제, 반응 등록은 멤버십과 작성자/방장 정책을 기준으로 동작합니다.

  • 사용자 프로필 이미지 변경/삭제는 본인 계정 기준으로 처리됩니다.

✅ 검증 결과

  • git log --oneline --no-merges b642e7c6..develop로 기준 커밋 이후 커밋 범위를 확인했습니다.
  • git diff --stat b642e7c6..develop 기준 158 files changed, 8959 insertions(+), 178 deletions(-) 변경을 확인했습니다.
  • git diff --name-status b642e7c6..develop로 변경 파일 범위를 확인했습니다.
  • PR 메시지 작성 시점에는 테스트를 직접 실행하지 않았습니다. 실제 PR 제출 전 아래 검증을 권장합니다.
    • ./gradlew test
    • 스터디룸 API 통합 테스트 전체
    • Flyway migration 적용 검증
    • RabbitMQ/Quartz/FCM 알림 흐름 스테이징 검증
    • Flutter 구버전 앱 응답 파싱 호환성 확인
  • 변경에 포함된 테스트
    • 스터디룸 생성/초대/참여/탈퇴/멤버 관리/목표 설정 통합 테스트
    • 스터디룸 피드/반응 통합 테스트
    • 스터디룸 챌린지 API 및 서비스 테스트
    • 공유 문제/댓글/댓글 반응 통합 테스트
    • 주간 리포트 통합 테스트
    • 학습 캘린더 감정 이모지 테스트
    • 복습노트 소감 이모지 테스트
    • 폴더 썸네일 problemCount 관련 테스트
    • 사용자 프로필 이미지 관련 테스트

🚀 배포 리스크

  • DB migration이 많고 신규 테이블/컬럼/인덱스/데이터 삭제가 포함되어 있어, 운영 배포 전 Flyway dry-run 또는 스테이징 적용 확인이 필요합니다.
  • V13__drop_study_session.sql, V14__delete_session_started_feeds.sql는 데이터 삭제 성격이 있으므로 운영 데이터 사용 여부를 반드시 확인해야 합니다.
  • RabbitMQ 기반 Discord Webhook, ProblemAnalysis DLQ, FCM 알림, Quartz 예약 작업이 포함되어 있어 큐/스케줄러 설정 누락 시 일부 알림이 지연되거나 발송되지 않을 수 있습니다.
  • 스터디룸 API는 신규 도메인 범위가 크므로 권한 검증 누락이 사용자 데이터 노출로 이어질 수 있습니다. 멤버십/방장/작성자 권한 흐름을 스테이징에서 재확인해야 합니다.
  • Presigned URL 방식은 클라이언트 업로드 순서와 URL 등록 API 호출 순서가 맞아야 하므로, Flutter 앱 배포 버전과 백엔드 배포 순서를 맞춰야 합니다.
  • 기존 응답 DTO에 필드가 추가되어 구버전 Flutter 앱에서 JSON 파싱 방식이 엄격하면 호환성 문제가 생길 수 있습니다.
  • refresh_token 인덱스 생성은 DB 크기에 따라 배포 중 lock 또는 지연 가능성이 있습니다.

↩️ 롤백/대응 방법

  • 애플리케이션 배포 문제만 발생한 경우, DB migration 적용 여부를 확인한 뒤 이전 서버 버전으로 롤백합니다.
  • migration 적용 후 롤백이 필요한 경우 신규 테이블/컬럼/인덱스와 데이터 삭제 migration 영향 때문에 단순 서버 롤백만으로는 완전 복구되지 않을 수 있습니다.
  • 배포 전 운영 DB 백업을 확보하고, 특히 study_session 테이블 및 SESSION_STARTED 피드 삭제 전 데이터 사용 여부를 확인합니다.
  • 알림 장애가 발생하면 RabbitMQ consumer, Quartz scheduler, FCM 설정을 우선 확인하고, 핵심 학습/문제 풀이 API와 분리해서 대응합니다.
  • Presigned URL 업로드 장애가 발생하면 기존 멀티파트 업로드 API 유지 여부를 확인해 클라이언트에서 임시 우회할 수 있습니다.
  • 스터디룸 기능에서 권한/데이터 노출 문제가 발견되면 스터디룸 관련 엔드포인트를 우선 제한하거나, 해당 Flutter 진입점을 비활성화하는 방식으로 사용자 노출을 줄입니다.

스크린샷 (선택)

  • 랜딩 페이지 스터디룸 섹션 이미지가 추가되었습니다.
  • API PR 본문에는 별도 스크린샷 생략 가능

KiSeungMin and others added 30 commits June 4, 2026 22:51
- .claude/settings.local.json: 머신별 권한 설정이므로 공유 제외
- CLAUDE.md: 운영 제약·빌드 명령·구조·작업 파이프라인 문서화
- .claude/agents/: logic-reviewer, api-contract-checker, code-tracer 등 전문 에이전트 정의
- .claude/commands/: feat, check, plan, test 등 슬래시 커맨드 정의
- .claude/hooks/db_safety_check.py: DROP·TRUNCATE·WHERE 없는 DELETE 차단 훅
- build.config.toml, review.config.toml: 빌드·리뷰 모드 설정
- skills/: feat, plan, check, test, perf 등 Codex 스킬 정의
- scripts/codex-notify-macos.sh: macOS 알림 스크립트
- 스키마 초기화 명령(flyway의 clean 서브커맨드) 감지 추가
- JPA ddl-auto 위험 모드(create/create-drop) 감지 추가
- 볼륨 삭제 플래그(-v) 포함한 compose down 차단
- 프로덕션 DB 직접 접속 명령 차단
- WHERE 절 없는 UPDATE 감지 추가
- 사용자 영향, API 호환성, DB migration 체크리스트 추가
- 인증/권한, 검증 결과, 배포 리스크, 롤백 방법 섹션 추가
- CLAUDE.md: 자유 작업 범위를 읽기·로컬 검증으로 한정, git 작업은 명시 요청 시에만 수행
- CLAUDE.md: 인프라·외부 발송·되돌리기 어려운 작업 사전 확인 절차 명확화
- .gitignore: /AGENTS.md 항목 제거
- .codex/USAGE.md: migrate, pr 스킬 추가 및 문서화
- .codex/skills/check/SKILL.md: description 영문화, 불필요 공백 제거
- .claude/hooks/__pycache__/: 바이트코드 캐시는 로컬 생성물이므로 제외
- AGENTS.md: AI 에이전트 작업 시 따를 공통 규칙 정의
- 사용자·서비스 맥락, 산출물 기준 등 포함
- .claude/commands/pr.md: 기준 커밋~현재 변경사항으로 PR 초안 작성 커맨드
- .codex/skills/pr/: Codex pr 스킬 정의
- .codex/skills/migrate/: Flyway 마이그레이션 파일 작성 및 안전성 검토 스킬
- .codex/scripts/agent-config-lint.sh: 에이전트 설정 파일 유효성 검사 스크립트
- .github/workflows/agent-config-lint.yml: PR 시 에이전트 설정 변경 자동 검사 워크플로
[Chore] 에이전트 작업 환경 정비 - Claude Code/Codex 설정 추가 DB 안전성 훅 및 lint CI 추가
[Chore] 에이전트 PR/이슈 명령 자동화 개선
- 허용 이모지 키 목록과 검증기, 에러 케이스 정의
- 복습노트 소감 컬럼·학습 캘린더 감정 테이블 추가 마이그레이션(V7) 추가
- 학습 기록이 있는 날짜에 한해 감정 이모지(mood) 등록/수정 PATCH API 추가
- 캘린더 응답에 moodEmojiKey 포함, 컨트롤러/서비스 테스트 보강
- 복습 완료 요청에 moodEmojiKey 옵션 추가, 최신 복습노트에 저장 및 응답 노출
- 허용되지 않은 이모지 키 검증 테스트 추가
- 피드/공유문제 반응의 고정 이모지 화이트리스트를 공통 CustomEmojiValidator로 대체
- 반응 emoji 컬럼 길이를 80자로 확장하는 마이그레이션(V9) 추가
- ATTENDANCE 등 신규 측정 지표와 챌린지 기간(DAILY/WEEKLY/MONTHLY) 컬럼 추가(V8)
- 기존 WEEKLY_PROBLEM_COUNT 등은 역직렬화 호환을 위해 @deprecated 유지, 챌린지 생성 권한을 방장에서 멤버로 완화
- 방 목록/상세에 멤버별·전체 오늘 복습 횟수·인원 통계 노출, 멤버 수 일괄 조회 쿼리 추가
- 통합 테스트의 반응 이모지 표기를 커스텀 이모지 키로 갱신
- @PathVariable/@RequestParam에 name 속성을 명시해 파라미터 이름 추론 실패 위험 제거
- 방장이 멀티파트 이미지를 업로드해 스터디룸 썸네일을 변경하는 PATCH 엔드포인트 추가
- S3 업로드 후 기존 썸네일은 비동기 삭제 큐로 정리, 응답으로 새 썸네일 URL 노출
- 정상 업로드/교체 및 비방장 접근 차단 검증 통합 테스트 추가
- 공유 문제 삭제 전 해당 문제에 달린 반응을 함께 삭제하는 리포지토리 메서드 추가
- 외래키 제약 위반 없이 공유 문제를 삭제할 수 있도록 서비스 로직 보강
- DAILY/WEEKLY/MONTHLY 주기 챌린지의 진행 상황을 전체 기간이 아닌 현재 구간 기준으로 집계하도록 변경
- 주기형 챌린지는 그룹·개인 목표 달성만으로 조기 완료 처리되지 않고 종료 시점까지 진행 상태 유지
- 집계 구간 산출 로직 검증 단위 테스트 추가
KiSeungMin and others added 25 commits June 29, 2026 19:29
- V14: study_room_feed 테이블에서 event_type='SESSION_STARTED' 행 전체 삭제
- 공부중 세션 기능 폐기 후 enum에서 SESSION_STARTED 제거로 발생하는 500 오류 해소
- isAllowedImageType, hasAllowedImageSignature에 image/jpg 케이스 추가
- 모바일(Flutter)에서 비표준 MIME 타입 image/jpg로 전송 시 400 오류 해소
image_cropper 등 모바일 라이브러리가 MIME 타입을 application/octet-stream으로
전송하는 경우 extension 기반으로 실제 이미지 타입을 추론하도록 수정.
magic bytes 검증은 그대로 유지하여 보안 수준은 동일하게 유지됨.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[Fix] 스터디룸 QA 수정 - StudySession 제거 및 썸네일 업로드 개선
- 4xx 상태코드의 ApplicationException은 Sentry 전송에서 제외
  (유효하지 않은 토큰, 파일/문제 없음, 태그 길이 초과 등 사용자 오류는 제외)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- analyzeProblemSync 트랜잭션을 데이터 조회/저장으로 분리
  (OpenAI 호출 중 DB 커넥션 장기 점유 방지 → 동시 업데이트 충돌 감소)
- RabbitMQ 분석 consumer 동시성 1-3 → 1-2 감소
  (Deadlock 발생 가능성 추가 완화)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- phone-duo gap 12px → 24px (노트북 기준 스크린샷 간격 개선)
- 스터디룸 피처 섹션 추가: 스터디룸 개설 · 챌린지 · 학습 피드 · 주간 리포트 설명

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- HibernatePropertiesCustomizer로 batch_size=50, order_inserts/updates=true 적용
- saveAll 호출 시 INSERT/UPDATE 묶음 처리로 DB 라운드트립 감소

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- StudyRoomChallengeService.checkAndNotifyChallengeCompletionForUser 추가
  (사용자가 속한 룸의 IN_PROGRESS 챌린지를 일괄 조회 후 완료 여부 즉시 확인)
- StudyRoomFeedService.handleActivity에서 활동 발생 시 챌린지 완료 체크 호출
  (문제 등록·복습 완료·문제 공유 시점에 즉시 알림 발송 가능)
- REQUIRES_NEW 독립 트랜잭션으로 피드 생성 트랜잭션과 격리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ProblemAnalysisDbService 신규 빈으로 fetchAnalysisPreparation, saveAnalysisSuccess 분리
  → analyzeProblemSync에서 직접 self-call 대신 별도 빈 호출로 AOP 프록시 정상 적용
- analyzeProblemSync에 @transactional(NOT_SUPPORTED) 추가
  → OpenAI 호출 중 DB 커넥션 미점유 설계 의도 실제 동작
- saveAnalysisSuccess에 COMPLETED 상태 중복 체크 추가
  → 동시 처리 시 이미 완료된 분석 덮어쓰기 방지
- PROBLEM_ANALYSIS_NOT_FOUND 예외를 Consumer와 Service 양쪽에서 graceful skip 처리
  → 문제 삭제 후 Phase 3 실행 시 불필요한 DLQ 처리 방지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- V15 마이그레이션: study_room_challenge 테이블에 completed_at 컬럼 추가
- StudyRoomChallengeRepository에 tryTransitionFromInProgress 추가
  → UPDATE WHERE status = 'IN_PROGRESS' 원자적 실행으로 단 하나의 스레드만 1 반환
- StudyRoomChallengeService.toResponse에서 COMPLETED 전이 시 원자적 쿼리 사용
  → 동시 트랜잭션이 같은 챌린지를 동시에 완료 처리해도 FCM은 1회만 발송

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GET /api/fileUpload/presigned-urls?count=N&contentType=image/jpeg
- 앱이 백엔드 경유 없이 S3에 직접 PUT 업로드 가능
- presignedUrl(10분 유효) + fileUrl(업로드 후 백엔드에 전달할 최종 URL) 반환
- count 최대 20 제한
- 기존 multipart 업로드 엔드포인트는 그대로 유지 (구 버전 앱 호환)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PATCH /api/study-room/{roomId}/thumbnail-url
  OnO S3 URL 검증 후 썸네일 교체, 기존 이미지 비동기 삭제
- POST /api/problems/{problemId}/imageData/urls
  기존 이미지 유지하며 새 이미지 URL 추가, AI 분석 재트리거
- POST /api/problem-solves/{problemSolveId}/image-urls
  복습 기록에 이미지 URL 추가 (순서 이어받기)
- FileUploadService.validateS3Url(): OnO 버킷 URL 검증 공통 헬퍼 추가
- 기존 multipart API 전부 유지 (구버전 앱 호환)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ChallengeMemberProgressResponse에 profileImageUrl 필드 추가
- WeeklyReportResponse에 topMemberProfileImageUrl, longestStreakProfileImageUrl 추가
  V16 마이그레이션으로 study_room_weekly_report 테이블에 컬럼 추가
  리포트 생성 시 User.getProfileImageUrl() 값 저장
- PATCH /api/users/me/profile-image-url 추가
  Presigned URL로 S3에 직접 업로드 후 URL만 전달하는 방식 지원
  기존 multipart API 유지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- UserService에 touchAndFindUser() 메서드 추가 (단일 트랜잭션)
- UserController에서 두 번 호출하던 방식 제거
- DiscordWebhookQueue / DLQ / 바인딩 Bean 추가 (TTL 5분)
- DiscordWebhookProducer, DiscordWebhookConsumer 구현
- DiscordWebhookNotificationService의 RestTemplate 직접 호출 제거
- DLQ 도달(최대 재시도 소진) 시 ProblemAnalysisFailureService.markFailed() 호출
- PROCESSING 상태 고착 방지
- FolderThumbnailResponseDto에 problemCount 추가
- FolderRepository에 countProblemsByFolderIds() 벌크 쿼리 추가
- FolderService에 toFolderThumbnailDtos(), findProblemCountsByFolderIds() 헬퍼 추가
- 관련 Repository / Service / 통합 테스트 보완
- StudyRoomMemberSummary record 추가 (userId, profileImageUrl, practicedToday)
- StudyRoomListResponse에 members 필드 추가
- 멤버카운트 별도 쿼리 제거, 멤버 목록 단건 조회로 통합
- [Fix] FCM RabbitMQ enqueue를 TransactionSynchronization.afterCommit으로 이동 — REQUIRES_NEW 롤백 시 중복 발송 방지
- [Fix] AddProblemImageUrlsRequest.imageDataList, ImageUrlsRequest.imageUrls에 @NotNull 추가 및 컨트롤러 @validated 적용 — null 전송 시 NPE → 500 방지
- [Perf] FolderService.findAllUserFolders 2N+1 쿼리 → 배치 쿼리 전환 (findProblemIdsByFolderIds 신규 추가)
- [Perf] StudyRoomChallengeService.checkAndNotifyChallengeCompletionForUser에 stats 캐시 도입 — 동일 range 챌린지의 중복 DB 쿼리 제거
- [Feat] Presigned URL 발급 엔드포인트에 일일 200회 Rate Limit 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[Feat] 3.6.1 — S3 Presigned URL, 스터디룸 챌린지 알림, 폴더·챌린지 개선 및 다수 버그 수정
@KiSeungMin KiSeungMin self-assigned this Jun 30, 2026
@KiSeungMin KiSeungMin added fix 버그, 오류 수정 feature 새로운 기능 추가 release 출시, main 브랜치에 반영 labels Jun 30, 2026
@KiSeungMin
KiSeungMin merged commit 5333dde into main Jun 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 새로운 기능 추가 fix 버그, 오류 수정 release 출시, main 브랜치에 반영

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant