Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import cmf.commitField.domain.commit.sinceCommit.dto.CommitAnalysisResponseDto;
import cmf.commitField.domain.commit.sinceCommit.dto.SinceCommitResponseDto;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand Down
22 changes: 14 additions & 8 deletions src/main/java/cmf/commitField/domain/noti/noti/entity/Noti.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import cmf.commitField.domain.user.entity.User;
import cmf.commitField.global.jpa.BaseEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.ColumnDefault;

import static lombok.AccessLevel.PROTECTED;

Expand All @@ -19,13 +22,16 @@
@Getter
@Setter
public class Noti extends BaseEntity {
@Enumerated(EnumType.STRING)
private NotiType typeCode; // 알림 타입
private NotiDetailType type2Code; // 알림 세부 타입
@ManyToOne
private User actor;
@ManyToOne
private User receiver;
private String relTypeCode;
private long relId;
private String typeCode;
private String type2Code;
private boolean read;
private User receiver; // 알림을 받는 사람
@ColumnDefault("false")
private boolean isRead; // 읽음 상태
private String message; // 알림 메시지

// TODO: 알림이 연결된 객체 어떻게 처리할지 고민 필요.
// private String relTypeCode; // 알림이 연결된 실제 객체 유형
// private long relId; // 알림 객체의 Id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cmf.commitField.domain.noti.noti.entity;

public enum NotiDetailType {
// 업적
ACHIEVEMENT_COMPLETED, // 업적 달성

// 연속
STREAK_CONTINUED, // 연속 커밋 이어짐
STREAK_BROKEN, // 연속 커밋 끊김

// 시즌
SEASON_START // 시즌 시작
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cmf.commitField.domain.noti.noti.entity;

import java.util.Map;

public class NotiMessageTemplates {
// 알림 메시지 템플릿을 저장하는 맵
private static final Map<NotiDetailType, String> TEMPLATES = Map.of(
NotiDetailType.ACHIEVEMENT_COMPLETED, "🎉 {0}님이 '{1}' 업적을 달성했습니다!",
NotiDetailType.STREAK_CONTINUED, "🔥 {0}님의 연속 커밋이 {1}일째 이어지고 있습니다!",
NotiDetailType.STREAK_BROKEN, "😢 {0}님의 연속 커밋 기록이 끊겼습니다. 다음번엔 더 오래 유지해봐요!",
NotiDetailType.SEASON_START, "🚀 새로운 시즌 '{0}'이 시작되었습니다! 랭킹 경쟁을 준비하세요!"
);

// 알림 메시지 템플릿을 반환하는 메서드
public static String getTemplate(NotiDetailType type) {
return TEMPLATES.getOrDefault(type, "알림 메시지가 없습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package cmf.commitField.domain.noti.noti.entity;

public enum NotiType {
RANK, // 랭킹
ACHIEVEMENT, // 업적
ABSENCE, // 부재
STREAK, // 연속
SEASON, // 시즌
NOTICE // 공지
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
package cmf.commitField.domain.noti.noti.eventListener;

import cmf.commitField.domain.noti.noti.entity.NotiDetailType;
import cmf.commitField.domain.noti.noti.entity.NotiType;
import cmf.commitField.domain.noti.noti.service.NotiService;
import cmf.commitField.global.chat.ChatMessageDto;
import cmf.commitField.global.event.CommitHistoryEvent;
import lombok.RequiredArgsConstructor;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class NotiEventListener {
// 이벤트가 호출될 때 실행되는 메서드
// 메서드를 별도의 스레드에서 비동기적으로 실행하도록 만듦
private final NotiService notiService;

// public void listenPost(PostCreatedEvent event){
// notiService.postCreated(event.getPost());
// }
//
// public void consume(ChatMessageDto message){
// System.out.println("Consumed message: " + message);
// }
//
// public void consumeChatRoom1DLT(byte[] in){
// String message = new String(in);
// System.out.println("Failed message: " + message);
// }
// 예시
// CommitHistoryEvent 이벤트가 발생하면 notiService.createCommitStreak() 메서드를 실행
public void listenCommitStreak(CommitHistoryEvent event){
notiService.createCommitStreak(event.getUsername(), NotiType.STREAK, NotiDetailType.STREAK_CONTINUED);
}

@KafkaListener(topics = "chat-room-1", groupId = "1")
public void consume(ChatMessageDto message){
System.out.println("Consumed message: " + message);
}

@KafkaListener(topics = "chat-room-1-dlt", groupId = "1")
public void consumeChatRoom1DLT(byte[] in){
String message = new String(in);
System.out.println("Failed message: " + message);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
package cmf.commitField.domain.noti.noti.service;

import cmf.commitField.domain.noti.noti.entity.Noti;
import cmf.commitField.domain.noti.noti.entity.NotiDetailType;
import cmf.commitField.domain.noti.noti.entity.NotiMessageTemplates;
import cmf.commitField.domain.noti.noti.entity.NotiType;
import cmf.commitField.domain.noti.noti.repository.NotiRepository;
import cmf.commitField.domain.user.entity.User;
import cmf.commitField.domain.user.repository.UserRepository;
import cmf.commitField.global.error.ErrorCode;
import cmf.commitField.global.exception.CustomException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Slf4j
public class NotiService {
private final NotiRepository notiRepository;
private final UserRepository userRepository;

// 알림 메시지 생성
public static String generateMessage(NotiDetailType type, Object... params) {
String template = NotiMessageTemplates.getTemplate(type);
return MessageFormat.format(template, params);
}

// 연속 커밋 알림 생성
@Transactional
public Noti createCommitStreak(String username, NotiType type, NotiDetailType detailType, Object... params) {
// 메시지 생성
String message = NotiService.generateMessage(detailType, params);

public void sendCommitStreakNotification(String username, int streakCount) {
log.info("🎉 {}님의 연속 커밋이 {}일로 증가했습니다!", username, streakCount);
// 알림을 DB 저장 또는 웹소켓 / 이메일 / 푸시 알림 전송 가능
// 사용자 조회 (없으면 예외 처리)
User user = userRepository.findByUsername(username).orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));

// 알림 객체 생성 후 저장
Noti noti = Noti.builder()
.typeCode(type)
.type2Code(detailType)
.receiver(user)
.isRead(false)
.message(message)
.build();

return notiRepository.save(noti);
}



// public CommitAnalysisResponseDto getCommitAnalysis(String owner, String repo, String username, LocalDateTime since, LocalDateTime until) {
// List<SinceCommitResponseDto> commits = getSinceCommits(owner, repo, since, until);
// StreakResult streakResult = calculateStreaks(commits);
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/cmf/commitField/global/chat/ChatMessageDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package cmf.commitField.global.chat;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessageDto {
private String msg;
}
14 changes: 14 additions & 0 deletions src/main/java/cmf/commitField/global/event/CommitHistoryEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cmf.commitField.global.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

// event 객체 참고
@Getter
public class CommitHistoryEvent extends ApplicationEvent {
private final String username;
public CommitHistoryEvent(Object source, String username) {
super(source);
this.username = username;
}
}
5 changes: 5 additions & 0 deletions src/main/java/cmf/commitField/global/jpa/BaseEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ public class BaseEntity {
@CreatedDate
@Getter
private LocalDateTime modifiedAt;

public String getModelName() {
String simpleName = this.getClass().getSimpleName();
return Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
}
}