-
Notifications
You must be signed in to change notification settings - Fork 3
[MERGE] dev->main 병합 #430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MERGE] dev->main 병합 #430
Changes from all commits
04a4d80
1aac9b1
a7db065
0f93843
3615d53
8f8a640
cbdf24f
daa30cc
dc83ab2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -15,7 +15,7 @@ | |||||
| import java.util.List; | ||||||
|
|
||||||
| @RestController | ||||||
| @RequestMapping("/api/notifications") | ||||||
| @RequestMapping("/notifications") | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 베이스 경로 변경은 외부 호환성 파괴 — 기존 경로 병행 제공 권장 /api/notifications → /notifications 변경은 클라이언트/게이트웨이/문서 전반에 영향이 큽니다. 최소 한 리리스 동안 구 경로를 병행 제공해 다운타임/배포 순서 문제를 방지하세요. 안전한 이행을 위한 최소 수정: -@RequestMapping("/notifications")
+@RequestMapping({"/notifications", "/api/notifications"})체크리스트:
📝 Committable suggestion
Suggested change
|
||||||
| @RequiredArgsConstructor | ||||||
| public class NotificationController { | ||||||
|
|
||||||
|
|
@@ -31,7 +31,10 @@ public ResponseEntity<ApiResponse<List<NotificationResponseDto.UnReadNotificatio | |||||
| return ResponseEntity.ok(ApiResponse.onSuccess(notificationQueryService.getAllUnReadNotifications())); | ||||||
| } | ||||||
|
|
||||||
| @Operation(summary = "알림 읽음 처리 API") | ||||||
| @Operation( | ||||||
| summary = "알림 읽음 처리 API", | ||||||
| description = "NotificationType은 알림 조회 응답의 type 필드를 그대로 보내면 됩니다" | ||||||
| ) | ||||||
| @ApiErrorCodeExamples({ | ||||||
| ErrorStatus.NOTIFICATION_NOT_FOUND, | ||||||
| ErrorStatus.INVALID_NOTIFICATION_TYPE | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package stackpot.stackpot.notification.entity; | ||
|
|
||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
| import stackpot.stackpot.common.BaseEntity; | ||
| import stackpot.stackpot.pot.entity.Pot; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Builder | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @AllArgsConstructor | ||
| public class PotEndNotification extends BaseEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "pot_end_notification_id") | ||
| private Long id; | ||
|
|
||
| private Boolean isRead; | ||
|
|
||
| @OneToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name = "pot_id") | ||
| private Pot pot; | ||
|
|
||
| public void updateIsRead(Boolean isRead) { | ||
| this.isRead = isRead; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package stackpot.stackpot.notification.event; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import stackpot.stackpot.notification.dto.NotificationResponseDto; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public class PotEndEvent { | ||
| private Long potId; | ||
| private NotificationResponseDto.UnReadNotificationDto unReadNotificationDto; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,20 +8,26 @@ | |||||||||||||
| import stackpot.stackpot.notification.entity.FeedCommentNotification; | ||||||||||||||
|
|
||||||||||||||
| import java.util.List; | ||||||||||||||
| import java.util.Optional; | ||||||||||||||
|
|
||||||||||||||
| public interface FeedCommentNotificationRepository extends JpaRepository<FeedCommentNotification, Long> { | ||||||||||||||
|
|
||||||||||||||
| @Query("SELECT new stackpot.stackpot.notification.dto.NotificationDto$UnReadNotificationDto(" + | ||||||||||||||
| "fcn.id, fcn.feedComment.feed.feedId, " + | ||||||||||||||
| "fcn.feedComment.user.nickname, 'FeedComment', fcn.feedComment.comment, fcn.createdAt) " + | ||||||||||||||
| "fcn.id, " + | ||||||||||||||
| "null, " + | ||||||||||||||
| "f.feedId, " + | ||||||||||||||
| "u.nickname, " + | ||||||||||||||
| "'피드 댓글 알림', " + | ||||||||||||||
| "CONCAT(u.nickname, ' 새싹님의 댓글이 달렸어요. ', fc.comment), " + | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JPQL CONCAT 3개 인자 사용은 JPA 표준 위반 — 런타임 에러 가능성이 큽니다 JPQL 표준 CONCAT은 2개 인자만 허용합니다. 현재 3개 인자를 사용하고 있어 데이터베이스/방언에 따라 즉시 실패할 수 있습니다. 중첩 CONCAT으로 치환해 주세요. 다음 패치를 적용하세요: - "CONCAT(u.nickname, ' 새싹님의 댓글이 달렸어요. ', fc.comment), " +
+ "CONCAT(CONCAT(u.nickname, ' 새싹님의 댓글이 달렸어요. '), fc.comment), " +📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| "fcn.createdAt) " + | ||||||||||||||
| "FROM FeedCommentNotification fcn " + | ||||||||||||||
| "WHERE fcn.isRead = false AND (" + | ||||||||||||||
| " (fcn.feedComment.parent is null AND fcn.feedComment.feed.user.id = :userId) OR " + | ||||||||||||||
| " (fcn.feedComment.parent is not null AND " + | ||||||||||||||
| " (fcn.feedComment.parent.user.id = :userId OR fcn.feedComment.feed.user.id = :userId)" + | ||||||||||||||
| " ))") | ||||||||||||||
| List<NotificationDto.UnReadNotificationDto> findAllUnReadNotificationsByUserId(Long userId); | ||||||||||||||
| "JOIN fcn.feedComment fc " + | ||||||||||||||
| "JOIN fc.user u " + | ||||||||||||||
| "JOIN fc.feed f " + | ||||||||||||||
| "LEFT JOIN fc.parent fcp " + | ||||||||||||||
| "WHERE fcn.isRead = false AND " + | ||||||||||||||
| "((fc.parent is null AND f.user.id = :userId) OR " + | ||||||||||||||
| " (fc.parent is not null AND (fcp.user.id = :userId OR f.user.id = :userId)))") | ||||||||||||||
|
Comment on lines
+27
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain자기 자신의 활동에 대한 알림 제외 조건 누락 댓글 작성자(u)가 수신자(:userId)와 동일한 경우까지 매칭되어 자기 자신의 행동에 대한 알림이 노출될 수 있습니다. 일반적으로는 제외하는 것이 기대 동작입니다. 확인 후 제외 조건을 추가해 주세요. 제안 패치: - "WHERE fcn.isRead = false AND " +
+ "WHERE fcn.isRead = false AND u.id <> :userId AND " +
"((fc.parent is null AND f.user.id = :userId) OR " +
" (fc.parent is not null AND (fcp.user.id = :userId OR f.user.id = :userId)))")의도적으로 자기 알림을 허용하는 요구사항이라면 본 제안은 무시하셔도 됩니다. 요구사항만 확인 부탁드립니다. 🏁 Script executed: #!/usr/bin/env bash
set -e
# Show 15 lines of context around the HQL query to verify alias definitions
rg -n '"WHERE fcn.isRead' -C15 src/main/java/stackpot/stackpot/notification/repository/FeedCommentNotificationRepository.java || trueLength of output: 1352 자기 자신의 활동에 대한 알림 제외 조건 추가 필요 아래 쿼리에서 댓글 작성자(u)가 수신자(:userId)와 동일한 경우에도 알림이 조회되고 있으므로, 문제가 되는 위치:
제안 수정(diff): - "WHERE fcn.isRead = false AND " +
+ "WHERE fcn.isRead = false AND u.id <> :userId AND " +
"((fc.parent is null AND f.user.id = :userId) OR " +
" (fc.parent is not null AND (fcp.user.id = :userId OR f.user.id = :userId)))")요구사항상 본인이 발생시킨 댓글 알림까지 허용해야 하는 특별한 이유가 없다면, 위 패치를 적용해 주세요. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| List<NotificationDto.UnReadNotificationDto> findAllUnReadNotificationsByUserId(@Param("userId") Long userId); | ||||||||||||||
|
|
||||||||||||||
| @Modifying | ||||||||||||||
| @Query("DELETE FROM FeedCommentNotification fcn WHERE fcn.feedComment.id = :feedCommentId") | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🛠️ Refactor suggestion
🧩 Analysis chain
JPA 스타터 중복 및 하이버네이트 개별 의존성 수동 지정은 제거 권장
중복/충돌 가능성을 빠르게 점검하려면:
추가 정리 예시(참고용): com.mysql:mysql-connector-j 하나만 유지하고, mysql:mysql-connector-java는 제거하는 구성이 최신 권장입니다.
dependencies { runtimeOnly 'com.mysql:mysql-connector-j' // mysql:mysql-connector-java 는 제거 }🏁 Script executed:
Length of output: 494
🏁 Script executed:
Length of output: 137
중복 및 불필요 의존성 제거 필요
아래 사항들을 반영해 빌드 스크립트에서 중복·불필요 의존성을 제거해주세요.
• 28줄에 이미 선언된 JPA 스타터를 93줄(또는 마지막 deps 블록)에서 다시 선언하고 있습니다. 중복 선언은 버전 충돌 및 빌드 속도 저하를 유발하므로 제거가 필요합니다.
• 94줄의
org.hibernate.common:hibernate-commons-annotations:6.0.6.Final은 Spring Boot BOM이 관리하는 항목입니다. 특별한 이슈가 없다면 수동 버전 고정 대신 BOM에 위임하세요.• 37줄에
com.mysql:mysql-connector-j를 선언하면서• 38, 62, 78줄에
mysql:mysql-connector-java:8.0.33을 여러 차례 선언하고 있습니다.→
runtimeOnly 'com.mysql:mysql-connector-j'하나만 남기고 나머지는 모두 제거하세요.dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.hibernate.common:hibernate-commons-annotations:6.0.6.Final' - runtimeOnly 'mysql:mysql-connector-java:8.0.33' - implementation 'mysql:mysql-connector-java:8.0.33' - implementation 'mysql:mysql-connector-java:8.0.33' + // spring-boot-starter-data-jpa, hibernate-commons-annotations: BOM 관리 + // mysql-connector-java: com.mysql:mysql-connector-j 로 통일 runtimeOnly 'com.mysql:mysql-connector-j' }📝 Committable suggestion