From 260569225c349ab7fb1686bb2ae5c77e8ed30067 Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 6 Apr 2026 17:36:19 +0900 Subject: [PATCH] =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20api=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/training/config/SecurityConfig.java | 2 +- .../filemanager/FileManagerApiController.java | 125 ++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/kamco/cd/training/filemanager/FileManagerApiController.java diff --git a/src/main/java/com/kamco/cd/training/config/SecurityConfig.java b/src/main/java/com/kamco/cd/training/config/SecurityConfig.java index 750cc34..efd625c 100644 --- a/src/main/java/com/kamco/cd/training/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/training/config/SecurityConfig.java @@ -137,6 +137,6 @@ public class SecurityConfig { /** 완전 제외(필터 자체를 안 탐) */ @Bean public WebSecurityCustomizer webSecurityCustomizer() { - return (web) -> web.ignoring().requestMatchers("/api/mapsheet/**"); + return (web) -> web.ignoring().requestMatchers("/api/mapsheet/**", "/api/file-manager/**"); } } diff --git a/src/main/java/com/kamco/cd/training/filemanager/FileManagerApiController.java b/src/main/java/com/kamco/cd/training/filemanager/FileManagerApiController.java new file mode 100644 index 0000000..20a8d9b --- /dev/null +++ b/src/main/java/com/kamco/cd/training/filemanager/FileManagerApiController.java @@ -0,0 +1,125 @@ +package com.kamco.cd.training.filemanager; + +import com.kamco.cd.training.config.api.ApiResponseDto; +import com.kamco.cd.training.filemanager.dto.FileManagerDto; +import com.kamco.cd.training.filemanager.service.FileManagerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +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.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@Tag(name = "파일 관리", description = "/data 디렉토리 파일 관리 API") +@RestController +@RequestMapping("/api/file-manager") +@RequiredArgsConstructor +public class FileManagerApiController { + + private final FileManagerService fileManagerService; + + @Operation( + summary = "파일 목록 조회", + description = "/data 디렉토리 내 파일 및 디렉토리 목록을 조회합니다. recursive=true로 설정하면 하위 디렉토리까지 조회합니다.") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "조회 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = FileManagerDto.ListFilesRes.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 (유효하지 않은 경로)", content = @Content), + @ApiResponse(responseCode = "404", description = "디렉토리를 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @GetMapping("/files") + public ApiResponseDto listFiles( + @Parameter(description = "조회할 디렉토리 경로 (기본값: /data)", example = "/data/request") + @RequestParam(required = false) + String directoryPath, + @Parameter(description = "하위 디렉토리 포함 여부", example = "false") + @RequestParam(required = false, defaultValue = "false") + Boolean recursive) { + + FileManagerDto.ListFilesReq request = + FileManagerDto.ListFilesReq.builder() + .directoryPath(directoryPath) + .recursive(recursive) + .build(); + + FileManagerDto.ListFilesRes response = fileManagerService.listFiles(request); + return ApiResponseDto.ok(response); + } + + @Operation( + summary = "파일/디렉토리 삭제", + description = "지정된 파일 또는 디렉토리를 삭제합니다. recursive=true로 설정하면 디렉토리 내 모든 파일을 삭제합니다.", + requestBody = + @io.swagger.v3.oas.annotations.parameters.RequestBody( + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = FileManagerDto.DeleteFileReq.class), + examples = { + @ExampleObject( + name = "단일 파일 삭제", + value = + """ + { + "filePaths": ["/data/request/old_file.zip"], + "recursive": false + } + """), + @ExampleObject( + name = "여러 파일 삭제", + value = + """ + { + "filePaths": ["/data/file1.txt", "/data/file2.txt"], + "recursive": false + } + """), + @ExampleObject( + name = "디렉토리 전체 삭제", + value = + """ + { + "filePaths": ["/data/old_folder"], + "recursive": true + } + """) + }))) + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "삭제 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = FileManagerDto.DeleteFileRes.class))), + @ApiResponse(responseCode = "400", description = "잘못된 요청 (유효하지 않은 경로)", content = @Content), + @ApiResponse(responseCode = "404", description = "파일을 찾을 수 없음", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @DeleteMapping("/files") + public ApiResponseDto deleteFiles( + @RequestBody FileManagerDto.DeleteFileReq request) { + + FileManagerDto.DeleteFileRes response = fileManagerService.deleteFiles(request); + return ApiResponseDto.ok(response); + } +}