diff --git a/src/main/java/com/back/domain/notification/controller/NotificationController.java b/src/main/java/com/back/domain/notification/controller/NotificationController.java index 988b9173..eb85c581 100644 --- a/src/main/java/com/back/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/back/domain/notification/controller/NotificationController.java @@ -2,6 +2,10 @@ import com.back.domain.notification.dto.NotificationGoResponseDto; import com.back.domain.notification.dto.NotificationListResponseDto; +import com.back.domain.notification.dto.NotificationSettingDto; +import com.back.domain.notification.service.NotificationSettingService; +import com.back.domain.notification.dto.NotificationSettingUpdateRequestDto; +import jakarta.validation.Valid; import com.back.domain.notification.service.NotificationService; import com.back.global.rsData.RsData; import jakarta.validation.constraints.Max; @@ -21,6 +25,7 @@ public class NotificationController { private final NotificationService notificationService; + private final NotificationSettingService notificationSettingService; @GetMapping("/notifications") public RsData getNotifications( @@ -33,6 +38,23 @@ public RsData getNotifications( return RsData.successOf(body); } + @GetMapping("/notification-setting") + public RsData getMyNotificationSetting( + @AuthenticationPrincipal(expression = "id") Long userId + ) { + NotificationSettingDto body = notificationSettingService.getMySetting(userId); + return RsData.successOf(body); + } + + @PatchMapping("/notification-setting") + public RsData setMyNotificationSetting( + @AuthenticationPrincipal(expression = "id") Long userId, + @Valid @RequestBody NotificationSettingUpdateRequestDto req + ) { + NotificationSettingDto body = notificationSettingService.setMySetting(userId, req.enabled()); + return RsData.successOf(body); + } + @PostMapping("/notifications/{id}") public RsData goPostLink( @AuthenticationPrincipal(expression = "id") Long userId, diff --git a/src/main/java/com/back/domain/notification/dto/NotificationSettingDto.java b/src/main/java/com/back/domain/notification/dto/NotificationSettingDto.java new file mode 100644 index 00000000..055a6605 --- /dev/null +++ b/src/main/java/com/back/domain/notification/dto/NotificationSettingDto.java @@ -0,0 +1,16 @@ +package com.back.domain.notification.dto; + +import com.back.domain.notification.entity.NotificationSetting; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class NotificationSettingDto { + private boolean enabled; + + public static NotificationSettingDto from(NotificationSetting s) { + return new NotificationSettingDto(s.isEnabled()); + } +} + diff --git a/src/main/java/com/back/domain/notification/dto/NotificationSettingUpdateRequestDto.java b/src/main/java/com/back/domain/notification/dto/NotificationSettingUpdateRequestDto.java new file mode 100644 index 00000000..602ab334 --- /dev/null +++ b/src/main/java/com/back/domain/notification/dto/NotificationSettingUpdateRequestDto.java @@ -0,0 +1,8 @@ +package com.back.domain.notification.dto; + +import jakarta.validation.constraints.NotNull; + +public record NotificationSettingUpdateRequestDto( + @NotNull Boolean enabled +) {} + diff --git a/src/main/java/com/back/domain/notification/entity/NotificationSetting.java b/src/main/java/com/back/domain/notification/entity/NotificationSetting.java new file mode 100644 index 00000000..9a2e7e48 --- /dev/null +++ b/src/main/java/com/back/domain/notification/entity/NotificationSetting.java @@ -0,0 +1,44 @@ +package com.back.domain.notification.entity; + +import com.back.domain.user.entity.User; +import jakarta.persistence.*; +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@EntityListeners(AuditingEntityListener.class) +@Getter +@Setter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@AllArgsConstructor +@Builder +public class NotificationSetting { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Setter + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false, unique = true) + private User user; + + @Setter + @Builder.Default + private boolean enabled = true; + + @CreatedDate + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; + + public void toggle() { + this.enabled = !this.enabled; + } + +} diff --git a/src/main/java/com/back/domain/notification/repository/NotificationSettingRepository.java b/src/main/java/com/back/domain/notification/repository/NotificationSettingRepository.java new file mode 100644 index 00000000..7505b8a8 --- /dev/null +++ b/src/main/java/com/back/domain/notification/repository/NotificationSettingRepository.java @@ -0,0 +1,18 @@ +package com.back.domain.notification.repository; + +import com.back.domain.notification.entity.NotificationSetting; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface NotificationSettingRepository extends JpaRepository { + + @Query(""" + select ns from NotificationSetting ns + where ns.user.id = :userId + """) + NotificationSetting findByUserId(@Param("userId") Long userId); +} + diff --git a/src/main/java/com/back/domain/notification/service/NotificationSettingService.java b/src/main/java/com/back/domain/notification/service/NotificationSettingService.java new file mode 100644 index 00000000..6128c5a2 --- /dev/null +++ b/src/main/java/com/back/domain/notification/service/NotificationSettingService.java @@ -0,0 +1,46 @@ +package com.back.domain.notification.service; + +import com.back.domain.notification.dto.NotificationSettingDto; +import com.back.domain.notification.entity.NotificationSetting; +import com.back.domain.notification.repository.NotificationSettingRepository; +import com.back.domain.user.entity.User; +import com.back.domain.user.repository.UserRepository; +import com.back.global.exception.ServiceException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class NotificationSettingService { + + private final NotificationSettingRepository notificationSettingRepository; + private final UserRepository userRepository; + + @Transactional(readOnly = true) + public NotificationSettingDto getMySetting(Long userId) { + NotificationSetting s = notificationSettingRepository.findByUserId(userId); + if (s == null) { + // Default when not created yet + return new NotificationSettingDto(true); + } + return NotificationSettingDto.from(s); + } + + @Transactional + public NotificationSettingDto setMySetting(Long userId, boolean enabled) { + NotificationSetting s = notificationSettingRepository.findByUserId(userId); + if (s == null) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다.")); + s = NotificationSetting.builder() + .user(user) + .enabled(enabled) + .build(); + } else { + s.setEnabled(enabled); + } + NotificationSetting saved = notificationSettingRepository.save(s); + return NotificationSettingDto.from(saved); + } +}