Skip to content

Commit ed4f57d

Browse files
CEO-Nickskydreamer21keongmini
authored
플레이리스트, 마이페이지 API, 작업 상태 수정 스케줄러 등 2차 MVP 개발 내용 운영 서버에 반영 (#204)
(# 입력 하고 이슈 선택) ### Proposed Changes (PR 목적과 변경사항을 적어주세요.) ### Code Review Point (리뷰어가 중점적으로 보면 좋을 부분을 적어주세요.) --------- Co-authored-by: JuHyun Kim <95271588+skydreamer21@users.noreply.github.com> Co-authored-by: keongmini <kmnam09@gmail.com> Co-authored-by: skydreamer <skydreamer210@gmail.com>
1 parent 1ab9218 commit ed4f57d

File tree

56 files changed

+1955
-89
lines changed

Some content is hidden

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

56 files changed

+1955
-89
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.ssak3.timeattack.common.config
2+
3+
import org.springframework.context.annotation.Bean
4+
import org.springframework.context.annotation.Configuration
5+
import org.springframework.scheduling.TaskScheduler
6+
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
7+
8+
@Configuration
9+
class SchedulerConfig {
10+
@Bean
11+
fun taskScheduler(): TaskScheduler {
12+
val taskScheduler = ThreadPoolTaskScheduler()
13+
taskScheduler.poolSize = 3
14+
taskScheduler.setThreadNamePrefix("task-scheduler-")
15+
taskScheduler.initialize()
16+
return taskScheduler
17+
}
18+
}

src/main/kotlin/com/ssak3/timeattack/common/exception/ApplicationExceptionType.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,33 @@ enum class ApplicationExceptionType(
192192

193193
// ======================== [END] OIDC ========================
194194

195+
// ======================== [START] RETROSPECTION ========================
196+
197+
/**
198+
* - {0} : Task ID
199+
* - {1} : Task Status
200+
*/
201+
CREATE_RETROSPECTION_NOT_ALLOWED(
202+
HttpStatus.BAD_REQUEST,
203+
"ERR_RETRO_001",
204+
"현재 task({0})의 상태가 {1} 이기에 회고 생성이 허용되지 않습니다.(COMPLETE or FOCUSED인 task에 대해서만 회고 생성 가능)",
205+
),
206+
207+
// ======================== [END] RETROSPECTION ========================
208+
209+
// ======================== [START] PERSONA ========================
210+
211+
/**
212+
* - {0} : Persona ID
213+
*/
214+
PERSONA_NOT_FOUND_BY_ID(
215+
HttpStatus.BAD_REQUEST,
216+
"ERR_PERSONA_001",
217+
"해당 ID로 Persona를 찾을 수 없습니다. : {0}",
218+
),
219+
220+
// ======================== [END] PERSONA ========================
221+
195222
// ======================== [START] GLOBAL ========================
196223

197224
/**
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.ssak3.timeattack.mypage.controller
2+
3+
import com.ssak3.timeattack.common.config.SwaggerConfig.Companion.SECURITY_SCHEME_NAME
4+
import com.ssak3.timeattack.member.domain.Member
5+
import com.ssak3.timeattack.mypage.controller.dto.MyPageResponse
6+
import com.ssak3.timeattack.mypage.service.MyPageService
7+
import io.swagger.v3.oas.annotations.Operation
8+
import io.swagger.v3.oas.annotations.security.SecurityRequirement
9+
import io.swagger.v3.oas.annotations.tags.Tag
10+
import org.springframework.http.ResponseEntity
11+
import org.springframework.security.core.annotation.AuthenticationPrincipal
12+
import org.springframework.web.bind.annotation.GetMapping
13+
import org.springframework.web.bind.annotation.RequestMapping
14+
import org.springframework.web.bind.annotation.RestController
15+
16+
@Tag(name = "MyPage APIs")
17+
@RestController
18+
@RequestMapping("/v1/mypage")
19+
class MyPageController(
20+
private val myPageService: MyPageService,
21+
) {
22+
@Operation(summary = "마이페이지 조회", security = [SecurityRequirement(name = SECURITY_SCHEME_NAME)])
23+
@GetMapping
24+
fun myPage(
25+
@AuthenticationPrincipal member: Member,
26+
): ResponseEntity<MyPageResponse> {
27+
val myPageDto = myPageService.getMyPage(member)
28+
29+
return ResponseEntity.ok(
30+
MyPageResponse(
31+
satisfactionAvg = myPageDto.satisfactionAvg,
32+
concentrationAvg = myPageDto.concentrationAvg,
33+
personas = myPageDto.personas,
34+
completedTasks = myPageDto.completedTasks,
35+
procrastinatedTasks = myPageDto.procrastinatedTasks,
36+
completedTaskCount = myPageDto.completedTasks.size,
37+
procrastinatedTaskCount = myPageDto.procrastinatedTasks.size,
38+
),
39+
)
40+
}
41+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.ssak3.timeattack.mypage.controller.dto
2+
3+
import com.ssak3.timeattack.persona.domain.Persona
4+
import com.ssak3.timeattack.task.domain.Task
5+
6+
data class MyPageResponse(
7+
val satisfactionAvg: Int,
8+
val concentrationAvg: Int,
9+
val personas: List<Persona>,
10+
val completedTasks: List<Task>,
11+
val procrastinatedTasks: List<Task>,
12+
val completedTaskCount: Int,
13+
val procrastinatedTaskCount: Int,
14+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.ssak3.timeattack.mypage.service
2+
3+
import com.ssak3.timeattack.common.utils.Logger
4+
import com.ssak3.timeattack.common.utils.checkNotNull
5+
import com.ssak3.timeattack.member.domain.Member
6+
import com.ssak3.timeattack.mypage.service.dto.MyPageDto
7+
import com.ssak3.timeattack.persona.domain.Persona
8+
import com.ssak3.timeattack.persona.repository.PersonaRepository
9+
import com.ssak3.timeattack.retrospection.repository.RetrospectionRepository
10+
import com.ssak3.timeattack.task.domain.Task
11+
import com.ssak3.timeattack.task.repository.TaskRepository
12+
import org.springframework.stereotype.Service
13+
14+
@Service
15+
class MyPageService(
16+
private val taskRepository: TaskRepository,
17+
private val personaRepository: PersonaRepository,
18+
private val retrospectionRepository: RetrospectionRepository,
19+
) : Logger {
20+
fun getMyPage(member: Member): MyPageDto {
21+
checkNotNull(member.id, "MemberId")
22+
// 회고 만족도, 집중도 평균 조회
23+
val retrospectives = retrospectionRepository.findAllByMemberId(member.id)
24+
val satisfactionAverage = retrospectives.map { it.satisfaction }.average().toInt()
25+
val concentrationAverage = retrospectives.map { it.concentration }.average().toInt()
26+
27+
// 역대 페르소나 조회
28+
val personas =
29+
personaRepository.findPersonasByMemberIdOrderByLatestTask(
30+
member.id,
31+
).map { Persona.fromEntity(it) }
32+
33+
// 완료한 일 목록 조회
34+
val completedTasks =
35+
taskRepository.findCompletedTasksOrderByCompletedTimeDesc(
36+
member.id,
37+
).map { Task.fromEntity(it) }
38+
39+
// 미룬일 목록 조회
40+
val procrastinatedTasks =
41+
taskRepository.findProcrastinatedTasksOrderByDueDateDesc(member.id).map {
42+
Task.fromEntity(it)
43+
}
44+
45+
return MyPageDto(
46+
satisfactionAvg = satisfactionAverage,
47+
concentrationAvg = concentrationAverage,
48+
personas = personas,
49+
completedTasks = completedTasks,
50+
procrastinatedTasks = procrastinatedTasks,
51+
)
52+
}
53+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.ssak3.timeattack.mypage.service.dto
2+
3+
import com.ssak3.timeattack.persona.domain.Persona
4+
import com.ssak3.timeattack.task.domain.Task
5+
6+
data class MyPageDto(
7+
val satisfactionAvg: Int,
8+
val concentrationAvg: Int,
9+
val personas: List<Persona>,
10+
val completedTasks: List<Task>,
11+
val procrastinatedTasks: List<Task>,
12+
)

0 commit comments

Comments
 (0)