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

Feat: 시간표 조회 API 구현 #23

Merged
merged 7 commits into from
Feb 4, 2025
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 @@ -3,4 +3,5 @@ package com.yourssu.soongpt.domain.course.implement
interface CourseRepository {
fun save(course: Course): Course
fun findAllByDepartmentId(departmentId: Long, classification: Classification): List<Course>
fun getAll(ids: List<Long>): List<Course>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yourssu.soongpt.domain.course.implement

import org.springframework.stereotype.Component

@Component
class CourseWriter(
private val courseRepository: CourseRepository,
) {
fun save(course: Course): Course {
return courseRepository.save(course)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class CourseRepositoryImpl(
.fetch()
.map { it.toDomain() }
}

override fun getAll(ids: List<Long>): List<Course> {
return jpaQueryFactory.selectFrom(courseEntity)
.where(courseEntity.id.`in`(ids))
.fetch()
.map { it.toDomain() }
}
}

interface CourseJpaRepository : JpaRepository<CourseEntity, Long> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.yourssu.soongpt.domain.timetable.application

import com.yourssu.soongpt.common.business.dto.Response
import com.yourssu.soongpt.domain.timetable.business.TimetableService
import com.yourssu.soongpt.domain.timetable.business.dto.TimetableResponse
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/timetables")
class TimetableController(
private val timetableService: TimetableService,
) {
@GetMapping("/{id}")
fun getTimetable(@PathVariable id: Long): ResponseEntity<Response<TimetableResponse>> {
val response = timetableService.getTimeTable(id)
return ResponseEntity.ok(Response(result=response))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.yourssu.soongpt.domain.timetable.business

import com.yourssu.soongpt.domain.courseTime.implement.CourseTimeReader
import com.yourssu.soongpt.domain.timetable.business.dto.TimetableCourseResponse
import com.yourssu.soongpt.domain.timetable.business.dto.TimetableResponse
import com.yourssu.soongpt.domain.timetable.implement.TimetableCourseReader
import com.yourssu.soongpt.domain.timetable.implement.TimetableReader
import org.springframework.stereotype.Service

@Service
class TimetableService(
private val timetableReader: TimetableReader,
private val timetableCourseReader: TimetableCourseReader,
private val courseTimeReader: CourseTimeReader,
) {
fun getTimeTable(id: Long): TimetableResponse {
val timetable = timetableReader.get(id)
val courses = timetableCourseReader.findAllCourseByTimetableId(id)
val response = courses.map { TimetableCourseResponse.from(it, courseTimeReader.findAllByCourseId(it.id!!)) }
return TimetableResponse.from(timetable, response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.yourssu.soongpt.domain.timetable.business.dto

import com.yourssu.soongpt.domain.course.implement.Course
import com.yourssu.soongpt.domain.courseTime.business.dto.CourseTimeResponse
import com.yourssu.soongpt.domain.courseTime.implement.CourseTime

data class TimetableCourseResponse(
val courseName: String,
val professorName: String?,
val classification: String,
val courseCode: Int,
val credit: Int,
val courseTime: List<CourseTimeResponse>,
) {
companion object {
fun from(course: Course, courseTimes: List<CourseTime>): TimetableCourseResponse {
return TimetableCourseResponse(
courseName = course.courseName,
professorName = course.professorName,
classification = course.classification.name,
courseCode = course.courseCode,
credit = course.credit,
courseTime = courseTimes.map { CourseTimeResponse.from(it) },
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.yourssu.soongpt.domain.timetable.business.dto

import com.yourssu.soongpt.domain.timetable.implement.Timetable

data class TimetableResponse(
val timetableId: Long,
val tag: String,
val courses: List<TimetableCourseResponse>,
) {
companion object {
fun from(timetable: Timetable, courses: List<TimetableCourseResponse>): TimetableResponse {
return TimetableResponse(
timetableId = timetable.id!!,
tag = timetable.tag.name,
courses = courses,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.yourssu.soongpt.domain.timetable.implement

enum class Tag {
DEFAULT,
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.yourssu.soongpt.domain.timetable.implement

class Timetable(
val id: Long? = null,
val tag: Tag,
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.yourssu.soongpt.domain.timetable.implement

class TimetableCourse(
val id: Long? = null,
val timetableId: Long,
val courseId: Long,
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.yourssu.soongpt.domain.timetable.implement

import com.yourssu.soongpt.domain.course.implement.Course
import com.yourssu.soongpt.domain.course.implement.CourseRepository
import org.springframework.stereotype.Component

@Component
class TimetableCourseReader(
private val timetableCourseRepository: TimetableCourseRepository,
private val courseRepository: CourseRepository,
) {
fun findAllCourseByTimetableId(timetableId: Long): List<Course> {
val courseIds = timetableCourseRepository.findAllCourseByTimetableId(timetableId).map { it.courseId }
return courseRepository.getAll(courseIds)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.yourssu.soongpt.domain.timetable.implement

interface TimetableCourseRepository {
fun save(timetableCourse: TimetableCourse): TimetableCourse
fun findAllCourseByTimetableId(id: Long): List<TimetableCourse>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yourssu.soongpt.domain.timetable.implement

import org.springframework.stereotype.Component

@Component
class TimetableCourseWriter(
private val timetableCourseRepository: TimetableCourseRepository,
) {
fun save(timetableCourse: TimetableCourse): TimetableCourse {
return timetableCourseRepository.save(timetableCourse)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yourssu.soongpt.domain.timetable.implement

import org.springframework.stereotype.Component

@Component
class TimetableReader(
private val timetableRepository: TimetableRepository,
) {
fun get(id: Long): Timetable {
return timetableRepository.get(id)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.yourssu.soongpt.domain.timetable.implement

interface TimetableRepository {
fun save(timetable: Timetable): Timetable
fun get(id: Long): Timetable
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.yourssu.soongpt.domain.timetable.implement

import org.springframework.stereotype.Component

@Component
class TimetableWriter(
private val timetableRepository: TimetableRepository,
) {
fun save(timetable: Timetable): Timetable {
return timetableRepository.save(timetable)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.yourssu.soongpt.domain.timetable.storage

import com.yourssu.soongpt.domain.timetable.implement.Timetable
import com.yourssu.soongpt.domain.timetable.implement.TimetableRepository
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
class TimetableRepositoryImpl(
private val timetableJpaRepository: TimetableJpaRepository,
): TimetableRepository {
override fun save(timetable: Timetable): Timetable {
return timetableJpaRepository.save(TimetableEntity.from(timetable))
.toDomain()
}

override fun get(id: Long): Timetable {
return timetableJpaRepository.findById(id).get().toDomain()
}
}

interface TimetableJpaRepository: JpaRepository<TimetableEntity, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.yourssu.soongpt.domain.timetable.storage

import com.yourssu.soongpt.domain.timetable.implement.TimetableCourse
import jakarta.persistence.*

@Entity
@Table(name = "timetable_course")
class TimetableCourseEntity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,

@Column(nullable = false)
val timetableId: Long,

@Column(nullable = false)
val courseId: Long,
) {
companion object {
fun from(timetableCourse: TimetableCourse): TimetableCourseEntity {
return TimetableCourseEntity(
id = timetableCourse.id,
timetableId = timetableCourse.timetableId,
courseId = timetableCourse.courseId
)
}
}

fun toDomain(): TimetableCourse {
return TimetableCourse(
id = id,
timetableId = timetableId,
courseId = courseId
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yourssu.soongpt.domain.timetable.storage

import com.querydsl.jpa.impl.JPAQueryFactory
import com.yourssu.soongpt.domain.timetable.implement.TimetableCourse
import com.yourssu.soongpt.domain.timetable.implement.TimetableCourseRepository
import com.yourssu.soongpt.domain.timetable.storage.QTimetableCourseEntity.timetableCourseEntity
import com.yourssu.soongpt.domain.timetable.storage.QTimetableEntity.timetableEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
class TimetableCourseRepositoryImpl(
private val timetableCourseJpaRepository: TimetableCourseJpaRepository,
private val jpaQueryFactory: JPAQueryFactory,
): TimetableCourseRepository {
override fun save(timetableCourse: TimetableCourse): TimetableCourse {
return timetableCourseJpaRepository.save(TimetableCourseEntity.from(timetableCourse))
.toDomain()
}

override fun findAllCourseByTimetableId(id: Long): List<TimetableCourse> {
return jpaQueryFactory.selectFrom(timetableCourseEntity)
.join(timetableEntity)
.on(timetableCourseEntity.timetableId.eq(timetableEntity.id))
.where(timetableEntity.id.eq(id))
.fetch()
.map { it.toDomain() }
}
}

interface TimetableCourseJpaRepository: JpaRepository<TimetableCourseEntity, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.yourssu.soongpt.domain.timetable.storage

import com.yourssu.soongpt.domain.timetable.implement.Tag
import com.yourssu.soongpt.domain.timetable.implement.Timetable
import jakarta.persistence.*

@Entity
@Table(name = "timetable")
class TimetableEntity(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,

@Column(nullable = false)
@Enumerated(EnumType.STRING)
val tag: Tag,
) {
companion object {
fun from(timetable: Timetable): TimetableEntity {
return TimetableEntity(
id = timetable.id,
tag = timetable.tag
)
}
}

fun toDomain(): Timetable {
return Timetable(
id = id,
tag = tag
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.yourssu.soongpt.common.support.fixture

import com.yourssu.soongpt.domain.timetable.implement.Tag
import com.yourssu.soongpt.domain.timetable.implement.Timetable

enum class TimetableFixture(
val tag: Tag,
) {
DEFAULT(Tag.DEFAULT),
;

fun toDomain() = Timetable(
tag = tag,
)
}
Loading