Skip to content

코드 리뷰 actions 스크립트 추가 - #72

Merged
jhan0121 merged 1 commit into
be/devfrom
chore/claude-ai-review
Feb 24, 2026
Merged

코드 리뷰 actions 스크립트 추가#72
jhan0121 merged 1 commit into
be/devfrom
chore/claude-ai-review

Conversation

@jhan0121

Copy link
Copy Markdown
Collaborator

🚀 작업 내용

AI 기반 코드 리뷰 actions 스크립트 추가

📸 이슈 번호

  • close #

✍ 궁금한 점

  • X

@jhan0121 jhan0121 self-assigned this Feb 24, 2026
@jhan0121 jhan0121 added the 🎨 chore 스타일 label Feb 24, 2026
@jhan0121 jhan0121 changed the title chore: 코드 리뷰 actions 스크립트 추가 코드 리뷰 actions 스크립트 추가 Feb 24, 2026
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set +e # Continue on error
PR_NUMBER=${{ github.event.pull_request.number }}

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.

[보안] 스크립트 인젝션 취약점

${{ ... }} 표현식을 run 블록 내에 직접 보간하면 스크립트 인젝션 위험이 있습니다. GitHub Actions 공식 보안 가이드에서는 컨텍스트 값을 환경 변수로 전달할 것을 권장합니다.

github.event.pull_request.number는 정수이므로 현재는 안전하지만, 패턴 자체가 위험한 습관입니다.

Suggested change
PR_NUMBER=${{ github.event.pull_request.number }}
PR_NUMBER=$PR_NUMBER_ENV
REPO=$REPO_ENV

env 블록에 다음을 추가하세요:

env:
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  PR_NUMBER_ENV: ${{ github.event.pull_request.number }}
  REPO_ENV: ${{ github.repository }}

}
}
}' \
--jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | select([.comments.nodes[].author.login] | all(. == "github-actions")) | .comments.nodes[].databaseId' \

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.

[버그] bot 로그인 식별자 불일치

25번째 줄에서는 "github-actions[bot]"을 사용하고, 여기서는 "github-actions"를 사용하고 있습니다. GitHub REST API와 GraphQL API에서 bot 계정의 login 필드가 다르게 반환될 수 있어 한쪽 삭제 로직이 동작하지 않을 수 있습니다.

  • REST API: user.login == "github-actions[bot]"
  • GraphQL API: author.login은 보통 "github-actions[bot]" 또는 "app/github-actions"

GraphQL에서 실제 반환값을 확인하고 일치시켜야 합니다.

Suggested change
--jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | select([.comments.nodes[].author.login] | all(. == "github-actions")) | .comments.nodes[].databaseId' \
--jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | select([.comments.nodes[].author.login] | all(. == "github-actions[bot]")) | .comments.nodes[].databaseId' \

@github-actions

Copy link
Copy Markdown
Contributor

🧪 테스트 커버리지 리포트

Overall Project 96.56% 🍏

There is no coverage information present for the Files changed

done
echo "✅ 이전 리뷰 삭제 완료"
- name: Run Claude Code Review
uses: anthropics/claude-code-action@v1

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.

[보안] 액션 버전 고정 권장

@v1과 같은 가변 태그는 태그가 다른 커밋을 가리키도록 변경될 경우 예기치 않은 코드가 실행될 수 있습니다(공급망 공격). 특히 외부 써드파티 액션은 특정 커밋 SHA로 고정하는 것이 더 안전합니다.

Suggested change
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@da822ce4b5bbccd4e0cf9e4cd1c4c6fb9a61f531 # v1

SHA는 사용 시점의 최신 v1 태그 커밋을 확인하여 업데이트하세요.

query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
reviewThreads(last: 100) {

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.

[제한] GraphQL 페이지네이션 미처리

reviewThreads(last: 100)은 최대 100개의 스레드만 가져옵니다. 리뷰 스레드가 100개를 초과하는 대형 PR에서는 오래된 스레드가 삭제되지 않고 남을 수 있습니다.

필요하다면 pageInfohasNextPage/endCursor를 이용한 페이지네이션을 추가하는 것을 고려해주세요. (일반적인 PR에서는 100개면 충분할 수 있으므로, 트레이드오프를 고려하여 판단하세요.)

on:
pull_request:
types: [ opened, reopened, synchronize ]
jobs:

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.

[개선] concurrency 설정 누락

synchronize 이벤트가 짧은 간격으로 여러 번 발생하면(빠른 연속 커밋) 여러 워크플로우가 동시에 실행될 수 있습니다. 이 경우 삭제 → 리뷰 생성 단계가 서로 경쟁하여 예상치 못한 동작이 발생할 수 있습니다.

concurrency 설정을 추가하면 동일 PR에 대한 이전 실행을 자동으로 취소할 수 있습니다:

Suggested change
jobs:
jobs:
concurrency:
group: code-review-${{ github.event.pull_request.number }}
cancel-in-progress: true

(들여쓰기 없이 jobs: 와 같은 레벨에 위치해야 합니다.)

@jhan0121
jhan0121 merged commit 71978ea into be/dev Feb 24, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in recycle-study Feb 24, 2026
jhan0121 added a commit that referenced this pull request Mar 2, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)
@jhan0121
jhan0121 deleted the chore/claude-ai-review branch March 7, 2026 05:28
jhan0121 added a commit that referenced this pull request Mar 7, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
jhan0121 added a commit that referenced this pull request Mar 9, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

* 이메일 재전송 포기 기준을 maxRetry 횟수 -> deadline 기반으로 전환 (#84)

* refactor: 전송 실패 이메일 재전송 기능 정리

* test: 테스트 회귀 문제 수정

* notification_history.review_cycle_id unique constraint 추가 (#86)

* chore: NotificationHistory review_cycle_id에 유니크 제약 조건 추가

* refactor: NotificationHistory 유니크 제약 조건명 명시

* style: NotificationHistory 테이블 설정 개행 정리

* deadline을 PENDING 생성 시점에 결정하도록 NotificationHistory 설계 개선 (#89)

* refactor: NotificationHistory deadline 계산 로직 변경
  - 새로운 복습 주기가 추가될 때, 계산하도록 수정

* README.md 설명 추가 (#90)

* docs: README.md 설명 추가

- 프로젝트 소개 추가
- 서비스 기능 설명 추가
- 기술 스택 추가
- 아키텍처 다이어그램 추가

* docs: README 문서 이미지 및 뱃지 수정

- 이미지 너비 100% 설정
- 기술 스택 뱃지 줄바꿈 추가

* docs: README 뱃지 색상 수정

- Loki, Tempo 뱃지 색상 변경

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
jhan0121 added a commit that referenced this pull request Mar 9, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

* 이메일 재전송 포기 기준을 maxRetry 횟수 -> deadline 기반으로 전환 (#84)

* refactor: 전송 실패 이메일 재전송 기능 정리

* test: 테스트 회귀 문제 수정

* notification_history.review_cycle_id unique constraint 추가 (#86)

* chore: NotificationHistory review_cycle_id에 유니크 제약 조건 추가

* refactor: NotificationHistory 유니크 제약 조건명 명시

* style: NotificationHistory 테이블 설정 개행 정리

* deadline을 PENDING 생성 시점에 결정하도록 NotificationHistory 설계 개선 (#89)

* refactor: NotificationHistory deadline 계산 로직 변경
  - 새로운 복습 주기가 추가될 때, 계산하도록 수정

* README.md 설명 추가 (#90)

* docs: README.md 설명 추가

- 프로젝트 소개 추가
- 서비스 기능 설명 추가
- 기술 스택 추가
- 아키텍처 다이어그램 추가

* docs: README 문서 이미지 및 뱃지 수정

- 이미지 너비 100% 설정
- 기술 스택 뱃지 줄바꿈 추가

* docs: README 뱃지 색상 수정

- Loki, Tempo 뱃지 색상 변경

* 서버 및 DB 시간 처리 정책 UTC로 통일 (#93)

* fix: 서버 타임존 처리 UTC로 통일

* fix: 서버 타임존 처리 UTC로 통일

* refactor: UTC 변환로직을 도메인 레이어로 이동

* refactor: Jackson 설정 application.yaml 설정으로 변경

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
jhan0121 added a commit that referenced this pull request May 19, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정



---------



* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

* 이메일 재전송 포기 기준을 maxRetry 횟수 -> deadline 기반으로 전환 (#84)

* refactor: 전송 실패 이메일 재전송 기능 정리

* test: 테스트 회귀 문제 수정

* notification_history.review_cycle_id unique constraint 추가 (#86)

* chore: NotificationHistory review_cycle_id에 유니크 제약 조건 추가

* refactor: NotificationHistory 유니크 제약 조건명 명시

* style: NotificationHistory 테이블 설정 개행 정리

* deadline을 PENDING 생성 시점에 결정하도록 NotificationHistory 설계 개선 (#89)

* refactor: NotificationHistory deadline 계산 로직 변경
  - 새로운 복습 주기가 추가될 때, 계산하도록 수정

* README.md 설명 추가 (#90)

* docs: README.md 설명 추가

- 프로젝트 소개 추가
- 서비스 기능 설명 추가
- 기술 스택 추가
- 아키텍처 다이어그램 추가

* docs: README 문서 이미지 및 뱃지 수정

- 이미지 너비 100% 설정
- 기술 스택 뱃지 줄바꿈 추가

* docs: README 뱃지 색상 수정

- Loki, Tempo 뱃지 색상 변경

* 서버 및 DB 시간 처리 정책 UTC로 통일 (#93)

* fix: 서버 타임존 처리 UTC로 통일

* fix: 서버 타임존 처리 UTC로 통일

* refactor: UTC 변환로직을 도메인 레이어로 이동

* refactor: Jackson 설정 application.yaml 설정으로 변경
jhan0121 added a commit that referenced this pull request May 19, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

* 이메일 재전송 포기 기준을 maxRetry 횟수 -> deadline 기반으로 전환 (#84)

* refactor: 전송 실패 이메일 재전송 기능 정리

* test: 테스트 회귀 문제 수정

* notification_history.review_cycle_id unique constraint 추가 (#86)

* chore: NotificationHistory review_cycle_id에 유니크 제약 조건 추가

* refactor: NotificationHistory 유니크 제약 조건명 명시

* style: NotificationHistory 테이블 설정 개행 정리

* deadline을 PENDING 생성 시점에 결정하도록 NotificationHistory 설계 개선 (#89)

* refactor: NotificationHistory deadline 계산 로직 변경
  - 새로운 복습 주기가 추가될 때, 계산하도록 수정

* README.md 설명 추가 (#90)

* docs: README.md 설명 추가

- 프로젝트 소개 추가
- 서비스 기능 설명 추가
- 기술 스택 추가
- 아키텍처 다이어그램 추가

* docs: README 문서 이미지 및 뱃지 수정

- 이미지 너비 100% 설정
- 기술 스택 뱃지 줄바꿈 추가

* docs: README 뱃지 색상 수정

- Loki, Tempo 뱃지 색상 변경

* 서버 및 DB 시간 처리 정책 UTC로 통일 (#93)

* fix: 서버 타임존 처리 UTC로 통일

* fix: 서버 타임존 처리 UTC로 통일

* refactor: UTC 변환로직을 도메인 레이어로 이동

* refactor: Jackson 설정 application.yaml 설정으로 변경

* notification_history 테이블에 status, deadline 복합 인덱스 추가 (#96)

* db 커넥션 풀 및 jvm 설정 추가 (#99)

- 컨테이너 별 메모리 제한
- jvm 힙 메모리 한도
- hikaricp 누수 감지 시간

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
jhan0121 added a commit that referenced this pull request May 24, 2026
* init: 프로젝트 초기 설정 추가

* 이메일 기반 멀티 디바이스 인증 및 관리 기능 구현 (#3)

* build: JPA 의존성 추가

* feat: BaseEntity 추가

* feat: NullValidator 추가

* feat: docker compose 파일 추가

* feat: Email 추가

* feat: DeviceIdentifier 추가

* test: BaseEntity equals 검증 테스트 추가

* feat: Member 추가

* feat: Device 추가

* style: 불필요한 개행 제거

* feat: DeviceIdentifier 추가

* feat: email에 toString 추가

* feat: Device 정적 팩터리 메서드 구조 수정

- isActive 추가

* feat: RecyclestudyApplication에 비동기 설정 추가

* feat: 이메일 전송 기능을 위한 의존성 추가

* feat: 전역 예외 처리용 ControllerAdvice 추가

* feat: EmailService  추가

* feat: IdentifierCreator 추가

* feat: 멤버 저장 기능 추가

- 멤버 저장
- 디바이스 id 발급

* feat: 멤버의 디바이스 전체 조회 기능 추가

* feat: 디바이스 이메일 인증 메일 발송 기능 추가

* feat: 이메일 인증 기능 추가

* test: MemberServiceTest 불필요한 검증 로직 제거

* feat: GlobalControllerAdvice 예외 처리 로직 추가

* test: MemberControllerTest 추가

* test: DeviceControllerTest 추가

* chore: DeviceControllerTest 패키지 위치 수정

* refactor: Member 이메일 유니크 제약 조건 설정

* refactor: Device 내 Member에 JoinColumn 추가

* refactor: Device identifier 유니크 제약 조건 설정

* refactor: DeviceController 패키지 위치 수정 및 파라미터명 변경

* feat: ActivationExpiredDateTime 추가

* refactor: EmailService 구조 개선

- 로그 추가
- 메서드 분리

* feat: Member 이메일 검증 기능 추가

* feat: Device 소유 검증 기능 추가

* feat: GlobalControllerAdvice  내 DeviceActivationExpiredException 처리 추가

* refactor: 이메일 인증 제한 시간 로직 추가

* jacoco 기반 테스트 커버리지 CI 구축 (#6)

* feat: jacoco 기반 테스트 커버리지 CI 스크립트 추자

* test: 테스트 환경 DB H2 사용하도록 변경

* 디바이스 삭제 기능 추가 (#7)

* feat: 디바이스 삭제 기능 추가

* chore: final 키워드 누락 수정

* fix: 대상 디바이스를 제거하도록 기능 수정

* 등록한 디바이스 조회 기능 응답 형식 수정 (#9)

* fix: 등록한 디바이스 조회 기능 응답 형식 수정

* chore: 실행 sql 로그 출력 기능 활성화

* 복습할 URL 저장 기능 추가 (#10)

* feat: 리뷰 대상 url 저장 기능 추가

* fix: ReviewService 트랜잭션 누락 수정

* swagger 기반 API 문서 작성 (#12)

* feat: swagger 기반 api 문서 기능 추가

* refactor: 불필요한 로그 출력 제거

* refactor: 누락된 타입 명시 로직 추가

* CI 대상 branch 설정 추가 (#13)

* 복습 대상 URL 이메일 전송 스케줄러 구현 (#19)

* feat: Review 엔티티에 Member 연관 관계 추가

* feat: 주기적 복습 이메일 전송 기능 추가

- 공통 이메일 전송 기능 별도 분리 리팩터링 진행

* test: ReviewCycleServiceTest 추가

* refactor: ReviewSendOutput collect 내 불변 리스트를 사용하도록 수정

* refactor: html 태그에 lang 추가

* feat: 이메일 전송 이력 관리 기능 추가

* style: 코드 구조 정리

* refactor: ReviewEmailSender 타임존 설정 추가

* test: 메일 발송 실패 처리 검증 추가

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* flyway 기반 db 마이그레이션 의존성 추가 (#24)

* feat: flyway 기반 db 마이그레이션 의존성 추가

- 환경별 jpa sql 출력 여부 분리

* fix: ReviewCycle#scheduledAt not null 누락 수정

* test: 테스트 환경에서 flyway 비활성화

* 로그 기능 추가 (#21)

* feat: 로그 기능 추가

* chore: 신규 유저 이메일 등록 시작 로그 태그명 수정

* feat: 이메일 마스킹 기능 적용

* refactor: 복습 주기 저장 로그 포맷 수정

* refactor: 이메일 전송 기능 도메인 객체 파라미터로 변경

* test: MemberServiceTest#authenticateDevice 테스트 커버리지 보완 (#22)

* 배포 스크립트 추가 (#31)

* feat: 배포 스크립트 추가

* refactor: docker-compose.yaml env 설정 수정

* chore: 태그 검증 로그 메시지 수정

* feat: 모니터링을 위한 alloy 설정 추가 (#34)

* 배포 최적화 적용 (#36)

* 배포 스크립트 오류 수정 (#38)

* fix: 배포 스크립트 오류 수정

* fix: trace 연결 문제 수정

* 모니터링 설정 불일치 수정 (#40)

* feat: 모니터링 설정 추가

* fix: 로그 경로 불일치 수정

* 모니터링 연결 오류 수정 (#43)

* fix: loki, tempo 연결 오류 수정

* refactor: 모니터링용 컨테이너 설정 코드 병합

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 1) (#46)

* feat: 디바이스 인증 기능 ArgumentResolver 추가

* refactor: 디바이스 id를 헤더를 활용하도록 마이그레이션 과정 추가

* 디바이스 인증 방식 헤더 마이그레이션 (Phase 3) (#49)

* hotfix: prod - dev 불일치 수정 (#51)

* 사용자 커스텀 복습 주기 관리 및 커스텀 주기 기반 리뷰 저장 기능 구현 (#53)

* chore: 불필요한 메서드 제거

* feat: 복습 주기 엔티티 추가

* feat: 커스텀 복습 주기 조회 기능 추가

* feat: 커스텀 복습 주기 저장 기능 추가

* feat: 커스텀 복습 주기 수정/삭제 기능 추가

* feat: 기본 복습 주기 처리 로직 수정

* style: 코드 컨벤션 정리

* style: 코드 컨벤션 정리

* feat: 주기별 리뷰 저장 기능 주기 옵션 설정 로직 추가

* refactor: 주기별 리뷰 저장 기능 주기 하위 호환성 분기 처리 추가

* refactor: ReviewService#calculateScheduledAts 초 단위 절삭 적용

* style: 불필요한 개행 제거

* LocalDateTime 초 단위 절삭 적용 (#54)

* 이메일 전송 실패 재시도 로직 구현 (#56)

* refactor: 리뷰 이메일 전송 기능 비동기 처리

* feat: 메일 전송 실패 재시도 로직 추가

* refactor: 리뷰 메일 재전송 로직 보완

- PENDING 데이터 고려
- 테스트 코드 추가 보완

* test: 불필요한 테스트 코드 제거

* 멤버 알림 시간 설정 변경 기능 추가 (#59)

* feat: 사용자 선호 알림 시간 설정 및 적용 기능 구현

- 리뷰 생성 시 1일 이상의 주기는 사용자 설정 시간에 맞춰 스케줄링되도록 로직 수정

* style: 테스트 코드 포맷팅 수정

* fix: 멤버 알림 시간 변경 로그의 이전 시간 표기 오류 수정

- 알림 시간 업데이트 후 로깅 시 변경 전 시간이 아닌 변경 후 시간이 기록되는 문제 수정

* 복습 주기 하위 호환성 로직 제거 (#61)

* style: 코드 컨벤션 정리

- 불필요한 import 제거
- 코드 포맷팅 수정

* refactor: 복습 주기 하위 호환성 로직 제거

- 프런트엔드 마이그레이션 완료에 따라 null 입력 시 기본 주기로 변환하는 로직 제거

* test: 불필요한 테스트 시나리오 제거

* test: 불필요한 테스트 시나리오 제거

* feat: 멤버 알림 시간 조회 API 추가 (#63)

- 멤버 조회 API에서 알림 시간 조회 기능 분리

* 로그 패턴에 스레드 정보 추가 (#65)

* chore: 콘솔 로그 패턴에 스레드 정보 추가

* chore: 파일 로그 패턴에 스레드 정보 추가

* 복습 주기 조회 쿼리 성능 개선 (#66)

* refactor: 복습 주기 조회 쿼리 성능 개선

- review_cycle 테이블 scheduled_at 컬럼 인덱스 추가
- findAllByScheduledAt 조회 시 fetch join 적용

* chore: 파일 개행 누락 수정

* 본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 (#69)

* refactor: 디바이스 인증 기능 마이그레이션

- 멤버 디바이스 조회 기능 수정
- RequestParam email 제거
- 인증된 디바이스 식별자로 멤버 조회하도록 변경

- 디바이스 삭제 기능 수정
- 인증된 디바이스 식별자로 요청자 식별
- 삭제 대상 디바이스 소유권 검증 로직 추가

- Service Input DTO 이메일 필드 제거
- MemberFindInput, DeviceDeleteInput

* refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정

- MemberServiceTest 예외 메시지 검증 구체화
- MemberControllerTest 불필요한 테스트 및 파라미터 제거

* test: 멤버 디바이스 조회 테스트 설명 수정

- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정

* feat: 리뷰 저장 시 커스텀 복습 주기 소유권 검증 로직 추가 (#71)

* 코드 리뷰 actions 스크립트 추가 (#72)

* Virtual Thread 적용을 통한 이메일 발송 처리량 개선 (#75)

* chore: virtual thread 설정 추가

- application.yaml VT 설정 추가
- Dockerfile 런타임 JDK 25버전으로 상향 조정

* chore: Docker 이미지 태그 버전 고정

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* 이메일 발송 로직 notification_history outbox 패턴 전환 (#77)

* refactor: 이메일 전송 로직 재구성

- notification_history를 outbox 패턴 전환: append-only INSERT → 단건 UPDATE 방식
- fail_count, last_attempted_at 컬럼 추가
- 스케줄러 조회를 정확 일치에서 범위 조회로 변경해 서버 다운 시 PENDING 누락 방지
- findAllRetryableCycles에 cutoffDateTime으로 단기 주기 재시도 제외

* refactor: 불필요한 트랜잭션 annotation 제거

* refactor: clearAutomatically 적용

* refactor: 벌크 update 결과 검증 로직 추가

* style: 단기 주기 판단 기준 주석화

* refactor: NotificationHistoryService#updateStatus 로직 최적화

* 다음 리뷰 전송 예정 정보 조회 API 구현 (#79)

* feat: 다음 리뷰 주기 조회 기능 추가

* refactor: NotificationHistoryRepository#findAllByMemberAndStatus로 메서드명 수정

* Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체 (#81)

* chore: Gmail SMTP에서 AWS SES SDK v2로 이메일 발송 인프라 교체

* refactor: 이메일 전송 예외 처리 및 테스트 보완

* 이메일 재전송 포기 기준을 maxRetry 횟수 -> deadline 기반으로 전환 (#84)

* refactor: 전송 실패 이메일 재전송 기능 정리

* test: 테스트 회귀 문제 수정

* notification_history.review_cycle_id unique constraint 추가 (#86)

* chore: NotificationHistory review_cycle_id에 유니크 제약 조건 추가

* refactor: NotificationHistory 유니크 제약 조건명 명시

* style: NotificationHistory 테이블 설정 개행 정리

* deadline을 PENDING 생성 시점에 결정하도록 NotificationHistory 설계 개선 (#89)

* refactor: NotificationHistory deadline 계산 로직 변경
  - 새로운 복습 주기가 추가될 때, 계산하도록 수정

* README.md 설명 추가 (#90)

* docs: README.md 설명 추가

- 프로젝트 소개 추가
- 서비스 기능 설명 추가
- 기술 스택 추가
- 아키텍처 다이어그램 추가

* docs: README 문서 이미지 및 뱃지 수정

- 이미지 너비 100% 설정
- 기술 스택 뱃지 줄바꿈 추가

* docs: README 뱃지 색상 수정

- Loki, Tempo 뱃지 색상 변경

* 서버 및 DB 시간 처리 정책 UTC로 통일 (#93)

* fix: 서버 타임존 처리 UTC로 통일

* fix: 서버 타임존 처리 UTC로 통일

* refactor: UTC 변환로직을 도메인 레이어로 이동

* refactor: Jackson 설정 application.yaml 설정으로 변경

* notification_history 테이블에 status, deadline 복합 인덱스 추가 (#96)

* db 커넥션 풀 및 jvm 설정 추가 (#99)

- 컨테이너 별 메모리 제한
- jvm 힙 메모리 한도
- hikaricp 누수 감지 시간

* Claude 코드 리뷰 동작 개선 및 코멘트 응답 기능 추가 (#102)

* feat: Claude 코드 리뷰 동작 개선 및 코멘트 응답 기능 추가

- `@claude` 멘션 시 응답하는 comment-response.yml 워크플로우 추가
- 중복 실행 방지를 위한 concurrency 설정 추가
- 리액션이 달린 인라인 코멘트는 삭제 대상에서 제외하도록 로직 수정

* fix: Claude 댓글 응답 워크플로우 접근 권한 및 동시성 제어 추가

* review_cycle에 notification_history 병합 및 복합 인덱스 적용 (#104)

* refactor: NotificationHistory 도메인을 ReviewCycle로 병합

- status, failCount, lastAttemptedAt, deadline 필드를 ReviewCycle 엔티티로 이동
- 불필요해진 NotificationHistory 도메인, 리포지토리, 서비스 클래스 제거
- 이메일 전송 상태 업데이트 및 조회 쿼리를 ReviewCycleRepository로 통합
- SingleReviewEmailSender에서 발송 결과 처리 시 ReviewCycleService를 사용하도록 변경
- ReviewService에서 ReviewCycle 엔티티를 생성할 때 발송 상태(PENDING)와 deadline을 함께 설정하도록 구조 변경
- 분리되어 있던 NotificationHistory 저장 로직 제거
- 기존 notification_history 테이블의 데이터를 review_cycle 테이블로 이전 및 제약조건 추가
- 발송 대상 및 재시도 조회를 위한 최적화 복합 인덱스(status, scheduled_at / status, deadline) 추가

* refactor: ReviewCycleRepository 조회 및 벌크 연산 쿼리 개선

- ReviewCycle 조회 쿼리에 Member 엔티티 fetch join 추가
- 상태 업데이트 벌크 연산(@Modifying) 실행 전 영속성 컨텍스트 동기화를 위해 flushAutomatically = true 옵션 추가

* test: ReviewCycleService updateStatus 테스트 추가

- ReviewCycleService updateStatus 관련 테스트 시나리오 추가
- ReviewCycleTest 내 불필요한 import 제거

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 chore 스타일

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant