From e13a605fc9fbc4661a9f594df26c1e7969c2663a Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 11:18:19 +0900 Subject: [PATCH 01/30] =?UTF-8?q?chore(#42):=20gitkeep=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/finda/findavolunteer/domain/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/.gitkeep 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 From 621873f3f04ad4060924731809d417705f4870e2 Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 11:18:19 +0900 Subject: [PATCH 02/30] =?UTF-8?q?chore(#42):=20gitkeep=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/finda/findavolunteer/domain/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/.gitkeep 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 From 2eb3690e4039e3808231976b8a7ce2ac23bf60b4 Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 13:54:41 +0900 Subject: [PATCH 03/30] feat(#41): userActivity --- .../activity/ActivityPersistenceAdapter.kt | 8 ++---- .../activity/UserActivityAdapter.kt | 25 +++++++++++++++++++ .../out/activity/UserActivityCommandPort.kt | 7 ++++++ .../out/activity/UserActivityQueryPort.kt | 8 ++++++ 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/UserActivityAdapter.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityCommandPort.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/activity/UserActivityQueryPort.kt 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..382ff860 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,7 @@ 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.port.out.activity.ActivityCommandPort import finda.findavolunteer.application.port.out.activity.ActivityQueryPort import finda.findavolunteer.domain.activity.model.Activity @@ -13,10 +11,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)) 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/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? +} From 1672417dd8924a2359e9548ea8d0b574e48921c0 Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 14:38:32 +0900 Subject: [PATCH 04/30] =?UTF-8?q?chore(#41):=20gitkeep=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/finda/findavolunteer/adapter/in/.gitkeep | 0 .../main/kotlin/finda/findavolunteer/application/port/in/.gitkeep | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/.gitkeep delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/.gitkeep 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/application/port/in/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/.gitkeep deleted file mode 100644 index e69de29b..00000000 From c0bf658f291192eaea40965210424f4043ac68ee Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 14:39:54 +0900 Subject: [PATCH 05/30] =?UTF-8?q?feat(#41):=20=EC=BB=AC=EB=9F=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=97=AD=ED=95=A0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/activity/ActivityWebAdapter.kt | 10 ++++++- .../dto/request/CreateUserActivityRequest.kt | 11 ++++++++ .../activity/entity/UserActivityJpaEntity.kt | 4 +++ .../activity/mapper/UserActivityMapper.kt | 6 +++- .../repository/UserActivityRepository.kt | 14 +++++++++- .../in/activity/CreateUserActivityUseCase.kt | 7 +++++ .../activity/CreateUserActivityService.kt | 28 +++++++++++++++++++ .../domain/activity/model/UserActivity.kt | 3 +- .../db/changelog-volunteer/master.xml | 1 + .../002-add-user-id-to-user-activity.sql | 5 ++++ 10 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/dto/request/CreateUserActivityRequest.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/CreateUserActivityUseCase.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/activity/CreateUserActivityService.kt create mode 100644 finda-volunteer/src/main/resources/db/changelog-volunteer/schema/002-add-user-id-to-user-activity.sql 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..cde90c19 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,16 @@ package finda.findavolunteer.adapter.`in`.activity +import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest +import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase +import org.springframework.web.bind.annotation.PostMapping 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(request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) +} 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..a7003d0b --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/dto/request/CreateUserActivityRequest.kt @@ -0,0 +1,11 @@ +package finda.findavolunteer.adapter.`in`.activity.dto.request + +import java.util.* + +data class CreateUserActivityRequest( + val userActivityList: List +) +data class UserActivity( + val userId: UUID, + val activityId: UUID +) 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/UserActivityRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/activity/repository/UserActivityRepository.kt index 1d7a1d71..39d1c2ca 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,21 @@ 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? +} 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..60716f2e --- /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.adapter.`in`.activity.dto.request.CreateUserActivityRequest + +interface CreateUserActivityUseCase { + fun execute(request: CreateUserActivityRequest) +} 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..85bd82e1 --- /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.adapter.`in`.activity.dto.request.CreateUserActivityRequest +import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase +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(request: CreateUserActivityRequest) { + request.userActivityList.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/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/resources/db/changelog-volunteer/master.xml b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml index e6142719..6ecc7b1d 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,6 @@ http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + 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; From 387a04fcd2f9e1ac920b3d3fe9e4acf23942c54f Mon Sep 17 00:00:00 2001 From: dohwi Date: Wed, 1 Apr 2026 14:40:14 +0900 Subject: [PATCH 06/30] =?UTF-8?q?chore(#42):=20gitkeep=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/finda/findavolunteer/application/port/out/.gitkeep | 0 .../main/kotlin/finda/findavolunteer/application/service/.gitkeep | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/.gitkeep delete mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/.gitkeep 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/service/.gitkeep b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/.gitkeep deleted file mode 100644 index e69de29b..00000000 From a0fb13a75749ff38a99c0283a0b0ee75448df422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A7=E1=86=AB=E1=84=83=E1=85=A9=E1=84=92?= =?UTF-8?q?=E1=85=B1?= Date: Wed, 1 Apr 2026 20:26:53 +0900 Subject: [PATCH 07/30] =?UTF-8?q?feat(#41):=20=EB=B4=89=EC=82=AC=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20api=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- finda-volunteer/build.gradle.kts | 24 ++++ .../in/volunteer/VolunteerWebAdapter.kt | 12 +- .../dto/response/VolunteerDetailResponse.kt | 59 ++++++++++ .../adapter/out/grpc/UserGrpcAdapter.kt | 41 +++++++ .../activity/repository/ActivityRepository.kt | 4 +- .../repository/UserActivityRepository.kt | 10 ++ .../StudentParticipationRepository.kt | 4 +- .../VolunteerDetailPersistenceAdapter.kt | 107 ++++++++++++++++++ .../ActivityRecurrenceMonthRepository.kt | 4 +- .../ActivityRecurrenceWeekRepository.kt | 4 +- .../repository/VolunteerScheduleRepository.kt | 4 +- .../exception/UserNotFoundException.kt | 8 ++ .../in/volunteer/VolunteerDetailUseCase.kt | 8 ++ .../port/out/user/UserQueryPort.kt | 7 ++ .../out/volunteer/VolunteerDetailQueryPort.kt | 8 ++ .../volunteer/VolunteerDetailService.kt | 71 ++++++++++++ .../domain/volunteer/model/VolunteerDetail.kt | 16 +++ .../global/error/exception/ErrorCode.kt | 3 +- finda-volunteer/src/main/proto/auth.proto | 42 +++++++ .../src/main/resources/application.yml | 6 + 20 files changed, 434 insertions(+), 8 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerDetailResponse.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerDetailPersistenceAdapter.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/UserNotFoundException.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerDetailUseCase.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/user/UserQueryPort.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerDetailQueryPort.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/model/VolunteerDetail.kt create mode 100644 finda-volunteer/src/main/proto/auth.proto diff --git a/finda-volunteer/build.gradle.kts b/finda-volunteer/build.gradle.kts index 44a77a26..77675cbe 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" @@ -28,6 +29,11 @@ dependencies { implementation(Dependencies.JACKSON) implementation(Dependencies.JACKSON_TYPE) 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 +44,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/volunteer/VolunteerWebAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt index a7c26b91..a146b806 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,14 @@ 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.application.port.`in`.volunteer.CreateVolunteerUseCase import finda.findavolunteer.application.port.`in`.volunteer.DeleteVolunteerUseCase +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase 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,13 +21,17 @@ import java.util.UUID @RequestMapping("/volunteers") class VolunteerWebAdapter( val createVolunteerUseCase: CreateVolunteerUseCase, - val deleteVolunteerUseCase: DeleteVolunteerUseCase + val deleteVolunteerUseCase: DeleteVolunteerUseCase, + val volunteerDetailUseCase: VolunteerDetailUseCase ) { @PostMapping @ResponseStatus(value = HttpStatus.CREATED) fun createVolunteer(@RequestBody request: CreateVolunteerRequest) = createVolunteerUseCase.execute(request) + @GetMapping("/{volunteerId}") + fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = + volunteerDetailUseCase.execute(volunteerId) + @DeleteMapping - @ResponseStatus(value = HttpStatus.NO_CONTENT) fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } 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/out/grpc/UserGrpcAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt new file mode 100644 index 00000000..aec24618 --- /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. userId=$userId", e) + throw e + } + } + } + } +} 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 39d1c2ca..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 @@ -18,4 +18,14 @@ interface UserActivityRepository : CrudRepository { """ ) 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/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..02265c9a --- /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.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/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/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/UserNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/UserNotFoundException.kt new file mode 100644 index 00000000..8b8a1637 --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/UserNotFoundException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception + +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/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..567e1f5e --- /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.adapter.`in`.volunteer.dto.response.VolunteerDetailResponse +import java.util.UUID + +interface VolunteerDetailUseCase { + fun execute(volunteerId: UUID): VolunteerDetailResponse +} 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/service/volunteer/VolunteerDetailService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt new file mode 100644 index 00000000..a7945f71 --- /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.adapter.`in`.volunteer.dto.response.ActivityResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.StudentParticipationResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerDetailResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerScheduleResponse +import finda.findavolunteer.adapter.`in`.volunteer.dto.response.UserActivityResponse +import finda.findavolunteer.application.exception.UserNotFoundException +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase +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): VolunteerDetailResponse { + val volunteerDetail = volunteerDetailQueryPort.findDetailByIdOrThrow(volunteerId) + val volunteer = volunteerDetail.volunteer + + return VolunteerDetailResponse( + 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, + weekdays = volunteerDetail.weekdays, + monthDate = volunteerDetail.monthDate, + remindTime = volunteer.remindTime, + groupVolunteerType = volunteer.groupVolunteerType, + volunteerType = volunteer.volunteerType, + writerUserId = volunteer.userId, + schedules = volunteerDetail.schedules.map { + VolunteerScheduleResponse( + scheduleId = it.id, + scheduleDate = it.scheduleDate + ) + }, + studentParticipations = volunteerDetail.studentParticipations.map { + StudentParticipationResponse( + userId = it.userId, + name = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + status = it.status, + participatedAt = it.participatedAt + ) + }, + activities = volunteerDetail.activities.map { + ActivityResponse( + activityId = it.id, + activityName = it.activityName + ) + }, + userActivities = volunteerDetail.userActivities.map { + UserActivityResponse( + userId = it.userId, + userName = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + activityId = it.activityId + ) + } + ) + } +} 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..65ed242d 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 @@ -15,7 +15,8 @@ enum class ErrorCode( 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); 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} From 1695d522d2af8d71190dd2be5411aee6568731cd Mon Sep 17 00:00:00 2001 From: dohwi Date: Thu, 2 Apr 2026 11:11:41 +0900 Subject: [PATCH 08/30] =?UTF-8?q?feat(#42):=20schema=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog-volunteer/master.xml | 1 + .../schema/001-create-volunteer-tables.sql | 2 +- .../schema/003-add-unique-teacher-participation-user-id.sql | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql 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 6ecc7b1d..164cfa4b 100644 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml @@ -7,5 +7,6 @@ + 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/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); From 21e486a25a88fd519c5af99360a216b95547ba56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A7=E1=86=AB=E1=84=83=E1=85=A9=E1=84=92?= =?UTF-8?q?=E1=85=B1?= Date: Thu, 2 Apr 2026 11:14:03 +0900 Subject: [PATCH 09/30] =?UTF-8?q?feat(#41):=20=EB=B4=89=EC=82=AC=ED=99=9C?= =?UTF-8?q?=EB=8F=99=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/volunteer/VolunteerWebAdapter.kt | 17 +++++++- .../dto/response/VolunteerListResponse.kt | 12 ++++++ .../volunteer/VolunteerPersistenceAdapter.kt | 16 +++++++- .../repository/VolunteerRepository.kt | 17 ++++++++ .../InvalidVolunteerSortByException.kt | 8 ++++ .../port/in/volunteer/VolunteerListUseCase.kt | 12 ++++++ .../out/volunteer/VolunteerListQueryPort.kt | 13 ++++++ .../service/volunteer/VolunteerListService.kt | 40 +++++++++++++++++++ .../domain/volunteer/enum/VolunteerSortBy.kt | 14 +++++++ .../global/error/exception/ErrorCode.kt | 1 + 10 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerListResponse.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerListUseCase.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerListQueryPort.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/enum/VolunteerSortBy.kt 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 a146b806..d170aa5b 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 @@ -2,9 +2,12 @@ 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.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 @@ -22,7 +25,8 @@ import java.util.UUID class VolunteerWebAdapter( val createVolunteerUseCase: CreateVolunteerUseCase, val deleteVolunteerUseCase: DeleteVolunteerUseCase, - val volunteerDetailUseCase: VolunteerDetailUseCase + val volunteerDetailUseCase: VolunteerDetailUseCase, + val volunteerListUseCase: VolunteerListUseCase ) { @PostMapping @ResponseStatus(value = HttpStatus.CREATED) @@ -32,6 +36,17 @@ class VolunteerWebAdapter( fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = volunteerDetailUseCase.execute(volunteerId) + @GetMapping + 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 + ) + @DeleteMapping fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } 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/out/persistence/volunteer/VolunteerPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt index 0fd137c4..a71fc6bc 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 @@ -8,7 +8,9 @@ import finda.findavolunteer.adapter.out.persistence.volunteer.repository.Activit import finda.findavolunteer.adapter.out.persistence.volunteer.repository.VolunteerRepository import finda.findavolunteer.application.exception.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/VolunteerRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt index 28b06e1e..cb41d9a3 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,6 +1,9 @@ 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.query.Param import org.springframework.data.repository.CrudRepository import org.springframework.stereotype.Repository import java.util.UUID @@ -8,4 +11,18 @@ 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/application/exception/InvalidVolunteerSortByException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt new file mode 100644 index 00000000..65e0da4c --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception + +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/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..ace6423e --- /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.adapter.`in`.volunteer.dto.response.VolunteerListResponse +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/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/volunteer/VolunteerListService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt new file mode 100644 index 00000000..63b483d2 --- /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.adapter.`in`.volunteer.dto.response.VolunteerListResponse +import finda.findavolunteer.application.exception.InvalidVolunteerSortByException +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerListUseCase +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 { + VolunteerListResponse( + 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/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/global/error/exception/ErrorCode.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt index 65ed242d..58e73d93 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,6 +11,7 @@ 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), From 1dfccad0cb141c5c7057c7e857d5fa6a586b86bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A7=E1=86=AB=E1=84=83=E1=85=A9=E1=84=92?= =?UTF-8?q?=E1=85=B1?= Date: Thu, 2 Apr 2026 11:14:07 +0900 Subject: [PATCH 10/30] =?UTF-8?q?fix(#41):=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=99=9C=EB=8F=99=20=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=B0=94=EB=94=94=20=EB=A7=A4=ED=95=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findavolunteer/adapter/in/activity/ActivityWebAdapter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 cde90c19..b3ae4aac 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 @@ -3,6 +3,7 @@ package finda.findavolunteer.adapter.`in`.activity import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase 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 @@ -12,5 +13,5 @@ class ActivityWebAdapter( private val createUserActivityUseCase: CreateUserActivityUseCase ) { @PostMapping("/user") - fun createUserActivity(request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) + fun createUserActivity(@RequestBody request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) } From e74e054a660696bb5fec612a406591b813a6e7f8 Mon Sep 17 00:00:00 2001 From: dohwi Date: Thu, 2 Apr 2026 11:16:10 +0900 Subject: [PATCH 11/30] sytle(#42): lint format --- .../out/persistence/volunteer/repository/VolunteerRepository.kt | 2 +- .../application/service/volunteer/VolunteerDetailService.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 cb41d9a3..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 @@ -3,8 +3,8 @@ 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.query.Param import org.springframework.data.repository.CrudRepository +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository import java.util.UUID 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 index a7945f71..e50099a1 100644 --- 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 @@ -2,9 +2,9 @@ package finda.findavolunteer.application.service.volunteer 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.VolunteerScheduleResponse -import finda.findavolunteer.adapter.`in`.volunteer.dto.response.UserActivityResponse import finda.findavolunteer.application.exception.UserNotFoundException import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase import finda.findavolunteer.application.port.out.user.UserQueryPort From 28b7a7c14f97cb44778f4dbb6e52a85c363d1106 Mon Sep 17 00:00:00 2001 From: dohwi Date: Fri, 3 Apr 2026 08:55:18 +0900 Subject: [PATCH 12/30] =?UTF-8?q?feat(#41):=20status=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt | 3 +++ 1 file changed, 3 insertions(+) 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 d170aa5b..0997131c 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 @@ -33,10 +33,12 @@ class VolunteerWebAdapter( fun createVolunteer(@RequestBody request: CreateVolunteerRequest) = createVolunteerUseCase.execute(request) @GetMapping("/{volunteerId}") + @ResponseStatus(value = HttpStatus.OK) fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = volunteerDetailUseCase.execute(volunteerId) @GetMapping + @ResponseStatus(value = HttpStatus.OK) fun getVolunteers( @RequestParam(required = false) status: VolunteerStatus?, @RequestParam(required = false) year: Int?, @@ -48,5 +50,6 @@ class VolunteerWebAdapter( ) @DeleteMapping + @ResponseStatus(value = HttpStatus.OK) fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } From 09e7c29be2910db1b674020f94566905d520f518 Mon Sep 17 00:00:00 2001 From: dohwi Date: Thu, 2 Apr 2026 11:11:41 +0900 Subject: [PATCH 13/30] =?UTF-8?q?feat(#41):=20schema=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog-volunteer/master.xml | 1 + .../schema/001-create-volunteer-tables.sql | 2 +- .../schema/003-add-unique-teacher-participation-user-id.sql | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql 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 6ecc7b1d..164cfa4b 100644 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml @@ -7,5 +7,6 @@ + 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/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); From c9d134cbf20fa14c9f39a2e249710321a89b4b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A7=E1=86=AB=E1=84=83=E1=85=A9=E1=84=92?= =?UTF-8?q?=E1=85=B1?= Date: Thu, 2 Apr 2026 11:14:03 +0900 Subject: [PATCH 14/30] =?UTF-8?q?feat(#41):=20=EB=B4=89=EC=82=AC=ED=99=9C?= =?UTF-8?q?=EB=8F=99=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/volunteer/VolunteerWebAdapter.kt | 17 +++++++- .../dto/response/VolunteerListResponse.kt | 12 ++++++ .../volunteer/VolunteerPersistenceAdapter.kt | 16 +++++++- .../repository/VolunteerRepository.kt | 17 ++++++++ .../InvalidVolunteerSortByException.kt | 8 ++++ .../port/in/volunteer/VolunteerListUseCase.kt | 12 ++++++ .../out/volunteer/VolunteerListQueryPort.kt | 13 ++++++ .../service/volunteer/VolunteerListService.kt | 40 +++++++++++++++++++ .../domain/volunteer/enum/VolunteerSortBy.kt | 14 +++++++ .../global/error/exception/ErrorCode.kt | 1 + 10 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/dto/response/VolunteerListResponse.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/VolunteerListUseCase.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/out/volunteer/VolunteerListQueryPort.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/domain/volunteer/enum/VolunteerSortBy.kt 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 a146b806..d170aa5b 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 @@ -2,9 +2,12 @@ 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.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 @@ -22,7 +25,8 @@ import java.util.UUID class VolunteerWebAdapter( val createVolunteerUseCase: CreateVolunteerUseCase, val deleteVolunteerUseCase: DeleteVolunteerUseCase, - val volunteerDetailUseCase: VolunteerDetailUseCase + val volunteerDetailUseCase: VolunteerDetailUseCase, + val volunteerListUseCase: VolunteerListUseCase ) { @PostMapping @ResponseStatus(value = HttpStatus.CREATED) @@ -32,6 +36,17 @@ class VolunteerWebAdapter( fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = volunteerDetailUseCase.execute(volunteerId) + @GetMapping + 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 + ) + @DeleteMapping fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } 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/out/persistence/volunteer/VolunteerPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerPersistenceAdapter.kt index 0fd137c4..a71fc6bc 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 @@ -8,7 +8,9 @@ import finda.findavolunteer.adapter.out.persistence.volunteer.repository.Activit import finda.findavolunteer.adapter.out.persistence.volunteer.repository.VolunteerRepository import finda.findavolunteer.application.exception.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/VolunteerRepository.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/repository/VolunteerRepository.kt index 28b06e1e..cb41d9a3 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,6 +1,9 @@ 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.query.Param import org.springframework.data.repository.CrudRepository import org.springframework.stereotype.Repository import java.util.UUID @@ -8,4 +11,18 @@ 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/application/exception/InvalidVolunteerSortByException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt new file mode 100644 index 00000000..65e0da4c --- /dev/null +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt @@ -0,0 +1,8 @@ +package finda.findavolunteer.application.exception + +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/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..ace6423e --- /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.adapter.`in`.volunteer.dto.response.VolunteerListResponse +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/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/volunteer/VolunteerListService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerListService.kt new file mode 100644 index 00000000..63b483d2 --- /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.adapter.`in`.volunteer.dto.response.VolunteerListResponse +import finda.findavolunteer.application.exception.InvalidVolunteerSortByException +import finda.findavolunteer.application.port.`in`.volunteer.VolunteerListUseCase +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 { + VolunteerListResponse( + 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/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/global/error/exception/ErrorCode.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/global/error/exception/ErrorCode.kt index 65ed242d..58e73d93 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,6 +11,7 @@ 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), From 9cfd30ef3e867d78e138bb23810619cee42f7eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A7=E1=86=AB=E1=84=83=E1=85=A9=E1=84=92?= =?UTF-8?q?=E1=85=B1?= Date: Thu, 2 Apr 2026 11:14:07 +0900 Subject: [PATCH 15/30] =?UTF-8?q?fix(#41):=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=99=9C=EB=8F=99=20=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=B0=94=EB=94=94=20=EB=A7=A4=ED=95=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findavolunteer/adapter/in/activity/ActivityWebAdapter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 cde90c19..b3ae4aac 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 @@ -3,6 +3,7 @@ package finda.findavolunteer.adapter.`in`.activity import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest import finda.findavolunteer.application.port.`in`.activity.CreateUserActivityUseCase 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 @@ -12,5 +13,5 @@ class ActivityWebAdapter( private val createUserActivityUseCase: CreateUserActivityUseCase ) { @PostMapping("/user") - fun createUserActivity(request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) + fun createUserActivity(@RequestBody request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) } From 272e3b4dd4e56bf6f5945353f4346ead7ff21a3d Mon Sep 17 00:00:00 2001 From: dohwi Date: Thu, 2 Apr 2026 11:16:10 +0900 Subject: [PATCH 16/30] sytle(#41): lint format --- .../out/persistence/volunteer/repository/VolunteerRepository.kt | 2 +- .../application/service/volunteer/VolunteerDetailService.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 cb41d9a3..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 @@ -3,8 +3,8 @@ 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.query.Param import org.springframework.data.repository.CrudRepository +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository import java.util.UUID 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 index a7945f71..e50099a1 100644 --- 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 @@ -2,9 +2,9 @@ package finda.findavolunteer.application.service.volunteer 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.VolunteerScheduleResponse -import finda.findavolunteer.adapter.`in`.volunteer.dto.response.UserActivityResponse import finda.findavolunteer.application.exception.UserNotFoundException import finda.findavolunteer.application.port.`in`.volunteer.VolunteerDetailUseCase import finda.findavolunteer.application.port.out.user.UserQueryPort From 21119a1f7c98cc8aa615cc90dddd9bea66f06bb4 Mon Sep 17 00:00:00 2001 From: dohwi Date: Fri, 3 Apr 2026 08:55:18 +0900 Subject: [PATCH 17/30] =?UTF-8?q?feat(#41):=20status=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt | 3 +++ 1 file changed, 3 insertions(+) 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 d170aa5b..0997131c 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 @@ -33,10 +33,12 @@ class VolunteerWebAdapter( fun createVolunteer(@RequestBody request: CreateVolunteerRequest) = createVolunteerUseCase.execute(request) @GetMapping("/{volunteerId}") + @ResponseStatus(value = HttpStatus.OK) fun getVolunteer(@PathVariable volunteerId: UUID): VolunteerDetailResponse = volunteerDetailUseCase.execute(volunteerId) @GetMapping + @ResponseStatus(value = HttpStatus.OK) fun getVolunteers( @RequestParam(required = false) status: VolunteerStatus?, @RequestParam(required = false) year: Int?, @@ -48,5 +50,6 @@ class VolunteerWebAdapter( ) @DeleteMapping + @ResponseStatus(value = HttpStatus.OK) fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } From 0306eac7be9c909326c29deeeb7c8ff45bbed2a3 Mon Sep 17 00:00:00 2001 From: dohwi Date: Fri, 3 Apr 2026 09:04:33 +0900 Subject: [PATCH 18/30] =?UTF-8?q?chore(#41):=20valid=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- finda-volunteer/build.gradle.kts | 1 + .../adapter/in/activity/ActivityWebAdapter.kt | 7 ++++++- .../in/activity/dto/request/CreateUserActivityRequest.kt | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/finda-volunteer/build.gradle.kts b/finda-volunteer/build.gradle.kts index 77675cbe..b99b2c47 100644 --- a/finda-volunteer/build.gradle.kts +++ b/finda-volunteer/build.gradle.kts @@ -28,6 +28,7 @@ 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) 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 b3ae4aac..e9e0c872 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 @@ -2,6 +2,7 @@ package finda.findavolunteer.adapter.`in`.activity import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest 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 @@ -13,5 +14,9 @@ class ActivityWebAdapter( private val createUserActivityUseCase: CreateUserActivityUseCase ) { @PostMapping("/user") - fun createUserActivity(@RequestBody request: CreateUserActivityRequest) = createUserActivityUseCase.execute(request) + fun createUserActivity( + @Valid @RequestBody + request: CreateUserActivityRequest + ) = + createUserActivityUseCase.execute(request) } 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 index a7003d0b..a3ce7bdd 100644 --- 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 @@ -1,10 +1,15 @@ 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 From 631094eaef18584b3470df330b5bef412c42170e Mon Sep 17 00:00:00 2001 From: dohwi Date: Fri, 3 Apr 2026 09:05:40 +0900 Subject: [PATCH 19/30] =?UTF-8?q?fix(#41):=20delete=20response=20status=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../findavolunteer/adapter/in/volunteer/VolunteerWebAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0997131c..ea5d23a9 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 @@ -50,6 +50,6 @@ class VolunteerWebAdapter( ) @DeleteMapping - @ResponseStatus(value = HttpStatus.OK) + @ResponseStatus(value = HttpStatus.NO_CONTENT) fun deleteVolunteer(@RequestParam volunteerId: UUID) = deleteVolunteerUseCase.execute(volunteerId) } From e2d4cd72867889f37b20d2ba156511a608a5790a Mon Sep 17 00:00:00 2001 From: dohwi Date: Fri, 3 Apr 2026 09:27:39 +0900 Subject: [PATCH 20/30] =?UTF-8?q?chore(#41):=20userId=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../finda/findavolunteer/adapter/out/grpc/UserGrpcAdapter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index aec24618..ea2b6a3b 100644 --- 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 @@ -32,7 +32,7 @@ class UserGrpcAdapter : UserQueryPort { when (e.status.code) { Status.Code.NOT_FOUND -> null else -> { - log.error("gRPC getUserName failed. userId=$userId", e) + log.error("gRPC getUserName failed.", e) throw e } } From c276ebff4fc997fed60a9bae37611c41afea7c71 Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 5 Apr 2026 01:34:20 +0900 Subject: [PATCH 21/30] =?UTF-8?q?chore(#41):=20=EB=82=B4=EB=B6=80/?= =?UTF-8?q?=EC=99=B8=EB=B6=80=20DTO=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/activity/ActivityWebAdapter.kt | 3 +- .../mapper/CreateUserActivityRequestMapper.kt | 15 +++++ .../in/volunteer/VolunteerWebAdapter.kt | 9 ++- .../mapper/CreateVolunteerRequestMapper.kt | 31 +++++++++ .../volunteer/mapper/VolunteerResultMapper.kt | 67 +++++++++++++++++++ .../in/activity/CreateUserActivityUseCase.kt | 4 +- .../dto/request/CreateUserActivityCommand.kt | 12 ++++ .../in/volunteer/CreateVolunteerUseCase.kt | 4 +- .../in/volunteer/VolunteerDetailUseCase.kt | 4 +- .../port/in/volunteer/VolunteerListUseCase.kt | 4 +- .../dto/request/CreateVolunteerCommand.kt | 33 +++++++++ .../dto/response/VolunteerDetailResult.kt | 59 ++++++++++++++++ .../dto/response/VolunteerListResult.kt | 12 ++++ .../activity/CreateUserActivityService.kt | 6 +- .../volunteer/CreateVolunteerService.kt | 42 ++++++------ .../volunteer/VolunteerDetailService.kt | 32 ++++----- .../service/volunteer/VolunteerListService.kt | 6 +- 17 files changed, 288 insertions(+), 55 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/activity/mapper/CreateUserActivityRequestMapper.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/CreateVolunteerRequestMapper.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/in/volunteer/mapper/VolunteerResultMapper.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/dto/request/CreateUserActivityCommand.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/request/CreateVolunteerCommand.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerDetailResult.kt create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/volunteer/dto/response/VolunteerListResult.kt 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 e9e0c872..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,6 +1,7 @@ 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 @@ -18,5 +19,5 @@ class ActivityWebAdapter( @Valid @RequestBody request: CreateUserActivityRequest ) = - createUserActivityUseCase.execute(request) + createUserActivityUseCase.execute(request.toCommand()) } 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 ea5d23a9..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 @@ -3,6 +3,8 @@ 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 @@ -30,12 +32,13 @@ class VolunteerWebAdapter( ) { @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) + volunteerDetailUseCase.execute(volunteerId).toResponse() @GetMapping @ResponseStatus(value = HttpStatus.OK) @@ -47,7 +50,7 @@ class VolunteerWebAdapter( 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/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/application/port/in/activity/CreateUserActivityUseCase.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/port/in/activity/CreateUserActivityUseCase.kt index 60716f2e..935a5994 100644 --- 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 @@ -1,7 +1,7 @@ package finda.findavolunteer.application.port.`in`.activity -import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest +import finda.findavolunteer.application.port.`in`.activity.dto.request.CreateUserActivityCommand interface CreateUserActivityUseCase { - fun execute(request: CreateUserActivityRequest) + 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 index 567e1f5e..83f8d370 100644 --- 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 @@ -1,8 +1,8 @@ package finda.findavolunteer.application.port.`in`.volunteer -import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerDetailResponse +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerDetailResult import java.util.UUID interface VolunteerDetailUseCase { - fun execute(volunteerId: UUID): VolunteerDetailResponse + 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 index ace6423e..e430cc1c 100644 --- 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 @@ -1,6 +1,6 @@ package finda.findavolunteer.application.port.`in`.volunteer -import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerListResponse +import finda.findavolunteer.application.port.`in`.volunteer.dto.response.VolunteerListResult import finda.findavolunteer.domain.volunteer.enum.VolunteerStatus interface VolunteerListUseCase { @@ -8,5 +8,5 @@ interface VolunteerListUseCase { status: VolunteerStatus?, year: Int?, sortBy: String? - ): List + ): 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/service/activity/CreateUserActivityService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/activity/CreateUserActivityService.kt index 85bd82e1..ec610065 100644 --- 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 @@ -1,7 +1,7 @@ package finda.findavolunteer.application.service.activity -import finda.findavolunteer.adapter.`in`.activity.dto.request.CreateUserActivityRequest 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 @@ -14,8 +14,8 @@ class CreateUserActivityService( val activityQueryPort: ActivityQueryPort ) : CreateUserActivityUseCase { @Transactional - override fun execute(request: CreateUserActivityRequest) { - request.userActivityList.forEach { + override fun execute(command: CreateUserActivityCommand) { + command.userActivityCommandList.forEach { val activity = activityQueryPort.findById(it.activityId) userActivityCommandPort.save( UserActivity( 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/VolunteerDetailService.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/service/volunteer/VolunteerDetailService.kt index e50099a1..2cb99529 100644 --- 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 @@ -1,12 +1,12 @@ package finda.findavolunteer.application.service.volunteer -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.VolunteerScheduleResponse import finda.findavolunteer.application.exception.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 @@ -17,11 +17,11 @@ class VolunteerDetailService( private val volunteerDetailQueryPort: VolunteerDetailQueryPort, private val userQueryPort: UserQueryPort ) : VolunteerDetailUseCase { - override fun execute(volunteerId: UUID): VolunteerDetailResponse { + override fun execute(volunteerId: UUID): VolunteerDetailResult { val volunteerDetail = volunteerDetailQueryPort.findDetailByIdOrThrow(volunteerId) val volunteer = volunteerDetail.volunteer - return VolunteerDetailResponse( + return VolunteerDetailResult( volunteerId = volunteer.id, title = volunteer.title, description = volunteer.description, @@ -33,34 +33,34 @@ class VolunteerDetailService( workStartDate = volunteer.workStartDate, workEndDate = volunteer.workEndDate, cycleType = volunteer.cycleType, - weekdays = volunteerDetail.weekdays, + weekdayList = volunteerDetail.weekdays, monthDate = volunteerDetail.monthDate, remindTime = volunteer.remindTime, groupVolunteerType = volunteer.groupVolunteerType, volunteerType = volunteer.volunteerType, writerUserId = volunteer.userId, - schedules = volunteerDetail.schedules.map { - VolunteerScheduleResponse( + scheduleResultList = volunteerDetail.schedules.map { + VolunteerScheduleResult( scheduleId = it.id, scheduleDate = it.scheduleDate ) }, - studentParticipations = volunteerDetail.studentParticipations.map { - StudentParticipationResponse( + studentParticipationResultList = volunteerDetail.studentParticipations.map { + StudentParticipationResult( userId = it.userId, name = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, status = it.status, participatedAt = it.participatedAt ) }, - activities = volunteerDetail.activities.map { - ActivityResponse( + activityResultList = volunteerDetail.activities.map { + ActivityResult( activityId = it.id, activityName = it.activityName ) }, - userActivities = volunteerDetail.userActivities.map { - UserActivityResponse( + 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 index 63b483d2..d082bd0a 100644 --- 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 @@ -1,8 +1,8 @@ package finda.findavolunteer.application.service.volunteer -import finda.findavolunteer.adapter.`in`.volunteer.dto.response.VolunteerListResponse import finda.findavolunteer.application.exception.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 @@ -16,7 +16,7 @@ class VolunteerListService( status: VolunteerStatus?, year: Int?, sortBy: String? - ): List { + ): List { val sortType = try { VolunteerSortBy.from(sortBy) } catch (_: IllegalArgumentException) { @@ -28,7 +28,7 @@ class VolunteerListService( year = year, sortBy = sortType ).map { - VolunteerListResponse( + VolunteerListResult( volunteerId = it.id, title = it.title, workStartDate = it.workStartDate, From f9a1e0aaf685b2b7e46fe1c190f6a6284d7b0321 Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 5 Apr 2026 21:54:04 +0900 Subject: [PATCH 22/30] =?UTF-8?q?chore(#41):=20=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2727550d..16164929 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,12 @@ 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 \ No newline at end of file From 66b5ea3bd9dd38f3236621e98aa7f1d4cd96e4aa Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 5 Apr 2026 21:58:23 +0900 Subject: [PATCH 23/30] =?UTF-8?q?chore(#41):=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=ED=8C=8C=EC=9D=BC=20ignore=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 16164929..5a7fd4e8 100644 --- a/.gitignore +++ b/.gitignore @@ -74,5 +74,5 @@ logs/ .env.local .env.dev .env.prod -!.env.example +.env.example CLAUDE.md \ No newline at end of file From 0558d0552a5017ff007ead001084729344eed7b4 Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 5 Apr 2026 21:59:40 +0900 Subject: [PATCH 24/30] =?UTF-8?q?chore(#41):=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=ED=8C=8C=EC=9D=BC=20ignore=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5a7fd4e8..9521126d 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,5 @@ logs/ .env.dev .env.prod .env.example -CLAUDE.md \ No newline at end of file +CLAUDE.md +run.sh \ No newline at end of file From 40aedab3809c8a4dfb8d5febab751d98ef59db9f Mon Sep 17 00:00:00 2001 From: dohwi Date: Mon, 6 Apr 2026 10:53:13 +0900 Subject: [PATCH 25/30] =?UTF-8?q?chore(#41):=20exception=20=ED=95=98?= =?UTF-8?q?=EC=9C=84=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/activity/ActivityPersistenceAdapter.kt | 6 ++++++ .../participation/TeacherParticipationAdapter.kt | 2 +- .../volunteer/VolunteerDetailPersistenceAdapter.kt | 2 +- .../persistence/volunteer/VolunteerPersistenceAdapter.kt | 2 +- .../exception/activity/ActivityNotFoundException.kt | 8 ++++++++ .../TeacherParticipationNotFoundException.kt | 2 +- .../exception/{ => user}/UserNotFoundException.kt | 2 +- .../{ => volunteer}/InvalidVolunteerSortByException.kt | 2 +- .../{ => volunteer}/VolunteerForbiddenException.kt | 2 +- .../{ => volunteer}/VolunteerNotFoundException.kt | 2 +- .../application/port/out/activity/ActivityQueryPort.kt | 1 + .../service/volunteer/DeleteVolunteerService.kt | 2 +- .../service/volunteer/VolunteerDetailService.kt | 2 +- .../application/service/volunteer/VolunteerListService.kt | 2 +- .../findavolunteer/global/error/exception/ErrorCode.kt | 3 ++- 15 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/activity/ActivityNotFoundException.kt rename finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/{ => participation}/TeacherParticipationNotFoundException.kt (78%) rename finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/{ => user}/UserNotFoundException.kt (78%) rename finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/{ => volunteer}/InvalidVolunteerSortByException.kt (78%) rename finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/{ => volunteer}/VolunteerForbiddenException.kt (78%) rename finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/{ => volunteer}/VolunteerNotFoundException.kt (78%) 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 382ff860..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 @@ -2,6 +2,7 @@ package finda.findavolunteer.adapter.out.persistence.activity import finda.findavolunteer.adapter.out.persistence.activity.mapper.ActivityMapper import finda.findavolunteer.adapter.out.persistence.activity.repository.ActivityRepository +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 @@ -23,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/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/volunteer/VolunteerDetailPersistenceAdapter.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/adapter/out/persistence/volunteer/VolunteerDetailPersistenceAdapter.kt index 02265c9a..5994c02e 100644 --- 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 @@ -7,7 +7,7 @@ import finda.findavolunteer.adapter.out.persistence.volunteer.repository.Activit 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.VolunteerNotFoundException +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 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 a71fc6bc..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,7 +6,7 @@ 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 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/UserNotFoundException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt similarity index 78% rename from finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/UserNotFoundException.kt rename to finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt index 8b8a1637..ac74d11b 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/UserNotFoundException.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/user/UserNotFoundException.kt @@ -1,4 +1,4 @@ -package finda.findavolunteer.application.exception +package finda.findavolunteer.application.exception.user 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/InvalidVolunteerSortByException.kt b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.kt similarity index 78% rename from finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt rename to finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.kt index 65e0da4c..43825551 100644 --- a/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/InvalidVolunteerSortByException.kt +++ b/finda-volunteer/src/main/kotlin/finda/findavolunteer/application/exception/volunteer/InvalidVolunteerSortByException.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/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/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/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 index 2cb99529..b1d57bcf 100644 --- 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 @@ -1,6 +1,6 @@ package finda.findavolunteer.application.service.volunteer -import finda.findavolunteer.application.exception.UserNotFoundException +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 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 index d082bd0a..eb8c340f 100644 --- 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 @@ -1,6 +1,6 @@ package finda.findavolunteer.application.service.volunteer -import finda.findavolunteer.application.exception.InvalidVolunteerSortByException +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 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 58e73d93..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 @@ -17,7 +17,8 @@ enum class ErrorCode( VOLUNTEER_NOT_FOUND(404, "Volunteer Not Found", 1), TEACHER_PARTICIPATION_NOT_FOUND(404, "Teacher Participation Not Found", 2), - USER_NOT_FOUND(404, "User Not Found", 3); + 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 From 52d1ba7df16436a41c078f31b1e7ef5e6ceab6ae Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 12 Apr 2026 20:58:23 +0900 Subject: [PATCH 26/30] =?UTF-8?q?fix:=20teacher=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=EC=9C=A0=EB=8B=88=ED=81=AC=20=EC=A0=9C?= =?UTF-8?q?=EC=95=BD=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog-volunteer/master.xml | 1 - .../schema/003-add-unique-teacher-participation-user-id.sql | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql 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 164cfa4b..6ecc7b1d 100644 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml +++ b/finda-volunteer/src/main/resources/db/changelog-volunteer/master.xml @@ -7,6 +7,5 @@ - 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 deleted file mode 100644 index cc4784e2..00000000 --- a/finda-volunteer/src/main/resources/db/changelog-volunteer/schema/003-add-unique-teacher-participation-user-id.sql +++ /dev/null @@ -1,5 +0,0 @@ ---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); From 4287f10092bef4beb820777761e5885f2b0a818e Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 12 Apr 2026 21:15:34 +0900 Subject: [PATCH 27/30] =?UTF-8?q?fix(#41):=20userName=20=ED=95=9C=20?= =?UTF-8?q?=EB=B2=88=EB=A7=8C=20=EC=A1=B0=ED=9A=8C=EB=90=98=EA=B2=8C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/volunteer/VolunteerDetailService.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 index b1d57bcf..d9ac4ae3 100644 --- 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 @@ -21,6 +21,11 @@ class VolunteerDetailService( val volunteerDetail = volunteerDetailQueryPort.findDetailByIdOrThrow(volunteerId) val volunteer = volunteerDetail.volunteer + val userNameMap = (volunteerDetail.studentParticipations.map { it.userId } + + volunteerDetail.userActivities.map { it.userId }) + .toSet() + .associateWith { userQueryPort.getUserName(it) ?: throw UserNotFoundException } + return VolunteerDetailResult( volunteerId = volunteer.id, title = volunteer.title, @@ -48,7 +53,7 @@ class VolunteerDetailService( studentParticipationResultList = volunteerDetail.studentParticipations.map { StudentParticipationResult( userId = it.userId, - name = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + name = userNameMap[it.userId]!!, status = it.status, participatedAt = it.participatedAt ) @@ -62,7 +67,7 @@ class VolunteerDetailService( userActivityResultList = volunteerDetail.userActivities.map { UserActivityResult( userId = it.userId, - userName = userQueryPort.getUserName(it.userId) ?: throw UserNotFoundException, + userName = userNameMap[it.userId]!!, activityId = it.activityId ) } From 1ca4b6c3f52fb17caef10349e1a5f2b48c41c1a3 Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 12 Apr 2026 21:25:31 +0900 Subject: [PATCH 28/30] =?UTF-8?q?fix(#41):=20=EC=A4=91=EB=B3=B5=20deleteBy?= =?UTF-8?q?Id=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/persistence/volunteer/VolunteerPersistenceAdapter.kt | 2 -- 1 file changed, 2 deletions(-) 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 abf091d1..b3d07969 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 @@ -72,8 +72,6 @@ class VolunteerPersistenceAdapter( } } - override fun deleteById(volunteerId: UUID) { - volunteerRepository.deleteById(volunteerId) override fun findAllWithRemindTime(): List { return volunteerRepository.findAllByRemindTimeIsNotNull() .map { volunteerMapper.toDomain(it) } From a38bb0d9c22175230146a75c935b354f528eb91b Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 12 Apr 2026 21:26:41 +0900 Subject: [PATCH 29/30] =?UTF-8?q?feat(#41):=20grpc=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?import=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- finda-volunteer/build.gradle.kts | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/finda-volunteer/build.gradle.kts b/finda-volunteer/build.gradle.kts index 9a636aa2..94da569b 100644 --- a/finda-volunteer/build.gradle.kts +++ b/finda-volunteer/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { implementation(Dependencies.SPRING_VALIDITY) implementation(Dependencies.LIQUIBASE) implementation(Dependencies.GRPC_CLIENT) + implementation(Dependencies.GRPC_SERVER) implementation(Dependencies.GRPC_PROTOBUF) implementation(Dependencies.GRPC_STUB) implementation(Dependencies.PROTOBUF_JAVA) @@ -43,32 +44,6 @@ dependencies { // Security Common implementation(project(":finda-security-common")) - - // gRPC - implementation(Dependencies.GRPC_SERVER) - implementation(Dependencies.GRPC_PROTOBUF) - implementation(Dependencies.GRPC_STUB) - - implementation(Dependencies.PROTOBUF_JAVA) - compileOnly(Dependencies.JAVAX_ANNOTATION) -} - -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") - } - } - } } protobuf { From d6642fbb03fb3272cc8152b059e6a86a55e81b9e Mon Sep 17 00:00:00 2001 From: dohwi Date: Sun, 12 Apr 2026 21:26:59 +0900 Subject: [PATCH 30/30] style(#41): ktlint --- .../application/service/volunteer/VolunteerDetailService.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 index d9ac4ae3..0b88f81a 100644 --- 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 @@ -21,8 +21,10 @@ class VolunteerDetailService( val volunteerDetail = volunteerDetailQueryPort.findDetailByIdOrThrow(volunteerId) val volunteer = volunteerDetail.volunteer - val userNameMap = (volunteerDetail.studentParticipations.map { it.userId } + - volunteerDetail.userActivities.map { it.userId }) + val userNameMap = ( + volunteerDetail.studentParticipations.map { it.userId } + + volunteerDetail.userActivities.map { it.userId } + ) .toSet() .associateWith { userQueryPort.getUserName(it) ?: throw UserNotFoundException }