Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#20] Task 등록, 수정, 삭제 기능에 Reminder 설정 기능 추가 #21

Merged
merged 7 commits into from
Oct 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.time.Duration;

@RequiredArgsConstructor
@RequestMapping("/v1/tasks")
Expand Down Expand Up @@ -43,6 +44,8 @@ ResponseEntity<ApiResponse<?>> createTask(@RequestBody TaskCreateRequest request
dummyUserId,
request.title(),
request.description(),
true,
Duration.ofMinutes(10),
request.timeFrame().startDateTime(),
request.timeFrame().endDateTime()
);
Expand All @@ -66,6 +69,8 @@ ResponseEntity<ApiResponse<?>> updateTaskContent(@PathVariable("id") Long id, @R
dummyUserId,
request.title(),
request.description(),
true,
Duration.ofMinutes(10),
request.timeFrame().startDateTime(),
request.timeFrame().endDateTime());
taskService.updateContent(taskContentUpdate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,21 @@ public class TaskEntity {

private LocalDateTime endDateTime;

private Boolean isReminderEnabled;

private LocalDateTime createdAt;

private LocalDateTime updatedAt;

@Builder
private TaskEntity(Long id, String title, Boolean isDone, String description, LocalDateTime startDateTime, LocalDateTime endDateTime, LocalDateTime createdAt, LocalDateTime updatedAt) {
private TaskEntity(Long id, String title, Boolean isDone, String description, LocalDateTime startDateTime, LocalDateTime endDateTime, Boolean isReminderEnabled, LocalDateTime createdAt, LocalDateTime updatedAt) {
this.id = id;
this.title = title;
this.isDone = isDone;
this.description = description;
this.startDateTime = startDateTime;
this.endDateTime = endDateTime;
this.isReminderEnabled = isReminderEnabled;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
Expand All @@ -52,6 +55,7 @@ public static TaskEntity from(Task task) {
.description(task.getDescription())
.startDateTime(task.getTimeFrame().startDateTime())
.endDateTime(task.getTimeFrame().endDateTime())
.isReminderEnabled(task.isReminderEnabled())
.createdAt(task.getCreatedAt())
.updatedAt(task.getUpdatedAt())
.build();
Expand All @@ -64,6 +68,7 @@ public Task toModel() {
.isDone(isDone)
.description(description)
.timeFrame(new TimeFrame(startDateTime, endDateTime))
.reminderEnabled(isReminderEnabled)
.createdAt(createdAt)
.updatedAt(updatedAt)
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.taskbuddy.core.database.repository;

import com.taskbuddy.core.domain.ReminderSettings;
import org.springframework.stereotype.Repository;

import java.util.Optional;

//임시생성
@Repository
public class DefaultReminderSettingsRepository implements ReminderSettingsRepository {

@Override
public Optional<ReminderSettings> findByTaskId(Long taskId) {
return Optional.empty();
}

@Override
public void save(ReminderSettings reminderSettings) {

}

@Override
public void deleteById(Long id) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.taskbuddy.core.database.repository;

import com.taskbuddy.core.domain.ReminderSettings;

import java.util.Optional;

public interface ReminderSettingsRepository {

Optional<ReminderSettings> findByTaskId(Long taskId);

void save(ReminderSettings reminderSettings);

void deleteById(Long id);
}
66 changes: 66 additions & 0 deletions core/src/main/java/com/taskbuddy/core/domain/ReminderSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.taskbuddy.core.domain;

import com.taskbuddy.core.service.port.ClockHolder;
import lombok.Builder;
import lombok.Getter;

import java.time.Duration;
import java.time.LocalDateTime;

@Getter
public class ReminderSettings {
private final Long id;
private final Task task;
private LocalDateTime lastReminderSentTime;
private Duration reminderInterval;
private final LocalDateTime createdAt;
private LocalDateTime updatedAt;

@Builder
public ReminderSettings(Long id, Task task, LocalDateTime lastReminderSentTime, Duration reminderInterval, LocalDateTime createdAt, LocalDateTime updatedAt) {
this.id = id;
this.task = task;
this.lastReminderSentTime = lastReminderSentTime;
this.reminderInterval = reminderInterval;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}

public static ReminderSettings from(Task task, Duration reminderInterval, ClockHolder clockHolder) {
final LocalDateTime currentDateTime = clockHolder.currentDateTime();

return ReminderSettings.builder()
.task(task)
.reminderInterval(reminderInterval)
.createdAt(currentDateTime)
.updatedAt(currentDateTime)
.build();
}

public void updateLastReminderSentTime(LocalDateTime lastReminderSentTime, ClockHolder clockHolder) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저 예전부터 궁금하던게 있는데요. clockHolder는 어떤 역할을 하는 것인가요?

this.lastReminderSentTime = lastReminderSentTime;
this.updatedAt = clockHolder.currentDateTime();
}

public boolean isReminderDue(ClockHolder clockHolder) {
LocalDateTime currentDateTime = clockHolder.currentDateTime();
LocalDateTime taskStartDateTime = task.getTimeFrame().startDateTime();

if (currentDateTime.isBefore(taskStartDateTime)) {
return false;
}

Duration timeSinceStart = Duration.between(taskStartDateTime, currentDateTime);

return timeSinceStart.toMinutes() % reminderInterval.toMinutes() == 0;
}

public void updateReminderInterval(Duration reminderInterval, ClockHolder clockHolder) {
this.reminderInterval = reminderInterval;
this.updatedAt = clockHolder.currentDateTime();
}

public Long getTaskId() {
return task.getId();
}
}
9 changes: 7 additions & 2 deletions core/src/main/java/com/taskbuddy/core/domain/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
@Getter
public class Task {
private final Long id;
// private User user;
private User user;
private String title;
private Boolean isDone;
private String description;
private TimeFrame timeFrame;
private boolean reminderEnabled;
private final LocalDateTime createdAt;
private LocalDateTime updatedAt;

@Builder
public Task(Long id, String title, Boolean isDone, String description, TimeFrame timeFrame, LocalDateTime createdAt, LocalDateTime updatedAt) {
public Task(Long id, User user, String title, Boolean isDone, String description, TimeFrame timeFrame, boolean reminderEnabled, LocalDateTime createdAt, LocalDateTime updatedAt) {
this.id = id;
this.user = user;
this.title = title;
this.isDone = isDone;
this.description = description;
this.timeFrame = timeFrame;
this.reminderEnabled = reminderEnabled;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
Expand All @@ -37,6 +40,7 @@ public static Task from(TaskCreate taskCreate, ClockHolder clockHolder) {
.isDone(isDoneDefaultValue)
.description(taskCreate.description())
.timeFrame(new TimeFrame(taskCreate.startDateTime(), taskCreate.endDateTime()))
.reminderEnabled(taskCreate.reminderEnabled())
.createdAt(createdAt)
.updatedAt(createdAt)
.build();
Expand All @@ -46,6 +50,7 @@ public void update(TaskContentUpdate taskContentUpdate, ClockHolder clockHolder)
title = taskContentUpdate.title();
description = taskContentUpdate.description();
timeFrame = new TimeFrame(taskContentUpdate.startDateTime(), taskContentUpdate.endDateTime());
reminderEnabled = taskContentUpdate.reminderEnabled();
updatedAt = clockHolder.currentDateTime();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.taskbuddy.core.domain;

import java.time.Duration;
import java.time.LocalDateTime;

public record TaskContentUpdate(
Long id,
Long userId,
String title,
String description,
Boolean reminderEnabled,
Duration reminderInterval,
LocalDateTime startDateTime,
LocalDateTime endDateTime
) {}
3 changes: 3 additions & 0 deletions core/src/main/java/com/taskbuddy/core/domain/TaskCreate.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.taskbuddy.core.domain;

import java.time.Duration;
import java.time.LocalDateTime;

public record TaskCreate (
Long userId,
String title,
String description,
Boolean reminderEnabled,
Duration reminderInterval,
LocalDateTime startDateTime,
LocalDateTime endDateTime
) {}
12 changes: 11 additions & 1 deletion core/src/main/java/com/taskbuddy/core/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
package com.taskbuddy.core.domain;

public record User(Long id) {
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class User {
private Long id;
private boolean loggedIn;
private boolean reminderEnabled;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.taskbuddy.core.service;

import com.taskbuddy.core.domain.ReminderSettings;
import com.taskbuddy.core.domain.Task;
import com.taskbuddy.core.domain.User;
import com.taskbuddy.core.service.port.ClockHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@RequiredArgsConstructor
@Service
public class ReminderNotificationService {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 로직은 좀 더 고민해보고, 어떻게 할지 생각해보죠. :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 지난시간에 말씀해주신 방법과 함께 고민해보겠습니다 ㅎㅎ

private final ReminderSettingsService reminderSettingsService;
private final UserService userService;
// private final NotificationService notificationService;
private final ClockHolder clockHolder;

public void sendNotification(Task task) {
User user = task.getUser();

// 1. 유저가 리마인드 알림설정이 켜져있는지 확인
if (!user.isReminderEnabled()) {
return; // 유저가 알림을 원하지 않으면 스킵
}

// 2. Task의 리마인드 설정이 켜져 있는지 확인
if (!task.isReminderEnabled()) {
return; // Task의 리마인드 설정이 꺼져 있으면 스킵
}

// 3. 리마인더주기에 맞는지 확인
ReminderSettings reminderSettings = reminderSettingsService.getByTaskId(task.getId());

// 마지막으로 알림을 보낼 시간이 리마인드 주기 이상일 경우에만 알림 전송
if (!reminderSettings.isReminderDue(clockHolder)) {
return; // 아직 리마인드 주기가 지나지 않았으므로 스킵
}

// 4. 유저가 현재 접속 중인지 확인 (접속 중이 아니면 리마인드)
if (!userService.isUserLoggedIn(user)) {
//리마인더 알림 전송
// notificationService.sendReminder(user, task);
reminderSettingsService.updateLastSentTime(reminderSettings, LocalDateTime.now());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.taskbuddy.core.service;

import com.taskbuddy.core.database.repository.ReminderSettingsRepository;
import com.taskbuddy.core.domain.ReminderSettings;
import com.taskbuddy.core.domain.Task;
import com.taskbuddy.core.service.port.ClockHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Optional;

@RequiredArgsConstructor
@Service
public class ReminderSettingsService {
private final ReminderSettingsRepository reminderSettingsRepository;
private final ClockHolder clockHolder;

public ReminderSettings getByTaskId(Long taskId) {
return reminderSettingsRepository.findByTaskId(taskId)
.orElseThrow(() -> new IllegalArgumentException("Task Settings with given task id does not exist."));
}

public void initialize(Task task, Duration reminderInterval) {
if (!task.isReminderEnabled()) {
return;
}

ReminderSettings reminderSettings = ReminderSettings.from(task, reminderInterval, clockHolder);
reminderSettingsRepository.save(reminderSettings);
}

public void update(Task task, Duration reminderInterval) {
Optional<ReminderSettings> optionalReminderSettings = reminderSettingsRepository.findByTaskId(task.getId());

if (optionalReminderSettings.isEmpty()) {
initialize(task, reminderInterval);
return;
}

ReminderSettings reminderSettings = optionalReminderSettings.get();

if (!task.isReminderEnabled()) {
reminderSettingsRepository.deleteById(reminderSettings.getId());
} else {
reminderSettings.updateReminderInterval(reminderInterval, clockHolder);
reminderSettingsRepository.save(reminderSettings);
}
}

public void updateLastSentTime(ReminderSettings reminderSettings, LocalDateTime lastSentTime) {
reminderSettings.updateLastReminderSentTime(lastSentTime, clockHolder);
}

public void deleteByTaskId(Long taskId) {
reminderSettingsRepository.findByTaskId(taskId)
.ifPresent(reminderSettings -> reminderSettingsRepository.deleteById(reminderSettings.getId()));
}
}
Loading
Loading