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
20 changes: 20 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582

- name: Add SSH host key
run: |
mkdir -p ~/.ssh
Expand All @@ -24,6 +33,17 @@ jobs:
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem
chmod 600 ~/.ssh/private_key.pem

- name: Build with Gradle
run: ./gradlew build -x test

- name: Upload JAR to Remote Server
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem
chmod 600 ~/.ssh/private_key.pem
scp -i ~/.ssh/private_key.pem build/libs/todo-0.0.1-SNAPSHOT.jar ${{ secrets.USER }}@${{ secrets.HOST }}:${{ secrets.APP_DIR }}
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

- name: Deploy to Remote Server
run: |
ssh -i ~/.ssh/private_key.pem ${{ secrets.USER }}@${{ secrets.HOST }} '
Expand Down
16 changes: 1 addition & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,4 @@ jobs:
run: ./gradlew test

- name: Build with Gradle
run: ./gradlew build -x test

- name: Add SSH host key
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ secrets.HOST }} >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts

- name: Upload JAR to Remote Server
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem
chmod 600 ~/.ssh/private_key.pem
scp -i ~/.ssh/private_key.pem build/libs/todo-0.0.1-SNAPSHOT.jar ${{ secrets.USER }}@${{ secrets.HOST }}:${{ secrets.APP_DIR }}
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: ./gradlew build -x test
6 changes: 6 additions & 0 deletions src/main/java/com/codeit/todo/repository/GoalRepository.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.codeit.todo.repository;

import com.codeit.todo.domain.Goal;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
Expand All @@ -10,4 +12,8 @@ public interface GoalRepository extends JpaRepository<Goal, Integer> {
List<Goal> findByUser_UserId(int userId);

Optional<Goal> findByGoalIdAndUser_UserId(int goalId, int userId);

Slice<Goal> findByUser_UserId(int userId, Pageable pageable);

Slice<Goal> findByGoalIdAndUser_UserId(Integer goalId, int userId, Pageable pageable);
}
5 changes: 4 additions & 1 deletion src/main/java/com/codeit/todo/repository/TodoRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ public interface TodoRepository extends JpaRepository<Todo, Integer> {
Slice<Todo> findByGoal_GoalIdAndTodoIdLessThanOrderByTodoIdDesc(int goalId, Integer lastTodoId, Pageable pageable);

@Query("select t from Todo t where t.goal.goalId in :goalIds and :today between t.startDate and t.endDate")
List<Todo> findTodosBetweenDates(@Param("goalIds") List<Integer> goalIds, @Param("today") LocalDate today);
List<Todo> findTodosByGoalIdsBetweenDates(@Param("goalIds") List<Integer> goalIds, @Param("today") LocalDate today);

@Query("select t from Todo t where t.goal.goalId = :goalId and :today between t.startDate and t.endDate")
List<Todo> findTodosByGoalIdBetweenDates(@Param("goalId") int goalId, @Param("today") LocalDate today);
}
7 changes: 2 additions & 5 deletions src/main/java/com/codeit/todo/service/todo/TodoService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.codeit.todo.service.todo;

import com.codeit.todo.web.dto.request.todo.CreateTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest;
import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest;
import com.codeit.todo.web.dto.request.todo.*;
import com.codeit.todo.web.dto.response.todo.*;
import org.springframework.data.domain.Slice;

Expand All @@ -15,7 +12,7 @@ public interface TodoService {

CreateTodoResponse saveTodo(int userId, CreateTodoRequest request);

List<ReadTodosWithGoalsResponse> findTodoListWithGoals(int userId, ReadTodoWithGoalRequest request);
Slice<ReadTodosWithGoalsResponse> findTodoListWithGoals(int userId, ReadDashBoardTodoWithGoalRequest request);

Slice<ReadTodoWithGoalResponse> findTodoListWithGoal(int userId, int goalId, ReadTodoWithGoalRequest request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
import com.codeit.todo.repository.TodoRepository;
import com.codeit.todo.service.storage.StorageService;
import com.codeit.todo.service.todo.TodoService;
import com.codeit.todo.web.dto.request.todo.CreateTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest;
import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest;
import com.codeit.todo.web.dto.request.todo.*;
import com.codeit.todo.web.dto.response.complete.ReadCompleteResponse;
import com.codeit.todo.web.dto.response.todo.*;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -108,19 +106,39 @@ public CreateTodoResponse saveTodo(int userId, CreateTodoRequest request) {

@Transactional(readOnly = true)
@Override
public List<ReadTodosWithGoalsResponse> findTodoListWithGoals(int userId, ReadTodoWithGoalRequest request) {
List<Goal> goals = goalRepository.findByUser_UserId(userId);
public Slice<ReadTodosWithGoalsResponse> findTodoListWithGoals(int userId, @Valid ReadDashBoardTodoWithGoalRequest request) {
int pageSize = request.size();
Pageable pageable = PageRequest.of(0, pageSize);

return goals.stream()
Slice<Goal> goals;
if (Objects.isNull(request.lastGoalId()) || request.lastGoalId() <= 0) {
goals = goalRepository.findByUser_UserId(userId, pageable);
} else {
goals = goalRepository.findByGoalIdAndUser_UserId(request.lastGoalId(), userId, pageable);
}

List<ReadTodosWithGoalsResponse> responses = goals.getContent().stream()
.map(goal -> {
Pageable pageable = PageRequest.of(0, request.size());
Slice<Todo> todos = todoRepository.findByGoal_GoalIdOrderByTodoIdDesc(goal.getGoalId(), pageable);
List<Todo> todos = todoRepository.findTodosByGoalIdBetweenDates(goal.getGoalId(), LocalDate.now());

List<ReadTodosResponse> responses = getTodoResponses(todos);
List<ReadTodosResponse> todosResponses = todos.stream()
.map(todo -> {
List<Complete> completes = completeRepository.findByTodo_TodoId(todo.getTodoId());

return ReadTodosWithGoalsResponse.from(goal, responses);
List<ReadCompleteResponse> completeResponses = completes.stream()
.map(ReadCompleteResponse::from)
.toList();

}).toList();
return ReadTodosResponse.from(todo, completeResponses);
}).toList();

double goalProgress = calculateGoalProgress(todos);

return ReadTodosWithGoalsResponse.from(goal, todosResponses, goalProgress);
})
.toList();

return new SliceImpl<>(responses, pageable, goals.hasNext());
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -234,7 +252,7 @@ private List<Todo> getTodayTodos(LocalDate today, int userId) {
.map(Goal::getGoalId)
.toList();

return todoRepository.findTodosBetweenDates(goalIds, today);
return todoRepository.findTodosByGoalIdsBetweenDates(goalIds, today);
}

private List<ReadTodosResponse> getTodoResponses(Slice<Todo> todos) {
Expand All @@ -249,4 +267,19 @@ private List<ReadTodosResponse> getTodoResponses(Slice<Todo> todos) {
return ReadTodosResponse.from(todo, completeResponses);
}).toList();
}

private double calculateGoalProgress(List<Todo> todos) {
long totalCompletes = 0;
long completedCompletes = 0;

for (Todo todo : todos) {
List<Complete> completes = completeRepository.findByTodo_TodoId(todo.getTodoId());
totalCompletes += completes.size();
completedCompletes += completes.stream()
.filter(complete -> COMPLETE.equals(complete.getCompleteStatus()))
.count();
}

return totalCompletes > 0 ? (completedCompletes / (double) totalCompletes) * 100 : 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import com.codeit.todo.repository.CustomUserDetails;
import com.codeit.todo.service.todo.TodoService;
import com.codeit.todo.web.dto.request.todo.CreateTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoRequest;
import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest;
import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest;
import com.codeit.todo.web.dto.request.todo.*;
import com.codeit.todo.web.dto.response.Response;
import com.codeit.todo.web.dto.response.goal.ReadGoalsResponse;
import com.codeit.todo.web.dto.response.todo.*;
Expand Down Expand Up @@ -51,8 +48,8 @@ public Response<Slice<ReadTodosResponse>> getTodoList(
@ApiResponse(responseCode = "200", description = "조회 성공")
})
@GetMapping("/goals")
public Response<List<ReadTodosWithGoalsResponse>> getTodoWithGoalList(
@Valid @ModelAttribute ReadTodoWithGoalRequest request,
public Response<Slice<ReadTodosWithGoalsResponse>> getTodoWithGoalList(
@Valid @ModelAttribute ReadDashBoardTodoWithGoalRequest request,
@AuthenticationPrincipal CustomUserDetails userDetails
) {
int userId = userDetails.getUserId();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.codeit.todo.web.dto.request.todo;

import jakarta.validation.constraints.Min;

public record ReadDashBoardTodoWithGoalRequest(
Integer lastGoalId,
@Min(3)
int size
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ public record ReadTodosWithGoalsResponse(
int goalId,
String goalTitle,
String goalColor,
double progress,
List<ReadTodosResponse> todos
) {
public static ReadTodosWithGoalsResponse from(Goal goal, List<ReadTodosResponse> responses) {
public static ReadTodosWithGoalsResponse from(Goal goal, List<ReadTodosResponse> responses, double goalProgress) {
return ReadTodosWithGoalsResponse.builder()
.goalId(goal.getGoalId())
.goalTitle(goal.getGoalTitle())
.goalColor(goal.getColor())
.progress(goalProgress)
.todos(responses)
.build();
}
Expand Down
Loading