Skip to content
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package kr.ac.kookmin.stream.api.app.welfare.feedback;

import jakarta.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import kr.ac.kookmin.stream.api.app.AppApiUser;
import kr.ac.kookmin.stream.api.app.welfare.feedback.request.FeedbackCreateRequest;
import kr.ac.kookmin.stream.api.app.welfare.feedback.response.FeedbackResponse;
Expand All @@ -9,9 +11,9 @@
import kr.ac.kookmin.stream.api.common.dto.PageParams;
import kr.ac.kookmin.stream.api.common.dto.PageResponse;
import kr.ac.kookmin.stream.common.PageResult;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackRoundOptions;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.OpenFeedback;
import kr.ac.kookmin.stream.welfare.domain.feedback.service.OpenFeedbackService;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.Feedback;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackPeriod;
import kr.ac.kookmin.stream.welfare.domain.feedback.service.FeedbackService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
Expand All @@ -27,12 +29,12 @@
@RequiredArgsConstructor
public class AppFeedbackController implements AppFeedbackApi {

private final OpenFeedbackService openFeedbackService;
private final FeedbackService feedbackService;

@Override
@GetMapping("/{feedbackId}")
public ApiResponse<FeedbackResponse> getFeedback(AppApiUser apiUser, @PathVariable Long feedbackId) {
OpenFeedback feedback = openFeedbackService.getById(feedbackId);
Feedback feedback = feedbackService.getById(feedbackId);
return ApiResponse.success(FeedbackResponse.from(feedback));
}

Expand All @@ -44,7 +46,8 @@ public ApiResponse<PageResponse<FeedbackResponse>> getFeedbacks(
@RequestParam(required = false) Integer round,
@Valid @ModelAttribute PageParams pageParams
) {
PageResult<OpenFeedback> result = openFeedbackService.search(year, round, pageParams.toOffset());
FeedbackPeriod period = FeedbackPeriod.of(year, round);
PageResult<Feedback> result = feedbackService.search(period, pageParams.toOffset());
return ApiResponse.success(PageResponse.from(result, FeedbackResponse::from));
}

Expand All @@ -54,7 +57,7 @@ public ApiResponse<FeedbackResponse> createFeedback(
AppApiUser apiUser,
@Valid @RequestBody FeedbackCreateRequest request
) {
OpenFeedback feedback = openFeedbackService.create(apiUser.userId(), request.question());
Feedback feedback = feedbackService.create(apiUser.userId(), request.question());
return ApiResponse.success(FeedbackResponse.from(feedback));
}

Expand All @@ -64,7 +67,9 @@ public ApiResponse<FeedbackRoundsResponse> getFeedbackRounds(
AppApiUser apiUser,
@RequestParam(required = false) Integer year
) {
FeedbackRoundOptions options = openFeedbackService.getRoundOptions(year);
return ApiResponse.success(FeedbackRoundsResponse.from(options));
List<Integer> years = feedbackService.getAvailableYears();
int targetYear = year != null ? year : LocalDateTime.now().getYear();
List<Integer> rounds = feedbackService.getRoundsOf(targetYear);
return ApiResponse.success(FeedbackRoundsResponse.of(years, targetYear, rounds));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package kr.ac.kookmin.stream.api.app.welfare.feedback.response;

import java.time.LocalDateTime;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.OpenFeedback;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.Feedback;

public record FeedbackResponse(
Long feedbackId,
Expand All @@ -12,7 +12,7 @@ public record FeedbackResponse(
LocalDateTime answeredAt,
String answer
) {
public static FeedbackResponse from(OpenFeedback feedback) {
public static FeedbackResponse from(Feedback feedback) {
return new FeedbackResponse(
feedback.id(),
feedback.year(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package kr.ac.kookmin.stream.api.app.welfare.feedback.response;

import java.util.List;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackRoundOptions;

public record FeedbackRoundsResponse(List<Integer> years, int year, List<Integer> rounds) {

public static FeedbackRoundsResponse from(FeedbackRoundOptions options) {
return new FeedbackRoundsResponse(options.years(), options.year(), options.rounds());
public static FeedbackRoundsResponse of(List<Integer> years, int year, List<Integer> rounds) {
return new FeedbackRoundsResponse(years, year, rounds);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.time.LocalDateTime;

public record OpenFeedback(
public record Feedback(
Long id,
int year,
int round,
Expand All @@ -15,12 +15,12 @@ public record OpenFeedback(
) {

// 회차는 서버가 자동 배정하므로 여기서 받는다(요청 시각 = questionedAt, 아직 답변 없음).
public static OpenFeedback create(int year, int round, String question, Long createdBy) {
return new OpenFeedback(null, year, round, question, LocalDateTime.now(), null, null, createdBy, null);
public static Feedback create(int year, int round, String question, Long createdBy) {
return new Feedback(null, year, round, question, LocalDateTime.now(), null, null, createdBy, null);
}

// DB에서 복원할 때 모든 필드를 그대로 받는다.
public static OpenFeedback of(
public static Feedback of(
Long id,
int year,
int round,
Expand All @@ -31,6 +31,6 @@ public static OpenFeedback of(
Long createdBy,
Long answeredBy
) {
return new OpenFeedback(id, year, round, question, questionedAt, answer, answeredAt, createdBy, answeredBy);
return new Feedback(id, year, round, question, questionedAt, answer, answeredAt, createdBy, answeredBy);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package kr.ac.kookmin.stream.welfare.domain.feedback.domain;

import kr.ac.kookmin.stream.common.BusinessException;

/**
* 연도·회차로 특정 회차를 가리키는 값. 실제로 존재하는 회차 엔티티({@link FeedbackRound})와 달리,
* 존재 여부와 무관하게 "어느 회차를 가리키는가"만 표현한다 — 둘 다 없으면 "지정 없음"을 뜻한다.
* round의 유효성(1 이상)은 이 값 자체의 불변식이라 여기서 검증한다.
*/
public record FeedbackPeriod(Integer year, Integer round) {

public static FeedbackPeriod of(Integer year, Integer round) {
if (round != null && round <= 0) {
throw new BusinessException(FeedbackErrorCode.INVALID_FEEDBACK_ROUND);
}
return new FeedbackPeriod(year, round);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package kr.ac.kookmin.stream.welfare.domain.feedback.repository;

import java.util.Optional;
import kr.ac.kookmin.stream.common.PageOffset;
import kr.ac.kookmin.stream.common.PageResult;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.Feedback;

public interface FeedbackRepository {

Optional<Feedback> findById(Long id);

// year/round가 null이면 그 조건은 필터하지 않는다
PageResult<Feedback> search(Integer year, Integer round, PageOffset pageOffset);

Feedback save(Feedback feedback);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package kr.ac.kookmin.stream.welfare.domain.feedback.service;

import java.util.List;
import kr.ac.kookmin.stream.common.PageOffset;
import kr.ac.kookmin.stream.common.PageResult;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.Feedback;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackPeriod;

public interface FeedbackService {

Feedback getById(Long id);

PageResult<Feedback> search(FeedbackPeriod period, PageOffset pageOffset);

// 회차는 현재 열려 있는 회차로 서버가 자동 배정한다
Feedback create(Long memberId, String question);

// 회차가 하나라도 존재했던 연도 목록(최신순)
List<Integer> getAvailableYears();

// 해당 연도에 실제로 존재하는 회차 번호(오름차순)
List<Integer> getRoundsOf(int year);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package kr.ac.kookmin.stream.welfare.domain.feedback.service.impl;

import java.time.LocalDateTime;
import java.util.List;
import kr.ac.kookmin.stream.common.BusinessException;
import kr.ac.kookmin.stream.common.PageOffset;
import kr.ac.kookmin.stream.common.PageResult;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.Feedback;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackErrorCode;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackPeriod;
import kr.ac.kookmin.stream.welfare.domain.feedback.domain.FeedbackRound;
import kr.ac.kookmin.stream.welfare.domain.feedback.repository.FeedbackRepository;
import kr.ac.kookmin.stream.welfare.domain.feedback.repository.FeedbackRoundRepository;
import kr.ac.kookmin.stream.welfare.domain.feedback.service.FeedbackService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
class FeedbackServiceImpl implements FeedbackService {

private final FeedbackRepository feedbackRepository;
private final FeedbackRoundRepository feedbackRoundRepository;

@Override
public Feedback getById(Long id) {
return feedbackRepository.findById(id)
.orElseThrow(() -> new BusinessException(FeedbackErrorCode.FEEDBACK_NOT_FOUND));
}

@Override
public PageResult<Feedback> search(FeedbackPeriod period, PageOffset pageOffset) {
return feedbackRepository.search(period.year(), period.round(), pageOffset);
}

@Override
@Transactional
public Feedback create(Long memberId, String question) {
FeedbackRound openRound = feedbackRoundRepository.findOpenAt(LocalDateTime.now())
.orElseThrow(() -> new BusinessException(FeedbackErrorCode.FEEDBACK_NOT_OPEN));

Feedback feedback = Feedback.create(openRound.year(), openRound.round(), question, memberId);
return feedbackRepository.save(feedback);
}

@Override
public List<Integer> getAvailableYears() {
return feedbackRoundRepository.findDistinctYears();
}

@Override
public List<Integer> getRoundsOf(int year) {
return feedbackRoundRepository.findRoundsByYear(year);
}
}

This file was deleted.

Loading