From bac405ec478f6a38833c64d737b89820ef896c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 22:43:08 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20student=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../student/controller/AdminStudentApi.java | 81 +++++++++++++++++++ .../controller/AdminStudentController.java | 61 ++++++++++++++ .../dto/AdminStudentResponse.java | 2 +- .../dto/AdminStudentUpdateRequest.java | 2 +- .../dto/AdminStudentUpdateResponse.java | 2 +- .../dto/AdminStudentsResponse.java | 2 +- .../repository/AdminStudentRepository.java | 2 +- .../student/service/AdminStudentService.java | 76 +++++++++++++++++ .../admin/user/controller/AdminUserApi.java | 56 ------------- .../user/controller/AdminUserController.java | 38 --------- .../admin/user/service/AdminUserService.java | 40 +-------- 11 files changed, 224 insertions(+), 138 deletions(-) create mode 100644 src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java create mode 100644 src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java rename src/main/java/in/koreatech/koin/admin/{user => student}/dto/AdminStudentResponse.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => student}/dto/AdminStudentUpdateRequest.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => student}/dto/AdminStudentUpdateResponse.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => student}/dto/AdminStudentsResponse.java (97%) rename src/main/java/in/koreatech/koin/admin/{user => student}/repository/AdminStudentRepository.java (96%) create mode 100644 src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java diff --git a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java new file mode 100644 index 000000000..02c89e3ee --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java @@ -0,0 +1,81 @@ +package in.koreatech.koin.admin.student.controller; + +import static in.koreatech.koin.domain.user.model.UserType.ADMIN; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import in.koreatech.koin.admin.student.dto.AdminStudentResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateRequest; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentsResponse; +import in.koreatech.koin.global.auth.Auth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; + +@Tag(name = "(Admin) Student: 학생", description = "관리자 권한으로 학생 정보를 관리한다") +public interface AdminStudentApi { + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "학생 리스트 조회(페이지네이션)") + @SecurityRequirement(name = "Jwt Authentication") + @GetMapping("/admin/students") + ResponseEntity getStudents( + @RequestParam(required = false) Integer page, + @RequestParam(required = false) Integer limit, + @RequestParam(required = false) Boolean isAuthed, + @RequestParam(required = false) String nickname, + @RequestParam(required = false) String email, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "학생 정보 조회") + @SecurityRequirement(name = "Jwt Authentication") + @GetMapping("/admin/users/student/{id}") + ResponseEntity getStudent( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "학생 정보 수정") + @SecurityRequirement(name = "Jwt Authentication") + @PutMapping("/admin/users/student/{id}") + ResponseEntity updateStudent( + @Valid @RequestBody AdminStudentUpdateRequest adminRequest, + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ); +} \ No newline at end of file diff --git a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java new file mode 100644 index 000000000..540101928 --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java @@ -0,0 +1,61 @@ +package in.koreatech.koin.admin.student.controller; + +import static in.koreatech.koin.domain.user.model.UserType.ADMIN; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import in.koreatech.koin.admin.student.service.AdminStudentService; +import in.koreatech.koin.admin.student.dto.AdminStudentResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateRequest; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentsResponse; +import in.koreatech.koin.admin.user.dto.StudentsCondition; +import in.koreatech.koin.global.auth.Auth; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class AdminStudentController implements AdminStudentApi{ + + private final AdminStudentService adminStudentService; + + @GetMapping("/admin/users/student/{id}") + public ResponseEntity getStudent( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ) { + AdminStudentResponse response = adminStudentService.getStudent(id); + return ResponseEntity.ok().body(response); + } + + @GetMapping("/admin/students") + public ResponseEntity getStudents( + @RequestParam(required = false) Integer page, + @RequestParam(required = false) Integer limit, + @RequestParam(required = false) Boolean isAuthed, + @RequestParam(required = false) String nickname, + @RequestParam(required = false) String email, + @Auth(permit = {ADMIN}) Integer adminId + ) { + StudentsCondition studentsCondition = new StudentsCondition(page, limit, isAuthed, nickname, email); + AdminStudentsResponse response = adminStudentService.getStudents(studentsCondition); + return ResponseEntity.ok().body(response); + } + + @PutMapping("/admin/users/student/{id}") + public ResponseEntity updateStudent( + @Valid @RequestBody AdminStudentUpdateRequest adminRequest, + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ) { + AdminStudentUpdateResponse response = adminStudentService.updateStudent(id, adminRequest); + return ResponseEntity.ok().body(response); + } +} \ No newline at end of file diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentResponse.java b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentResponse.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentResponse.java rename to src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentResponse.java index 9f34a9ba5..26acdebeb 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentResponse.java +++ b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.student.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateRequest.java b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateRequest.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateRequest.java rename to src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateRequest.java index e21faf23f..f14bcd408 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateRequest.java +++ b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateRequest.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.student.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateResponse.java b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateResponse.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateResponse.java rename to src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateResponse.java index d4324ebe7..df9dfdca1 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentUpdateResponse.java +++ b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentUpdateResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.student.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentsResponse.java b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentsResponse.java similarity index 97% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentsResponse.java rename to src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentsResponse.java index f9bc41eb9..01c85c2fc 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminStudentsResponse.java +++ b/src/main/java/in/koreatech/koin/admin/student/dto/AdminStudentsResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.student.dto; import java.util.List; import java.util.stream.Collectors; diff --git a/src/main/java/in/koreatech/koin/admin/user/repository/AdminStudentRepository.java b/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java similarity index 96% rename from src/main/java/in/koreatech/koin/admin/user/repository/AdminStudentRepository.java rename to src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java index db32b0ddf..22f54636b 100644 --- a/src/main/java/in/koreatech/koin/admin/user/repository/AdminStudentRepository.java +++ b/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.repository; +package in.koreatech.koin.admin.student.repository; import java.util.Optional; diff --git a/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java b/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java new file mode 100644 index 000000000..8cfabbd7c --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java @@ -0,0 +1,76 @@ +package in.koreatech.koin.admin.student.service; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import in.koreatech.koin.admin.student.repository.AdminStudentRepository; +import in.koreatech.koin.admin.student.dto.AdminStudentResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateRequest; +import in.koreatech.koin.admin.student.dto.AdminStudentUpdateResponse; +import in.koreatech.koin.admin.student.dto.AdminStudentsResponse; +import in.koreatech.koin.admin.user.dto.StudentsCondition; +import in.koreatech.koin.admin.user.repository.AdminUserRepository; +import in.koreatech.koin.domain.student.exception.StudentDepartmentNotValidException; +import in.koreatech.koin.domain.student.model.Student; +import in.koreatech.koin.domain.student.model.StudentDepartment; +import in.koreatech.koin.domain.user.exception.DuplicationNicknameException; +import in.koreatech.koin.domain.user.model.User; +import in.koreatech.koin.domain.user.model.UserGender; +import in.koreatech.koin.global.model.Criteria; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AdminStudentService { + + private final AdminStudentRepository adminStudentRepository; + private final AdminUserRepository adminUserRepository; + private final PasswordEncoder passwordEncoder; + + public AdminStudentResponse getStudent(Integer userId) { + Student student = adminStudentRepository.getById(userId); + return AdminStudentResponse.from(student); + } + + public AdminStudentsResponse getStudents(StudentsCondition studentsCondition) { + Integer totalStudents = adminStudentRepository.findAllStudentCount(); + Criteria criteria = Criteria.of(studentsCondition.page(), studentsCondition.limit(), totalStudents); + + PageRequest pageRequest = PageRequest.of(criteria.getPage(), criteria.getLimit()); + Page studentsPage = adminStudentRepository.findByConditions(studentsCondition, pageRequest); + + return AdminStudentsResponse.from(studentsPage); + } + + @Transactional + public AdminStudentUpdateResponse updateStudent(Integer id, AdminStudentUpdateRequest adminRequest) { + Student student = adminStudentRepository.getById(id); + User user = student.getUser(); + validateNicknameDuplication(adminRequest.nickname(), id); + validateDepartmentValid(adminRequest.major()); + user.update(adminRequest.nickname(), adminRequest.name(), + adminRequest.phoneNumber(), UserGender.from(adminRequest.gender())); + user.updateStudentPassword(passwordEncoder, adminRequest.password()); + student.update(adminRequest.studentNumber(), adminRequest.major()); + adminStudentRepository.save(student); + + return AdminStudentUpdateResponse.from(student); + } + + private void validateNicknameDuplication(String nickname, Integer userId) { + if (nickname != null && + adminUserRepository.existsByNicknameAndIdNot(nickname, userId)) { + throw DuplicationNicknameException.withDetail("nickname : " + nickname); + } + } + + private void validateDepartmentValid(String department) { + if (department != null && !StudentDepartment.isValid(department)) { + throw StudentDepartmentNotValidException.withDetail("학부(학과) : " + department); + } + } +} diff --git a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java index 26a867e36..6e65660c6 100644 --- a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java +++ b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java @@ -23,10 +23,6 @@ import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentsResponse; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshRequest; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshResponse; import in.koreatech.koin.admin.user.dto.AdminUpdateRequest; @@ -48,25 +44,6 @@ @Tag(name = "(Admin) User: 회원", description = "관리자 권한으로 회원 정보를 관리한다") public interface AdminUserApi { - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "학생 리스트 조회(페이지네이션)") - @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/admin/students") - ResponseEntity getStudents( - @RequestParam(required = false) Integer page, - @RequestParam(required = false) Integer limit, - @RequestParam(required = false) Boolean isAuthed, - @RequestParam(required = false) String nickname, - @RequestParam(required = false) String email, - @Auth(permit = {ADMIN}) Integer adminId - ); @ApiResponses( value = { @@ -257,39 +234,6 @@ ResponseEntity allowOwnerPermission( @Auth(permit = {ADMIN}) Integer adminId ); - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "회원 정보 조회") - @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/admin/users/student/{id}") - ResponseEntity getStudent( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ); - - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "회원 정보 수정") - @SecurityRequirement(name = "Jwt Authentication") - @PutMapping("/admin/users/student/{id}") - ResponseEntity updateStudent( - @Valid @RequestBody AdminStudentUpdateRequest adminRequest, - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ); - @ApiResponses( value = { @ApiResponse(responseCode = "200"), diff --git a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java index db36de701..6f75ff52e 100644 --- a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java +++ b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java @@ -26,10 +26,6 @@ import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentsResponse; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshRequest; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshResponse; import in.koreatech.koin.admin.user.dto.AdminUpdateRequest; @@ -37,7 +33,6 @@ import in.koreatech.koin.admin.user.dto.AdminsResponse; import in.koreatech.koin.admin.user.dto.CreateAdminRequest; import in.koreatech.koin.admin.user.dto.OwnersCondition; -import in.koreatech.koin.admin.user.dto.StudentsCondition; import in.koreatech.koin.admin.user.enums.TeamType; import in.koreatech.koin.admin.user.enums.TrackType; import in.koreatech.koin.admin.user.service.AdminUserService; @@ -60,20 +55,6 @@ public ResponseEntity allowOwnerPermission( return ResponseEntity.ok().build(); } - @GetMapping("/admin/students") - public ResponseEntity getStudents( - @RequestParam(required = false) Integer page, - @RequestParam(required = false) Integer limit, - @RequestParam(required = false) Boolean isAuthed, - @RequestParam(required = false) String nickname, - @RequestParam(required = false) String email, - @Auth(permit = {ADMIN}) Integer adminId - ) { - StudentsCondition studentsCondition = new StudentsCondition(page, limit, isAuthed, nickname, email); - AdminStudentsResponse adminStudentsResponse = adminUserService.getStudents(studentsCondition); - return ResponseEntity.ok().body(adminStudentsResponse); - } - @PostMapping("/admin") public ResponseEntity createAdmin( @RequestBody @Valid CreateAdminRequest request, @@ -178,25 +159,6 @@ public ResponseEntity updateAdminPermission( return ResponseEntity.ok().build(); } - @GetMapping("/admin/users/student/{id}") - public ResponseEntity getStudent( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ) { - AdminStudentResponse adminStudentResponse = adminUserService.getStudent(id); - return ResponseEntity.ok().body(adminStudentResponse); - } - - @PutMapping("/admin/users/student/{id}") - public ResponseEntity updateStudent( - @Valid @RequestBody AdminStudentUpdateRequest adminRequest, - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ) { - AdminStudentUpdateResponse adminStudentUpdateResponse = adminUserService.updateStudent(id, adminRequest); - return ResponseEntity.ok().body(adminStudentUpdateResponse); - } - @GetMapping("/admin/users/owner/{id}") public ResponseEntity getOwner( @PathVariable Integer id, diff --git a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java index 0fc2c41d3..bc1f0b499 100644 --- a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java +++ b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java @@ -7,7 +7,6 @@ import java.util.Objects; import java.util.Optional; import java.util.UUID; -import java.util.stream.Collectors; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -27,10 +26,6 @@ import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminStudentUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminStudentsResponse; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshRequest; import in.koreatech.koin.admin.user.dto.AdminTokenRefreshResponse; import in.koreatech.koin.admin.user.dto.AdminUpdateRequest; @@ -38,12 +33,11 @@ import in.koreatech.koin.admin.user.dto.AdminsResponse; import in.koreatech.koin.admin.user.dto.CreateAdminRequest; import in.koreatech.koin.admin.user.dto.OwnersCondition; -import in.koreatech.koin.admin.user.dto.StudentsCondition; import in.koreatech.koin.admin.user.model.Admin; import in.koreatech.koin.admin.user.repository.AdminOwnerRepository; import in.koreatech.koin.admin.user.repository.AdminOwnerShopRedisRepository; import in.koreatech.koin.admin.user.repository.AdminRepository; -import in.koreatech.koin.admin.user.repository.AdminStudentRepository; +import in.koreatech.koin.admin.student.repository.AdminStudentRepository; import in.koreatech.koin.admin.user.repository.AdminTokenRepository; import in.koreatech.koin.admin.user.repository.AdminUserRepository; import in.koreatech.koin.domain.owner.model.Owner; @@ -51,12 +45,10 @@ import in.koreatech.koin.domain.owner.model.OwnerShop; import in.koreatech.koin.domain.shop.model.shop.Shop; import in.koreatech.koin.domain.student.exception.StudentDepartmentNotValidException; -import in.koreatech.koin.domain.student.model.Student; import in.koreatech.koin.domain.student.model.StudentDepartment; import in.koreatech.koin.domain.user.exception.DuplicationNicknameException; import in.koreatech.koin.domain.user.exception.UserNotFoundException; import in.koreatech.koin.domain.user.model.User; -import in.koreatech.koin.domain.user.model.UserGender; import in.koreatech.koin.domain.user.model.UserToken; import in.koreatech.koin.domain.user.model.UserType; import in.koreatech.koin.global.auth.JwtProvider; @@ -82,16 +74,6 @@ public class AdminUserService { private final AdminTokenRepository adminTokenRepository; private final AdminRepository adminRepository; - public AdminStudentsResponse getStudents(StudentsCondition studentsCondition) { - Integer totalStudents = adminStudentRepository.findAllStudentCount(); - Criteria criteria = Criteria.of(studentsCondition.page(), studentsCondition.limit(), totalStudents); - - PageRequest pageRequest = PageRequest.of(criteria.getPage(), criteria.getLimit()); - Page studentsPage = adminStudentRepository.findByConditions(studentsCondition, pageRequest); - - return AdminStudentsResponse.from(studentsPage); - } - @Transactional public AdminResponse createAdmin(CreateAdminRequest request, Integer adminId) { Admin admin = adminRepository.getById(adminId); @@ -248,26 +230,6 @@ public void allowOwnerPermission(Integer id) { } } - public AdminStudentResponse getStudent(Integer userId) { - Student student = adminStudentRepository.getById(userId); - return AdminStudentResponse.from(student); - } - - @Transactional - public AdminStudentUpdateResponse updateStudent(Integer id, AdminStudentUpdateRequest adminRequest) { - Student student = adminStudentRepository.getById(id); - User user = student.getUser(); - validateNicknameDuplication(adminRequest.nickname(), id); - validateDepartmentValid(adminRequest.major()); - user.update(adminRequest.nickname(), adminRequest.name(), - adminRequest.phoneNumber(), UserGender.from(adminRequest.gender())); - user.updateStudentPassword(passwordEncoder, adminRequest.password()); - student.update(adminRequest.studentNumber(), adminRequest.major()); - adminStudentRepository.save(student); - - return AdminStudentUpdateResponse.from(student); - } - public AdminNewOwnersResponse getNewOwners(OwnersCondition ownersCondition) { ownersCondition.checkDataConstraintViolation(); From bbd404bdaea1a9321ca26b75a78169ad4cb59f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 22:53:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20student=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/admin/student/controller/AdminStudentController.java | 2 +- .../koin/admin/{user => student}/dto/StudentsCondition.java | 2 +- .../koin/admin/student/repository/AdminStudentRepository.java | 2 +- .../koin/admin/student/service/AdminStudentService.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/in/koreatech/koin/admin/{user => student}/dto/StudentsCondition.java (96%) diff --git a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java index 540101928..9fbef879e 100644 --- a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java +++ b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java @@ -15,7 +15,7 @@ import in.koreatech.koin.admin.student.dto.AdminStudentUpdateRequest; import in.koreatech.koin.admin.student.dto.AdminStudentUpdateResponse; import in.koreatech.koin.admin.student.dto.AdminStudentsResponse; -import in.koreatech.koin.admin.user.dto.StudentsCondition; +import in.koreatech.koin.admin.student.dto.StudentsCondition; import in.koreatech.koin.global.auth.Auth; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/StudentsCondition.java b/src/main/java/in/koreatech/koin/admin/student/dto/StudentsCondition.java similarity index 96% rename from src/main/java/in/koreatech/koin/admin/user/dto/StudentsCondition.java rename to src/main/java/in/koreatech/koin/admin/student/dto/StudentsCondition.java index 9da9fd9e4..643135fb4 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/StudentsCondition.java +++ b/src/main/java/in/koreatech/koin/admin/student/dto/StudentsCondition.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.student.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java b/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java index 22f54636b..689411cde 100644 --- a/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java +++ b/src/main/java/in/koreatech/koin/admin/student/repository/AdminStudentRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.query.Param; -import in.koreatech.koin.admin.user.dto.StudentsCondition; +import in.koreatech.koin.admin.student.dto.StudentsCondition; import in.koreatech.koin.domain.user.exception.UserNotFoundException; import in.koreatech.koin.domain.student.model.Student; diff --git a/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java b/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java index 8cfabbd7c..9234be3c2 100644 --- a/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java +++ b/src/main/java/in/koreatech/koin/admin/student/service/AdminStudentService.java @@ -11,7 +11,7 @@ import in.koreatech.koin.admin.student.dto.AdminStudentUpdateRequest; import in.koreatech.koin.admin.student.dto.AdminStudentUpdateResponse; import in.koreatech.koin.admin.student.dto.AdminStudentsResponse; -import in.koreatech.koin.admin.user.dto.StudentsCondition; +import in.koreatech.koin.admin.student.dto.StudentsCondition; import in.koreatech.koin.admin.user.repository.AdminUserRepository; import in.koreatech.koin.domain.student.exception.StudentDepartmentNotValidException; import in.koreatech.koin.domain.student.model.Student; From 2cbd15a9fa07c7ddab19efe647f19ab116b03796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 22:53:23 +0900 Subject: [PATCH 3/8] =?UTF-8?q?refactor:=20owner=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/owner/controller/AdminOwnerApi.java | 112 ++++++++++++++ .../controller/AdminOwnerController.java | 73 +++++++++ .../dto/AdminNewOwnersResponse.java | 2 +- .../dto/AdminOwnerResponse.java | 6 +- .../dto/AdminOwnerUpdateRequest.java | 2 +- .../dto/AdminOwnerUpdateResponse.java | 2 +- .../dto/AdminOwnersResponse.java | 2 +- .../{user => owner}/dto/OwnersCondition.java | 2 +- .../repository/AdminOwnerRepository.java | 2 +- .../AdminOwnerShopRedisRepository.java | 2 +- .../owner/service/AdminOwnerService.java | 138 +++++++++++++++++ .../admin/user/controller/AdminUserApi.java | 89 ----------- .../user/controller/AdminUserController.java | 51 ------- .../admin/user/service/AdminUserService.java | 141 +----------------- .../koin/domain/owner/model/Owner.java | 2 +- 15 files changed, 334 insertions(+), 292 deletions(-) create mode 100644 src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java create mode 100644 src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/AdminNewOwnersResponse.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/AdminOwnerResponse.java (94%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/AdminOwnerUpdateRequest.java (97%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/AdminOwnerUpdateResponse.java (97%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/AdminOwnersResponse.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/dto/OwnersCondition.java (98%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/repository/AdminOwnerRepository.java (97%) rename src/main/java/in/koreatech/koin/admin/{user => owner}/repository/AdminOwnerShopRedisRepository.java (86%) create mode 100644 src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java diff --git a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java new file mode 100644 index 000000000..67b41ce95 --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java @@ -0,0 +1,112 @@ +package in.koreatech.koin.admin.owner.controller; + +import static in.koreatech.koin.domain.user.model.UserType.ADMIN; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import in.koreatech.koin.admin.owner.dto.AdminNewOwnersResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateRequest; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnersResponse; +import in.koreatech.koin.admin.owner.dto.OwnersCondition; +import in.koreatech.koin.global.auth.Auth; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; + +@Tag(name = "(Admin) Owner: 사장님", description = "관리자 권한으로 사장님 정보를 관리한다") +public interface AdminOwnerApi { + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "사장님 권한 요청 허용") + @SecurityRequirement(name = "Jwt Authentication") + @PutMapping("/admin/owner/{id}/authed") + ResponseEntity allowOwnerPermission( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "특정 사장님 조회") + @SecurityRequirement(name = "Jwt Authentication") + @GetMapping("/admin/users/owner/{id}") + ResponseEntity getOwner( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), + } + ) + @Operation(summary = "특정 사장님 수정") + @SecurityRequirement(name = "Jwt Authentication") + @PutMapping("/admin/users/owner/{id}") + ResponseEntity updateOwner( + @PathVariable Integer id, + @RequestBody @Valid AdminOwnerUpdateRequest request, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))) + } + ) + @Operation(summary = "가입 신청한 사장님 리스트 조회 (페이지네이션)") + @SecurityRequirement(name = "Jwt Authentication") + @GetMapping("/admin/users/new-owners") + ResponseEntity getNewOwners( + @ParameterObject @ModelAttribute OwnersCondition ownersCondition, + @Auth(permit = {ADMIN}) Integer adminId + ); + + @ApiResponses( + value = { + @ApiResponse(responseCode = "200"), + @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))) + } + ) + @Operation(summary = "사장 리스트 조회 (페이지네이션)") + @SecurityRequirement(name = "Jwt Authentication") + @GetMapping("/admin/users/owners") + ResponseEntity getOwners( + @ParameterObject @ModelAttribute OwnersCondition ownersCondition, + @Auth(permit = {ADMIN}) Integer adminId + ); +} \ No newline at end of file diff --git a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java new file mode 100644 index 000000000..5105cb880 --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java @@ -0,0 +1,73 @@ +package in.koreatech.koin.admin.owner.controller; + +import static in.koreatech.koin.domain.user.model.UserType.ADMIN; + +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import in.koreatech.koin.admin.owner.service.AdminOwnerService; +import in.koreatech.koin.admin.owner.dto.AdminNewOwnersResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateRequest; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnersResponse; +import in.koreatech.koin.admin.owner.dto.OwnersCondition; +import in.koreatech.koin.global.auth.Auth; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class AdminOwnerController implements AdminOwnerApi{ + + private final AdminOwnerService adminOwnerService; + + @PutMapping("/admin/owner/{id}/authed") + public ResponseEntity allowOwnerPermission( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId) { + adminOwnerService.allowOwnerPermission(id); + return ResponseEntity.ok().build(); + } + + @GetMapping("/admin/users/owner/{id}") + public ResponseEntity getOwner( + @PathVariable Integer id, + @Auth(permit = {ADMIN}) Integer adminId + ) { + AdminOwnerResponse response = adminOwnerService.getOwner(id); + return ResponseEntity.ok().body(response); + } + + @PutMapping("/admin/users/owner/{id}") + public ResponseEntity updateOwner( + @PathVariable Integer id, + @RequestBody @Valid AdminOwnerUpdateRequest request, + @Auth(permit = {ADMIN}) Integer adminId + ) { + AdminOwnerUpdateResponse response = adminOwnerService.updateOwner(id, request); + return ResponseEntity.ok().body(response); + } + + @GetMapping("/admin/users/new-owners") + public ResponseEntity getNewOwners( + @ParameterObject @ModelAttribute OwnersCondition ownersCondition, + @Auth(permit = {ADMIN}) Integer adminId + ) { + return ResponseEntity.ok().body(adminOwnerService.getNewOwners(ownersCondition)); + } + + @GetMapping("/admin/users/owners") + public ResponseEntity getOwners( + @ParameterObject @ModelAttribute OwnersCondition ownersCondition, + @Auth(permit = {ADMIN}) Integer adminId + ) { + return ResponseEntity.ok().body(adminOwnerService.getOwners(ownersCondition)); + } +} \ No newline at end of file diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminNewOwnersResponse.java b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminNewOwnersResponse.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminNewOwnersResponse.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/AdminNewOwnersResponse.java index 818d069d4..a11ba6fe2 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminNewOwnersResponse.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminNewOwnersResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerResponse.java b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerResponse.java similarity index 94% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerResponse.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerResponse.java index 75c3003a1..6b1e75f7b 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerResponse.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; @@ -7,16 +7,12 @@ import java.util.List; import java.util.stream.Collectors; -import org.springframework.data.domain.Page; - import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; import in.koreatech.koin.domain.owner.model.Owner; import in.koreatech.koin.domain.owner.model.OwnerAttachment; -import in.koreatech.koin.domain.owner.model.OwnerIncludingShop; -import in.koreatech.koin.global.model.Criteria; import io.swagger.v3.oas.annotations.media.Schema; @JsonNaming(value = SnakeCaseStrategy.class) diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateRequest.java b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateRequest.java similarity index 97% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateRequest.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateRequest.java index 237ddb8d7..277f4c68f 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateRequest.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateRequest.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateResponse.java b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateResponse.java similarity index 97% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateResponse.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateResponse.java index f288e6fa3..434ba9634 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnerUpdateResponse.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnerUpdateResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnersResponse.java b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnersResponse.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnersResponse.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnersResponse.java index e74ef1ba3..9dc3fd0b8 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/AdminOwnersResponse.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/AdminOwnersResponse.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/dto/OwnersCondition.java b/src/main/java/in/koreatech/koin/admin/owner/dto/OwnersCondition.java similarity index 98% rename from src/main/java/in/koreatech/koin/admin/user/dto/OwnersCondition.java rename to src/main/java/in/koreatech/koin/admin/owner/dto/OwnersCondition.java index 12a3ebace..f42482a4a 100644 --- a/src/main/java/in/koreatech/koin/admin/user/dto/OwnersCondition.java +++ b/src/main/java/in/koreatech/koin/admin/owner/dto/OwnersCondition.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.dto; +package in.koreatech.koin.admin.owner.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; diff --git a/src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerRepository.java b/src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerRepository.java similarity index 97% rename from src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerRepository.java rename to src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerRepository.java index 7b4ae2209..50b418556 100644 --- a/src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerRepository.java +++ b/src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerRepository.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.repository; +package in.koreatech.koin.admin.owner.repository; import java.util.Optional; diff --git a/src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerShopRedisRepository.java b/src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerShopRedisRepository.java similarity index 86% rename from src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerShopRedisRepository.java rename to src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerShopRedisRepository.java index 7b95e3371..765b309ec 100644 --- a/src/main/java/in/koreatech/koin/admin/user/repository/AdminOwnerShopRedisRepository.java +++ b/src/main/java/in/koreatech/koin/admin/owner/repository/AdminOwnerShopRedisRepository.java @@ -1,4 +1,4 @@ -package in.koreatech.koin.admin.user.repository; +package in.koreatech.koin.admin.owner.repository; import java.util.Optional; diff --git a/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java new file mode 100644 index 000000000..11c28e816 --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java @@ -0,0 +1,138 @@ +package in.koreatech.koin.admin.owner.service; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import in.koreatech.koin.admin.owner.repository.AdminOwnerRepository; +import in.koreatech.koin.admin.owner.repository.AdminOwnerShopRedisRepository; +import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; +import in.koreatech.koin.admin.owner.dto.AdminNewOwnersResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateRequest; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateResponse; +import in.koreatech.koin.admin.owner.dto.AdminOwnersResponse; +import in.koreatech.koin.admin.owner.dto.OwnersCondition; +import in.koreatech.koin.admin.user.repository.AdminUserRepository; +import in.koreatech.koin.domain.owner.model.Owner; +import in.koreatech.koin.domain.owner.model.OwnerIncludingShop; +import in.koreatech.koin.domain.shop.model.shop.Shop; +import in.koreatech.koin.domain.user.model.UserType; +import in.koreatech.koin.global.model.Criteria; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AdminOwnerService { + + private final AdminOwnerRepository adminOwnerRepository; + private final AdminOwnerShopRedisRepository adminOwnerShopRedisRepository; + private final AdminShopRepository adminShopRepository; + private final AdminUserRepository adminUserRepository; + + @Transactional + public void allowOwnerPermission(Integer id) { + Owner owner = adminOwnerRepository.getById(id); + owner.getUser().auth(); + adminOwnerShopRedisRepository.findById(id).ifPresent(ownerShop -> { + Integer shopId = ownerShop.getShopId(); + if (shopId != null) { + Shop shop = adminShopRepository.getById(shopId); + shop.updateOwner(owner); + owner.setGrantShop(true); + } + adminOwnerShopRedisRepository.deleteById(id); + }); + } + + public AdminOwnerResponse getOwner(Integer ownerId) { + Owner owner = adminOwnerRepository.getById(ownerId); + + List shopsId = adminShopRepository.findAllByOwnerId(ownerId) + .stream() + .map(Shop::getId) + .toList(); + + return AdminOwnerResponse.of(owner, shopsId); + } + + @Transactional + public AdminOwnerUpdateResponse updateOwner(Integer ownerId, AdminOwnerUpdateRequest request) { + Owner owner = adminOwnerRepository.getById(ownerId); + owner.update(request); + return AdminOwnerUpdateResponse.from(owner); + } + + public AdminNewOwnersResponse getNewOwners(OwnersCondition ownersCondition) { + ownersCondition.checkDataConstraintViolation(); + + Integer totalOwners = adminUserRepository.findUsersCountByUserTypeAndIsAuthed(UserType.OWNER, false); + Criteria criteria = Criteria.of(ownersCondition.page(), ownersCondition.limit(), totalOwners); + Sort.Direction direction = ownersCondition.getDirection(); + + Page result = getNewOwnersResultPage(ownersCondition, criteria, direction); + + List ownerIncludingShops = new ArrayList<>(); + for (Owner owner: result.getContent()) { + adminOwnerShopRedisRepository.findById(owner.getId()).ifPresent(ownerShop -> { + Shop shop = adminShopRepository.findById(ownerShop.getShopId()).orElse(null); + OwnerIncludingShop ownerIncludingShop = OwnerIncludingShop.of(owner, shop); + ownerIncludingShops.add(ownerIncludingShop); + }); + } + + return AdminNewOwnersResponse.of(ownerIncludingShops, result, criteria); + } + + public AdminOwnersResponse getOwners(OwnersCondition ownersCondition) { + ownersCondition.checkDataConstraintViolation(); + + Integer totalOwners = adminUserRepository.findUsersCountByUserTypeAndIsAuthed(UserType.OWNER, true); + Criteria criteria = Criteria.of(ownersCondition.page(), ownersCondition.limit(), totalOwners); + Sort.Direction direction = ownersCondition.getDirection(); + + Page result = getOwnersResultPage(ownersCondition, criteria, direction); + + return AdminOwnersResponse.of(result, criteria); + } + + private Page getNewOwnersResultPage(OwnersCondition ownersCondition, Criteria criteria, + Sort.Direction direction) { + PageRequest pageRequest = PageRequest.of( + criteria.getPage(), + criteria.getLimit(), + Sort.by(direction, "user.createdAt") + ); + + if (ownersCondition.searchType() == OwnersCondition.SearchType.EMAIL) { + return adminOwnerRepository.findPageUnauthenticatedOwnersByEmail(ownersCondition.query(), pageRequest); + } + if (ownersCondition.searchType() == OwnersCondition.SearchType.NAME) { + return adminOwnerRepository.findPageUnauthenticatedOwnersByName(ownersCondition.query(), pageRequest); + } + return adminOwnerRepository.findPageUnauthenticatedOwners(pageRequest); + } + + private Page getOwnersResultPage(OwnersCondition ownersCondition, Criteria criteria, + Sort.Direction direction) { + PageRequest pageRequest = PageRequest.of( + criteria.getPage(), + criteria.getLimit(), + Sort.by(direction, "user.createdAt") + ); + + if (ownersCondition.searchType() == OwnersCondition.SearchType.EMAIL) { + return adminOwnerRepository.findPageOwnersByEmail(ownersCondition.query(), pageRequest); + } + if (ownersCondition.searchType() == OwnersCondition.SearchType.NAME) { + return adminOwnerRepository.findPageOwnersByName(ownersCondition.query(), pageRequest); + } + return adminOwnerRepository.findPageOwners(pageRequest); + } +} \ No newline at end of file diff --git a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java index 6e65660c6..182763adb 100644 --- a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java +++ b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserApi.java @@ -2,11 +2,9 @@ import static in.koreatech.koin.domain.user.model.UserType.ADMIN; -import org.springdoc.core.annotations.ParameterObject; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -15,11 +13,6 @@ import in.koreatech.koin.admin.user.dto.AdminLoginRequest; import in.koreatech.koin.admin.user.dto.AdminLoginResponse; -import in.koreatech.koin.admin.user.dto.AdminNewOwnersResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnersResponse; import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; @@ -28,7 +21,6 @@ import in.koreatech.koin.admin.user.dto.AdminUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminsResponse; import in.koreatech.koin.admin.user.dto.CreateAdminRequest; -import in.koreatech.koin.admin.user.dto.OwnersCondition; import in.koreatech.koin.admin.user.enums.TeamType; import in.koreatech.koin.admin.user.enums.TrackType; import in.koreatech.koin.domain.user.model.User; @@ -218,87 +210,6 @@ ResponseEntity updateAdminPermission( @Auth(permit = {ADMIN}) Integer adminId ); - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "사장님 권한 요청 허용") - @SecurityRequirement(name = "Jwt Authentication") - @PutMapping("/admin/owner/{id}/authed") - ResponseEntity allowOwnerPermission( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ); - - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "특정 사장님 조회") - @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/admin/users/owner/{id}") - ResponseEntity getOwner( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ); - - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))), - } - ) - @Operation(summary = "특정 사장님 수정") - @SecurityRequirement(name = "Jwt Authentication") - @PutMapping("/admin/users/owner/{id}") - ResponseEntity updateOwner( - @PathVariable Integer id, - @RequestBody @Valid AdminOwnerUpdateRequest request, - @Auth(permit = {ADMIN}) Integer adminId - ); - - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))) - } - ) - @Operation(summary = "가입 신청한 사장님 리스트 조회 (페이지네이션)") - @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/admin/users/new-owners") - ResponseEntity getNewOwners( - @ParameterObject @ModelAttribute OwnersCondition ownersCondition, - @Auth(permit = {ADMIN}) Integer adminId - ); - - @ApiResponses( - value = { - @ApiResponse(responseCode = "200"), - @ApiResponse(responseCode = "401", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", content = @Content(schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "404", content = @Content(schema = @Schema(hidden = true))) - } - ) - @Operation(summary = "사장 리스트 조회 (페이지네이션)") - @SecurityRequirement(name = "Jwt Authentication") - @GetMapping("/admin/users/owners") - ResponseEntity getOwners( - @ParameterObject @ModelAttribute OwnersCondition ownersCondition, - @Auth(permit = {ADMIN}) Integer adminId - ); - @ApiResponses( value = { @ApiResponse(responseCode = "200"), diff --git a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java index 6f75ff52e..7c510d75c 100644 --- a/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java +++ b/src/main/java/in/koreatech/koin/admin/user/controller/AdminUserController.java @@ -4,11 +4,9 @@ import java.net.URI; -import org.springdoc.core.annotations.ParameterObject; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -18,11 +16,6 @@ import in.koreatech.koin.admin.user.dto.AdminLoginRequest; import in.koreatech.koin.admin.user.dto.AdminLoginResponse; -import in.koreatech.koin.admin.user.dto.AdminNewOwnersResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnersResponse; import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; @@ -32,7 +25,6 @@ import in.koreatech.koin.admin.user.dto.AdminsCondition; import in.koreatech.koin.admin.user.dto.AdminsResponse; import in.koreatech.koin.admin.user.dto.CreateAdminRequest; -import in.koreatech.koin.admin.user.dto.OwnersCondition; import in.koreatech.koin.admin.user.enums.TeamType; import in.koreatech.koin.admin.user.enums.TrackType; import in.koreatech.koin.admin.user.service.AdminUserService; @@ -47,14 +39,6 @@ public class AdminUserController implements AdminUserApi{ private final AdminUserService adminUserService; - @PutMapping("/admin/owner/{id}/authed") - public ResponseEntity allowOwnerPermission( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId) { - adminUserService.allowOwnerPermission(id); - return ResponseEntity.ok().build(); - } - @PostMapping("/admin") public ResponseEntity createAdmin( @RequestBody @Valid CreateAdminRequest request, @@ -159,41 +143,6 @@ public ResponseEntity updateAdminPermission( return ResponseEntity.ok().build(); } - @GetMapping("/admin/users/owner/{id}") - public ResponseEntity getOwner( - @PathVariable Integer id, - @Auth(permit = {ADMIN}) Integer adminId - ) { - AdminOwnerResponse adminOwnerResponse = adminUserService.getOwner(id); - return ResponseEntity.ok().body(adminOwnerResponse); - } - - @PutMapping("/admin/users/owner/{id}") - public ResponseEntity updateOwner( - @PathVariable Integer id, - @RequestBody @Valid AdminOwnerUpdateRequest request, - @Auth(permit = {ADMIN}) Integer adminId - ) { - AdminOwnerUpdateResponse adminOwnerUpdateResponse = adminUserService.updateOwner(id, request); - return ResponseEntity.ok().body(adminOwnerUpdateResponse); - } - - @GetMapping("/admin/users/new-owners") - public ResponseEntity getNewOwners( - @ParameterObject @ModelAttribute OwnersCondition ownersCondition, - @Auth(permit = {ADMIN}) Integer adminId - ) { - return ResponseEntity.ok().body(adminUserService.getNewOwners(ownersCondition)); - } - - @GetMapping("/admin/users/owners") - public ResponseEntity getOwners( - @ParameterObject @ModelAttribute OwnersCondition ownersCondition, - @Auth(permit = {ADMIN}) Integer adminId - ) { - return ResponseEntity.ok().body(adminUserService.getOwners(ownersCondition)); - } - @GetMapping("/admin/users/{id}") public ResponseEntity getUser( @PathVariable Integer id, diff --git a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java index bc1f0b499..bef987bd4 100644 --- a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java +++ b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java @@ -3,14 +3,11 @@ import static in.koreatech.koin.domain.user.model.UserType.ADMIN; import java.time.LocalDateTime; -import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,11 +15,6 @@ import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; import in.koreatech.koin.admin.user.dto.AdminLoginRequest; import in.koreatech.koin.admin.user.dto.AdminLoginResponse; -import in.koreatech.koin.admin.user.dto.AdminNewOwnersResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateRequest; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateResponse; -import in.koreatech.koin.admin.user.dto.AdminOwnersResponse; import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; import in.koreatech.koin.admin.user.dto.AdminPermissionUpdateRequest; import in.koreatech.koin.admin.user.dto.AdminResponse; @@ -32,21 +24,13 @@ import in.koreatech.koin.admin.user.dto.AdminsCondition; import in.koreatech.koin.admin.user.dto.AdminsResponse; import in.koreatech.koin.admin.user.dto.CreateAdminRequest; -import in.koreatech.koin.admin.user.dto.OwnersCondition; import in.koreatech.koin.admin.user.model.Admin; -import in.koreatech.koin.admin.user.repository.AdminOwnerRepository; -import in.koreatech.koin.admin.user.repository.AdminOwnerShopRedisRepository; +import in.koreatech.koin.admin.owner.repository.AdminOwnerRepository; +import in.koreatech.koin.admin.owner.repository.AdminOwnerShopRedisRepository; import in.koreatech.koin.admin.user.repository.AdminRepository; import in.koreatech.koin.admin.student.repository.AdminStudentRepository; import in.koreatech.koin.admin.user.repository.AdminTokenRepository; import in.koreatech.koin.admin.user.repository.AdminUserRepository; -import in.koreatech.koin.domain.owner.model.Owner; -import in.koreatech.koin.domain.owner.model.OwnerIncludingShop; -import in.koreatech.koin.domain.owner.model.OwnerShop; -import in.koreatech.koin.domain.shop.model.shop.Shop; -import in.koreatech.koin.domain.student.exception.StudentDepartmentNotValidException; -import in.koreatech.koin.domain.student.model.StudentDepartment; -import in.koreatech.koin.domain.user.exception.DuplicationNicknameException; import in.koreatech.koin.domain.user.exception.UserNotFoundException; import in.koreatech.koin.domain.user.model.User; import in.koreatech.koin.domain.user.model.UserToken; @@ -67,9 +51,7 @@ public class AdminUserService { private final JwtProvider jwtProvider; private final AdminStudentRepository adminStudentRepository; private final AdminOwnerRepository adminOwnerRepository; - private final AdminOwnerShopRedisRepository adminOwnerShopRedisRepository; private final AdminUserRepository adminUserRepository; - private final AdminShopRepository adminShopRepository; private final PasswordEncoder passwordEncoder; private final AdminTokenRepository adminTokenRepository; private final AdminRepository adminRepository; @@ -214,125 +196,6 @@ public void updateAdminPermission(AdminPermissionUpdateRequest request, Integer adminRepository.getById(id).updatePermission(request); } - @Transactional - public void allowOwnerPermission(Integer id) { - Owner owner = adminOwnerRepository.getById(id); - owner.getUser().auth(); - Optional ownerShop = adminOwnerShopRedisRepository.findById(id); - if (ownerShop.isPresent()) { - Integer shopId = ownerShop.get().getShopId(); - if (shopId != null) { - Shop shop = adminShopRepository.getById(shopId); - shop.updateOwner(owner); - owner.setGrantShop(true); - } - adminOwnerShopRedisRepository.deleteById(id); - } - } - - public AdminNewOwnersResponse getNewOwners(OwnersCondition ownersCondition) { - ownersCondition.checkDataConstraintViolation(); - - Integer totalOwners = adminUserRepository.findUsersCountByUserTypeAndIsAuthed(UserType.OWNER, false); - Criteria criteria = Criteria.of(ownersCondition.page(), ownersCondition.limit(), totalOwners); - Sort.Direction direction = ownersCondition.getDirection(); - - Page result = getNewOwnersResultPage(ownersCondition, criteria, direction); - - List ownerIncludingShops = result.getContent().stream() - .map(owner -> { - Optional ownerShop = adminOwnerShopRedisRepository.findById(owner.getId()); - return ownerShop - .map(os -> { - Shop shop = adminShopRepository.findById(os.getShopId()).orElse(null); - return OwnerIncludingShop.of(owner, shop); - }) - .orElseGet(() -> OwnerIncludingShop.of(owner, null)); - }) - .toList(); - - return AdminNewOwnersResponse.of(ownerIncludingShops, result, criteria); - } - - public AdminOwnersResponse getOwners(OwnersCondition ownersCondition) { - ownersCondition.checkDataConstraintViolation(); - - Integer totalOwners = adminUserRepository.findUsersCountByUserTypeAndIsAuthed(UserType.OWNER, true); - Criteria criteria = Criteria.of(ownersCondition.page(), ownersCondition.limit(), totalOwners); - Sort.Direction direction = ownersCondition.getDirection(); - - Page result = getOwnersResultPage(ownersCondition, criteria, direction); - - return AdminOwnersResponse.of(result, criteria); - } - - private Page getOwnersResultPage(OwnersCondition ownersCondition, Criteria criteria, - Sort.Direction direction) { - PageRequest pageRequest = PageRequest.of(criteria.getPage(), criteria.getLimit(), - Sort.by(direction, "user.createdAt")); - - Page result; - - if (ownersCondition.searchType() == OwnersCondition.SearchType.EMAIL) { - result = adminOwnerRepository.findPageOwnersByEmail(ownersCondition.query(), pageRequest); - } else if (ownersCondition.searchType() == OwnersCondition.SearchType.NAME) { - result = adminOwnerRepository.findPageOwnersByName(ownersCondition.query(), pageRequest); - } else { - result = adminOwnerRepository.findPageOwners(pageRequest); - } - - return result; - } - - private Page getNewOwnersResultPage(OwnersCondition ownersCondition, Criteria criteria, - Sort.Direction direction) { - PageRequest pageRequest = PageRequest.of(criteria.getPage(), criteria.getLimit(), - Sort.by(direction, "user.createdAt")); - - Page result; - - if (ownersCondition.searchType() == OwnersCondition.SearchType.EMAIL) { - result = adminOwnerRepository.findPageUnauthenticatedOwnersByEmail(ownersCondition.query(), pageRequest); - } else if (ownersCondition.searchType() == OwnersCondition.SearchType.NAME) { - result = adminOwnerRepository.findPageUnauthenticatedOwnersByName(ownersCondition.query(), pageRequest); - } else { - result = adminOwnerRepository.findPageUnauthenticatedOwners(pageRequest); - } - - return result; - } - - private void validateNicknameDuplication(String nickname, Integer userId) { - if (nickname != null && - adminUserRepository.existsByNicknameAndIdNot(nickname, userId)) { - throw DuplicationNicknameException.withDetail("nickname : " + nickname); - } - } - - private void validateDepartmentValid(String department) { - if (department != null && !StudentDepartment.isValid(department)) { - throw StudentDepartmentNotValidException.withDetail("학부(학과) : " + department); - } - } - - public AdminOwnerResponse getOwner(Integer ownerId) { - Owner owner = adminOwnerRepository.getById(ownerId); - - List shopsId = adminShopRepository.findAllByOwnerId(ownerId) - .stream() - .map(Shop::getId) - .toList(); - - return AdminOwnerResponse.of(owner, shopsId); - } - - @Transactional - public AdminOwnerUpdateResponse updateOwner(Integer ownerId, AdminOwnerUpdateRequest request) { - Owner owner = adminOwnerRepository.getById(ownerId); - owner.update(request); - return AdminOwnerUpdateResponse.from(owner); - } - @Transactional public User getUser(Integer userId) { return adminUserRepository.getById(userId); diff --git a/src/main/java/in/koreatech/koin/domain/owner/model/Owner.java b/src/main/java/in/koreatech/koin/domain/owner/model/Owner.java index 22c380241..21700c78f 100644 --- a/src/main/java/in/koreatech/koin/domain/owner/model/Owner.java +++ b/src/main/java/in/koreatech/koin/domain/owner/model/Owner.java @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.util.List; -import in.koreatech.koin.admin.user.dto.AdminOwnerUpdateRequest; +import in.koreatech.koin.admin.owner.dto.AdminOwnerUpdateRequest; import in.koreatech.koin.domain.user.model.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; From 203475eb16e8ebe4df1cf4cac3a046a398b156b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 22:59:22 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20AdminUserService=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/user/service/AdminUserService.java | 47 ++------------- .../user/validation/AdminUserValidation.java | 60 +++++++++++++++++++ 2 files changed, 64 insertions(+), 43 deletions(-) create mode 100644 src/main/java/in/koreatech/koin/admin/user/validation/AdminUserValidation.java diff --git a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java index bef987bd4..2f1dfe0b9 100644 --- a/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java +++ b/src/main/java/in/koreatech/koin/admin/user/service/AdminUserService.java @@ -1,7 +1,5 @@ package in.koreatech.koin.admin.user.service; -import static in.koreatech.koin.domain.user.model.UserType.ADMIN; - import java.time.LocalDateTime; import java.util.Objects; import java.util.UUID; @@ -12,7 +10,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import in.koreatech.koin.admin.shop.repository.shop.AdminShopRepository; import in.koreatech.koin.admin.user.dto.AdminLoginRequest; import in.koreatech.koin.admin.user.dto.AdminLoginResponse; import in.koreatech.koin.admin.user.dto.AdminPasswordChangeRequest; @@ -26,19 +23,16 @@ import in.koreatech.koin.admin.user.dto.CreateAdminRequest; import in.koreatech.koin.admin.user.model.Admin; import in.koreatech.koin.admin.owner.repository.AdminOwnerRepository; -import in.koreatech.koin.admin.owner.repository.AdminOwnerShopRedisRepository; import in.koreatech.koin.admin.user.repository.AdminRepository; import in.koreatech.koin.admin.student.repository.AdminStudentRepository; import in.koreatech.koin.admin.user.repository.AdminTokenRepository; import in.koreatech.koin.admin.user.repository.AdminUserRepository; -import in.koreatech.koin.domain.user.exception.UserNotFoundException; +import in.koreatech.koin.admin.user.validation.AdminUserValidation; import in.koreatech.koin.domain.user.model.User; import in.koreatech.koin.domain.user.model.UserToken; import in.koreatech.koin.domain.user.model.UserType; import in.koreatech.koin.global.auth.JwtProvider; import in.koreatech.koin.global.auth.exception.AuthorizationException; -import in.koreatech.koin.global.domain.email.exception.DuplicationEmailException; -import in.koreatech.koin.global.domain.email.model.EmailAddress; import in.koreatech.koin.global.exception.KoinIllegalArgumentException; import in.koreatech.koin.global.model.Criteria; import lombok.RequiredArgsConstructor; @@ -55,6 +49,7 @@ public class AdminUserService { private final PasswordEncoder passwordEncoder; private final AdminTokenRepository adminTokenRepository; private final AdminRepository adminRepository; + private final AdminUserValidation adminUserValidation; @Transactional public AdminResponse createAdmin(CreateAdminRequest request, Integer adminId) { @@ -63,27 +58,12 @@ public AdminResponse createAdmin(CreateAdminRequest request, Integer adminId) { throw new AuthorizationException("어드민 계정 생성 권한이 없습니다."); } - validateAdminCreate(request); + adminUserValidation.validateEmailForAdminCreated(request.email()); Admin createAdmin = adminRepository.save(request.toEntity(passwordEncoder)); return AdminResponse.from(createAdmin); } - private void validateAdminCreate(CreateAdminRequest request) { - EmailAddress emailAddress = EmailAddress.from(request.email()); - emailAddress.validateKoreatechEmail(); - emailAddress.validateAdminEmail(); - - validateDuplicateEmail(request); - } - - private void validateDuplicateEmail(CreateAdminRequest request) { - adminUserRepository.findByEmail(request.email()) - .ifPresent(user -> { - throw DuplicationEmailException.withDetail("account: " + request.email()); - }); - } - @Transactional public void adminPasswordChange(AdminPasswordChangeRequest request, Integer adminId) { Admin admin = adminRepository.getById(adminId); @@ -97,7 +77,7 @@ public void adminPasswordChange(AdminPasswordChangeRequest request, Integer admi @Transactional public AdminLoginResponse adminLogin(AdminLoginRequest request) { User user = adminUserRepository.getByEmail(request.email()); - validateAdminLogin(user, request); + adminUserValidation.validateAdminLogin(user, request); String accessToken = jwtProvider.createToken(user); String refreshToken = String.format("%s-%d", UUID.randomUUID(), user.getId()); @@ -107,25 +87,6 @@ public AdminLoginResponse adminLogin(AdminLoginRequest request) { return AdminLoginResponse.of(accessToken, savedtoken.getRefreshToken()); } - private void validateAdminLogin(User user, AdminLoginRequest request) { - /* 어드민 권한이 없으면 없는 회원으로 간주 */ - if (user.getUserType() != ADMIN) { - throw UserNotFoundException.withDetail("account" + request.email()); - } - - if (adminRepository.findById(user.getId()).isEmpty()) { - throw UserNotFoundException.withDetail("account" + request.email()); - } - - if (!user.isSamePassword(passwordEncoder, request.password())) { - throw new KoinIllegalArgumentException("비밀번호가 틀렸습니다."); - } - - if (!user.isAuthed()) { - throw new AuthorizationException("PL 인증 대기중입니다."); - } - } - @Transactional public void adminLogout(Integer adminId) { adminTokenRepository.deleteById(adminId); diff --git a/src/main/java/in/koreatech/koin/admin/user/validation/AdminUserValidation.java b/src/main/java/in/koreatech/koin/admin/user/validation/AdminUserValidation.java new file mode 100644 index 000000000..e62663c9c --- /dev/null +++ b/src/main/java/in/koreatech/koin/admin/user/validation/AdminUserValidation.java @@ -0,0 +1,60 @@ +package in.koreatech.koin.admin.user.validation; + +import static in.koreatech.koin.domain.user.model.UserType.ADMIN; + +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import in.koreatech.koin.admin.user.dto.AdminLoginRequest; +import in.koreatech.koin.admin.user.repository.AdminRepository; +import in.koreatech.koin.admin.user.repository.AdminUserRepository; +import in.koreatech.koin.domain.user.exception.UserNotFoundException; +import in.koreatech.koin.domain.user.model.User; +import in.koreatech.koin.global.auth.exception.AuthorizationException; +import in.koreatech.koin.global.domain.email.exception.DuplicationEmailException; +import in.koreatech.koin.global.domain.email.model.EmailAddress; +import in.koreatech.koin.global.exception.KoinIllegalArgumentException; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class AdminUserValidation { + + private final PasswordEncoder passwordEncoder; + private final AdminRepository adminRepository; + private final AdminUserRepository adminUserRepository; + + public void validateEmailForAdminCreated(String email) { + EmailAddress emailAddress = EmailAddress.from(email); + emailAddress.validateKoreatechEmail(); + emailAddress.validateAdminEmail(); + + validateDuplicateEmail(email); + } + + private void validateDuplicateEmail(String email) { + adminUserRepository.findByEmail(email) + .ifPresent(user -> { + throw DuplicationEmailException.withDetail("account: " + email); + }); + } + + public void validateAdminLogin(User user, AdminLoginRequest request) { + /* 어드민 권한이 없으면 없는 회원으로 간주 */ + if (user.getUserType() != ADMIN) { + throw UserNotFoundException.withDetail("account" + request.email()); + } + + if (adminRepository.findById(user.getId()).isEmpty()) { + throw UserNotFoundException.withDetail("account" + request.email()); + } + + if (!user.isSamePassword(passwordEncoder, request.password())) { + throw new KoinIllegalArgumentException("비밀번호가 틀렸습니다."); + } + + if (!user.isAuthed()) { + throw new AuthorizationException("PL 인증 대기중입니다."); + } + } +} \ No newline at end of file From 300a7f4468307a42ed0e02e088949a11bb6adb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 23:16:13 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/acceptance/AdminOwnerApiTest.java | 325 +++++++++++ .../admin/acceptance/AdminStudentApiTest.java | 270 +++++++++ .../admin/acceptance/AdminUserApiTest.java | 526 ------------------ 3 files changed, 595 insertions(+), 526 deletions(-) create mode 100644 src/test/java/in/koreatech/koin/admin/acceptance/AdminOwnerApiTest.java create mode 100644 src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java diff --git a/src/test/java/in/koreatech/koin/admin/acceptance/AdminOwnerApiTest.java b/src/test/java/in/koreatech/koin/admin/acceptance/AdminOwnerApiTest.java new file mode 100644 index 000000000..c6eea0431 --- /dev/null +++ b/src/test/java/in/koreatech/koin/admin/acceptance/AdminOwnerApiTest.java @@ -0,0 +1,325 @@ +package in.koreatech.koin.admin.acceptance; + +import static in.koreatech.koin.domain.user.model.UserGender.MAN; +import static in.koreatech.koin.domain.user.model.UserType.OWNER; +import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; + +import java.util.ArrayList; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Transactional; + +import in.koreatech.koin.AcceptanceTest; +import in.koreatech.koin.admin.owner.repository.AdminOwnerRepository; +import in.koreatech.koin.admin.owner.repository.AdminOwnerShopRedisRepository; +import in.koreatech.koin.admin.user.model.Admin; +import in.koreatech.koin.domain.owner.model.Owner; +import in.koreatech.koin.domain.owner.model.OwnerAttachment; +import in.koreatech.koin.domain.owner.model.OwnerShop; +import in.koreatech.koin.domain.owner.repository.OwnerShopRedisRepository; +import in.koreatech.koin.domain.shop.model.shop.Shop; +import in.koreatech.koin.domain.user.model.User; +import in.koreatech.koin.fixture.ShopFixture; +import in.koreatech.koin.fixture.UserFixture; + +@SuppressWarnings("NonAsciiCharacters") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Transactional +public class AdminOwnerApiTest extends AcceptanceTest { + + @Autowired + private AdminOwnerRepository adminOwnerRepository; + + @Autowired + private AdminOwnerShopRedisRepository adminOwnerShopRedisRepository; + + @Autowired + private OwnerShopRedisRepository ownerShopRedisRepository; + + @Autowired + private UserFixture userFixture; + + @Autowired + private ShopFixture shopFixture; + + @Autowired + private PasswordEncoder passwordEncoder; + + @BeforeAll + void setup() { + clear(); + } + + @Test + void 관리자가_사장님_권한_요청을_허용한다() throws Exception { + Owner owner = userFixture.철수_사장님(); + Shop shop = shopFixture.마슬랜(null, null); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + OwnerShop ownerShop = OwnerShop.builder() + .ownerId(owner.getId()) + .shopId(shop.getId()) + .build(); + + ownerShopRedisRepository.save(ownerShop); + + mockMvc.perform( + put("/admin/owner/{id}/authed", owner.getUser().getId()) + .header("Authorization", "Bearer " + token) + ) + .andExpect(status().isOk()); + + //영속성 컨테스트 동기화 + Owner updatedOwner = adminOwnerRepository.getById(owner.getId()); + var resultOwnerShop = adminOwnerShopRedisRepository.findById(owner.getId()); + + assertSoftly( + softly -> { + softly.assertThat(updatedOwner.getUser().isAuthed()).isEqualTo(true); + softly.assertThat(updatedOwner.isGrantShop()).isEqualTo(true); + softly.assertThat(resultOwnerShop).isEmpty(); + } + ); + } + + @Test + void 관리자가_특정_사장을_조회한다() throws Exception { + Owner owner = userFixture.현수_사장님(); + Shop shop = shopFixture.마슬랜(owner, null); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/users/owner/{id}", owner.getUser().getId()) + .header("Authorization", "Bearer " + token) + ) + .andExpect(status().isOk()) + .andExpect(content().json(String.format(""" + { + "id": 1, + "email": "hysoo@naver.com", + "name": "테스트용_현수", + "nickname": "현수", + "company_registration_number": "123-45-67190", + "attachments_url": [ + "https://test.com/현수_사장님_인증사진_1.jpg", + "https://test.com/현수_사장님_인증사진_2.jpg" + ], + "shops_id": [ + %d + ], + "phone_number": "01098765432", + "is_authed": true, + "user_type": "OWNER", + "gender": 0, + "created_at" : "2024-01-15 12:00:00", + "updated_at" : "2024-01-15 12:00:00", + "last_logged_at" : null + } + """, shop.getId()))); + } + + @Test + void 관리자가_특정_사장을_수정한다() throws Exception { + Owner owner = userFixture.현수_사장님(); + Shop shop = shopFixture.마슬랜(owner, null); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + put("/admin/users/owner/{id}", owner.getUser().getId()) + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "company_registration_number" : "123-45-67190", + "grant_shop" : "false", + "grant_event" : "false" + } + """) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "company_registration_number" : "123-45-67190", + "email" : "hysoo@naver.com", + "gender" : 0, + "grant_shop" : false, + "grant_event" : false, + "name" : "테스트용_현수", + "nickname" : "현수", + "phone_number" : "01098765432" + } + """)); + } + + @Test + void 관리자가_가입_신청한_사장님_리스트_조회한다() throws Exception { + Owner owner = userFixture.철수_사장님(); + Shop shop = shopFixture.마슬랜(null, null); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + OwnerShop ownerShop = OwnerShop.builder() + .ownerId(owner.getId()) + .shopId(shop.getId()) + .build(); + + ownerShopRedisRepository.save(ownerShop); + + mockMvc.perform( + get("/admin/users/new-owners") + .header("Authorization", "Bearer " + token) + .param("searchType", "NAME") + .param("query", "철수") + .param("sort", "CREATED_AT_DESC") + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "total_count": 1, + "current_count": 1, + "total_page": 1, + "current_page": 1, + "owners": [ + { + "id": 1, + "email": "testchulsu@gmail.com", + "name": "테스트용_철수(인증X)", + "phone_number": "01097765112", + "shop_id": 1, + "shop_name": "마슬랜 치킨", + "created_at" : "2024-01-15 12:00:00" + } + ] + } + """)); + } + + @Test + void 관리자가_가입_신청한_사장님_리스트_조회한다_V2() throws Exception { + for (int i = 0; i < 11; i++) { + User user = User.builder() + .password(passwordEncoder.encode("1234")) + .nickname("사장님" + i) + .name("테스트용(인증X)" + i) + .phoneNumber("0109776511" + i) + .userType(OWNER) + .gender(MAN) + .email("testchulsu@gmail.com" + i) + .isAuthed(false) + .isDeleted(false) + .build(); + + Owner owner = Owner.builder() + .user(user) + .companyRegistrationNumber("118-80-567" + i) + .grantShop(true) + .grantEvent(true) + .attachments(new ArrayList<>()) + .build(); + + OwnerAttachment attachment1 = OwnerAttachment.builder() + .url("https://test.com/사장님_인증사진_1" + i + ".jpg") + .isDeleted(false) + .owner(owner) + .build(); + + OwnerAttachment attachment2 = OwnerAttachment.builder() + .url("https://test.com/사장님_인증사진_2" + i + ".jpg") + .isDeleted(false) + .owner(owner) + .build(); + + owner.getAttachments().add(attachment1); + owner.getAttachments().add(attachment2); + + adminOwnerRepository.save(owner); + } + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/users/new-owners") + .header("Authorization", "Bearer " + token) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.total_count").value(11)) + .andExpect(jsonPath("$.current_count").value(10)) + .andExpect(jsonPath("$.total_page").value(2)) + .andExpect(jsonPath("$.current_page").value(1)) + .andExpect(jsonPath("$.owners.length()").value(10)); + } + + @Test + void 관리자가_가입_사장님_리스트_조회한다() throws Exception { + for (int i = 0; i < 11; i++) { + User user = User.builder() + .password(passwordEncoder.encode("1234")) + .nickname("사장님" + i) + .name("테스트용(인증X)" + i) + .phoneNumber("0109776511" + i) + .userType(OWNER) + .gender(MAN) + .email("testchulsu@gmail.com" + i) + .isAuthed(true) + .isDeleted(false) + .build(); + + Owner owner = Owner.builder() + .user(user) + .companyRegistrationNumber("118-80-567" + i) + .grantShop(true) + .grantEvent(true) + .attachments(new ArrayList<>()) + .build(); + + OwnerAttachment attachment1 = OwnerAttachment.builder() + .url("https://test.com/사장님_인증사진_1" + i + ".jpg") + .isDeleted(false) + .owner(owner) + .build(); + + OwnerAttachment attachment2 = OwnerAttachment.builder() + .url("https://test.com/사장님_인증사진_2" + i + ".jpg") + .isDeleted(false) + .owner(owner) + .build(); + + owner.getAttachments().add(attachment1); + owner.getAttachments().add(attachment2); + + adminOwnerRepository.save(owner); + } + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/users/owners") + .header("Authorization", "Bearer " + token) + + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.total_count").value(11)) + .andExpect(jsonPath("$.current_count").value(10)) + .andExpect(jsonPath("$.total_page").value(2)) + .andExpect(jsonPath("$.current_page").value(1)) + .andExpect(jsonPath("$.owners.length()").value(10)); + } +} diff --git a/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java b/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java new file mode 100644 index 000000000..d5eff7645 --- /dev/null +++ b/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java @@ -0,0 +1,270 @@ +package in.koreatech.koin.admin.acceptance; + +import static in.koreatech.koin.domain.user.model.UserGender.MAN; +import static in.koreatech.koin.domain.user.model.UserIdentity.UNDERGRADUATE; +import static in.koreatech.koin.domain.user.model.UserType.STUDENT; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.assertj.core.api.SoftAssertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; + +import in.koreatech.koin.AcceptanceTest; +import in.koreatech.koin.admin.student.repository.AdminStudentRepository; +import in.koreatech.koin.admin.user.model.Admin; +import in.koreatech.koin.domain.student.model.Student; +import in.koreatech.koin.domain.user.model.User; +import in.koreatech.koin.domain.user.model.UserGender; +import in.koreatech.koin.fixture.UserFixture; + +@SuppressWarnings("NonAsciiCharacters") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Transactional +public class AdminStudentApiTest extends AcceptanceTest { + + @Autowired + private AdminStudentRepository adminStudentRepository; + + @Autowired + private TransactionTemplate transactionTemplate; + + @Autowired + private UserFixture userFixture; + + @Autowired + private PasswordEncoder passwordEncoder; + + @BeforeAll + void setup() { + clear(); + } + + @Test + void 관리자가_학생_리스트를_파라미터가_없이_조회한다_페이지네이션() throws Exception { + Admin adminUser = userFixture.코인_운영자(); + + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/students") + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "current_count": 1, + "current_page": 1, + "students": [ + { + "email": "juno@koreatech.ac.kr", + "id": 1, + "major": "컴퓨터공학부", + "name": "테스트용_준호", + "nickname": "준호", + "student_number": "2019136135" + } + ], + "total_count": 1, + "total_page": 1 + } + """)); + } + + @Test + void 관리자가_학생_리스트를_페이지_수와_limits으로_조회한다_페이지네이션() throws Exception { + for (int i = 0; i < 11; i++) { + Student student = Student.builder() + .studentNumber("2019136135") + .anonymousNickname("익명" + i) + .department("컴퓨터공학부") + .userIdentity(UNDERGRADUATE) + .isGraduated(false) + .user( + User.builder() + .password(passwordEncoder.encode("1234")) + .nickname("성재" + i) + .name("테스트용_성재" + i) + .phoneNumber("01012345670") + .userType(STUDENT) + .gender(MAN) + .email("seongjae@koreatech.ac.kr") + .isAuthed(true) + .isDeleted(false) + .build() + ) + .build(); + + adminStudentRepository.save(student); + } + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/students") + .header("Authorization", "Bearer " + token) + .param("page", "2") + .param("limit", "10") + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "current_count": 1, + "current_page": 2, + "students": [ + { + "email": "seongjae@koreatech.ac.kr", + "id": 11, + "major": "컴퓨터공학부", + "name": "테스트용_성재10", + "nickname": "성재10", + "student_number": "2019136135" + } + ], + "total_count": 11, + "total_page": 2 + } + """)); + } + + @Test + void 관리자가_학생_리스트를_닉네임으로_조회한다_페이지네이션() throws Exception { + Student student1 = userFixture.성빈_학생(); + Student student2 = userFixture.준호_학생(); + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/students") + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + .param("nickname", "준호") + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "current_count": 1, + "current_page": 1, + "students": [ + { + "email": "juno@koreatech.ac.kr", + "id": 2, + "major": "컴퓨터공학부", + "name": "테스트용_준호", + "nickname": "준호", + "student_number": "2019136135" + } + ], + "total_count": 1, + "total_page": 1 + } + """)); + } + + @Test + void 관리자가_특정_학생_정보를_조회한다_관리자가_아니면_403_반환() throws Exception { + Student student = userFixture.준호_학생(); + String token = userFixture.getToken(student.getUser()); + + mockMvc.perform( + get("/admin/users/student/{id}", student.getUser().getId()) + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isForbidden()); + } + + @Test + void 관리자가_특정_학생_정보를_조회한다() throws Exception { + Student student = userFixture.준호_학생(); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + get("/admin/users/student/{id}", student.getUser().getId()) + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "anonymous_nickname": "익명", + "created_at": "2024-01-15 12:00:00", + "email": "juno@koreatech.ac.kr", + "gender": 0, + "id": 1, + "is_authed": true, + "is_graduated": false, + "last_logged_at": null, + "major": "컴퓨터공학부", + "name": "테스트용_준호", + "nickname": "준호", + "phone_number": "01012345678", + "student_number": "2019136135", + "updated_at": "2024-01-15 12:00:00", + "user_type": "STUDENT" + } + """)); + } + + @Test + void 관리자가_특정_학생_정보를_수정한다() throws Exception { + Student student = userFixture.준호_학생(); + + Admin adminUser = userFixture.코인_운영자(); + String token = userFixture.getToken(adminUser.getUser()); + + mockMvc.perform( + put("/admin/users/student/{id}", student.getUser().getId()) + .header("Authorization", "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "gender" : 1, + "major" : "기계공학부", + "name" : "서정빈", + "password" : "0c4be6acaba1839d3433c1ccf04e1eec4d1fa841ee37cb019addc269e8bc1b77", + "nickname" : "duehee", + "phone_number" : "01023456789", + "student_number" : "2019136136" + } + """) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "anonymous_nickname": "익명", + "email": "juno@koreatech.ac.kr", + "gender": 1, + "major": "기계공학부", + "name": "서정빈", + "nickname": "duehee", + "phone_number": "01023456789", + "student_number": "2019136136" + } + """)); + + transactionTemplate.executeWithoutResult(status -> { + Student result = adminStudentRepository.getById(student.getId()); + SoftAssertions.assertSoftly( + softly -> { + softly.assertThat(result.getUser().getName()).isEqualTo("서정빈"); + softly.assertThat(result.getUser().getNickname()).isEqualTo("duehee"); + softly.assertThat(result.getUser().getGender()).isEqualTo(UserGender.from(1)); + softly.assertThat(result.getStudentNumber()).isEqualTo("2019136136"); + } + ); + }); + } +} \ No newline at end of file diff --git a/src/test/java/in/koreatech/koin/admin/acceptance/AdminUserApiTest.java b/src/test/java/in/koreatech/koin/admin/acceptance/AdminUserApiTest.java index 76a8b0ea7..46ce84c2d 100644 --- a/src/test/java/in/koreatech/koin/admin/acceptance/AdminUserApiTest.java +++ b/src/test/java/in/koreatech/koin/admin/acceptance/AdminUserApiTest.java @@ -1,45 +1,25 @@ package in.koreatech.koin.admin.acceptance; -import static in.koreatech.koin.domain.user.model.UserGender.MAN; -import static in.koreatech.koin.domain.user.model.UserIdentity.UNDERGRADUATE; -import static in.koreatech.koin.domain.user.model.UserType.OWNER; -import static in.koreatech.koin.domain.user.model.UserType.STUDENT; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import java.util.ArrayList; - -import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.test.web.servlet.MvcResult; import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionTemplate; import com.fasterxml.jackson.databind.JsonNode; import in.koreatech.koin.AcceptanceTest; import in.koreatech.koin.admin.user.model.Admin; -import in.koreatech.koin.admin.user.repository.AdminOwnerRepository; -import in.koreatech.koin.admin.user.repository.AdminOwnerShopRedisRepository; import in.koreatech.koin.admin.user.repository.AdminRepository; -import in.koreatech.koin.admin.user.repository.AdminStudentRepository; import in.koreatech.koin.admin.user.repository.AdminUserRepository; -import in.koreatech.koin.domain.owner.model.Owner; -import in.koreatech.koin.domain.owner.model.OwnerAttachment; -import in.koreatech.koin.domain.owner.model.OwnerShop; -import in.koreatech.koin.domain.owner.repository.OwnerShopRedisRepository; -import in.koreatech.koin.domain.shop.model.shop.Shop; import in.koreatech.koin.domain.student.model.Student; import in.koreatech.koin.domain.user.model.User; -import in.koreatech.koin.domain.user.model.UserGender; -import in.koreatech.koin.fixture.ShopFixture; import in.koreatech.koin.fixture.UserFixture; import in.koreatech.koin.support.JsonAssertions; @@ -48,165 +28,20 @@ @Transactional class AdminUserApiTest extends AcceptanceTest { - @Autowired - private AdminStudentRepository adminStudentRepository; - - @Autowired - private AdminOwnerRepository adminOwnerRepository; - @Autowired private AdminUserRepository adminUserRepository; - @Autowired - private AdminOwnerShopRedisRepository adminOwnerShopRedisRepository; - - @Autowired - private OwnerShopRedisRepository ownerShopRedisRepository; - @Autowired private AdminRepository adminRepository; - @Autowired - private TransactionTemplate transactionTemplate; - @Autowired private UserFixture userFixture; - @Autowired - private ShopFixture shopFixture; - - @Autowired - private PasswordEncoder passwordEncoder; - @BeforeAll void setup() { clear(); } - @Test - void 관리자가_학생_리스트를_파라미터가_없이_조회한다_페이지네이션() throws Exception { - Student student = userFixture.준호_학생(); - Admin adminUser = userFixture.코인_운영자(); - - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/students") - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "current_count": 1, - "current_page": 1, - "students": [ - { - "email": "juno@koreatech.ac.kr", - "id": 1, - "major": "컴퓨터공학부", - "name": "테스트용_준호", - "nickname": "준호", - "student_number": "2019136135" - } - ], - "total_count": 1, - "total_page": 1 - } - """)); - } - - @Test - void 관리자가_학생_리스트를_페이지_수와_limits으로_조회한다_페이지네이션() throws Exception { - for (int i = 0; i < 11; i++) { - Student student = Student.builder() - .studentNumber("2019136135") - .anonymousNickname("익명" + i) - .department("컴퓨터공학부") - .userIdentity(UNDERGRADUATE) - .isGraduated(false) - .user( - User.builder() - .password(passwordEncoder.encode("1234")) - .nickname("성재" + i) - .name("테스트용_성재" + i) - .phoneNumber("01012345670") - .userType(STUDENT) - .gender(MAN) - .email("seongjae@koreatech.ac.kr") - .isAuthed(true) - .isDeleted(false) - .build() - ) - .build(); - - adminStudentRepository.save(student); - } - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/students") - .header("Authorization", "Bearer " + token) - .param("page", "2") - .param("limit", "10") - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "current_count": 1, - "current_page": 2, - "students": [ - { - "email": "seongjae@koreatech.ac.kr", - "id": 11, - "major": "컴퓨터공학부", - "name": "테스트용_성재10", - "nickname": "성재10", - "student_number": "2019136135" - } - ], - "total_count": 11, - "total_page": 2 - } - """)); - } - - @Test - void 관리자가_학생_리스트를_닉네임으로_조회한다_페이지네이션() throws Exception { - Student student1 = userFixture.성빈_학생(); - Student student2 = userFixture.준호_학생(); - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/students") - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - .param("nickname", "준호") - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "current_count": 1, - "current_page": 1, - "students": [ - { - "email": "juno@koreatech.ac.kr", - "id": 2, - "major": "컴퓨터공학부", - "name": "테스트용_준호", - "nickname": "준호", - "student_number": "2019136135" - } - ], - "total_count": 1, - "total_page": 1 - } - """)); - } - @Test void 관리자가_로그인_한다() throws Exception { Admin adminUser = userFixture.코인_운영자(); @@ -313,367 +148,6 @@ void setup() { .andExpect(status().isCreated()); } - @Test - void 관리자가_사장님_권한_요청을_허용한다() throws Exception { - Owner owner = userFixture.철수_사장님(); - Shop shop = shopFixture.마슬랜(null, null); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - OwnerShop ownerShop = OwnerShop.builder() - .ownerId(owner.getId()) - .shopId(shop.getId()) - .build(); - - ownerShopRedisRepository.save(ownerShop); - - mockMvc.perform( - put("/admin/owner/{id}/authed", owner.getUser().getId()) - .header("Authorization", "Bearer " + token) - ) - .andExpect(status().isOk()); - - //영속성 컨테스트 동기화 - Owner updatedOwner = adminOwnerRepository.getById(owner.getId()); - var resultOwnerShop = adminOwnerShopRedisRepository.findById(owner.getId()); - - assertSoftly( - softly -> { - softly.assertThat(updatedOwner.getUser().isAuthed()).isEqualTo(true); - softly.assertThat(updatedOwner.isGrantShop()).isEqualTo(true); - softly.assertThat(resultOwnerShop).isEmpty(); - } - ); - } - - @Test - void 관리자가_특정_학생_정보를_조회한다_관리자가_아니면_403_반환() throws Exception { - Student student = userFixture.준호_학생(); - String token = userFixture.getToken(student.getUser()); - - mockMvc.perform( - get("/admin/users/student/{id}", student.getUser().getId()) - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - ) - .andExpect(status().isForbidden()); - } - - @Test - void 관리자가_특정_학생_정보를_조회한다() throws Exception { - Student student = userFixture.준호_학생(); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/users/student/{id}", student.getUser().getId()) - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "anonymous_nickname": "익명", - "created_at": "2024-01-15 12:00:00", - "email": "juno@koreatech.ac.kr", - "gender": 0, - "id": 1, - "is_authed": true, - "is_graduated": false, - "last_logged_at": null, - "major": "컴퓨터공학부", - "name": "테스트용_준호", - "nickname": "준호", - "phone_number": "01012345678", - "student_number": "2019136135", - "updated_at": "2024-01-15 12:00:00", - "user_type": "STUDENT" - } - """)); - } - - @Test - void 관리자가_특정_학생_정보를_수정한다() throws Exception { - Student student = userFixture.준호_학생(); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - put("/admin/users/student/{id}", student.getUser().getId()) - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "gender" : 1, - "major" : "기계공학부", - "name" : "서정빈", - "password" : "0c4be6acaba1839d3433c1ccf04e1eec4d1fa841ee37cb019addc269e8bc1b77", - "nickname" : "duehee", - "phone_number" : "01023456789", - "student_number" : "2019136136" - } - """) - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "anonymous_nickname": "익명", - "email": "juno@koreatech.ac.kr", - "gender": 1, - "major": "기계공학부", - "name": "서정빈", - "nickname": "duehee", - "phone_number": "01023456789", - "student_number": "2019136136" - } - """)); - - transactionTemplate.executeWithoutResult(status -> { - Student result = adminStudentRepository.getById(student.getId()); - SoftAssertions.assertSoftly( - softly -> { - softly.assertThat(result.getUser().getName()).isEqualTo("서정빈"); - softly.assertThat(result.getUser().getNickname()).isEqualTo("duehee"); - softly.assertThat(result.getUser().getGender()).isEqualTo(UserGender.from(1)); - softly.assertThat(result.getStudentNumber()).isEqualTo("2019136136"); - } - ); - }); - } - - @Test - void 관리자가_특정_사장을_조회한다() throws Exception { - Owner owner = userFixture.현수_사장님(); - Shop shop = shopFixture.마슬랜(owner, null); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/users/owner/{id}", owner.getUser().getId()) - .header("Authorization", "Bearer " + token) - ) - .andExpect(status().isOk()) - .andExpect(content().json(String.format(""" - { - "id": 1, - "email": "hysoo@naver.com", - "name": "테스트용_현수", - "nickname": "현수", - "company_registration_number": "123-45-67190", - "attachments_url": [ - "https://test.com/현수_사장님_인증사진_1.jpg", - "https://test.com/현수_사장님_인증사진_2.jpg" - ], - "shops_id": [ - %d - ], - "phone_number": "01098765432", - "is_authed": true, - "user_type": "OWNER", - "gender": 0, - "created_at" : "2024-01-15 12:00:00", - "updated_at" : "2024-01-15 12:00:00", - "last_logged_at" : null - } - """, shop.getId()))); - } - - @Test - void 관리자가_특정_사장을_수정한다() throws Exception { - Owner owner = userFixture.현수_사장님(); - Shop shop = shopFixture.마슬랜(owner, null); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - put("/admin/users/owner/{id}", owner.getUser().getId()) - .header("Authorization", "Bearer " + token) - .contentType(MediaType.APPLICATION_JSON) - .content(""" - { - "company_registration_number" : "123-45-67190", - "grant_shop" : "false", - "grant_event" : "false" - } - """) - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "company_registration_number" : "123-45-67190", - "email" : "hysoo@naver.com", - "gender" : 0, - "grant_shop" : false, - "grant_event" : false, - "name" : "테스트용_현수", - "nickname" : "현수", - "phone_number" : "01098765432" - } - """)); - } - - @Test - void 관리자가_가입_신청한_사장님_리스트_조회한다() throws Exception { - Owner owner = userFixture.철수_사장님(); - Shop shop = shopFixture.마슬랜(null, null); - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - OwnerShop ownerShop = OwnerShop.builder() - .ownerId(owner.getId()) - .shopId(shop.getId()) - .build(); - - ownerShopRedisRepository.save(ownerShop); - - mockMvc.perform( - get("/admin/users/new-owners") - .header("Authorization", "Bearer " + token) - .param("searchType", "NAME") - .param("query", "철수") - .param("sort", "CREATED_AT_DESC") - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "total_count": 1, - "current_count": 1, - "total_page": 1, - "current_page": 1, - "owners": [ - { - "id": 1, - "email": "testchulsu@gmail.com", - "name": "테스트용_철수(인증X)", - "phone_number": "01097765112", - "shop_id": 1, - "shop_name": "마슬랜 치킨", - "created_at" : "2024-01-15 12:00:00" - } - ] - } - """)); - } - - @Test - void 관리자가_가입_신청한_사장님_리스트_조회한다_V2() throws Exception { - for (int i = 0; i < 11; i++) { - User user = User.builder() - .password(passwordEncoder.encode("1234")) - .nickname("사장님" + i) - .name("테스트용(인증X)" + i) - .phoneNumber("0109776511" + i) - .userType(OWNER) - .gender(MAN) - .email("testchulsu@gmail.com" + i) - .isAuthed(false) - .isDeleted(false) - .build(); - - Owner owner = Owner.builder() - .user(user) - .companyRegistrationNumber("118-80-567" + i) - .grantShop(true) - .grantEvent(true) - .attachments(new ArrayList<>()) - .build(); - - OwnerAttachment attachment1 = OwnerAttachment.builder() - .url("https://test.com/사장님_인증사진_1" + i + ".jpg") - .isDeleted(false) - .owner(owner) - .build(); - - OwnerAttachment attachment2 = OwnerAttachment.builder() - .url("https://test.com/사장님_인증사진_2" + i + ".jpg") - .isDeleted(false) - .owner(owner) - .build(); - - owner.getAttachments().add(attachment1); - owner.getAttachments().add(attachment2); - - adminOwnerRepository.save(owner); - } - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/users/new-owners") - .header("Authorization", "Bearer " + token) - ) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.total_count").value(11)) - .andExpect(jsonPath("$.current_count").value(10)) - .andExpect(jsonPath("$.total_page").value(2)) - .andExpect(jsonPath("$.current_page").value(1)) - .andExpect(jsonPath("$.owners.length()").value(10)); - } - - @Test - void 관리자가_가입_사장님_리스트_조회한다() throws Exception { - for (int i = 0; i < 11; i++) { - User user = User.builder() - .password(passwordEncoder.encode("1234")) - .nickname("사장님" + i) - .name("테스트용(인증X)" + i) - .phoneNumber("0109776511" + i) - .userType(OWNER) - .gender(MAN) - .email("testchulsu@gmail.com" + i) - .isAuthed(true) - .isDeleted(false) - .build(); - - Owner owner = Owner.builder() - .user(user) - .companyRegistrationNumber("118-80-567" + i) - .grantShop(true) - .grantEvent(true) - .attachments(new ArrayList<>()) - .build(); - - OwnerAttachment attachment1 = OwnerAttachment.builder() - .url("https://test.com/사장님_인증사진_1" + i + ".jpg") - .isDeleted(false) - .owner(owner) - .build(); - - OwnerAttachment attachment2 = OwnerAttachment.builder() - .url("https://test.com/사장님_인증사진_2" + i + ".jpg") - .isDeleted(false) - .owner(owner) - .build(); - - owner.getAttachments().add(attachment1); - owner.getAttachments().add(attachment2); - - adminOwnerRepository.save(owner); - } - - Admin adminUser = userFixture.코인_운영자(); - String token = userFixture.getToken(adminUser.getUser()); - - mockMvc.perform( - get("/admin/users/owners") - .header("Authorization", "Bearer " + token) - - ) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.total_count").value(11)) - .andExpect(jsonPath("$.current_count").value(10)) - .andExpect(jsonPath("$.total_page").value(2)) - .andExpect(jsonPath("$.current_page").value(1)) - .andExpect(jsonPath("$.owners.length()").value(10)); - } - @Test void 관리자가_회원을_조회한다() throws Exception { Student student = userFixture.준호_학생(); From 23c5d479a2ecbc5a86291e8dfb2b7619a12bcca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 23:31:07 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20=EB=93=A4=EC=97=AC=EC=93=B0?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koreatech/koin/admin/owner/controller/AdminOwnerApi.java | 2 +- .../koin/admin/owner/controller/AdminOwnerController.java | 2 +- .../koreatech/koin/admin/owner/service/AdminOwnerService.java | 2 +- .../koin/admin/student/controller/AdminStudentApi.java | 2 +- .../koin/admin/student/controller/AdminStudentController.java | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java index 67b41ce95..9f2ecf4fd 100644 --- a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java +++ b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerApi.java @@ -109,4 +109,4 @@ ResponseEntity getOwners( @ParameterObject @ModelAttribute OwnersCondition ownersCondition, @Auth(permit = {ADMIN}) Integer adminId ); -} \ No newline at end of file +} diff --git a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java index 5105cb880..23cd9ab72 100644 --- a/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java +++ b/src/main/java/in/koreatech/koin/admin/owner/controller/AdminOwnerController.java @@ -70,4 +70,4 @@ public ResponseEntity getOwners( ) { return ResponseEntity.ok().body(adminOwnerService.getOwners(ownersCondition)); } -} \ No newline at end of file +} diff --git a/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java index 11c28e816..b297ec563 100644 --- a/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java +++ b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java @@ -135,4 +135,4 @@ private Page getOwnersResultPage(OwnersCondition ownersCondition, Criteri } return adminOwnerRepository.findPageOwners(pageRequest); } -} \ No newline at end of file +} diff --git a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java index 02c89e3ee..47104b683 100644 --- a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java +++ b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentApi.java @@ -78,4 +78,4 @@ ResponseEntity updateStudent( @PathVariable Integer id, @Auth(permit = {ADMIN}) Integer adminId ); -} \ No newline at end of file +} diff --git a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java index 9fbef879e..3083ceb2e 100644 --- a/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java +++ b/src/main/java/in/koreatech/koin/admin/student/controller/AdminStudentController.java @@ -22,7 +22,7 @@ @RestController @RequiredArgsConstructor -public class AdminStudentController implements AdminStudentApi{ +public class AdminStudentController implements AdminStudentApi { private final AdminStudentService adminStudentService; @@ -58,4 +58,4 @@ public ResponseEntity updateStudent( AdminStudentUpdateResponse response = adminStudentService.updateStudent(id, adminRequest); return ResponseEntity.ok().body(response); } -} \ No newline at end of file +} From 0a00fbb4c43c88878e00fdb3faf90666f4723709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 23:36:42 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koreatech/koin/admin/acceptance/AdminStudentApiTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java b/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java index d5eff7645..adf17f6dd 100644 --- a/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java +++ b/src/test/java/in/koreatech/koin/admin/acceptance/AdminStudentApiTest.java @@ -50,6 +50,7 @@ void setup() { @Test void 관리자가_학생_리스트를_파라미터가_없이_조회한다_페이지네이션() throws Exception { + Student student = userFixture.준호_학생(); Admin adminUser = userFixture.코인_운영자(); String token = userFixture.getToken(adminUser.getUser()); @@ -267,4 +268,4 @@ void setup() { ); }); } -} \ No newline at end of file +} From 8aaf75a34f720fca7dd4af30ccda55cbd035a798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=9B=90=EA=B2=BD?= Date: Mon, 25 Nov 2024 23:59:36 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20getNewOwners=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/admin/owner/service/AdminOwnerService.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java index b297ec563..c22ca75ca 100644 --- a/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java +++ b/src/main/java/in/koreatech/koin/admin/owner/service/AdminOwnerService.java @@ -79,12 +79,13 @@ public AdminNewOwnersResponse getNewOwners(OwnersCondition ownersCondition) { Page result = getNewOwnersResultPage(ownersCondition, criteria, direction); List ownerIncludingShops = new ArrayList<>(); - for (Owner owner: result.getContent()) { - adminOwnerShopRedisRepository.findById(owner.getId()).ifPresent(ownerShop -> { - Shop shop = adminShopRepository.findById(ownerShop.getShopId()).orElse(null); - OwnerIncludingShop ownerIncludingShop = OwnerIncludingShop.of(owner, shop); - ownerIncludingShops.add(ownerIncludingShop); - }); + for (Owner owner : result.getContent()) { + Shop shop = adminOwnerShopRedisRepository.findById(owner.getId()) + .map(ownerShop -> adminShopRepository.findById(ownerShop.getShopId()).orElse(null)) + .orElse(null); + + OwnerIncludingShop ownerIncludingShop = OwnerIncludingShop.of(owner, shop); + ownerIncludingShops.add(ownerIncludingShop); } return AdminNewOwnersResponse.of(ownerIncludingShops, result, criteria);