diff --git a/.gitignore b/.gitignore index 2727550d..9521126d 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,13 @@ logs/ **/application-secret.properties ### Firebase ### -**/firebase-service-account.json \ No newline at end of file +**/firebase-service-account.json + +### Environment Variables ### +.env +.env.local +.env.dev +.env.prod +.env.example +CLAUDE.md +run.sh \ No newline at end of file diff --git a/finda-volunteer/build.gradle.kts b/finda-volunteer/build.gradle.kts index 44a77a26..b99b2c47 100644 --- a/finda-volunteer/build.gradle.kts +++ b/finda-volunteer/build.gradle.kts @@ -3,6 +3,7 @@ plugins { kotlin("plugin.spring") id("org.springframework.boot") id("io.spring.dependency-management") + id("com.google.protobuf") version "0.9.4" } group = "finda" @@ -27,7 +28,13 @@ dependencies { implementation(Dependencies.SPRING_SECURITY) implementation(Dependencies.JACKSON) implementation(Dependencies.JACKSON_TYPE) + implementation(Dependencies.SPRING_VALIDITY) implementation(Dependencies.LIQUIBASE) + implementation(Dependencies.GRPC_CLIENT) + implementation(Dependencies.GRPC_PROTOBUF) + implementation(Dependencies.GRPC_STUB) + implementation(Dependencies.PROTOBUF_JAVA) + compileOnly(Dependencies.JAVAX_ANNOTATION) // JWT implementation(Dependencies.JWT_API) @@ -38,6 +45,24 @@ dependencies { implementation(project(":finda-security-common")) } +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:3.24.0" + } + plugins { + create("grpc") { + artifact = "io.grpc:protoc-gen-grpc-java:1.59.0" + } + } + generateProtoTasks { + all().forEach { + it.plugins { + create("grpc") + } + } + } +} + kotlin { compilerOptions { freeCompilerArgs.addAll("-Xjsr305=strict", "-Xannotation-default-target=param-property") diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/ActivityWebAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/ActivityWebAdapter.kt index 145831aa..0f55331c 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/ActivityWebAdapter.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/ActivityWebAdapter.kt @@ -1,8 +1,23 @@ package finda.findavolunteer.adapter.`in`.activity +import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest +import finda.findavolunteer.adapter.`in`.activity.mapper.toCommand +import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase +import jakarta.validation.Valid +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/activities") -class ActivityWebAdapter +class ActivityWebAdapter( + private val createUserActivityUseCase: CreateUserActivityUseCase +) { + @PostMapping("/user") + fun createUserActivity( + @Valid @RequestBody + request: CreateUserActivityRequest + ) = + createUserActivityUseCase.execute(request.toCommand()) +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/dto/request/CreateUserActivityRequest.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/dto/request/CreateUserActivityRequest.kt new file mode 100644 index 00000000..a3ce7bdd --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/dto/request/CreateUserActivityRequest.kt @@ -0,0 +1,16 @@ +package finda.findavolunteer.adapter.`in`.activity.dto.request + +import jakarta.validation.Valid +import jakarta.validation.constraints.NotEmpty +import java.util.* + +data class CreateUserActivityRequest( + @field:Valid + @field:NotEmpty + val userActivityList: List +) + +data class UserActivity( + val userId: UUID, + val activityId: UUID +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/mapper/CreateUserActivityRequestMapper.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/mapper/CreateUserActivityRequestMapper.kt new file mode 100644 index 00000000..56b18dee --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/mapper/CreateUserActivityRequestMapper.kt @@ -0,0 +1,15 @@ +package finda.findavolunteer.adapter.`in`.activity.mapper + +import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest +import finda.findavolunteer.application.port.`in`.activity.dto.request.CreateUserActivityCommand +import finda.findavolunteer.application.port.`in`.activity.dto.request.UserActivityCommand + +fun CreateUserActivityRequest.toCommand(): CreateUserActivityCommand = + CreateUserActivityCommand( + userActivityCommandList = userActivityList.map { + UserActivityCommand( + userId = it.userId, + activityId = it.activityId + ) + } + ) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt index a7c26b91..09ff0361 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt @@ -1,10 +1,19 @@ package finda.findavolunteer.adapter.`in`.volunteer import finda.findavolunteer.adapter.`in`.volunteer.dto.request.CreateVolunteerRequest +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerDetailResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerListResponse +import finda.findavolunteer.adapter.`in`.volunteer.mapper.toCommand +import finda.findavolunteer.adapter.`in`.volunteer.mapper.toResponse import finda.findavolunteer.application.port.`in`.volunteer.CreateVolunteerUseCase import finda.findavolunteer.application.port.`in`.volunteer.DeleteVolunteerUseCase +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerListUseCase +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.DeleteMapping +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping @@ -17,11 +26,31 @@ import java.util.UUID @RequestMapping("/volunteers") class VolunteerWebAdapter( val createVolunteerUseCase: CreateVolunteerUseCase, - val deleteVolunteerUseCase: DeleteVolunteerUseCase + val deleteVolunteerUseCase: DeleteVolunteerUseCase, + val volunteerDetailUseCase: VolunteerDetailUseCase, + val volunteerListUseCase: VolunteerListUseCase ) { @PostMapping @ResponseStatus(value = HttpStatus.CREATED) - fun createVolunteer(@RequestBody request: CreateVolunteerRequest) = createVolunteerUseCase.execute(request) + fun createVolunteer(@RequestBody request: CreateVolunteerRequest) = + createVolunteerUseCase.execute(request.toCommand()) + + @GetMapping("/{volunteerId}") + @ResponseStatus(value = HttpStatus.OK) + fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = + volunteerDetailUseCase.execute(volunteerId).toResponse() + + @GetMapping + @ResponseStatus(value = HttpStatus.OK) + fun getVolunteers( + @RequestParam(required = false) status: VolunteerStatus?, + @RequestParam(required = false) year: Int?, + @RequestParam(required = false) sortBy: String? + ): List = volunteerListUseCase.execute( + status = status, + year = year, + sortBy = sortBy + ).map { it.toResponse() } @DeleteMapping @ResponseStatus(value = HttpStatus.NO_CONTENT) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerDetailResponse.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerDetailResponse.kt new file mode 100644 index 00000000..d5d396eb --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerDetailResponse.kt @@ -0,0 +1,59 @@ +package finda.findavolunteer.adapter.`in`.volunteer.dto.response + +import finda.findavolunteer.domain.participation.enum.ParticipationStatus +import finda.findavolunteer.domain.volunteer.enum.CycleType +import finda.findavolunteer.domain.volunteer.enum.GroupVolunteerType +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus +import finda.findavolunteer.domain.volunteer.enum.VolunteerType +import finda.findavolunteer.domain.volunteer.enum.Weekday +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.util.UUID + +data class VolunteerDetailResponse( + val volunteerId: UUID, + val title: String, + val description: String, + val status: VolunteerStatus, + val personnel: Int, + val unitVolunteerHours: Float, + val applicationStartDate: LocalDate, + val applicationEndDate: LocalDate, + val workStartDate: LocalDate, + val workEndDate: LocalDate, + val cycleType: CycleType, + val weekdays: List, + val monthDate: Int?, + val remindTime: LocalTime, + val groupVolunteerType: GroupVolunteerType, + val volunteerType: VolunteerType, + val writerUserId: UUID, + val schedules: List, + val studentParticipations: List, + val activities: List, + val userActivities: List +) + +data class VolunteerScheduleResponse( + val scheduleId: UUID, + val scheduleDate: LocalDate +) + +data class StudentParticipationResponse( + val userId: UUID, + val name: String, + val status: ParticipationStatus, + val participatedAt: LocalDateTime +) + +data class ActivityResponse( + val activityId: UUID, + val activityName: String +) + +data class UserActivityResponse( + val userId: UUID, + val userName: String, + val activityId: UUID +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerListResponse.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerListResponse.kt new file mode 100644 index 00000000..535b9e03 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerListResponse.kt @@ -0,0 +1,12 @@ +package finda.findavolunteer.adapter.`in`.volunteer.dto.response + +import java.time.LocalDate +import java.util.UUID + +data class VolunteerListResponse( + val volunteerId: UUID, + val title: String, + val workStartDate: LocalDate, + val workEndDate: LocalDate, + val unitVolunteerHours: Float +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/CreateVolunteerRequestMapper.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/CreateVolunteerRequestMapper.kt new file mode 100644 index 00000000..eeef4f6f --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/CreateVolunteerRequestMapper.kt @@ -0,0 +1,31 @@ +package finda.findavolunteer.adapter.`in`.volunteer.mapper + +import finda.findavolunteer.adapter.`in`.volunteer.dto.request.CreateVolunteerRequest +import finda.findavolunteer.application.port.`in`.volunteer.dto.request.CreateVolunteerCommand +import finda.findavolunteer.application.port.`in`.volunteer.dto.request.VolunteerDateCommand + +fun CreateVolunteerRequest.toCommand(): CreateVolunteerCommand = + CreateVolunteerCommand( + personnel = personnal, + title = title, + description = description, + unitVolunteerTime = unitVolunteerTime, + applicationDateCommand = VolunteerDateCommand( + startDate = applicationDate.startDate, + endDate = applicationDate.endDate + ), + workDateCommand = VolunteerDateCommand( + startDate = workDate.startDate, + endDate = workDate.endDate + ), + cycle = cycle, + volunteerDateList = volunteerDate, + teacherIdList = teachers, + studentIdList = students, + remindTime = remindTime, + volunteerType = volunteerType, + groupVolunteerType = groupVolunteerType, + activityNameList = activity, + weekdayList = weekdays, + monthDate = monthDate + ) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/VolunteerResultMapper.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/VolunteerResultMapper.kt new file mode 100644 index 00000000..47d1bf90 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/VolunteerResultMapper.kt @@ -0,0 +1,67 @@ +package finda.findavolunteer.adapter.`in`.volunteer.mapper + +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.ActivityResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.StudentParticipationResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.UserActivityResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerDetailResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerListResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerScheduleResponse +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerDetailResult +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerListResult + +fun VolunteerDetailResult.toResponse(): VolunteerDetailResponse = + VolunteerDetailResponse( + volunteerId = volunteerId, + title = title, + description = description, + status = status, + personnel = personnel, + unitVolunteerHours = unitVolunteerHours, + applicationStartDate = applicationStartDate, + applicationEndDate = applicationEndDate, + workStartDate = workStartDate, + workEndDate = workEndDate, + cycleType = cycleType, + weekdays = weekdayList, + monthDate = monthDate, + remindTime = remindTime, + groupVolunteerType = groupVolunteerType, + volunteerType = volunteerType, + writerUserId = writerUserId, + schedules = scheduleResultList.map { + VolunteerScheduleResponse( + scheduleId = it.scheduleId, + scheduleDate = it.scheduleDate + ) + }, + studentParticipations = studentParticipationResultList.map { + StudentParticipationResponse( + userId = it.userId, + name = it.name, + status = it.status, + participatedAt = it.participatedAt + ) + }, + activities = activityResultList.map { + ActivityResponse( + activityId = it.activityId, + activityName = it.activityName + ) + }, + userActivities = userActivityResultList.map { + UserActivityResponse( + userId = it.userId, + userName = it.userName, + activityId = it.activityId + ) + } + ) + +fun VolunteerListResult.toResponse(): VolunteerListResponse = + VolunteerListResponse( + volunteerId = volunteerId, + title = title, + workStartDate = workStartDate, + workEndDate = workEndDate, + unitVolunteerHours = unitVolunteerHours + ) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt new file mode 100644 index 00000000..ea2b6a3b --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt @@ -0,0 +1,41 @@ +package finda.findavolunteer.adapter.out.grpc + +import finda.findaauth.adapter.`in`.grpc.AuthServiceGrpc +import finda.findaauth.adapter.`in`.grpc.UserRequest +import finda.findavolunteer.application.port.out.user.UserQueryPort +import io.grpc.Status +import io.grpc.StatusRuntimeException +import net.devh.boot.grpc.client.inject.GrpcClient +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Component +import java.util.UUID +import java.util.concurrent.TimeUnit + +@Component +class UserGrpcAdapter : UserQueryPort { + private val log = LoggerFactory.getLogger(javaClass) + + @GrpcClient("auth-service") + private lateinit var authServiceStub: AuthServiceGrpc.AuthServiceBlockingStub + + override fun getUserName(userId: UUID): String? { + return try { + authServiceStub + .withDeadlineAfter(2L, TimeUnit.SECONDS) + .getUserName( + UserRequest.newBuilder() + .setUserId(userId.toString()) + .build() + ) + .userName + } catch (e: StatusRuntimeException) { + when (e.status.code) { + Status.Code.NOT_FOUND -> null + else -> { + log.error("gRPC getUserName failed.", e) + throw e + } + } + } + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/ActivityPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/ActivityPersistenceAdapter.kt index 6495a699..105e76e8 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/ActivityPersistenceAdapter.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/ActivityPersistenceAdapter.kt @@ -1,9 +1,8 @@ package finda.findavolunteer.adapter.out.persistence.activity import finda.findavolunteer.adapter.out.persistence.activity.mapper.ActivityMapper -import finda.findavolunteer.adapter.out.persistence.activity.mapper.UserActivityMapper import finda.findavolunteer.adapter.out.persistence.activity.repository.ActivityRepository -import finda.findavolunteer.adapter.out.persistence.activity.repository.UserActivityRepository +import finda.findavolunteer.application.exception.activity.ActivityNotFoundException import finda.findavolunteer.application.port.out.activity.ActivityCommandPort import finda.findavolunteer.application.port.out.activity.ActivityQueryPort import finda.findavolunteer.domain.activity.model.Activity @@ -13,10 +12,8 @@ import java.util.UUID @Component class ActivityPersistenceAdapter( - val userActivityRepository: UserActivityRepository, - val userActivityMapper: UserActivityMapper, - val activityRepository: ActivityRepository, - val activityMapper: ActivityMapper + private val activityRepository: ActivityRepository, + private val activityMapper: ActivityMapper ) : ActivityCommandPort, ActivityQueryPort { override fun save(activity: Activity): Activity { val entity = activityRepository.save(activityMapper.toEntity(activity)) @@ -27,4 +24,9 @@ class ActivityPersistenceAdapter( val entity = activityRepository.findByIdOrNull(id) return entity?.let(activityMapper::toDomain) } + + override fun findByIdOrThrow(id: UUID): Activity { + val entity = activityRepository.findByIdOrNull(id) ?: throw ActivityNotFoundException + return activityMapper.toDomain(entity) + } } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/UserActivityAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/UserActivityAdapter.kt new file mode 100644 index 00000000..d3f7988a --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/UserActivityAdapter.kt @@ -0,0 +1,25 @@ +package finda.findavolunteer.adapter.out.persistence.activity + +import finda.findavolunteer.adapter.out.persistence.activity.mapper.UserActivityMapper +import finda.findavolunteer.adapter.out.persistence.activity.repository.UserActivityRepository +import finda.findavolunteer.application.port.out.activity.UserActivityCommandPort +import finda.findavolunteer.application.port.out.activity.UserActivityQueryPort +import finda.findavolunteer.domain.activity.model.UserActivity +import org.springframework.stereotype.Component +import java.util.UUID + +@Component +class UserActivityAdapter( + private val userActivityRepository: UserActivityRepository, + private val userActivityMapper: UserActivityMapper +) : UserActivityCommandPort, UserActivityQueryPort { + override fun save(userActivity: UserActivity): UserActivity { + val entity = userActivityRepository.save(userActivityMapper.toEntity(userActivity)) + return userActivityMapper.toDomain(entity) + } + + override fun findById(id: UUID): UserActivity? { + val entity = userActivityRepository.findWithActivityById(id) + return entity?.let(userActivityMapper::toDomain) + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/entity/UserActivityJpaEntity.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/entity/UserActivityJpaEntity.kt index 6e3157cd..548ea5a1 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/entity/UserActivityJpaEntity.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/entity/UserActivityJpaEntity.kt @@ -1,6 +1,7 @@ package finda.findavolunteer.adapter.out.persistence.activity.entity import finda.findavolunteer.adapter.out.persistence.BaseEntity +import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.FetchType import jakarta.persistence.JoinColumn @@ -13,6 +14,9 @@ import java.util.UUID class UserActivityJpaEntity( id: UUID?, + @Column(name = "user_id", nullable = false) + val userId: UUID, + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "activity_id", nullable = true) val activity: ActivityJpaEntity? diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/mapper/UserActivityMapper.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/mapper/UserActivityMapper.kt index 6f57107e..e087cfd1 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/mapper/UserActivityMapper.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/mapper/UserActivityMapper.kt @@ -15,7 +15,10 @@ class UserActivityMapper( override fun toDomain(entity: UserActivityJpaEntity): UserActivity { return UserActivity( id = entity.id!!, - activityId = entity.activity!!.id!! + activityId = requireNotNull(entity.activity?.id) { + "UserActivity(${entity.id}) is missing activity reference" + }, + userId = entity.userId ) } @@ -24,6 +27,7 @@ class UserActivityMapper( return UserActivityJpaEntity( id = domain.id, + userId = domain.userId, activity = activity ) } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/ActivityRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/ActivityRepository.kt index f467141f..bbef6bb1 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/ActivityRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/ActivityRepository.kt @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface ActivityRepository : CrudRepository +interface ActivityRepository : CrudRepository { + fun findAllByVolunteerId(volunteerId: UUID): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/UserActivityRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/UserActivityRepository.kt index 1d7a1d71..688cb504 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/UserActivityRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/UserActivityRepository.kt @@ -1,9 +1,31 @@ package finda.findavolunteer.adapter.out.persistence.activity.repository import finda.findavolunteer.adapter.out.persistence.activity.entity.UserActivityJpaEntity +import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.CrudRepository +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface UserActivityRepository : CrudRepository +interface UserActivityRepository : CrudRepository { + @Query( + """ + select userActivity + from UserActivityJpaEntity userActivity + left join fetch userActivity.activity + where userActivity.id = :id + """ + ) + fun findWithActivityById(@Param("id") id: UUID): UserActivityJpaEntity? + + @Query( + """ + select userActivity + from UserActivityJpaEntity userActivity + join fetch userActivity.activity activity + where activity.volunteer.id = :volunteerId + """ + ) + fun findAllWithActivityByVolunteerId(@Param("volunteerId") volunteerId: UUID): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/TeacherParticipationAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/TeacherParticipationAdapter.kt index c44a6139..513c67ef 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/TeacherParticipationAdapter.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/TeacherParticipationAdapter.kt @@ -2,7 +2,7 @@ package finda.findavolunteer.adapter.out.persistence.participation import finda.findavolunteer.adapter.out.persistence.participation.mapper.TeacherParticipationMapper import finda.findavolunteer.adapter.out.persistence.participation.repository.TeacherParticipationRepository -import finda.findavolunteer.application.exception.TeacherParticipationNotFoundException +import finda.findavolunteer.application.exception.participation.TeacherParticipationNotFoundException import finda.findavolunteer.application.port.out.participation.TeacherParticipationCommandPort import finda.findavolunteer.application.port.out.participation.TeacherParticipationQueryPort import finda.findavolunteer.domain.participation.model.TeacherParticipation diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/repository/StudentParticipationRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/repository/StudentParticipationRepository.kt index eb91d700..d70c500c 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/repository/StudentParticipationRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/participation/repository/StudentParticipationRepository.kt @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface StudentParticipationRepository : CrudRepository +interface StudentParticipationRepository : CrudRepository { + fun findAllByVolunteerId(volunteerId: UUID): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerDetailPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerDetailPersistenceAdapter.kt new file mode 100644 index 00000000..5994c02e --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerDetailPersistenceAdapter.kt @@ -0,0 +1,107 @@ +package finda.findavolunteer.adapter.out.persistence.volunteer + +import finda.findavolunteer.adapter.out.persistence.activity.repository.ActivityRepository +import finda.findavolunteer.adapter.out.persistence.activity.repository.UserActivityRepository +import finda.findavolunteer.adapter.out.persistence.participation.repository.StudentParticipationRepository +import finda.findavolunteer.adapter.out.persistence.volunteer.repository.ActivityRecurrenceMonthRepository +import finda.findavolunteer.adapter.out.persistence.volunteer.repository.ActivityRecurrenceWeekRepository +import finda.findavolunteer.adapter.out.persistence.volunteer.repository.VolunteerRepository +import finda.findavolunteer.adapter.out.persistence.volunteer.repository.VolunteerScheduleRepository +import finda.findavolunteer.application.exception.volunteer.VolunteerNotFoundException +import finda.findavolunteer.application.port.out.volunteer.VolunteerDetailQueryPort +import finda.findavolunteer.domain.activity.model.Activity +import finda.findavolunteer.domain.activity.model.UserActivity +import finda.findavolunteer.domain.participation.model.StudentParticipation +import finda.findavolunteer.domain.volunteer.model.Volunteer +import finda.findavolunteer.domain.volunteer.model.VolunteerDetail +import finda.findavolunteer.domain.volunteer.model.VolunteerSchedule +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Component +import java.util.UUID + +@Component +class VolunteerDetailPersistenceAdapter( + private val volunteerRepository: VolunteerRepository, + private val volunteerScheduleRepository: VolunteerScheduleRepository, + private val studentParticipationRepository: StudentParticipationRepository, + private val activityRepository: ActivityRepository, + private val userActivityRepository: UserActivityRepository, + private val activityRecurrenceWeekRepository: ActivityRecurrenceWeekRepository, + private val activityRecurrenceMonthRepository: ActivityRecurrenceMonthRepository +) : VolunteerDetailQueryPort { + override fun findDetailByIdOrThrow(volunteerId: UUID): VolunteerDetail { + val volunteerEntity = volunteerRepository.findByIdOrNull(volunteerId) + ?: throw VolunteerNotFoundException + + val schedules = volunteerScheduleRepository.findAllByVolunteerIdOrderByScheduleDateAsc(volunteerId) + .map { + VolunteerSchedule( + id = requireNotNull(it.id), + scheduleDate = it.scheduleDate, + volunteerId = volunteerId + ) + } + + val studentParticipations = studentParticipationRepository.findAllByVolunteerId(volunteerId) + .map { + StudentParticipation( + id = requireNotNull(it.id), + volunteerId = volunteerId, + status = it.status, + participatedAt = it.participatedAt, + userId = it.userId + ) + } + + val activities = activityRepository.findAllByVolunteerId(volunteerId) + .map { + Activity( + id = requireNotNull(it.id), + activityName = it.activityName, + volunteerId = volunteerId + ) + } + + val userActivities = userActivityRepository.findAllWithActivityByVolunteerId(volunteerId) + .map { + UserActivity( + id = requireNotNull(it.id), + activityId = requireNotNull(it.activity?.id), + userId = it.userId + ) + } + + val weekdays = activityRecurrenceWeekRepository.findAllByVolunteerId(volunteerId) + .map { it.weekday } + + val monthDate = activityRecurrenceMonthRepository.findByVolunteerId(volunteerId)?.day + + val volunteer = Volunteer( + id = requireNotNull(volunteerEntity.id), + status = volunteerEntity.status, + personnel = volunteerEntity.personnel, + title = volunteerEntity.title, + description = volunteerEntity.description, + unitVolunteerHours = volunteerEntity.unitVolunteerHours, + applicationStartDate = volunteerEntity.applicationStartDate, + applicationEndDate = volunteerEntity.applicationEndDate, + workStartDate = volunteerEntity.workStartDate, + workEndDate = volunteerEntity.workEndDate, + cycleType = volunteerEntity.cycleType, + userId = volunteerEntity.userId, + remindTime = volunteerEntity.remindTime, + groupVolunteerType = volunteerEntity.groupVolunteerType, + volunteerType = volunteerEntity.volunteerType + ) + + return VolunteerDetail( + volunteer = volunteer, + schedules = schedules, + studentParticipations = studentParticipations, + activities = activities, + userActivities = userActivities, + weekdays = weekdays, + monthDate = monthDate + ) + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt index 0fd137c4..2be21115 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt @@ -6,9 +6,11 @@ import finda.findavolunteer.adapter.out.persistence.volunteer.mapper.VolunteerMa import finda.findavolunteer.adapter.out.persistence.volunteer.repository.ActivityRecurrenceMonthRepository import finda.findavolunteer.adapter.out.persistence.volunteer.repository.ActivityRecurrenceWeekRepository import finda.findavolunteer.adapter.out.persistence.volunteer.repository.VolunteerRepository -import finda.findavolunteer.application.exception.VolunteerNotFoundException +import finda.findavolunteer.application.exception.volunteer.VolunteerNotFoundException import finda.findavolunteer.application.port.out.volunteer.VolunteerCommandPort +import finda.findavolunteer.application.port.out.volunteer.VolunteerListQueryPort import finda.findavolunteer.application.port.out.volunteer.VolunteerQueryPort +import finda.findavolunteer.domain.volunteer.enum.VolunteerSortBy import finda.findavolunteer.domain.volunteer.model.Volunteer import finda.findavolunteer.domain.volunteer.model.recurrence.ActivityRecurrenceMonth import finda.findavolunteer.domain.volunteer.model.recurrence.ActivityRecurrenceWeek @@ -24,7 +26,7 @@ class VolunteerPersistenceAdapter( val activityRecurrenceMonthMapper: ActivityRecurrenceMonthMapper, val activityRecurrenceWeekRepository: ActivityRecurrenceWeekRepository, val activityRecurrenceWeekMapper: ActivityRecurrenceWeekMapper -) : VolunteerCommandPort, VolunteerQueryPort { +) : VolunteerCommandPort, VolunteerQueryPort, VolunteerListQueryPort { override fun save(volunteer: Volunteer): Volunteer { val entity = volunteerRepository.save(volunteerMapper.toEntity(volunteer)) return volunteerMapper.toDomain(entity) @@ -54,6 +56,18 @@ class VolunteerPersistenceAdapter( return findById(id) ?: throw VolunteerNotFoundException } + override fun findAll( + status: finda.findavolunteer.domain.volunteer.enum.VolunteerStatus?, + year: Int?, + sortBy: VolunteerSortBy + ): List { + return when (sortBy) { + VolunteerSortBy.WORK_START_DATE -> + volunteerRepository.findAllByStatusAndYearOrderByWorkStartDateDesc(status, year) + .map(volunteerMapper::toDomain) + } + } + override fun deleteById(volunteerId: UUID) { volunteerRepository.deleteById(volunteerId) } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceMonthRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceMonthRepository.kt index 92abc678..724c3188 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceMonthRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceMonthRepository.kt @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface ActivityRecurrenceMonthRepository : CrudRepository +interface ActivityRecurrenceMonthRepository : CrudRepository { + fun findByVolunteerId(volunteerId: UUID): ActivityRecurrenceMonthJpaEntity? +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceWeekRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceWeekRepository.kt index 3ceb85d7..00b6c849 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceWeekRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/ActivityRecurrenceWeekRepository.kt @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface ActivityRecurrenceWeekRepository : CrudRepository +interface ActivityRecurrenceWeekRepository : CrudRepository { + fun findAllByVolunteerId(volunteerId: UUID): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt index 28b06e1e..3f1df65c 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt @@ -1,11 +1,28 @@ package finda.findavolunteer.adapter.out.persistence.volunteer.repository import finda.findavolunteer.adapter.out.persistence.volunteer.entity.VolunteerJpaEntity +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus +import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.CrudRepository +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository import java.util.UUID @Repository interface VolunteerRepository : CrudRepository { fun findAllByUserId(userId: UUID): List + + @Query( + """ + select volunteer + from VolunteerJpaEntity volunteer + where (:status is null or volunteer.status = :status) + and (:year is null or function('year', volunteer.workStartDate) = :year) + order by volunteer.workStartDate desc + """ + ) + fun findAllByStatusAndYearOrderByWorkStartDateDesc( + @Param("status") status: VolunteerStatus?, + @Param("year") year: Int? + ): List } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerScheduleRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerScheduleRepository.kt index d8b395ae..07184150 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerScheduleRepository.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerScheduleRepository.kt @@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository import java.util.UUID @Repository -interface VolunteerScheduleRepository : CrudRepository +interface VolunteerScheduleRepository : CrudRepository { + fun findAllByVolunteerIdOrderByScheduleDateAsc(volunteerId: UUID): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/activity/ActivityNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/activity/ActivityNotFoundException.kt new file mode 100644 index 00000000..55e8b0f1 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/activity/ActivityNotFoundException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception.activity + +import finda.findavolunteer.global.error.exception.ErrorCode +import finda.findavolunteer.global.error.exception.FindaException + +object ActivityNotFoundException : FindaException( + ErrorCode.ACTIVITY_NOT_FOUND +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/TeacherParticipationNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/participation/TeacherParticipationNotFoundException.kt similarity index 78% rename from finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/TeacherParticipationNotFoundException.kt rename to finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/participation/TeacherParticipationNotFoundException.kt index 4a908669..0877422d 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/TeacherParticipationNotFoundException.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/participation/TeacherParticipationNotFoundException.kt @@ -1,4 +1,4 @@ -package finda.findavolunteer.application.exception +package finda.findavolunteer.application.exception.participation import finda.findavolunteer.global.error.exception.ErrorCode import finda.findavolunteer.global.error.exception.FindaException diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt new file mode 100644 index 00000000..ac74d11b --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception.user + +import finda.findavolunteer.global.error.exception.ErrorCode +import finda.findavolunteer.global.error.exception.FindaException + +object UserNotFoundException : FindaException( + ErrorCode.USER_NOT_FOUND +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.kt new file mode 100644 index 00000000..43825551 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception.volunteer + +import finda.findavolunteer.global.error.exception.ErrorCode +import finda.findavolunteer.global.error.exception.FindaException + +object InvalidVolunteerSortByException : FindaException( + ErrorCode.INVALID_VOLUNTEER_SORT_BY +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerForbiddenException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerForbiddenException.kt similarity index 78% rename from finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerForbiddenException.kt rename to finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerForbiddenException.kt index dab39543..cb000311 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerForbiddenException.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerForbiddenException.kt @@ -1,4 +1,4 @@ -package finda.findavolunteer.application.exception +package finda.findavolunteer.application.exception.volunteer import finda.findavolunteer.global.error.exception.ErrorCode import finda.findavolunteer.global.error.exception.FindaException diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerNotFoundException.kt similarity index 78% rename from finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerNotFoundException.kt rename to finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerNotFoundException.kt index a158938e..875f6762 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/VolunteerNotFoundException.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/VolunteerNotFoundException.kt @@ -1,4 +1,4 @@ -package finda.findavolunteer.application.exception +package finda.findavolunteer.application.exception.volunteer import finda.findavolunteer.global.error.exception.ErrorCode import finda.findavolunteer.global.error.exception.FindaException diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/CreateUserActivityUseCase.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/CreateUserActivityUseCase.kt new file mode 100644 index 00000000..935a5994 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/CreateUserActivityUseCase.kt @@ -0,0 +1,7 @@ +package finda.findavolunteer.application.port.`in`.activity + +import finda.findavolunteer.application.port.`in`.activity.dto.request.CreateUserActivityCommand + +interface CreateUserActivityUseCase { + fun execute(command: CreateUserActivityCommand) +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/dto/request/CreateUserActivityCommand.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/dto/request/CreateUserActivityCommand.kt new file mode 100644 index 00000000..7fee8d2f --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/dto/request/CreateUserActivityCommand.kt @@ -0,0 +1,12 @@ +package finda.findavolunteer.application.port.`in`.activity.dto.request + +import java.util.UUID + +data class CreateUserActivityCommand( + val userActivityCommandList: List +) + +data class UserActivityCommand( + val userId: UUID, + val activityId: UUID +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/CreateVolunteerUseCase.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/CreateVolunteerUseCase.kt index aa9c8728..77c14a0c 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/CreateVolunteerUseCase.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/CreateVolunteerUseCase.kt @@ -1,7 +1,7 @@ package finda.findavolunteer.application.port.`in`.volunteer -import finda.findavolunteer.adapter.`in`.volunteer.dto.request.CreateVolunteerRequest +import finda.findavolunteer.application.port.`in`.volunteer.dto.request.CreateVolunteerCommand interface CreateVolunteerUseCase { - fun execute(request: CreateVolunteerRequest) + fun execute(command: CreateVolunteerCommand) } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerDetailUseCase.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerDetailUseCase.kt new file mode 100644 index 00000000..83f8d370 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerDetailUseCase.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.port.`in`.volunteer + +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerDetailResult +import java.util.UUID + +interface VolunteerDetailUseCase { + fun execute(volunteerId: UUID): VolunteerDetailResult +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerListUseCase.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerListUseCase.kt new file mode 100644 index 00000000..e430cc1c --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerListUseCase.kt @@ -0,0 +1,12 @@ +package finda.findavolunteer.application.port.`in`.volunteer + +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerListResult +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus + +interface VolunteerListUseCase { + fun execute( + status: VolunteerStatus?, + year: Int?, + sortBy: String? + ): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/request/CreateVolunteerCommand.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/request/CreateVolunteerCommand.kt new file mode 100644 index 00000000..4320c18b --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/request/CreateVolunteerCommand.kt @@ -0,0 +1,33 @@ +package finda.findavolunteer.application.port.`in`.volunteer.dto.request + +import finda.findavolunteer.domain.volunteer.enum.CycleType +import finda.findavolunteer.domain.volunteer.enum.GroupVolunteerType +import finda.findavolunteer.domain.volunteer.enum.VolunteerType +import finda.findavolunteer.domain.volunteer.enum.Weekday +import java.time.LocalDate +import java.time.LocalTime +import java.util.UUID + +data class CreateVolunteerCommand( + val personnel: Int, + val title: String, + val description: String, + val unitVolunteerTime: Float, + val applicationDateCommand: VolunteerDateCommand, + val workDateCommand: VolunteerDateCommand, + val cycle: CycleType, + val volunteerDateList: List, + val teacherIdList: List, + val studentIdList: List, + val remindTime: LocalTime, + val volunteerType: VolunteerType, + val groupVolunteerType: GroupVolunteerType, + val activityNameList: List, + val weekdayList: List, + val monthDate: Int? +) + +data class VolunteerDateCommand( + val startDate: LocalDate, + val endDate: LocalDate +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerDetailResult.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerDetailResult.kt new file mode 100644 index 00000000..a1ec6081 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerDetailResult.kt @@ -0,0 +1,59 @@ +package finda.findavolunteer.application.port.`in`.volunteer.dto.response + +import finda.findavolunteer.domain.participation.enum.ParticipationStatus +import finda.findavolunteer.domain.volunteer.enum.CycleType +import finda.findavolunteer.domain.volunteer.enum.GroupVolunteerType +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus +import finda.findavolunteer.domain.volunteer.enum.VolunteerType +import finda.findavolunteer.domain.volunteer.enum.Weekday +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import java.util.UUID + +data class VolunteerDetailResult( + val volunteerId: UUID, + val title: String, + val description: String, + val status: VolunteerStatus, + val personnel: Int, + val unitVolunteerHours: Float, + val applicationStartDate: LocalDate, + val applicationEndDate: LocalDate, + val workStartDate: LocalDate, + val workEndDate: LocalDate, + val cycleType: CycleType, + val weekdayList: List, + val monthDate: Int?, + val remindTime: LocalTime, + val groupVolunteerType: GroupVolunteerType, + val volunteerType: VolunteerType, + val writerUserId: UUID, + val scheduleResultList: List, + val studentParticipationResultList: List, + val activityResultList: List, + val userActivityResultList: List +) + +data class VolunteerScheduleResult( + val scheduleId: UUID, + val scheduleDate: LocalDate +) + +data class StudentParticipationResult( + val userId: UUID, + val name: String, + val status: ParticipationStatus, + val participatedAt: LocalDateTime +) + +data class ActivityResult( + val activityId: UUID, + val activityName: String +) + +data class UserActivityResult( + val userId: UUID, + val userName: String, + val activityId: UUID +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerListResult.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerListResult.kt new file mode 100644 index 00000000..aa2a223a --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerListResult.kt @@ -0,0 +1,12 @@ +package finda.findavolunteer.application.port.`in`.volunteer.dto.response + +import java.time.LocalDate +import java.util.UUID + +data class VolunteerListResult( + val volunteerId: UUID, + val title: String, + val workStartDate: LocalDate, + val workEndDate: LocalDate, + val unitVolunteerHours: Float +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/ActivityQueryPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/ActivityQueryPort.kt index cff94108..b619cb82 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/ActivityQueryPort.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/ActivityQueryPort.kt @@ -5,4 +5,5 @@ import java.util.UUID interface ActivityQueryPort { fun findById(id: UUID): Activity? + fun findByIdOrThrow(id: UUID): Activity } diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityCommandPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityCommandPort.kt new file mode 100644 index 00000000..560719f9 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityCommandPort.kt @@ -0,0 +1,7 @@ +package finda.findavolunteer.application.port.out.activity + +import finda.findavolunteer.domain.activity.model.UserActivity + +interface UserActivityCommandPort { + fun save(userActivity: UserActivity): UserActivity +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityQueryPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityQueryPort.kt new file mode 100644 index 00000000..8c49fb92 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityQueryPort.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.port.out.activity + +import finda.findavolunteer.domain.activity.model.UserActivity +import java.util.UUID + +interface UserActivityQueryPort { + fun findById(id: UUID): UserActivity? +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/user/UserQueryPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/user/UserQueryPort.kt new file mode 100644 index 00000000..2ac6d4b3 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/user/UserQueryPort.kt @@ -0,0 +1,7 @@ +package finda.findavolunteer.application.port.out.user + +import java.util.UUID + +interface UserQueryPort { + fun getUserName(userId: UUID): String? +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerDetailQueryPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerDetailQueryPort.kt new file mode 100644 index 00000000..f3365fb8 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerDetailQueryPort.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.port.out.volunteer + +import finda.findavolunteer.domain.volunteer.model.VolunteerDetail +import java.util.UUID + +interface VolunteerDetailQueryPort { + fun findDetailByIdOrThrow(volunteerId: UUID): VolunteerDetail +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerListQueryPort.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerListQueryPort.kt new file mode 100644 index 00000000..bc3cc945 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerListQueryPort.kt @@ -0,0 +1,13 @@ +package finda.findavolunteer.application.port.out.volunteer + +import finda.findavolunteer.domain.volunteer.enum.VolunteerSortBy +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus +import finda.findavolunteer.domain.volunteer.model.Volunteer + +interface VolunteerListQueryPort { + fun findAll( + status: VolunteerStatus?, + year: Int?, + sortBy: VolunteerSortBy + ): List +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/activity/CreateUserActivityService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/activity/CreateUserActivityService.kt new file mode 100644 index 00000000..ec610065 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/activity/CreateUserActivityService.kt @@ -0,0 +1,28 @@ +package finda.findavolunteer.application.service.activity + +import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase +import finda.findavolunteer.application.port.`in`.activity.dto.request.CreateUserActivityCommand +import finda.findavolunteer.application.port.out.activity.ActivityQueryPort +import finda.findavolunteer.application.port.out.activity.UserActivityCommandPort +import finda.findavolunteer.domain.activity.model.UserActivity +import jakarta.transaction.Transactional +import org.springframework.stereotype.Service + +@Service +class CreateUserActivityService( + val userActivityCommandPort: UserActivityCommandPort, + val activityQueryPort: ActivityQueryPort +) : CreateUserActivityUseCase { + @Transactional + override fun execute(command: CreateUserActivityCommand) { + command.userActivityCommandList.forEach { + val activity = activityQueryPort.findById(it.activityId) + userActivityCommandPort.save( + UserActivity( + activityId = activity!!.id, + userId = it.userId + ) + ) + } + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/CreateVolunteerService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/CreateVolunteerService.kt index 9027b29b..27098432 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/CreateVolunteerService.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/CreateVolunteerService.kt @@ -1,8 +1,8 @@ package finda.findavolunteer.application.service.volunteer -import finda.findavolunteer.adapter.`in`.volunteer.dto.request.CreateVolunteerRequest import finda.findavolunteer.application.facade.UserFacade import finda.findavolunteer.application.port.`in`.volunteer.CreateVolunteerUseCase +import finda.findavolunteer.application.port.`in`.volunteer.dto.request.CreateVolunteerCommand import finda.findavolunteer.application.port.out.activity.ActivityCommandPort import finda.findavolunteer.application.port.out.participation.StudentParticipationCommandPort import finda.findavolunteer.application.port.out.participation.TeacherParticipationCommandPort @@ -32,29 +32,29 @@ class CreateVolunteerService( val teacherParticipationCommandPort: TeacherParticipationCommandPort ) : CreateVolunteerUseCase { @Transactional - override fun execute(request: CreateVolunteerRequest) { + override fun execute(command: CreateVolunteerCommand) { val userId = userFacade.currentUserId() val volunteer = volunteerCommandPort.save( Volunteer( status = VolunteerStatus.APPLICATION, - personnel = request.personnal, - title = request.title, - description = request.description, - unitVolunteerHours = request.unitVolunteerTime, - applicationStartDate = request.applicationDate.startDate, - applicationEndDate = request.applicationDate.endDate, - workStartDate = request.workDate.startDate, - workEndDate = request.workDate.endDate, - cycleType = request.cycle, + personnel = command.personnel, + title = command.title, + description = command.description, + unitVolunteerHours = command.unitVolunteerTime, + applicationStartDate = command.applicationDateCommand.startDate, + applicationEndDate = command.applicationDateCommand.endDate, + workStartDate = command.workDateCommand.startDate, + workEndDate = command.workDateCommand.endDate, + cycleType = command.cycle, userId = userId, - remindTime = request.remindTime, - groupVolunteerType = request.groupVolunteerType, - volunteerType = request.volunteerType + remindTime = command.remindTime, + groupVolunteerType = command.groupVolunteerType, + volunteerType = command.volunteerType ) ) - request.volunteerDate.forEach { + command.volunteerDateList.forEach { volunteerScheduleCommandPort.save( VolunteerSchedule( scheduleDate = it, @@ -63,10 +63,10 @@ class CreateVolunteerService( ) } - when (request.cycle) { + when (command.cycle) { CycleType.NONE -> Unit CycleType.WEEK -> { - request.weekdays.forEach { + command.weekdayList.forEach { volunteerCommandPort.saveWeekRecurrence( ActivityRecurrenceWeek( weekday = it, @@ -79,13 +79,13 @@ class CreateVolunteerService( volunteerCommandPort.saveMonthRecurrence( ActivityRecurrenceMonth( volunteerId = volunteer.id, - day = request.monthDate!! + day = command.monthDate!! ) ) } } - request.activity.forEach { + command.activityNameList.forEach { activityCommandPort.save( Activity( activityName = it, @@ -94,7 +94,7 @@ class CreateVolunteerService( ) } - request.students.forEach { + command.studentIdList.forEach { studentParticipationCommandPort.save( StudentParticipation( volunteerId = volunteer.id, @@ -105,7 +105,7 @@ class CreateVolunteerService( ) } - request.teachers.forEach { + command.teacherIdList.forEach { teacherParticipationCommandPort.save( TeacherParticipation( volunteerId = volunteer.id, diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/DeleteVolunteerService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/DeleteVolunteerService.kt index a43576dc..49c0bbf1 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/DeleteVolunteerService.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/DeleteVolunteerService.kt @@ -1,6 +1,6 @@ package finda.findavolunteer.application.service.volunteer -import finda.findavolunteer.application.exception.VolunteerForbiddenException +import finda.findavolunteer.application.exception.volunteer.VolunteerForbiddenException import finda.findavolunteer.application.facade.UserFacade import finda.findavolunteer.application.port.`in`.volunteer.DeleteVolunteerUseCase import finda.findavolunteer.application.port.out.volunteer.VolunteerCommandPort diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt new file mode 100644 index 00000000..b1d57bcf --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt @@ -0,0 +1,71 @@ +package finda.findavolunteer.application.service.volunteer + +import finda.findavolunteer.application.exception.user.UserNotFoundException +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.ActivityResult +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.StudentParticipationResult +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.UserActivityResult +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerDetailResult +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerScheduleResult +import finda.findavolunteer.application.port.out.user.UserQueryPort +import finda.findavolunteer.application.port.out.volunteer.VolunteerDetailQueryPort +import org.springframework.stereotype.Service +import java.util.UUID + +@Service +class VolunteerDetailService( + private val volunteerDetailQueryPort: VolunteerDetailQueryPort, + private val userQueryPort: UserQueryPort +) : VolunteerDetailUseCase { + override fun execute(volunteerId: UUID): VolunteerDetailResult { + val volunteerDetail = volunteerDetailQueryPort.findDetailByIdOrThrow(volunteerId) + val volunteer = volunteerDetail.volunteer + + return VolunteerDetailResult( + volunteerId = volunteer.id, + title = volunteer.title, + description = volunteer.description, + status = volunteer.status, + personnel = volunteer.personnel, + unitVolunteerHours = volunteer.unitVolunteerHours, + applicationStartDate = volunteer.applicationStartDate, + applicationEndDate = volunteer.applicationEndDate, + workStartDate = volunteer.workStartDate, + workEndDate = volunteer.workEndDate, + cycleType = volunteer.cycleType, + weekdayList = volunteerDetail.weekdays, + monthDate = volunteerDetail.monthDate, + remindTime = volunteer.remindTime, + groupVolunteerType = volunteer.groupVolunteerType, + volunteerType = volunteer.volunteerType, + writerUserId = volunteer.userId, + scheduleResultList = volunteerDetail.schedules.map { + VolunteerScheduleResult( + scheduleId = it.id, + scheduleDate = it.scheduleDate + ) + }, + studentParticipationResultList = volunteerDetail.studentParticipations.map { + StudentParticipationResult( + userId = it.userId, + name = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + status = it.status, + participatedAt = it.participatedAt + ) + }, + activityResultList = volunteerDetail.activities.map { + ActivityResult( + activityId = it.id, + activityName = it.activityName + ) + }, + userActivityResultList = volunteerDetail.userActivities.map { + UserActivityResult( + userId = it.userId, + userName = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + activityId = it.activityId + ) + } + ) + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt new file mode 100644 index 00000000..eb8c340f --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt @@ -0,0 +1,40 @@ +package finda.findavolunteer.application.service.volunteer + +import finda.findavolunteer.application.exception.volunteer.InvalidVolunteerSortByException +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerListUseCase +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerListResult +import finda.findavolunteer.application.port.out.volunteer.VolunteerListQueryPort +import finda.findavolunteer.domain.volunteer.enum.VolunteerSortBy +import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus +import org.springframework.stereotype.Service + +@Service +class VolunteerListService( + private val volunteerListQueryPort: VolunteerListQueryPort +) : VolunteerListUseCase { + override fun execute( + status: VolunteerStatus?, + year: Int?, + sortBy: String? + ): List { + val sortType = try { + VolunteerSortBy.from(sortBy) + } catch (_: IllegalArgumentException) { + throw InvalidVolunteerSortByException + } + + return volunteerListQueryPort.findAll( + status = status, + year = year, + sortBy = sortType + ).map { + VolunteerListResult( + volunteerId = it.id, + title = it.title, + workStartDate = it.workStartDate, + workEndDate = it.workEndDate, + unitVolunteerHours = it.unitVolunteerHours + ) + } + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/activity/model/UserActivity.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/activity/model/UserActivity.kt index 2e126533..f93b8fcf 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/activity/model/UserActivity.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/activity/model/UserActivity.kt @@ -4,5 +4,6 @@ import java.util.UUID data class UserActivity( val id: UUID = UUID(0, 0), - val activityId: UUID + val activityId: UUID, + val userId: UUID ) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/enum/VolunteerSortBy.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/enum/VolunteerSortBy.kt new file mode 100644 index 00000000..c3e5ae4a --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/enum/VolunteerSortBy.kt @@ -0,0 +1,14 @@ +package finda.findavolunteer.domain.volunteer.enum + +enum class VolunteerSortBy { + WORK_START_DATE; + + companion object { + fun from(value: String?): VolunteerSortBy { + if (value == null) return WORK_START_DATE + + return entries.firstOrNull { it.name == value.uppercase() } + ?: throw IllegalArgumentException("Invalid volunteer sort by: $value") + } + } +} diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/model/VolunteerDetail.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/model/VolunteerDetail.kt new file mode 100644 index 00000000..e2a8307d --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/model/VolunteerDetail.kt @@ -0,0 +1,16 @@ +package finda.findavolunteer.domain.volunteer.model + +import finda.findavolunteer.domain.activity.model.Activity +import finda.findavolunteer.domain.activity.model.UserActivity +import finda.findavolunteer.domain.participation.model.StudentParticipation +import finda.findavolunteer.domain.volunteer.enum.Weekday + +data class VolunteerDetail( + val volunteer: Volunteer, + val schedules: List, + val studentParticipations: List, + val activities: List, + val userActivities: List, + val weekdays: List, + val monthDate: Int? +) diff --git a/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt index ad917a10..5c84ab75 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt @@ -11,11 +11,14 @@ enum class ErrorCode( // client error BAD_REQUEST(400, "Bad Request", 1), + INVALID_VOLUNTEER_SORT_BY(400, "Invalid Volunteer Sort By", 2), VOLUNTEER_FORBIDDEN(403, "Volunteer Forbidden", 1), VOLUNTEER_NOT_FOUND(404, "Volunteer Not Found", 1), - TEACHER_PARTICIPATION_NOT_FOUND(404, "Teacher Participation Not Found", 2); + TEACHER_PARTICIPATION_NOT_FOUND(404, "Teacher Participation Not Found", 2), + USER_NOT_FOUND(404, "User Not Found", 3), + ACTIVITY_NOT_FOUND(404, "Activity Not Found", 4); override fun status(): Int = status override fun message(): String = message diff --git a/finda-volunteer/src/main/proto/auth.proto b/finda-volunteer/src/main/proto/auth.proto new file mode 100644 index 00000000..e000dbe0 --- /dev/null +++ b/finda-volunteer/src/main/proto/auth.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package auth; + +option java_package = "finda.findaauth.adapter.in.grpc"; +option java_multiple_files = true; + +service AuthService { + rpc GetDeviceToken (UserRequest) returns (DeviceTokenResponse); + rpc GetDeviceTokens (UserListRequest) returns (DeviceTokenListResponse); + rpc GetUserName (UserRequest) returns (UserNameResponse); +} + +message UserRequest { + string user_id = 1; +} + +message UserListRequest { + repeated string user_ids = 1; +} + +message DeviceTokenResponse { + string device_token = 1; + string os = 2; +} + +message DeviceTokenListResponse { + repeated DeviceTokenResponse tokens = 1; +} + +message UserNameResponse { + string user_name = 1; +} + +message UserDevice { + string user_id = 1; + repeated DeviceTokenResponse devices = 2; +} + +message UserDeviceListResponse { + repeated UserDevice users = 1; +} diff --git a/finda-volunteer/src/main/resources/application.yml b/finda-volunteer/src/main/resources/application.yml index 2fa655dc..2be26689 100644 --- a/finda-volunteer/src/main/resources/application.yml +++ b/finda-volunteer/src/main/resources/application.yml @@ -4,6 +4,12 @@ server: servlet: context-path: /finda-volunteer +grpc: + client: + auth-service: + address: ${AUTH_GRPC_ADDRESS} + negotiation-type: plaintext + spring: profiles: active: ${PROFILE:local} diff --git a/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml index e6142719..164cfa4b 100644 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml @@ -6,5 +6,7 @@ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + + diff --git a/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/001-create-volunteer-tables.sql b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/001-create-volunteer-tables.sql index fa17128b..9c29d144 100644 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/001-create-volunteer-tables.sql +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/001-create-volunteer-tables.sql @@ -142,7 +142,7 @@ CREATE TABLE tbl_user_activity CREATE INDEX idx_activity_volunteer_id ON tbl_activity (volunteer_id); CREATE INDEX idx_volunteer_schedule_volunteer_id ON tbl_volunteer_schedule (volunteer_id); CREATE INDEX idx_volunteer_record_volunteer_id ON tbl_volunteer_record (volunteer_id); -CREATE INDEX idx_student_particitation_volunteer_id ON tbl_student_particitation (volunteer_id); +CREATE INDEX idx_student_participation_volunteer_id ON tbl_student_participation (volunteer_id); CREATE INDEX idx_teacher_participation_volunteer_id ON tbl_teacher_participation (volunteer_id); CREATE INDEX idx_qr_code_volunteer_id ON tbl_qr_code (volunteer_id); CREATE INDEX idx_activity_recurrence_month_volunteer_id ON activity_recurrence_month (volunteer_id); diff --git a/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/002-add-user-id-to-user-activity.sql b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/002-add-user-id-to-user-activity.sql new file mode 100644 index 00000000..f7f03de2 --- /dev/null +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/002-add-user-id-to-user-activity.sql @@ -0,0 +1,5 @@ +--liquibase formatted sql + +--changeset byeondohwi:002-add-user-id-to-user-activity +ALTER TABLE tbl_user_activity + ADD COLUMN user_id BINARY(16) NOT NULL; diff --git a/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql new file mode 100644 index 00000000..cc4784e2 --- /dev/null +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql @@ -0,0 +1,5 @@ +--liquibase formatted sql + +--changeset byeondohwi:003-add-unique-teacher-participation-user-id +ALTER TABLE tbl_teacher_participation + ADD CONSTRAINT uk_teacher_participation_user_id UNIQUE (user_id);