Skip to content

Commit

Permalink
Merge Dev Branch to Main Branch
Browse files Browse the repository at this point in the history
  • Loading branch information
yummygyudon committed Oct 19, 2023
2 parents b736b73 + ee6c28e commit 46b7cb1
Show file tree
Hide file tree
Showing 59 changed files with 719 additions and 921 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ http-client.private.env.json
http-client.env.json
**/resources/http/**/env/
**/resources/http/**/data/
**/resources/http
*.http
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,23 @@ app-server
- 2기 API 문서 [바로가기](https://parangjy.notion.site/3278da92a8f646aea4eba1d0f5a45f43?v=15ca2103aaec4bbaaaea7808c872484c)
- 1기 솝탬프 유스케이스 [바로가기](https://github.com/sopt-makers/app-server/wiki/솝탬프-프로젝트-유스케이스)
- 1기 API 문서 [바로가기](https://parangjy.notion.site/166132ae964d4bc483c71e507497bb9c)

# Architecture
Layered Architecture방식을 채택.
presentation layer, domain layer, interface layer, application layer, facade layer로 구성되어있다.
## Presentation Layer
presentation layer는 사용자의 요청을 받아서 응답을 해주는 역할을 한다.
해당 layer에서는 facade layer 혹은 application layer를 호출하여 사용자의 요청에 대한 응답을 해준다.
해당 layer에서는 response를 위한 dto를 정의하고, request를 위한 dto를 정의한다. 또한 response를 만드는 역할을 한다.
## Domain Layer
domain layer는 entity와 entity의 관계를 정의한다.
## Interface Layer
interface layer는 외부와의 통신을 위한 interface를 정의한다.
repository interface가 해당된다.
## Application Layer
application layer는 비즈니스 로직을 정의한다.
해당 layer에서는 service를 정의한다.
해당 layer에서는 entity를 dto로 변환하는 역할을 한다.
## Facade Layer
facade layer는 application layer를 호출하는 역할을 한다.
해당 layer에서는 service의 orchestrator 역할을 한다.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ dependencies {

// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// DB
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/sopt/app/AppApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableAsync;

import javax.annotation.PostConstruct;
import java.util.TimeZone;

@EnableJpaAuditing // JPA Auditing(감시, 감사) 기능을 활성화 하는 어노테이션 createdDate, modifiedDate 저장 활성화
@EnableAsync
@SpringBootApplication
Expand All @@ -14,4 +17,8 @@ public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}

@PostConstruct
void setApplicationTimeZone(){
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package org.sopt.app.application.notification;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.Notification;
import org.sopt.app.domain.entity.User;
import org.sopt.app.domain.enums.NotificationType;
import org.sopt.app.interfaces.postgres.NotificationRepository;
import org.sopt.app.interfaces.postgres.UserRepository;
import org.sopt.app.presentation.notification.NotificationRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
Expand All @@ -19,31 +24,54 @@
public class NotificationService {

private final NotificationRepository notificationRepository;
private final UserRepository userRepository;

@Transactional(readOnly = true)
public Notification findNotification(User user, Long notificationId) {
return notificationRepository.findByIdAndUserId(notificationId, user.getId())
.orElseThrow(() -> new BadRequestException(ErrorCode.NOTIFICATION_NOT_FOUND.getMessage()));
}

@Transactional(readOnly = true)
public List<Notification> findNotificationList(User user, Pageable pageable) {
val notificationList = notificationRepository.findAllByUserId(user.getId(), pageable);
return notificationList;
return notificationRepository.findAllByUserId(user.getId(), pageable);
}

@Transactional
public Notification registerNotification(
Long userId,
public void registerNotification(
NotificationRequest.RegisterNotificationRequest registerNotificationRequest
) {
val notification = Notification.builder()
.userId(userId)
.title(registerNotificationRequest.getTitle())
.content(registerNotificationRequest.getContent())
// .type(registerNotificationRequest.getType())
.isRead(false)
.build();
return notificationRepository.save(notification);
List<Long> playgroundIds = new ArrayList<>();
if (registerNotificationRequest.getType().equals(NotificationType.SEND_ALL)) {
playgroundIds = userRepository.findAllPlaygroundId();
} else if (registerNotificationRequest.getType().equals(NotificationType.SEND)) {
playgroundIds = registerNotificationRequest.getPlaygroundIds().stream()
.map(Long::parseLong)
.toList();
}
registerTo(playgroundIds, registerNotificationRequest);
}
private void registerTo(List<Long> playgroundIds, NotificationRequest.RegisterNotificationRequest registerNotificationRequest) {
val targetUserIds = userRepository.findAllIdByPlaygroundIdIn(playgroundIds);
val notifications = targetUserIds.stream()
.map(userId -> Notification.builder()
.userId(userId)
.title(registerNotificationRequest.getTitle())
.content(registerNotificationRequest.getContent())
.type(registerNotificationRequest.getType())
.category(registerNotificationRequest.getCategory())
.deepLink(registerNotificationRequest.getDeepLink())
.webLink(registerNotificationRequest.getWebLink())
.isRead(false)
.build()
).toList();
notificationRepository.saveAll(notifications);
}


@Transactional
public void updateNotificationIsRead(User user, Long notificationId) {
if (notificationId == 0) {
if (Objects.isNull(notificationId)) {
updateAllNotificationIsRead(user);
} else {
updateSingleNotificationIsRead(user, notificationId);
Expand All @@ -52,10 +80,12 @@ public void updateNotificationIsRead(User user, Long notificationId) {

private void updateAllNotificationIsRead(User user) {
val notificationList = notificationRepository.findAllByUserId(user.getId());
val readNotificationList = notificationList.stream().map(notification -> {
notification.updateIsRead();
return notification;
}).collect(Collectors.toList());
val readNotificationList = notificationList.stream()
.map(notification -> {
notification.updateIsRead();
return notification;
}
).collect(Collectors.toList());
notificationRepository.saveAll(readNotificationList);
}

Expand All @@ -67,11 +97,11 @@ private void updateSingleNotificationIsRead(User user, Long notificationId) {
}

@Transactional(readOnly = true)
public Boolean getNotificationMainViewStatus(User user) {
public Boolean getNotificationConfirmStatus(User user) {
val notificationList = notificationRepository.findAllByUserId(user.getId());
val unreadNotificationList = notificationList.stream()
.filter(notification -> !notification.getIsRead())
.collect(Collectors.toList());
.toList();
return unreadNotificationList.size() == 0;
}
}
Loading

0 comments on commit 46b7cb1

Please sign in to comment.