Skip to content

Commit a9676b8

Browse files
authored
Merge pull request #30 from FlipNoteTeam/feat/notification
Feat: [FN-124][FN-125] 알림 생성 및 목록 조회 기능
2 parents 04e50bf + 33e955b commit a9676b8

46 files changed

Lines changed: 869 additions & 39 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ dependencies {
4040
implementation 'net.javacrumbs.shedlock:shedlock-spring:6.9.2'
4141
implementation 'net.javacrumbs.shedlock:shedlock-provider-redis-spring:6.9.2'
4242
implementation 'org.redisson:redisson-spring-boot-starter:3.46.0'
43+
implementation 'org.apache.commons:commons-text:1.14.0'
44+
implementation 'com.google.firebase:firebase-admin:9.5.0'
4345
compileOnly 'org.projectlombok:lombok'
4446
runtimeOnly 'com.mysql:mysql-connector-j'
4547
annotationProcessor 'org.projectlombok:lombok'

src/main/java/project/flipnote/auth/listener/UserWithdrawnEventListener.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package project.flipnote.auth.listener;
22

3-
import org.springframework.context.event.EventListener;
43
import org.springframework.retry.annotation.Backoff;
54
import org.springframework.retry.annotation.Recover;
65
import org.springframework.retry.annotation.Retryable;
76
import org.springframework.scheduling.annotation.Async;
87
import org.springframework.stereotype.Component;
8+
import org.springframework.transaction.event.TransactionPhase;
9+
import org.springframework.transaction.event.TransactionalEventListener;
910

1011
import lombok.RequiredArgsConstructor;
1112
import lombok.extern.slf4j.Slf4j;
1213
import project.flipnote.auth.entity.AccountStatus;
1314
import project.flipnote.auth.repository.UserAuthRepository;
14-
import project.flipnote.common.event.UserWithdrawnEvent;
15+
import project.flipnote.common.model.event.UserWithdrawnEvent;
1516

1617
@Slf4j
1718
@RequiredArgsConstructor
@@ -25,7 +26,7 @@ public class UserWithdrawnEventListener {
2526
maxAttempts = 3,
2627
backoff = @Backoff(delay = 2000, multiplier = 2)
2728
)
28-
@EventListener
29+
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
2930
public void handleUserWithdrawnEvent(UserWithdrawnEvent event) {
3031
userAuthRepository.findByUserIdAndStatus(event.userId(), AccountStatus.ACTIVE)
3132
.ifPresent(userAuth -> {

src/main/java/project/flipnote/auth/model/UserRegisterRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import jakarta.validation.constraints.Email;
44
import jakarta.validation.constraints.NotBlank;
55
import jakarta.validation.constraints.NotNull;
6-
import project.flipnote.common.dto.UserCreateCommand;
6+
import project.flipnote.common.model.request.UserCreateCommand;
77
import project.flipnote.common.util.PhoneUtil;
88
import project.flipnote.common.validation.annotation.ValidPassword;
99
import project.flipnote.common.validation.annotation.ValidPhone;

src/main/java/project/flipnote/auth/service/AuthService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
import project.flipnote.auth.util.PasswordResetTokenGenerator;
3535
import project.flipnote.auth.util.VerificationCodeGenerator;
3636
import project.flipnote.common.config.ClientProperties;
37-
import project.flipnote.common.dto.UserCreateCommand;
38-
import project.flipnote.common.event.UserRegisteredEvent;
37+
import project.flipnote.common.model.request.UserCreateCommand;
38+
import project.flipnote.common.model.event.UserRegisteredEvent;
3939
import project.flipnote.common.exception.BizException;
4040
import project.flipnote.common.security.dto.AuthPrinciple;
4141
import project.flipnote.common.security.jwt.JwtComponent;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package project.flipnote.common.entity;
2+
3+
import java.io.IOException;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
import org.springframework.stereotype.Component;
8+
9+
import com.fasterxml.jackson.core.JsonProcessingException;
10+
import com.fasterxml.jackson.core.type.TypeReference;
11+
import com.fasterxml.jackson.databind.ObjectMapper;
12+
13+
import jakarta.persistence.AttributeConverter;
14+
import jakarta.persistence.Converter;
15+
import lombok.RequiredArgsConstructor;
16+
17+
@RequiredArgsConstructor
18+
@Converter
19+
@Component
20+
public class MapToJsonConverter implements AttributeConverter<Map<String, Object>, String> {
21+
22+
private final ObjectMapper objectMapper;
23+
24+
@Override
25+
public String convertToDatabaseColumn(Map<String, Object> attribute) {
26+
if (attribute == null || attribute.isEmpty()) {
27+
return "{}";
28+
}
29+
try {
30+
return objectMapper.writeValueAsString(attribute);
31+
} catch (JsonProcessingException ex) {
32+
throw new IllegalArgumentException("JSON 변환 실패", ex);
33+
}
34+
}
35+
36+
@Override
37+
public Map<String, Object> convertToEntityAttribute(String dbData) {
38+
if (dbData == null || dbData.isBlank()) {
39+
return new HashMap<>();
40+
}
41+
try {
42+
return objectMapper.readValue(dbData, new TypeReference<Map<String, Object>>() {
43+
});
44+
} catch (IOException ex) {
45+
throw new IllegalArgumentException("JSON 파싱 실패", ex);
46+
}
47+
}
48+
}

src/main/java/project/flipnote/common/exception/GlobalExceptionHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.springframework.web.bind.annotation.RestControllerAdvice;
1010

1111
import lombok.extern.slf4j.Slf4j;
12-
import project.flipnote.common.response.ApiResponse;
12+
import project.flipnote.common.model.response.ApiResponse;
1313

1414
@Slf4j
1515
@RestControllerAdvice
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package project.flipnote.common.model.event;
2+
3+
public record GroupInvitationCreatedEvent(
4+
Long groupId,
5+
Long inviteeId
6+
) {
7+
}

src/main/java/project/flipnote/common/event/UserRegisteredEvent.java renamed to src/main/java/project/flipnote/common/model/event/UserRegisteredEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package project.flipnote.common.event;
1+
package project.flipnote.common.model.event;
22

33
public record UserRegisteredEvent(
44
String email

src/main/java/project/flipnote/common/event/UserWithdrawnEvent.java renamed to src/main/java/project/flipnote/common/model/event/UserWithdrawnEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package project.flipnote.common.event;
1+
package project.flipnote.common.model.event;
22

33
public record UserWithdrawnEvent(
44
Long userId
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package project.flipnote.common.model.request;
2+
3+
import org.springframework.util.StringUtils;
4+
5+
import io.swagger.v3.oas.annotations.media.Schema;
6+
import jakarta.validation.constraints.Max;
7+
import jakarta.validation.constraints.Min;
8+
import lombok.Getter;
9+
import lombok.Setter;
10+
11+
@Getter
12+
@Setter
13+
public class CursorPageRequest {
14+
15+
private String cursor;
16+
17+
@Min(1)
18+
@Max(30)
19+
private Integer size = 10;
20+
21+
@Schema(hidden = true)
22+
public Long getCursorId() {
23+
if (!StringUtils.hasText(cursor)) {
24+
return null;
25+
}
26+
27+
final String normalized = cursor.trim();
28+
if (normalized.isEmpty()) {
29+
return null;
30+
}
31+
32+
return Long.valueOf(normalized);
33+
}
34+
}

0 commit comments

Comments
 (0)