본인 소유 검증 누락으로 인한 멤버/디바이스 권한 문제 수정 - #69
Conversation
- 멤버 디바이스 조회 기능 수정 - RequestParam email 제거 - 인증된 디바이스 식별자로 멤버 조회하도록 변경 - 디바이스 삭제 기능 수정 - 인증된 디바이스 식별자로 요청자 식별 - 삭제 대상 디바이스 소유권 검증 로직 추가 - Service Input DTO 이메일 필드 제거 - MemberFindInput, DeviceDeleteInput
- MemberServiceTest 예외 메시지 검증 구체화 - MemberControllerTest 불필요한 테스트 및 파라미터 제거
🧪 테스트 커버리지 리포트
|
There was a problem hiding this comment.
Pull request overview
GET /api/v1/members 및 DELETE /api/v1/device에서 email 기반 권한 판단을 제거하고, X-Device-Id 기반으로 본인 조회/본인 소유 디바이스만 삭제되도록 동작을 수정하는 PR입니다. Issue #67에서 지적된 “타 계정 조회/타인 디바이스 삭제 가능” 문제를 해소하는 방향의 변경입니다.
Changes:
GET /api/v1/members조회 기준을email→X-Device-Id(@AuthDevice)로 전환하고 입력 모델을 정리DELETE /api/v1/device에 요청자 디바이스 기반 소유권 검증 추가 및 비소유 시404정책 적용- 관련 테스트/REST Docs 및 에러 메시지 일부 수정
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/com/recyclestudy/member/controller/MemberController.java | 멤버 조회에서 email 쿼리 파라미터 제거, 헤더 기반 조회로 전환 |
| src/main/java/com/recyclestudy/member/controller/DeviceController.java | 디바이스 삭제 입력 생성 시 email 제거(legacy body 값 무시) |
| src/main/java/com/recyclestudy/member/service/MemberService.java | 멤버 조회를 device identifier 기반으로 변경, 디바이스 삭제 시 소유권 검증 추가 |
| src/main/java/com/recyclestudy/member/service/input/MemberFindInput.java | email 의존 제거(식별자만 받도록 변경) |
| src/main/java/com/recyclestudy/member/service/input/DeviceDeleteInput.java | email 의존 제거(요청 디바이스/대상 디바이스 식별자만 사용) |
| src/test/java/com/recyclestudy/member/service/MemberServiceTest.java | 서비스 로직 변경에 맞춘 테스트 수정 및 소유권/Unauthorized 케이스 추가 |
| src/test/java/com/recyclestudy/member/controller/MemberControllerTest.java | 멤버 조회 API 문서/테스트를 헤더 기반으로 일부 전환(일부 레거시 문서 잔존) |
| src/test/java/com/recyclestudy/member/controller/DeviceControllerTest.java | 디바이스 인증/삭제 문서 및 legacy email optional 처리, 에러 메시지 갱신 |
Comments suppressed due to low confidence (2)
src/test/java/com/recyclestudy/member/controller/MemberControllerTest.java:197
- GET /api/v1/members는 이제 @AuthDevice(X-Device-Id) 기반으로만 조회하도록 변경되어 email 쿼리 파라미터로 멤버를 찾지 않습니다(MemberController에서도 @RequestParam 제거). 그런데 이 테스트는 email 파라미터를 문서화/요청에 포함하고, 404(존재하지 않는 멤버) 시나리오를 유지하고 있어 변경된 API 동작과 문서가 어긋납니다. 404 시나리오를 실제 발생 가능한 케이스(예: 401/Unauthorized - 유효하지 않거나 비활성 디바이스)로 바꾸거나, email 파라미터 문서화를 일관되게 optional로 정리해 주세요.
@DisplayName("존재하지 않는 멤버 조회 시 404 응답을 반환한다")
void findAllMemberDevices_NotFoundMember() {
// given
final String email = "notfound@test.com";
final String headerIdentifier = "device-identifier";
given(memberService.findAllMemberDevices(any()))
.willThrow(new NotFoundException("존재하지 않는 멤버입니다"));
// when
// then
given(this.spec)
.filter(document(DEFAULT_REST_DOC_PATH,
builder()
.tag("Member")
.summary("멤버 디바이스 조회")
.description("존재하지 않는 멤버 조회 시 404 응답을 반환한다")
.requestHeaders(
headerWithName("X-Device-Id").description("디바이스 식별자")
)
.queryParameters(
parameterWithName("email").description("이메일 (다음 버전에서 제거 예정)")
)
.responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지")
),
queryParameters(
parameterWithName("email").description("이메일 (다음 버전에서 제거 예정)")
)
))
.header("X-Device-Id", headerIdentifier)
.param("email", email)
.when()
.get("/api/v1/members")
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.body("message", equalTo("존재하지 않는 멤버입니다"));
}
src/test/java/com/recyclestudy/member/controller/MemberControllerTest.java:329
- "존재하지 않는 디바이스 식별자"로 조회 시나리오가 404로 문서화/검증되어 있는데, 실제로는 @AuthDevice 리졸버에서 디바이스 미존재/비활성은 401(UnauthorizedException)로 처리됩니다. 또한 queryParameters 블록 내 email 설명이 한 곳은 "이메일"로, 다른 곳은 "다음 버전에서 제거 예정"으로 섞여 있어 문서가 일관되지 않습니다. 이 케이스를 401로 정리하고, legacy email 파라미터를 유지한다면 optional로 동일하게 표기해 주세요.
@Test
@DisplayName("존재하지 않는 디바이스 식별자로 조회 시 404 응답을 반환한다")
void findAllMemberDevices_NotFoundDevice() {
// given
final String email = "test@test.com";
final String headerIdentifier = "not-found-id";
given(memberService.findAllMemberDevices(any()))
.willThrow(new NotFoundException("존재하지 않는 디바이스 아이디입니다"));
// when
// then
given(this.spec)
.filter(document(DEFAULT_REST_DOC_PATH,
builder()
.tag("Member")
.summary("멤버 디바이스 조회")
.description("존재하지 않는 디바이스 식별자로 조회 시 404 응답을 반환한다")
.requestHeaders(
headerWithName("X-Device-Id").description("디바이스 식별자")
)
.queryParameters(
parameterWithName("email").description("이메일")
)
.responseFields(
fieldWithPath("message").type(JsonFieldType.STRING).description("에러 메시지")
),
queryParameters(
parameterWithName("email").description("이메일 (다음 버전에서 제거 예정)")
)
))
.header("X-Device-Id", headerIdentifier)
.param("email", email)
.when()
.get("/api/v1/members")
.then()
.statusCode(HttpStatus.NOT_FOUND.value())
.body("message", equalTo("존재하지 않는 디바이스 아이디입니다"));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| final List<Device> devices = deviceRepository.findAllByMemberEmail(input.email()); | ||
| return MemberFindOutput.of(input.email(), devices); | ||
| final Member member = memberRepository.findByIdentifier(input.deviceIdentifier()) | ||
| .orElseThrow(() -> new UnauthorizedException("인증되지 않은 디바이스입니다")); |
There was a problem hiding this comment.
memberRepository.findByIdentifier() 실패 시 findAllMemberDevices()만 "인증되지 않은 디바이스입니다"를 사용하고, 같은 패턴을 쓰는 다른 메서드들(findNotificationTime/updateNotificationTime/deleteDevice)은 "유효하지 않은 디바이스입니다"를 사용하고 있습니다. @AuthDevice 리졸버의 메시지/다른 서비스들과도 달라서 클라이언트 입장에서 에러 메시지가 일관되지 않습니다. 이 메서드도 동일한 메시지로 통일하거나(권장), 여기서 구분하려면 실제로 활성 여부를 판단하는 로직을 함께 두는 쪽이 맞습니다.
| .orElseThrow(() -> new UnauthorizedException("인증되지 않은 디바이스입니다")); | |
| .orElseThrow(() -> new UnauthorizedException("유효하지 않은 디바이스입니다")); |
| public void deleteDevice(final DeviceDeleteInput input) { | ||
| deviceRepository.deleteByIdentifier(input.targetDeviceIdentifier()); | ||
| final Member requestMember = memberRepository.findByIdentifier(input.deviceIdentifier()) | ||
| .orElseThrow(() -> new UnauthorizedException("유효하지 않은 디바이스입니다")); | ||
|
|
||
| final Device targetDevice = deviceRepository.findByIdentifier(input.targetDeviceIdentifier()) | ||
| .orElseThrow(() -> new NotFoundException("존재하지 않는 디바이스입니다: %s" | ||
| .formatted(input.targetDeviceIdentifier().getValue()))); | ||
|
|
||
| if (!targetDevice.getMember().hasEmail(requestMember.getEmail())) { | ||
| throw new NotFoundException("존재하지 않는 디바이스입니다: %s".formatted(input.targetDeviceIdentifier().getValue())); | ||
| } | ||
|
|
||
| deviceRepository.delete(targetDevice); |
There was a problem hiding this comment.
deleteDevice()에서 deviceRepository.findByIdentifier(...)는 member를 fetch join하지 않기 때문에, 이후 targetDevice.getMember().hasEmail(...) 호출 시 추가 쿼리가 발생합니다(지금은 1건이라도 항상 추가 round-trip). 소유권 검증/삭제를 한 번의 쿼리로 처리하도록 (1) findByIdentifier에 JOIN FETCH를 추가한 메서드를 만들거나, (2) identifier+member 조건으로 조회/삭제하는 전용 repository 메서드(예: findByIdentifierAndMemberEmail / deleteByIdentifierAndMemberEmail)를 고려해 주세요.
- 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정
* refactor: 디바이스 인증 기능 마이그레이션 - 멤버 디바이스 조회 기능 수정 - RequestParam email 제거 - 인증된 디바이스 식별자로 멤버 조회하도록 변경 - 디바이스 삭제 기능 수정 - 인증된 디바이스 식별자로 요청자 식별 - 삭제 대상 디바이스 소유권 검증 로직 추가 - Service Input DTO 이메일 필드 제거 - MemberFindInput, DeviceDeleteInput * refactor: 리뷰 저장 시 커스텀 주기 소유권 검증 로직 수정 - MemberServiceTest 예외 메시지 검증 구체화 - MemberControllerTest 불필요한 테스트 및 파라미터 제거 * test: 멤버 디바이스 조회 테스트 설명 수정 - 이메일 파라미터 누락 시 200 응답 반환에 맞춰 테스트 설명 수정
* 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)
* 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>
* 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>
* 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>
* 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 설정으로 변경
* 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>
* 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>
🚀 작업 내용
GET /api/v1/members조회 기준을email에서X-Device-Id로 전환DELETE /api/v1/device에 요청자-디바이스 소유권 검증 추가404반환 정책 적용MemberFindInput,DeviceDeleteInput정리 (email의존 제거)📸 이슈 번호
✍ 궁금한 점