package com.gcsc.guide.controller; import com.gcsc.guide.dto.UpdateRolesRequest; import com.gcsc.guide.dto.UserResponse; import com.gcsc.guide.service.UserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; 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; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/admin/users") @RequiredArgsConstructor @Tag(name = "02. 관리자 - 사용자", description = "사용자 관리 (승인/거절/비활성화/롤/관리자 권한)") @SecurityRequirement(name = "Bearer JWT") public class AdminUserController { private final UserService userService; @Operation(summary = "전체 사용자 목록 조회", description = "모든 사용자 목록을 조회합니다. status 파라미터로 특정 상태의 사용자만 필터링할 수 있습니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(array = @ArraySchema(schema = @Schema(implementation = UserResponse.class)))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content) }) @GetMapping public ResponseEntity> getUsers( @Parameter(description = "사용자 상태 필터 (PENDING, ACTIVE, REJECTED, DISABLED)", example = "PENDING") @RequestParam(required = false) String status) { return ResponseEntity.ok(userService.getUsers(status)); } @Operation(summary = "사용자 승인", description = "PENDING 상태의 사용자를 ACTIVE로 변경합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "승인 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @PutMapping("/{id}/approve") public ResponseEntity approveUser( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id) { return ResponseEntity.ok(userService.approveUser(id)); } @Operation(summary = "사용자 거절", description = "PENDING 상태의 사용자를 REJECTED로 변경합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "거절 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @PutMapping("/{id}/reject") public ResponseEntity rejectUser( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id) { return ResponseEntity.ok(userService.rejectUser(id)); } @Operation(summary = "사용자 비활성화", description = "ACTIVE 상태의 사용자를 DISABLED로 변경합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "비활성화 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @PutMapping("/{id}/disable") public ResponseEntity disableUser( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id) { return ResponseEntity.ok(userService.disableUser(id)); } @Operation(summary = "사용자 롤 업데이트", description = "사용자에게 할당된 롤을 변경합니다. 기존 롤을 모두 제거하고 전달된 roleIds로 교체합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "롤 업데이트 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @PutMapping("/{id}/roles") public ResponseEntity updateUserRoles( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id, @Valid @RequestBody UpdateRolesRequest request) { return ResponseEntity.ok(userService.updateUserRoles(id, request.roleIds())); } @Operation(summary = "관리자 권한 부여", description = "사용자에게 관리자(isAdmin) 권한을 부여합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "관리자 권한 부여 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @PostMapping("/{id}/admin") public ResponseEntity grantAdmin( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id) { return ResponseEntity.ok(userService.grantAdmin(id)); } @Operation(summary = "관리자 권한 해제", description = "사용자의 관리자(isAdmin) 권한을 해제합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "관리자 권한 해제 성공", content = @Content(schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "401", description = "인증 실패", content = @Content), @ApiResponse(responseCode = "403", description = "관리자 권한 필요", content = @Content), @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content) }) @DeleteMapping("/{id}/admin") public ResponseEntity revokeAdmin( @Parameter(description = "사용자 ID", required = true) @PathVariable Long id) { return ResponseEntity.ok(userService.revokeAdmin(id)); } }