NotificationCommandService.java

package com.newbit.notification.command.application.service;

import com.newbit.common.exception.BusinessException;
import com.newbit.common.exception.ErrorCode;
import com.newbit.notification.command.application.dto.response.NotificationSendResponse;
import com.newbit.notification.command.domain.aggregate.Notification;
import com.newbit.notification.command.domain.aggregate.NotificationType;
import com.newbit.notification.command.domain.repository.NotificationRepository;
import com.newbit.notification.command.domain.repository.NotificationTypeRepository;
import com.newbit.notification.command.application.dto.request.NotificationSendRequest;
import com.newbit.notification.command.infrastructure.SseEmitterRepository;
import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
@RequiredArgsConstructor
public class NotificationCommandService {

    private final NotificationRepository notificationRepository;
    private final NotificationTypeRepository notificationTypeRepository;
    private final SseEmitterRepository sseEmitterRepository;

    @Transactional
    public void sendNotification(NotificationSendRequest request) {
        // 1. 알림 타입 조회
        NotificationType type = notificationTypeRepository.findById(request.getNotificationTypeId())
                .orElseThrow(() -> new BusinessException(ErrorCode.NOTIFICATION_TYPE_NOT_FOUND));

        // 2. 알림 생성 및 저장
        Notification notification = Notification.create(
                request.getUserId(),
                type,
                request.getServiceId(),
                request.getContent()
        );
        notificationRepository.save(notification);

        // 3. 실시간 알림 전송
        NotificationSendResponse response = NotificationSendResponse.from(notification);
        sseEmitterRepository.send(request.getUserId(), response);
    }



    @Transactional
    public void markAsRead(Long userId, Long notificationId) {
        Notification notification = notificationRepository.findById(notificationId)
                .orElseThrow(() -> new BusinessException(ErrorCode.NOTIFICATION_NOT_FOUND));

        if (!notification.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.UNAUTHORIZED_ACCESS);
        }

        notification.markAsRead(); // 내부에서 isRead = true 처리
    }

    @Transactional
    public void markAllAsRead(Long userId) {
        notificationRepository.markAllAsReadByUserId(userId);
    }
}