diff --git a/.gitignore b/.gitignore index 009f7f8b..4a44c233 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,8 @@ out/ /src/main/resources/application-oauth.yml /src/main/resources/application-minio.yml +/src/main/resources/application-dev.yml +/src/main/resources/application-email.yml +/src/main/resources/application-notion.yml + +.DS_Store diff --git a/src/docs/asciidoc/file-controller-test.adoc b/src/docs/asciidoc/file-controller-test.adoc index c41dbc9a..92ca466a 100644 --- a/src/docs/asciidoc/file-controller-test.adoc +++ b/src/docs/asciidoc/file-controller-test.adoc @@ -4,11 +4,19 @@ --- === 다중 파일 업로드 (POST /files) + ==== operation::file-controller-test/upload-files[snippets="http-request,request-parts,http-response,response-fields"] ==== === 파일 조회 (GET /files/{fileId}) + ==== operation::file-controller-test/get-file[snippets="http-request,path-parameters,http-response"] -==== \ No newline at end of file +==== + +=== 프로젝트 일괄 등록 양식 다운로드 (GET /files/form/projects) + +==== +operation::file-controller-test/get-project-excel-form[snippets="http-request,http-response"] +==== diff --git a/src/docs/asciidoc/project.adoc b/src/docs/asciidoc/project.adoc index c601d947..d4767b92 100644 --- a/src/docs/asciidoc/project.adoc +++ b/src/docs/asciidoc/project.adoc @@ -3,73 +3,79 @@ --- === 프로젝트 조회 (GET /projects) -==== 200 OK + ==== operation::project-controller-test/get-projects[snippets="http-request,http-response,query-parameters,response-fields"] ==== === 프로젝트 생성 (POST /projects) -==== 201 Created + ==== operation::project-controller-test/create-project[snippets="http-request,http-response,request-fields,response-fields"] ==== +=== 프로젝트 엑셀 일괄등록 (POST /projects/excel) + +==== +operation::project-excel-controller-test/create-project-excel[snippets="http-request,request-parts,http-response,response-fields"] +==== + === 프로젝트 조회 (GET /projects/{projectId}) -==== 200 OK + ==== operation::project-controller-test/get-project[snippets="http-request,http-response,path-parameters,response-fields"] ==== === 프로젝트 수정 (PUT /projects/{projectId}) -==== 200 OK + ==== operation::project-controller-test/update-project[snippets="http-request,http-response,path-parameters,request-fields,response-fields"] ==== === 프로젝트 삭제 (DELETE /projects/{projectId}) -==== 204 No Content + ==== operation::project-controller-test/delete-project[snippets="http-request,http-response,path-parameters"] ==== === 관심 프로젝트 등록 (POST /projects/{projectId}/favorite) -==== 201 Created + ==== operation::project-controller-test/create-project-favorite[snippets="http-request,http-response,path-parameters"] ==== === 관심 프로젝트 삭제 (DELETE /projects/{projectId}/favorite) -==== 204 No Content + ==== operation::project-controller-test/delete-project-favorite[snippets="http-request,http-response,path-parameters"] ==== === 프로젝트 좋아요 등록 (POST /projects/{projectId}/like) -==== 201 Created + ==== operation::project-controller-test/create-project-like[snippets="http-request,http-response,path-parameters"] ==== === 프로젝트 좋아요 삭제 (DELETE /projects/{projectId}/like) -==== 204 No Content + ==== operation::project-controller-test/delete-project-like[snippets="http-request,http-response,path-parameters"] ==== === 프로젝트 댓글 등록 (POST /projects/{projectId}/comment) -==== 201 Created + ==== operation::project-controller-test/create-project-comment[snippets="http-request,http-response,path-parameters,request-fields,response-fields"] ==== === 프로젝트 댓글 삭제 (DELETE /projects/{projectId}/comment) -==== 204 No Content + ==== operation::project-controller-test/delete-project-comment[snippets="http-request,http-response,path-parameters"] ==== === 수상 프로젝트 조회 (GET /projects/award?year={year}) -==== 200 No Content + ==== operation::project-controller-test/get-award-projects[snippets="http-request,http-response,query-parameters,response-fields"] -==== \ No newline at end of file +==== diff --git a/src/main/java/com/scg/stop/file/controller/FileController.java b/src/main/java/com/scg/stop/file/controller/FileController.java index 03e3916f..fe4ac30f 100644 --- a/src/main/java/com/scg/stop/file/controller/FileController.java +++ b/src/main/java/com/scg/stop/file/controller/FileController.java @@ -1,22 +1,25 @@ package com.scg.stop.file.controller; +import com.scg.stop.auth.annotation.AuthUser; import com.scg.stop.file.domain.File; import com.scg.stop.file.dto.response.FileResponse; import com.scg.stop.file.service.FileService; -import java.io.InputStream; -import java.util.List; +import com.scg.stop.user.domain.AccessType; +import com.scg.stop.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.core.io.InputStreamResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; 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.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestPart; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.util.UriUtils; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; @RestController @RequiredArgsConstructor @@ -39,4 +42,19 @@ public ResponseEntity getFile(@PathVariable("fileId") Long .contentType(MediaType.parseMediaType(file.getMimeType())) .body(new InputStreamResource(stream)); } + + @GetMapping("/form/projects") + public ResponseEntity getProjectExcelForm(@AuthUser(accessType = AccessType.ADMIN) User user) { + String directoryPath = "form/"; + String fileName = "project_upload_form.xlsx"; + Resource resource = fileService.getLocalFile(directoryPath, fileName); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentDispositionFormData("attachment", UriUtils.encode(fileName, StandardCharsets.UTF_8)); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + + return ResponseEntity.ok() + .headers(headers) + .body(resource); + } } diff --git a/src/main/java/com/scg/stop/file/service/FileService.java b/src/main/java/com/scg/stop/file/service/FileService.java index 243474d7..78346fff 100644 --- a/src/main/java/com/scg/stop/file/service/FileService.java +++ b/src/main/java/com/scg/stop/file/service/FileService.java @@ -1,19 +1,28 @@ package com.scg.stop.file.service; import static com.scg.stop.global.exception.ExceptionCode.FILE_NOT_FOUND; +import static com.scg.stop.global.exception.ExceptionCode.INVALID_FILE_PATH; import com.scg.stop.file.domain.File; import com.scg.stop.file.dto.response.FileResponse; import com.scg.stop.file.repository.FileRepository; import com.scg.stop.global.exception.BadRequestException; +import com.scg.stop.global.exception.InternalServerErrorException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ResourceUtils; import org.springframework.web.multipart.MultipartFile; @Service @@ -53,4 +62,12 @@ public InputStream getFile(Long fileId) { public File getFileMetadata(Long fileId) { return fileRepository.findById(fileId).orElseThrow(() -> new BadRequestException(FILE_NOT_FOUND)); } + + public Resource getLocalFile(String directoryPath, String fileName) { + ClassPathResource file = new ClassPathResource(directoryPath + fileName); + if (!file.exists()) { + throw new InternalServerErrorException(FILE_NOT_FOUND); + } + return file; + } } diff --git a/src/main/java/com/scg/stop/global/excel/ExcelUtil.java b/src/main/java/com/scg/stop/global/excel/ExcelUtil.java index 03304c9e..22c640ee 100644 --- a/src/main/java/com/scg/stop/global/excel/ExcelUtil.java +++ b/src/main/java/com/scg/stop/global/excel/ExcelUtil.java @@ -9,7 +9,6 @@ import java.lang.reflect.Field; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -22,13 +21,12 @@ public Excel toExcel(String filename, SXSSFWorkbook workbook) { } - public String getFilename(Workbook workbook, Class clazz) { LocalDateTime time = LocalDateTime.now(); - if( workbook instanceof SXSSFWorkbook) { - return String.format("%s-%s.xlsx",clazz.getDeclaredAnnotation(ExcelDownload.class).fileName(), time); + if (workbook instanceof SXSSFWorkbook) { + return String.format("%s-%s.xlsx", clazz.getDeclaredAnnotation(ExcelDownload.class).fileName(), time); } - return String.format("%s-%s.xls",clazz.getDeclaredAnnotation(ExcelDownload.class).fileName(), time); + return String.format("%s-%s.xls", clazz.getDeclaredAnnotation(ExcelDownload.class).fileName(), time); } public SXSSFWorkbook createExcel(List lists, Class clazz) { @@ -39,10 +37,10 @@ public SXSSFWorkbook createExcel(List lists, Class clazz) { Row row = sheet.createRow(rowNum++); List headers = Arrays.stream(clazz.getDeclaredFields()) .filter(field -> field.isAnnotationPresent(ExcelColumn.class)) - .map( field -> field.getAnnotation(ExcelColumn.class).headerName()) + .map(field -> field.getAnnotation(ExcelColumn.class).headerName()) .toList(); renderHeaderRow(row, headers); - for(T data: lists) { + for (T data : lists) { row = sheet.createRow(rowNum++); renderBodyRow(row, data, clazz); } @@ -55,7 +53,7 @@ public SXSSFWorkbook append(SXSSFWorkbook workbook, List lists, Class ); int rowNum = sheet.getLastRowNum() + 1; Row row; - for(T data: lists) { + for (T data : lists) { row = sheet.createRow(rowNum++); renderBodyRow(row, data, clazz); } @@ -68,7 +66,7 @@ private SXSSFWorkbook createWorkBook() { private void renderHeaderRow(Row firstRow, List headers) { int cellIdx = 0; - for(String header: headers) { + for (String header : headers) { Cell headerCell = firstRow.createCell(cellIdx++); setHeaderCellStyle(headerCell); renderCellValue(headerCell, header); @@ -78,7 +76,7 @@ private void renderHeaderRow(Row firstRow, List headers) { private void renderBodyRow(Row row, T data, Class clazz) { Field[] fields = clazz.getDeclaredFields(); int cellIdx = 0; - for(Field field: fields) { + for (Field field : fields) { Cell cell = row.createCell(cellIdx++); Object value; field.setAccessible(true); @@ -93,7 +91,7 @@ private void renderBodyRow(Row row, T data, Class clazz) { } private void renderCellValue(Cell cell, Object value) { - if(value instanceof Number num) { + if (value instanceof Number num) { cell.setCellValue(num.doubleValue()); return; } diff --git a/src/main/java/com/scg/stop/global/exception/BadRequestException.java b/src/main/java/com/scg/stop/global/exception/BadRequestException.java index 18b78f47..793781f5 100644 --- a/src/main/java/com/scg/stop/global/exception/BadRequestException.java +++ b/src/main/java/com/scg/stop/global/exception/BadRequestException.java @@ -12,4 +12,9 @@ public BadRequestException(final ExceptionCode exceptionCode) { this.code = exceptionCode.getCode(); this.message = exceptionCode.getMessage(); } + + public BadRequestException(final ExceptionCode exceptionCode, final String customMessage) { + this.code = exceptionCode.getCode(); + this.message = customMessage; + } } diff --git a/src/main/java/com/scg/stop/global/exception/ExceptionCode.java b/src/main/java/com/scg/stop/global/exception/ExceptionCode.java index 43483cf1..ee9e5258 100644 --- a/src/main/java/com/scg/stop/global/exception/ExceptionCode.java +++ b/src/main/java/com/scg/stop/global/exception/ExceptionCode.java @@ -18,9 +18,9 @@ public enum ExceptionCode { UNABLE_TO_GET_USER_INFO(2001, "소셜 로그인 공급자로부터 유저 정보를 받아올 수 없습니다."), UNABLE_TO_GET_ACCESS_TOKEN(2002, "소셜 로그인 공급자로부터 인증 토큰을 받아올 수 없습니다."), UNAUTHORIZED_ACCESS(3000, "접근할 수 없는 리소스입니다."), - INVALID_REFRESH_TOKEN(3001,"유효하지 않은 Refresh Token 입니다."), - FAILED_TO_VALIDATE_TOKEN(3002,"토큰 검증에 실패했습니다."), - INVALID_ACCESS_TOKEN(3003,"유효하지 않은 Access Token 입니다."), + INVALID_REFRESH_TOKEN(3001, "유효하지 않은 Refresh Token 입니다."), + FAILED_TO_VALIDATE_TOKEN(3002, "토큰 검증에 실패했습니다."), + INVALID_ACCESS_TOKEN(3003, "유효하지 않은 Access Token 입니다."), // notion domain FAILED_TO_FETCH_NOTION_DATA(13000, "Notion 데이터를 가져오는데 실패했습니다."), @@ -49,11 +49,26 @@ public enum ExceptionCode { NOT_FOUND_COMMENT(77010, "댓글을 찾을 수 없습니다"), NOT_MATCH_USER(77011, "유저 정보가 일치하지 않습니다"), + // project excel + INVALID_FILE_SIZE(78000, "엑셀 행의 개수와 업로드한 이미지의 개수가 일치해야합니다."), + INVALID_THUMBNAIL_NAME(78001, "썸네일 이미지 이름을 찾을 수 없습니다."), + INVALID_POSTER_NAME(78002, "포스터 이미지 이름을 찾을 수 없습니다."), + INVALID_AWARD_STATUS_KOREAN_NAME(78003, "수상 내역의 한글 이름이 올바르지 않습니다."), + INVALID_PROJECT_TYPE_KOREAN_NAME(78004, "프로젝트 종류의 한글 이름이 올바르지 않습니다."), + INVALID_PROJECT_CATEGORY_KOREAN_NAME(78005, "프로젝트 분야의 한글 이름이 올바르지 않습니다."), + EMPTY_CELL(78006, "모든 셀은 값이 있어야 합니다."), + INVALID_EXCEL_FORMAT(78007, "엑셀 형식이 올바르지 않습니다."), + DUPLICATE_THUMBNAIL_ID(78008, "중복된 썸네일 이미지 이름이 존재합니다."), + DUPLICATE_POSTER_ID(78009, "중복된 포스터 이미지 이름이 존재합니다."), + INVALID_YEAR_FORMAT(780010, "프로젝트 년도는 숫자만 입력해야 합니다."), + INVALID_EXCEL(780011, "엑셀 파일을 열 수 없습니다."), + // file domain FAILED_TO_UPLOAD_FILE(5000, "파일 업로드를 실패했습니다."), FAILED_TO_GET_FILE(5001, "파일 가져오기를 실패했습니다."), FILE_NOT_FOUND(5002, "요청한 ID에 해당하는 파일이 존재하지 않습니다."), NOT_FOUND_FILE_ID(5002, "요청한 ID에 해당하는 파일이 존재하지 않습니다."), + INVALID_FILE_PATH(5004, "파일을 찾을 수 없습니다."), // notice domain NOTICE_NOT_FOUND(10000, "요청한 ID에 해당하는 공지사항이 존재하지 않습니다."), @@ -66,7 +81,7 @@ public enum ExceptionCode { UNAUTHORIZED_USER(8003, "해당 문의에 대한 권한이 없습니다."), // video domain - ID_NOT_FOUND(8200,"해당 ID에 해당하는 잡페어 인터뷰가 없습니다."), + ID_NOT_FOUND(8200, "해당 ID에 해당하는 잡페어 인터뷰가 없습니다."), TALK_ID_NOT_FOUND(8400, "해당 ID에 해당하는 대담 영상이 없습니다."), NO_QUIZ(8401, "퀴즈 데이터가 존재하지 않습니다."), NOT_FOUND_USER_QUIZ(8402, "퀴즈 제출 데이터가 존재하지 않습니다."), diff --git a/src/main/java/com/scg/stop/project/controller/ProjectExcelController.java b/src/main/java/com/scg/stop/project/controller/ProjectExcelController.java new file mode 100644 index 00000000..99b2bdbf --- /dev/null +++ b/src/main/java/com/scg/stop/project/controller/ProjectExcelController.java @@ -0,0 +1,37 @@ +package com.scg.stop.project.controller; + +import com.scg.stop.auth.annotation.AuthUser; +import com.scg.stop.project.dto.response.FileResponse; +import com.scg.stop.project.dto.response.ProjectExcelResponse; +import com.scg.stop.project.service.ProjectExcelService; +import com.scg.stop.user.domain.AccessType; +import com.scg.stop.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/projects/excel") +public class ProjectExcelController { + + private final ProjectExcelService projectExcelService; + + @PostMapping + public ResponseEntity createProjectExcel( + @RequestPart("excel") MultipartFile excelFile, + @RequestPart("thumbnails") List thumbnails, + @RequestPart("posters") List posters, + @AuthUser(accessType = {AccessType.ADMIN}) User user + ) { + ProjectExcelResponse projectExcelResponse = projectExcelService.createProjectExcel(excelFile, thumbnails, posters); + return ResponseEntity.status(HttpStatus.CREATED).body(projectExcelResponse); + } +} diff --git a/src/main/java/com/scg/stop/project/domain/AwardStatus.java b/src/main/java/com/scg/stop/project/domain/AwardStatus.java index 98dd5f78..c6c3ef93 100644 --- a/src/main/java/com/scg/stop/project/domain/AwardStatus.java +++ b/src/main/java/com/scg/stop/project/domain/AwardStatus.java @@ -1,11 +1,38 @@ package com.scg.stop.project.domain; +import com.scg.stop.global.exception.BadRequestException; + +import java.util.HashMap; +import java.util.Map; + +import static com.scg.stop.global.exception.ExceptionCode.INVALID_AWARD_STATUS_KOREAN_NAME; + public enum AwardStatus { - NONE, - FIRST, // 대상 - SECOND, // 최우수상 - THIRD, // 우수상 - FOURTH, // 장려상 - FIFTH // 인기상 + NONE("없음"), + FIRST("대상"), + SECOND("최우수상"), + THIRD("우수상"), + FOURTH("장려상"), + FIFTH("인기상"); + + private static final Map KOREAN_NAME_MAP = new HashMap<>(); + private final String koreanName; + + static { + for (AwardStatus awardStatus : AwardStatus.values()) { + KOREAN_NAME_MAP.put(awardStatus.koreanName, awardStatus); + } + } + + AwardStatus(String koreanName) { + this.koreanName = koreanName; + } + + public static AwardStatus fromKoreanName(String koreanName) { + if (!KOREAN_NAME_MAP.containsKey(koreanName)) { + throw new BadRequestException(INVALID_AWARD_STATUS_KOREAN_NAME, String.format("수상 내역의 한글 이름이 올바르지 않습니다 : %s", koreanName)); + } + return KOREAN_NAME_MAP.get(koreanName); + } } diff --git a/src/main/java/com/scg/stop/project/domain/ProjectCategory.java b/src/main/java/com/scg/stop/project/domain/ProjectCategory.java index a6cedcdb..f375d5b0 100644 --- a/src/main/java/com/scg/stop/project/domain/ProjectCategory.java +++ b/src/main/java/com/scg/stop/project/domain/ProjectCategory.java @@ -1,13 +1,40 @@ package com.scg.stop.project.domain; +import com.scg.stop.global.exception.BadRequestException; + +import java.util.HashMap; +import java.util.Map; + +import static com.scg.stop.global.exception.ExceptionCode.INVALID_PROJECT_CATEGORY_KOREAN_NAME; + public enum ProjectCategory { - COMPUTER_VISION, - SYSTEM_NETWORK, - WEB_APPLICATION, - SECURITY_SOFTWARE_ENGINEERING, - NATURAL_LANGUAGE_PROCESSING, - BIG_DATA_ANALYSIS, - AI_MACHINE_LEARNING, - INTERACTION_AUGMENTED_REALITY + COMPUTER_VISION("컴퓨터비전"), + SYSTEM_NETWORK("시스템/네트워크"), + WEB_APPLICATION("웹/어플리케이션"), + SECURITY_SOFTWARE_ENGINEERING("보안/SW공학"), + NATURAL_LANGUAGE_PROCESSING("자연어처리"), + BIG_DATA_ANALYSIS("빅데이터분석"), + AI_MACHINE_LEARNING("AI/머신러닝"), + INTERACTION_AUGMENTED_REALITY("인터렉션/증강현실"); + + private static final Map KOREAN_NAME_MAP = new HashMap<>(); + private final String koreanName; + + static { + for (ProjectCategory projectCategory : ProjectCategory.values()) { + KOREAN_NAME_MAP.put(projectCategory.koreanName, projectCategory); + } + } + + ProjectCategory(String koreanName) { + this.koreanName = koreanName; + } + + public static ProjectCategory fromKoreanName(String koreanName) { + if (!KOREAN_NAME_MAP.containsKey(koreanName)) { + throw new BadRequestException(INVALID_PROJECT_CATEGORY_KOREAN_NAME, String.format("프로젝트 분야의 한글 이름이 올바르지 않습니다 : %s", koreanName)); + } + return KOREAN_NAME_MAP.get(koreanName); + } } diff --git a/src/main/java/com/scg/stop/project/domain/ProjectType.java b/src/main/java/com/scg/stop/project/domain/ProjectType.java index a0239bfe..437649c4 100644 --- a/src/main/java/com/scg/stop/project/domain/ProjectType.java +++ b/src/main/java/com/scg/stop/project/domain/ProjectType.java @@ -1,9 +1,36 @@ package com.scg.stop.project.domain; +import com.scg.stop.global.exception.BadRequestException; + +import java.util.HashMap; +import java.util.Map; + +import static com.scg.stop.global.exception.ExceptionCode.INVALID_PROJECT_TYPE_KOREAN_NAME; + public enum ProjectType { - RESEARCH_AND_BUSINESS_FOUNDATION, - LAB, - STARTUP, - CLUB + RESEARCH_AND_BUSINESS_FOUNDATION("산학"), + LAB("연구실"), + STARTUP("창업/SPARK"), + CLUB("동아리"); + + private static final Map KOREAN_NAME_MAP = new HashMap<>(); + private final String koreanName; + + static { + for (ProjectType projectType : ProjectType.values()) { + KOREAN_NAME_MAP.put(projectType.koreanName, projectType); + } + } + + ProjectType(String koreanName) { + this.koreanName = koreanName; + } + + public static ProjectType fromKoreanName(String koreanName) { + if (!KOREAN_NAME_MAP.containsKey(koreanName)) { + throw new BadRequestException(INVALID_PROJECT_TYPE_KOREAN_NAME, String.format("프로젝트 종류의 한글 이름이 올바르지 않습니다 : %s", koreanName)); + } + return KOREAN_NAME_MAP.get(koreanName); + } } diff --git a/src/main/java/com/scg/stop/project/dto/request/ProjectRequest.java b/src/main/java/com/scg/stop/project/dto/request/ProjectRequest.java index dc0513f2..385fb30d 100644 --- a/src/main/java/com/scg/stop/project/dto/request/ProjectRequest.java +++ b/src/main/java/com/scg/stop/project/dto/request/ProjectRequest.java @@ -2,9 +2,6 @@ import com.scg.stop.file.domain.File; import com.scg.stop.project.domain.*; -import com.scg.stop.global.exception.BadRequestException; -import com.scg.stop.global.exception.ExceptionCode; -import com.scg.stop.project.domain.*; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -82,7 +79,7 @@ public ProjectRequest( } public Project toEntity(Long id, File thumbnail, File poster) { - Project project = new Project( + Project project = new Project( id, projectName, projectType, @@ -110,4 +107,4 @@ public Project toEntity(Long id, File thumbnail, File poster) { return project; } -} \ No newline at end of file +} diff --git a/src/main/java/com/scg/stop/project/dto/response/ProjectDetailResponse.java b/src/main/java/com/scg/stop/project/dto/response/ProjectDetailResponse.java index fbc22f23..10c3195b 100644 --- a/src/main/java/com/scg/stop/project/dto/response/ProjectDetailResponse.java +++ b/src/main/java/com/scg/stop/project/dto/response/ProjectDetailResponse.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -32,7 +31,7 @@ public class ProjectDetailResponse { private String url; private String description; - public static ProjectDetailResponse of(User user, Project project){ + public static ProjectDetailResponse of(User user, Project project) { List studentNames = project.getMembers().stream() .filter(member -> member.getRole() == Role.STUDENT) .map(Member::getName) diff --git a/src/main/java/com/scg/stop/project/dto/response/ProjectExcelResponse.java b/src/main/java/com/scg/stop/project/dto/response/ProjectExcelResponse.java new file mode 100644 index 00000000..78fa67b3 --- /dev/null +++ b/src/main/java/com/scg/stop/project/dto/response/ProjectExcelResponse.java @@ -0,0 +1,10 @@ +package com.scg.stop.project.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ProjectExcelResponse { + private int successCount; +} diff --git a/src/main/java/com/scg/stop/project/dto/response/ProjectResponse.java b/src/main/java/com/scg/stop/project/dto/response/ProjectResponse.java index 97609c49..3ab9626d 100644 --- a/src/main/java/com/scg/stop/project/dto/response/ProjectResponse.java +++ b/src/main/java/com/scg/stop/project/dto/response/ProjectResponse.java @@ -5,7 +5,6 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -28,7 +27,7 @@ public class ProjectResponse { private String url; private String description; - public static ProjectResponse of(User user, Project project){ + public static ProjectResponse of(User user, Project project) { List studentNames = project.getMembers().stream() .filter(member -> member.getRole() == Role.STUDENT) .map(Member::getName) diff --git a/src/main/java/com/scg/stop/project/service/ProjectExcelService.java b/src/main/java/com/scg/stop/project/service/ProjectExcelService.java new file mode 100644 index 00000000..af923ae5 --- /dev/null +++ b/src/main/java/com/scg/stop/project/service/ProjectExcelService.java @@ -0,0 +1,206 @@ +package com.scg.stop.project.service; + +import com.scg.stop.global.exception.BadRequestException; +import com.scg.stop.global.exception.InternalServerErrorException; +import com.scg.stop.project.domain.AwardStatus; +import com.scg.stop.project.domain.ProjectCategory; +import com.scg.stop.project.domain.ProjectType; +import com.scg.stop.project.domain.Role; +import com.scg.stop.project.dto.request.MemberRequest; +import com.scg.stop.project.dto.request.ProjectRequest; +import com.scg.stop.project.dto.response.FileResponse; +import com.scg.stop.project.dto.response.ProjectExcelResponse; +import lombok.RequiredArgsConstructor; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.text.Normalizer; +import java.util.*; + +import static com.scg.stop.global.exception.ExceptionCode.*; + +@Service +@Transactional +@RequiredArgsConstructor +public class ProjectExcelService { + + private final ProjectService projectService; + + private static final int COLUMN_SIZE = 13; + + public ProjectExcelResponse createProjectExcel(MultipartFile excelFile, List thumbnails, List posters) { + try (XSSFWorkbook workbook = new XSSFWorkbook(excelFile.getInputStream())) { + XSSFSheet sheet = workbook.getSheetAt(0); + validateRequestSize(sheet, thumbnails.size(), posters.size()); + + // ProjectRequest DTO로 변환 + Map headerMap = getHeaderMap(sheet); + List projectRequests = convertExcelToDtoList(sheet, headerMap, thumbnails, posters); + validateNoDuplicateFile(projectRequests); + + // 프로젝트 생성 + projectRequests.forEach(projectRequest -> projectService.createProject(projectRequest, null)); + return new ProjectExcelResponse(projectRequests.size()); + } catch (IOException e) { + throw new InternalServerErrorException(INVALID_EXCEL); + } catch (BadRequestException e) { + throw new BadRequestException(INVALID_EXCEL_FORMAT, e.getMessage()); + } + } + + private List convertExcelToDtoList(XSSFSheet sheet, Map headerMap, List thumbnails, List posters) { + List projectRequests = new ArrayList<>(); + for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) { + Row row = sheet.getRow(rowIndex); + if (isRowEmpty(row)) { + continue; + } + try { + validateNoEmptyShell(row); + projectRequests.add(convertRowToDto(row, headerMap, thumbnails, posters)); + } catch (BadRequestException e) { + throw new BadRequestException(INVALID_EXCEL_FORMAT, String.format("%d행의 형식이 올바르지 않습니다: %s", rowIndex + 1, e.getMessage())); + } + } + return projectRequests; + } + + private ProjectRequest convertRowToDto(Row row, Map headerMap, List thumbnails, List posters) { + String projectName = row.getCell(headerMap.get("프로젝트명")).getStringCellValue().strip(); + String projectTypeStr = row.getCell(headerMap.get("프로젝트 종류")).getStringCellValue().strip(); + String projectCategoryStr = row.getCell(headerMap.get("프로젝트 분야")).getStringCellValue().strip(); + String teamName = row.getCell(headerMap.get("참가팀명")).getStringCellValue().strip(); + String professors = row.getCell(headerMap.get("담당 교수")).getStringCellValue().strip(); + String students = row.getCell(headerMap.get("학생")).getStringCellValue().strip(); + String youtubeId = row.getCell(headerMap.get("유튜브 아이디")).getStringCellValue().strip(); + String url = row.getCell(headerMap.get("웹사이트")).getStringCellValue().strip(); + String description = row.getCell(headerMap.get("간략 설명")).getStringCellValue().strip(); + Integer year = validateAndParseNumericCellValue(row.getCell(headerMap.get("프로젝트 년도"))); + String awardStatusStr = row.getCell(headerMap.get("수상 내역")).getStringCellValue().strip(); + String thumbnailImageName = row.getCell(headerMap.get("썸네일 이미지")).getStringCellValue().strip(); + String posterImageName = row.getCell(headerMap.get("포스터 이미지")).getStringCellValue().strip(); + + // 이미지 이름으로 아이디 검색 + Long thumbnailId = thumbnails.stream() + .filter(thumbnail -> normalize(thumbnail.getName()).equals(normalize(thumbnailImageName))) + .map(FileResponse::getId) + .findFirst() + .orElseThrow(() -> new BadRequestException(INVALID_THUMBNAIL_NAME)); + Long posterId = posters.stream() + .filter(poster -> normalize(poster.getName()).equals(normalize(posterImageName))) + .map(FileResponse::getId) + .findFirst() + .orElseThrow(() -> new BadRequestException(INVALID_POSTER_NAME)); + + // enum 변환 + ProjectType projectType = ProjectType.fromKoreanName(projectTypeStr); + ProjectCategory projectCategory = ProjectCategory.fromKoreanName(projectCategoryStr); + AwardStatus awardStatus = AwardStatus.fromKoreanName(awardStatusStr); + + // 교수 이름, 학생 이름 -> List + List members = new ArrayList<>(); + Arrays.stream(professors.split(",")).forEach(name -> members.add(new MemberRequest(name.strip(), Role.PROFESSOR))); + Arrays.stream(students.split(",")).forEach(name -> members.add(new MemberRequest(name.strip(), Role.STUDENT))); + + return new ProjectRequest( + thumbnailId, + posterId, + projectName, + projectType, + projectCategory, + teamName, + youtubeId, + year, + awardStatus, + members, + url, + description); + } + + private Integer validateAndParseNumericCellValue(Cell cell) { + try { + return (int) cell.getNumericCellValue(); + } catch (Exception e) { + throw new BadRequestException(INVALID_YEAR_FORMAT); + } + } + + private void validateNoEmptyShell(Row row) { + short lastCellNum = row.getLastCellNum(); + if (lastCellNum != COLUMN_SIZE) { + throw new BadRequestException(EMPTY_CELL); + } + for (int cellIndex = 0; cellIndex < lastCellNum; cellIndex++) { + Cell cell = row.getCell(cellIndex); + if (cell == null || cell.getCellType() == CellType.BLANK) { + throw new BadRequestException(EMPTY_CELL); + } + } + } + + private void validateRequestSize(Sheet sheet, int thumbnails, int posters) { + int dataRowCount = 0; + for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) { + if (!isRowEmpty(sheet.getRow(rowIndex))) { + dataRowCount++; + } + } + if (dataRowCount != thumbnails || dataRowCount != posters) { + throw new BadRequestException(INVALID_FILE_SIZE); + } + } + + private void validateNoDuplicateFile(List projectRequests) { + List thumbnailIdList = projectRequests.stream().map(ProjectRequest::getThumbnailId).toList(); + Set thumbnailIdSet = Set.copyOf(thumbnailIdList); + if (thumbnailIdList.size() != thumbnailIdSet.size()) { + throw new BadRequestException(DUPLICATE_THUMBNAIL_ID); + } + + List posterIdList = projectRequests.stream().map(ProjectRequest::getPosterId).toList(); + Set posterIdSet = Set.copyOf(posterIdList); + if (posterIdList.size() != posterIdSet.size()) { + throw new BadRequestException(DUPLICATE_POSTER_ID); + } + } + + private boolean isRowEmpty(Row row) { + if (row == null) { + return true; + } + for (Cell cell : row) { + if (!isCellEmpty(cell)) { + return false; + } + } + return true; + } + + private boolean isCellEmpty(Cell cell) { + return cell == null || cell.getCellType() == CellType.BLANK; + } + + /** + * 문자열 유니코드 정규화 + */ + private String normalize(String input) { + return Normalizer.normalize(input, Normalizer.Form.NFC); + } + + private Map getHeaderMap(XSSFSheet sheet) { + Map headerMap = new HashMap<>(); + Row headerRow = sheet.getRow(0); + for (Cell cell : headerRow) { + headerMap.put(cell.getStringCellValue(), cell.getColumnIndex()); + } + return headerMap; + } +} diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 3318df98..d24c6f97 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -10,7 +10,7 @@ spring: open-in-view: false show-sql: true hibernate: - ddl-auto: create + ddl-auto: update properties: hibernate: default_batch_fetch_size: 15 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d0bf015c..7ef1b5b5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,7 @@ spring: - profiles: - default: local - group: - local: common, oauth, minio, notion, email - prod: common, oauth, minio, notion, email - + profiles: + default: local + group: + local: common, oauth, minio, notion, email + prod: common, oauth, minio, notion, email + dev: common, oauth, minio, notion, email diff --git a/src/main/resources/form/project_upload_form.xlsx b/src/main/resources/form/project_upload_form.xlsx new file mode 100644 index 00000000..178849af Binary files /dev/null and b/src/main/resources/form/project_upload_form.xlsx differ diff --git a/src/main/resources/static/docs/aiHub-controller-test.html b/src/main/resources/static/docs/aihub-controller-test.html similarity index 99% rename from src/main/resources/static/docs/aiHub-controller-test.html rename to src/main/resources/static/docs/aihub-controller-test.html index 5025b31d..2e5d3de5 100644 --- a/src/main/resources/static/docs/aiHub-controller-test.html +++ b/src/main/resources/static/docs/aihub-controller-test.html @@ -566,10 +566,8 @@

HTTP response

Content-Length: 1221 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "title" : "title", @@ -600,7 +598,6 @@

HTTP response

"sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -613,6 +610,9 @@

HTTP response

"paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -944,10 +944,8 @@

HTTP response

Content-Length: 1217 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "title" : "title", @@ -978,7 +976,6 @@

HTTP response

"sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -991,6 +988,9 @@

HTTP response

"paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -1206,7 +1206,7 @@

Response fields

diff --git a/src/main/resources/static/docs/application.html b/src/main/resources/static/docs/application.html index 5bef031e..6fa4003b 100644 --- a/src/main/resources/static/docs/application.html +++ b/src/main/resources/static/docs/application.html @@ -497,13 +497,11 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 1176 +Content-Length: 1178 { - "totalElements" : 3, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 3, "size" : 10, "content" : [ { "id" : 1, @@ -511,24 +509,24 @@

HTTP response

"division" : "배민", "position" : null, "userType" : "INACTIVE_COMPANY", - "createdAt" : "2024-10-29T22:38:57.12596", - "updatedAt" : "2024-10-29T22:38:57.125962" + "createdAt" : "2024-11-18T19:55:54.259219", + "updatedAt" : "2024-11-18T19:55:54.259222" }, { "id" : 2, "name" : "김교수", "division" : "솦융대", "position" : "교수", "userType" : "INACTIVE_PROFESSOR", - "createdAt" : "2024-10-29T22:38:57.12597", - "updatedAt" : "2024-10-29T22:38:57.125972" + "createdAt" : "2024-11-18T19:55:54.259235", + "updatedAt" : "2024-11-18T19:55:54.259235" }, { "id" : 3, "name" : "박교수", "division" : "정통대", "position" : "교수", "userType" : "INACTIVE_PROFESSOR", - "createdAt" : "2024-10-29T22:38:57.125975", - "updatedAt" : "2024-10-29T22:38:57.125975" + "createdAt" : "2024-11-18T19:55:54.259245", + "updatedAt" : "2024-11-18T19:55:54.259246" } ], "number" : 0, "sort" : { @@ -536,7 +534,6 @@

HTTP response

"sorted" : false, "unsorted" : true }, - "numberOfElements" : 3, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -549,6 +546,9 @@

HTTP response

"paged" : true, "unpaged" : false }, + "numberOfElements" : 3, + "first" : true, + "last" : true, "empty" : false } @@ -796,8 +796,8 @@

HTTP response

"division" : "배민", "position" : "CEO", "userType" : "INACTIVE_COMPANY", - "createdAt" : "2024-10-29T22:38:57.150487", - "updatedAt" : "2024-10-29T22:38:57.150489" + "createdAt" : "2024-11-18T19:55:54.344894", + "updatedAt" : "2024-11-18T19:55:54.344897" } @@ -926,7 +926,7 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 262 +Content-Length: 263 { "id" : 1, @@ -936,8 +936,8 @@

HTTP response

"division" : "배민", "position" : "CEO", "userType" : "COMPANY", - "createdAt" : "2024-10-29T22:38:57.14394", - "updatedAt" : "2024-10-29T22:38:57.143942" + "createdAt" : "2024-11-18T19:55:54.328644", + "updatedAt" : "2024-11-18T19:55:54.328648" } @@ -1077,7 +1077,7 @@

HTTP response

diff --git a/src/main/resources/static/docs/auth-controller-test.html b/src/main/resources/static/docs/auth-controller-test.html index 870be9e4..355afd9e 100644 --- a/src/main/resources/static/docs/auth-controller-test.html +++ b/src/main/resources/static/docs/auth-controller-test.html @@ -489,17 +489,35 @@

HTTP response

Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers -Set-Cookie: refresh-token=refresh_token; Path=/; Max-Age=604800; Expires=Tue, 5 Nov 2024 13:38:54 GMT; Secure; HttpOnly; SameSite=None -Set-Cookie: access-token=access_token; Path=/; Max-Age=604800; Expires=Tue, 5 Nov 2024 13:38:54 GMT; Secure; SameSite=None +Set-Cookie: refresh-token=refresh_token; Path=/; Max-Age=604800; Expires=Mon, 25 Nov 2024 10:55:46 GMT; Secure; HttpOnly; SameSite=None +Set-Cookie: access-token=access_token; Path=/; Max-Age=604800; Expires=Mon, 25 Nov 2024 10:55:46 GMT; Secure; SameSite=None Location: https://localhost:3000/login/kakao

Response fields

-
-

Snippet response-fields not found for operation::auth-controller-test/kakao-social-login

-
+ +++++ + + + + + + + + + + + + + + +
PathTypeDescription

accessToken

String

access token

@@ -785,7 +803,7 @@

HTTP response

diff --git a/src/main/resources/static/docs/department.html b/src/main/resources/static/docs/department.html new file mode 100644 index 00000000..2679ba6e --- /dev/null +++ b/src/main/resources/static/docs/department.html @@ -0,0 +1,524 @@ + + + + + + + +학과 API + + + + + +
+
+

학과 API

+
+
+
+

학과 리스트 조회 (GET /departments)

+
+
+
+

HTTP request

+
+
+
GET /departments HTTP/1.1
+Content-Type: application/json;charset=UTF-8
+Host: localhost:8080
+
+
+
+
+

HTTP response

+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Type: application/json
+Content-Length: 92
+
+[ {
+  "id" : 1,
+  "name" : "소프트웨어학과"
+}, {
+  "id" : 2,
+  "name" : "학과2"
+} ]
+
+
+
+
+

Response fields

+ +++++ + + + + + + + + + + + + + + + + + + + +
PathTypeDescription

[].id

Number

학과 ID

[].name

String

학과 이름

+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/static/docs/eventNotice.html b/src/main/resources/static/docs/eventNotice.html index ebc2768e..6f5385f6 100644 --- a/src/main/resources/static/docs/eventNotice.html +++ b/src/main/resources/static/docs/eventNotice.html @@ -521,7 +521,7 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 979 +Content-Length: 980 { "id" : 1, @@ -529,29 +529,29 @@

HTTP response

"content" : "이벤트 공지 사항 내용", "hitCount" : 0, "fixed" : true, - "createdAt" : "2024-10-29T22:38:55.011501", - "updatedAt" : "2024-10-29T22:38:55.011503", + "createdAt" : "2024-11-18T19:55:47.17606", + "updatedAt" : "2024-11-18T19:55:47.176061", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.011484", - "updatedAt" : "2024-10-29T22:38:55.011492" + "createdAt" : "2024-11-18T19:55:47.176039", + "updatedAt" : "2024-11-18T19:55:47.176047" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.011494", - "updatedAt" : "2024-10-29T22:38:55.011496" + "createdAt" : "2024-11-18T19:55:47.176051", + "updatedAt" : "2024-11-18T19:55:47.176053" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.011498", - "updatedAt" : "2024-10-29T22:38:55.0115" + "createdAt" : "2024-11-18T19:55:47.176055", + "updatedAt" : "2024-11-18T19:55:47.176057" } ] } @@ -722,28 +722,26 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 874 +Content-Length: 873 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "id" : 1, "title" : "이벤트 공지 사항 1", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-10-29T22:38:55.024738", - "updatedAt" : "2024-10-29T22:38:55.024743" + "createdAt" : "2024-11-18T19:55:47.21455", + "updatedAt" : "2024-11-18T19:55:47.214557" }, { "id" : 2, "title" : "이벤트 공지 사항 2", "hitCount" : 10, "fixed" : false, - "createdAt" : "2024-10-29T22:38:55.024751", - "updatedAt" : "2024-10-29T22:38:55.024753" + "createdAt" : "2024-11-18T19:55:47.214576", + "updatedAt" : "2024-11-18T19:55:47.214578" } ], "number" : 0, "sort" : { @@ -751,7 +749,6 @@

HTTP response

"sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -764,6 +761,9 @@

HTTP response

"paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -994,7 +994,7 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 958 +Content-Length: 959 { "id" : 1, @@ -1002,29 +1002,29 @@

HTTP response

"content" : "content", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-10-29T22:38:54.991825", - "updatedAt" : "2024-10-29T22:38:54.991827", + "createdAt" : "2024-11-18T19:55:47.117036", + "updatedAt" : "2024-11-18T19:55:47.117038", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:54.991809", - "updatedAt" : "2024-10-29T22:38:54.991815" + "createdAt" : "2024-11-18T19:55:47.117012", + "updatedAt" : "2024-11-18T19:55:47.117022" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:54.991817", - "updatedAt" : "2024-10-29T22:38:54.99182" + "createdAt" : "2024-11-18T19:55:47.117026", + "updatedAt" : "2024-11-18T19:55:47.117029" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:54.991821", - "updatedAt" : "2024-10-29T22:38:54.991823" + "createdAt" : "2024-11-18T19:55:47.117032", + "updatedAt" : "2024-11-18T19:55:47.117034" } ] } @@ -1247,28 +1247,28 @@

HTTP response

"hitCount" : 10, "fixed" : false, "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:54.967831", + "updatedAt" : "2024-11-18T19:55:47.026018", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:54.967785" + "updatedAt" : "2024-11-18T19:55:47.025945" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:54.967795" + "updatedAt" : "2024-11-18T19:55:47.025971" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:54.967803" + "updatedAt" : "2024-11-18T19:55:47.025978" } ] } @@ -1440,7 +1440,7 @@

HTTP response

diff --git a/src/main/resources/static/docs/eventPeriod.html b/src/main/resources/static/docs/eventPeriod.html index bc1433aa..5eab31e0 100644 --- a/src/main/resources/static/docs/eventPeriod.html +++ b/src/main/resources/static/docs/eventPeriod.html @@ -460,8 +460,8 @@

HTTP request

Cookie: refresh-token=refresh_token { - "start" : "2024-10-29T22:38:55.260304", - "end" : "2024-11-08T22:38:55.260308" + "start" : "2024-11-18T19:55:47.738113", + "end" : "2024-11-28T19:55:47.738129" } @@ -513,10 +513,10 @@

HTTP response

{ "id" : 1, "year" : 2024, - "start" : "2024-10-29T22:38:55.260312", - "end" : "2024-11-08T22:38:55.260313", - "createdAt" : "2024-10-29T22:38:55.260315", - "updatedAt" : "2024-10-29T22:38:55.260317" + "start" : "2024-11-18T19:55:47.738137", + "end" : "2024-11-28T19:55:47.738139", + "createdAt" : "2024-11-18T19:55:47.738142", + "updatedAt" : "2024-11-18T19:55:47.738144" } @@ -610,10 +610,10 @@

HTTP response

{ "id" : 1, "year" : 2024, - "start" : "2024-10-29T22:38:55.251774", - "end" : "2024-11-08T22:38:55.251775", - "createdAt" : "2024-10-29T22:38:55.251778", - "updatedAt" : "2024-10-29T22:38:55.25178" + "start" : "2024-11-18T19:55:47.71465", + "end" : "2024-11-28T19:55:47.714653", + "createdAt" : "2024-11-18T19:55:47.714657", + "updatedAt" : "2024-11-18T19:55:47.714659" } @@ -702,22 +702,22 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 416 +Content-Length: 414 [ { "id" : 1, "year" : 2024, - "start" : "2024-10-29T22:38:55.269307", - "end" : "2024-11-08T22:38:55.269311", - "createdAt" : "2024-10-29T22:38:55.269314", - "updatedAt" : "2024-10-29T22:38:55.269315" + "start" : "2024-11-18T19:55:47.776458", + "end" : "2024-11-28T19:55:47.77647", + "createdAt" : "2024-11-18T19:55:47.776475", + "updatedAt" : "2024-11-18T19:55:47.776477" }, { "id" : 2, "year" : 2025, - "start" : "2024-10-29T22:38:55.269317", - "end" : "2024-11-08T22:38:55.269319", - "createdAt" : "2024-10-29T22:38:55.269321", - "updatedAt" : "2024-10-29T22:38:55.269323" + "start" : "2024-11-18T19:55:47.77648", + "end" : "2024-11-28T19:55:47.776481", + "createdAt" : "2024-11-18T19:55:47.776483", + "updatedAt" : "2024-11-18T19:55:47.776485" } ] @@ -798,8 +798,8 @@

HTTP request

Cookie: refresh-token=refresh_token { - "start" : "2024-10-29T22:38:55.233418", - "end" : "2024-11-08T22:38:55.233422" + "start" : "2024-11-18T19:55:47.657836", + "end" : "2024-11-28T19:55:47.657846" } @@ -851,10 +851,10 @@

HTTP response

{ "id" : 1, "year" : 2024, - "start" : "2024-10-29T22:38:55.233454", - "end" : "2024-11-08T22:38:55.233455", - "createdAt" : "2024-10-29T22:38:55.233457", - "updatedAt" : "2024-10-29T22:38:55.233459" + "start" : "2024-11-18T19:55:47.657891", + "end" : "2024-11-28T19:55:47.657893", + "createdAt" : "2024-11-18T19:55:47.657895", + "updatedAt" : "2024-11-18T19:55:47.657897" } @@ -925,7 +925,7 @@

Response fields

diff --git a/src/main/resources/static/docs/exceptionCode.html b/src/main/resources/static/docs/exceptionCode.html new file mode 100644 index 00000000..cf8220c6 --- /dev/null +++ b/src/main/resources/static/docs/exceptionCode.html @@ -0,0 +1,480 @@ + + + + + + + +커스텀 예외 코드 + + + + + +
+
+

커스텀 예외 코드

+
+
+ ++++ + + + + + + + + + + + + + + + + +
CodeMessage

1000

요청 형식이 올바르지 않습니다.

1001

해당 연도의 행사 기간이 이미 존재합니다.

+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/static/docs/file-controller-test.html b/src/main/resources/static/docs/file-controller-test.html index 9513dbc3..335837fc 100644 --- a/src/main/resources/static/docs/file-controller-test.html +++ b/src/main/resources/static/docs/file-controller-test.html @@ -500,22 +500,22 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 446 +Content-Length: 445 [ { "id" : 1, - "uuid" : "e5fd517c-7376-4dce-83ea-693607200e43", + "uuid" : "29efd2b4-7c45-46ce-aa54-d68239b3f35c", "name" : "첨부파일1.png", "mimeType" : "image/png", - "createdAt" : "2024-10-29T22:38:55.703391", - "updatedAt" : "2024-10-29T22:38:55.703395" + "createdAt" : "2024-11-18T19:55:49.208335", + "updatedAt" : "2024-11-18T19:55:49.208345" }, { "id" : 2, - "uuid" : "338f27eb-914c-4ef2-a5b2-6f0d6b7f2053", + "uuid" : "71d5b9f6-2c69-4db1-8055-b6cfd5ef5003", "name" : "첨부파일2.pdf", "mimeType" : "application/pdf", - "createdAt" : "2024-10-29T22:38:55.703419", - "updatedAt" : "2024-10-29T22:38:55.703421" + "createdAt" : "2024-11-18T19:55:49.20852", + "updatedAt" : "2024-11-18T19:55:49.208524" } ] @@ -633,13 +633,47 @@

HTTP response

+
+

프로젝트 일괄 등록 양식 다운로드 (GET /files/form/projects)

+
+
+
+

HTTP request

+
+
+
GET /files/form/projects HTTP/1.1
+Authorization: admin_access_token
+Host: localhost:8080
+Cookie: refresh-token=refresh_token
+
+
+
+
+

HTTP response

+
+
+
HTTP/1.1 200 OK
+Vary: Origin
+Vary: Access-Control-Request-Method
+Vary: Access-Control-Request-Headers
+Content-Disposition: form-data; name="attachment"; filename="project_upload_form.xlsx"
+Content-Type: application/octet-stream;charset=UTF-8
+Content-Length: 19
+
+project_upload_form
+
+
+
+
+
+
diff --git a/src/main/resources/static/docs/gallery.html b/src/main/resources/static/docs/gallery.html index 6e6802b3..33c1ce63 100644 --- a/src/main/resources/static/docs/gallery.html +++ b/src/main/resources/static/docs/gallery.html @@ -522,7 +522,7 @@

HTTP response

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 889 +Content-Length: 891 { "id" : 1, @@ -530,29 +530,29 @@

HTTP response

"year" : 2024, "month" : 4, "hitCount" : 1, - "createdAt" : "2024-10-29T22:38:55.963428", - "updatedAt" : "2024-10-29T22:38:55.96343", + "createdAt" : "2024-11-18T19:55:49.947753", + "updatedAt" : "2024-11-18T19:55:49.947755", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.963412", - "updatedAt" : "2024-10-29T22:38:55.963416" + "createdAt" : "2024-11-18T19:55:49.947735", + "updatedAt" : "2024-11-18T19:55:49.947743" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.963418", - "updatedAt" : "2024-10-29T22:38:55.96342" + "createdAt" : "2024-11-18T19:55:49.947746", + "updatedAt" : "2024-11-18T19:55:49.947747" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.963421", - "updatedAt" : "2024-10-29T22:38:55.963423" + "createdAt" : "2024-11-18T19:55:49.947749", + "updatedAt" : "2024-11-18T19:55:49.947751" } ] } @@ -731,10 +731,8 @@

HTTP response

Content-Length: 1234 { - "totalElements" : 1, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 1, "size" : 1, "content" : [ { "id" : 1, @@ -742,29 +740,29 @@

HTTP response

"year" : 2024, "month" : 4, "hitCount" : 0, - "createdAt" : "2024-10-29T22:38:55.939716", - "updatedAt" : "2024-10-29T22:38:55.939717", + "createdAt" : "2024-11-18T19:55:49.866951", + "updatedAt" : "2024-11-18T19:55:49.866952", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.939702", - "updatedAt" : "2024-10-29T22:38:55.939706" + "createdAt" : "2024-11-18T19:55:49.866926", + "updatedAt" : "2024-11-18T19:55:49.866935" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.939708", - "updatedAt" : "2024-10-29T22:38:55.93971" + "createdAt" : "2024-11-18T19:55:49.866938", + "updatedAt" : "2024-11-18T19:55:49.86694" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.939711", - "updatedAt" : "2024-10-29T22:38:55.939712" + "createdAt" : "2024-11-18T19:55:49.866942", + "updatedAt" : "2024-11-18T19:55:49.866944" } ] } ], "number" : 0, @@ -773,8 +771,10 @@

HTTP response

"sorted" : false, "unsorted" : true }, - "numberOfElements" : 1, "pageable" : "INSTANCE", + "numberOfElements" : 1, + "first" : true, + "last" : true, "empty" : false } @@ -1013,29 +1013,29 @@

HTTP response

"year" : 2024, "month" : 4, "hitCount" : 1, - "createdAt" : "2024-10-29T22:38:55.954566", - "updatedAt" : "2024-10-29T22:38:55.954568", + "createdAt" : "2024-11-18T19:55:49.918362", + "updatedAt" : "2024-11-18T19:55:49.918364", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.954554", - "updatedAt" : "2024-10-29T22:38:55.954558" + "createdAt" : "2024-11-18T19:55:49.918345", + "updatedAt" : "2024-11-18T19:55:49.918351" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.95456", - "updatedAt" : "2024-10-29T22:38:55.954561" + "createdAt" : "2024-11-18T19:55:49.918355", + "updatedAt" : "2024-11-18T19:55:49.918356" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.954563", - "updatedAt" : "2024-10-29T22:38:55.954564" + "createdAt" : "2024-11-18T19:55:49.918358", + "updatedAt" : "2024-11-18T19:55:49.91836" } ] } @@ -1297,29 +1297,29 @@

HTTP response

"year" : 2024, "month" : 5, "hitCount" : 1, - "createdAt" : "2024-10-29T22:38:55.911236", - "updatedAt" : "2024-10-29T22:38:55.911238", + "createdAt" : "2024-11-18T19:55:49.714135", + "updatedAt" : "2024-11-18T19:55:49.714137", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.911175", - "updatedAt" : "2024-10-29T22:38:55.911179" + "createdAt" : "2024-11-18T19:55:49.714027", + "updatedAt" : "2024-11-18T19:55:49.714047" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.911184", - "updatedAt" : "2024-10-29T22:38:55.911185" + "createdAt" : "2024-11-18T19:55:49.714057", + "updatedAt" : "2024-11-18T19:55:49.71406" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:55.91119", - "updatedAt" : "2024-10-29T22:38:55.911191" + "createdAt" : "2024-11-18T19:55:49.714063", + "updatedAt" : "2024-11-18T19:55:49.714065" } ] } @@ -1439,7 +1439,7 @@

Response fields

diff --git a/src/main/resources/static/docs/index.html b/src/main/resources/static/docs/index.html index 7453de6e..46143e8c 100644 --- a/src/main/resources/static/docs/index.html +++ b/src/main/resources/static/docs/index.html @@ -459,6 +459,7 @@

S-TOP Rest Docs

  • 잡페어 인터뷰 API @@ -552,6 +553,7 @@

    S-TOP Rest Docs

    • 프로젝트 조회 (GET /projects)
    • 프로젝트 생성 (POST /projects)
    • +
    • 프로젝트 엑셀 일괄등록 (POST /projects/excel)
    • 프로젝트 조회 (GET /projects/{projectId})
    • 프로젝트 수정 (PUT /projects/{projectId})
    • 프로젝트 삭제 (DELETE /projects/{projectId})
    • @@ -714,6 +716,54 @@

      커스텀 예외 코드

      유저 정보가 일치하지 않습니다

      +

      78000

      +

      엑셀 행의 개수와 업로드한 이미지의 개수가 일치해야합니다.

      + + +

      78001

      +

      썸네일 이미지 이름을 찾을 수 없습니다.

      + + +

      78002

      +

      포스터 이미지 이름을 찾을 수 없습니다.

      + + +

      78003

      +

      수상 내역의 한글 이름이 올바르지 않습니다.

      + + +

      78004

      +

      프로젝트 종류의 한글 이름이 올바르지 않습니다.

      + + +

      78005

      +

      프로젝트 분야의 한글 이름이 올바르지 않습니다.

      + + +

      78006

      +

      모든 셀은 값이 있어야 합니다.

      + + +

      78007

      +

      엑셀 형식이 올바르지 않습니다.

      + + +

      78008

      +

      중복된 썸네일 이미지 이름이 존재합니다.

      + + +

      78009

      +

      중복된 포스터 이미지 이름이 존재합니다.

      + + +

      780010

      +

      프로젝트 년도는 숫자만 입력해야 합니다.

      + + +

      780011

      +

      엑셀 파일을 열 수 없습니다.

      + +

      5000

      파일 업로드를 실패했습니다.

      @@ -730,6 +780,10 @@

      커스텀 예외 코드

      요청한 ID에 해당하는 파일이 존재하지 않습니다.

      +

      5004

      +

      파일을 찾을 수 없습니다.

      + +

      10000

      요청한 ID에 해당하는 공지사항이 존재하지 않습니다.

      @@ -853,17 +907,35 @@

      HTTP response

      Vary: Origin Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers -Set-Cookie: refresh-token=refresh_token; Path=/; Max-Age=604800; Expires=Wed, 20 Nov 2024 14:55:18 GMT; Secure; HttpOnly; SameSite=None -Set-Cookie: access-token=access_token; Path=/; Max-Age=604800; Expires=Wed, 20 Nov 2024 14:55:18 GMT; Secure; SameSite=None +Set-Cookie: refresh-token=refresh_token; Path=/; Max-Age=604800; Expires=Mon, 25 Nov 2024 10:55:46 GMT; Secure; HttpOnly; SameSite=None +Set-Cookie: access-token=access_token; Path=/; Max-Age=604800; Expires=Mon, 25 Nov 2024 10:55:46 GMT; Secure; SameSite=None Location: https://localhost:3000/login/kakao

      Response fields

      -
      -

      Snippet response-fields not found for operation::auth-controller-test/kakao-social-login

      -
      + +++++ + + + + + + + + + + + + + + +
      PathTypeDescription

      accessToken

      String

      access token

      @@ -1209,18 +1281,18 @@

      HTTP response

      [ { "id" : 1, - "uuid" : "a1691219-b07c-46c6-9dab-d01a92953aac", + "uuid" : "29efd2b4-7c45-46ce-aa54-d68239b3f35c", "name" : "첨부파일1.png", "mimeType" : "image/png", - "createdAt" : "2024-11-13T23:55:19.86685", - "updatedAt" : "2024-11-13T23:55:19.866855" + "createdAt" : "2024-11-18T19:55:49.208335", + "updatedAt" : "2024-11-18T19:55:49.208345" }, { "id" : 2, - "uuid" : "9e0f2c46-5aab-4963-a694-a0b4a2327c3c", + "uuid" : "71d5b9f6-2c69-4db1-8055-b6cfd5ef5003", "name" : "첨부파일2.pdf", "mimeType" : "application/pdf", - "createdAt" : "2024-11-13T23:55:19.866879", - "updatedAt" : "2024-11-13T23:55:19.866881" + "createdAt" : "2024-11-18T19:55:49.20852", + "updatedAt" : "2024-11-18T19:55:49.208524" } ] @@ -1338,6 +1410,40 @@

      HTTP response

      +
      +

      프로젝트 일괄 등록 양식 다운로드 (GET /files/form/projects)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /files/form/projects HTTP/1.1
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Disposition: form-data; name="attachment"; filename="project_upload_form.xlsx"
      +Content-Type: application/octet-stream;charset=UTF-8
      +Content-Length: 19
      +
      +project_upload_form
      +
      +
      +
      +
      +
      +
      @@ -1446,8 +1552,8 @@

      HTTP response

      "talkerBelonging" : "대담자의 소속", "talkerName" : "대담자의 성명", "category" : "INTERN", - "createdAt" : "2024-11-13T23:55:21.665471", - "updatedAt" : "2024-11-13T23:55:21.665472" + "createdAt" : "2024-11-18T19:55:54.938534", + "updatedAt" : "2024-11-18T19:55:54.938537" }
      @@ -1604,8 +1710,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -1616,8 +1720,8 @@

      HTTP response

      "talkerName" : "대담자의 성명1", "favorite" : false, "category" : "INTERN", - "createdAt" : "2024-11-13T23:55:21.646459", - "updatedAt" : "2024-11-13T23:55:21.64646" + "createdAt" : "2024-11-18T19:55:54.88224", + "updatedAt" : "2024-11-18T19:55:54.882242" }, { "id" : 2, "title" : "잡페어 인터뷰의 제목2", @@ -1627,8 +1731,8 @@

      HTTP response

      "talkerName" : "대담자의 성명2", "favorite" : true, "category" : "INTERN", - "createdAt" : "2024-11-13T23:55:21.646475", - "updatedAt" : "2024-11-13T23:55:21.646475" + "createdAt" : "2024-11-18T19:55:54.882264", + "updatedAt" : "2024-11-18T19:55:54.882265" } ], "number" : 0, "sort" : { @@ -1636,7 +1740,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -1649,6 +1752,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -1916,8 +2022,8 @@

      HTTP response

      "talkerName" : "대담자의 성명", "favorite" : false, "category" : "INTERN", - "createdAt" : "2024-11-13T23:55:21.658362", - "updatedAt" : "2024-11-13T23:55:21.658363" + "createdAt" : "2024-11-18T19:55:54.921774", + "updatedAt" : "2024-11-18T19:55:54.921776" } @@ -2131,7 +2237,7 @@

      HTTP response

      "talkerName" : "수정된 대담자 성명", "category" : "INTERN", "createdAt" : "2021-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:21.627827" + "updatedAt" : "2024-11-18T19:55:54.788456" } @@ -2512,8 +2618,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-11-13T23:55:22.275217", - "updatedAt" : "2024-11-13T23:55:22.275218" + "createdAt" : "2024-11-18T19:55:56.391775", + "updatedAt" : "2024-11-18T19:55:56.391777" } @@ -2683,8 +2789,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 1, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -2703,8 +2807,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-11-13T23:55:22.284266", - "updatedAt" : "2024-11-13T23:55:22.284267" + "createdAt" : "2024-11-18T19:55:56.416019", + "updatedAt" : "2024-11-18T19:55:56.416023" } ], "number" : 0, "sort" : { @@ -2712,7 +2816,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 1, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -2725,6 +2828,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 1, + "first" : true, + "last" : true, "empty" : false } @@ -3018,8 +3124,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-11-13T23:55:22.267111", - "updatedAt" : "2024-11-13T23:55:22.267113" + "createdAt" : "2024-11-18T19:55:56.373952", + "updatedAt" : "2024-11-18T19:55:56.373955" } @@ -3266,7 +3372,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 564 +Content-Length: 565 { "id" : 1, @@ -3284,8 +3390,8 @@

      HTTP response

      "answer" : 0, "options" : [ "수정한 선지1", "수정한 선지2" ] } ], - "createdAt" : "2024-11-13T23:55:22.23066", - "updatedAt" : "2024-11-13T23:55:22.230661" + "createdAt" : "2024-11-18T19:55:56.226099", + "updatedAt" : "2024-11-18T19:55:56.226104" } @@ -3945,8 +4051,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "userId" : 1, @@ -3967,7 +4071,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -3980,6 +4083,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -4215,10 +4321,9 @@

      HTTP response

      �($}��v?�I�Q.���uӂ�h���x>=��@��p�H"�~�}� �n����*"�H�׺؁�����8�Z�^'�#��7m{��O�3���G�u�ܓ�'��y|a�����D� ��l_EYȾ����vql3�ML�eh���*���\3�Y0���oJ׏� :��^��}PK��z��IPK-docProps/app.xmlM�� �0D�~EȽ��ADҔ���A? ��6�lB�J?ߜ���0���ͯ�)�@��׍H6���V>��$;�SC ;̢(�ra�g�l�&�e��L!y�%��49��`_���4G���F��J��Wg �GS�b���� -~�PK�|wؑ�PK-docProps/core.xmlm��J�0F_�依�� mQ�+�w!�b�C����u���%��&_�;�1yG��kB��$�����j����s������XmȮ��e�8<8cх}5�3ak҇`�=*�H���x�Wׁ��wE�����%fajW#9)�X��͍�@ -����f~؀N��d%�~X�i���\����ۛ�e�t�����:��p��$ -X�����䱼�j��)�b�R�Ҳ��ݲ�>W�k~~��k.b!=&���[�+�Ss� PKZ��PK-xl/sharedStrings.xml=�A� ツ��.z0Ɣ�`� �����,�����q2��o�ԇ���N�E��x5�z>�W���(R�K���^4{�����ŀ�5��y�V����y�m�XV�\�.�j���� 8�PKp��&x�PK- xl/styles.xml���n� ��>bop2TQ��P)U�RWb�6*�����ӤS�Nw�s���3ߍ֐ ���t��(l��������ҝx�!N=@$ɀ��}��3c���ʰr`:i��2��w, � -�d �T��R#�voc �;c�iE��Û��E<|��4Iɣ����F#��n���B�z�F���y�j3y��yҥ�jt>���2��Lژ�!6��2F�OY��4@M�!���G��������1�t��y��p��" n����u�����a�ΦDi�9�&#��%I��9��}���cK��T��$?������`J������7���o��f��M|PK�1X@C�PK-xl/workbook.xmlM���0��>E�wi1ƨ����z/�HmI�_j��qf��)ʧٌ��w�LC��ָ��[u��T�b�a��؊;���8�9��G�)��5�|�:�2<8MuK=b�#� q�V�u ����K��H\)�\�&�t͌��%���?��B��T� PK ���PK-xl/_rels/workbook.xml.rels��ͪ1 �_�d�tt!"V7� n������LZ�(����r�� ��p����6�JY���U ����s����;[�E8D&a��h@- ��$� Xt�im���F�*&�41���̭M��ؒ]����WL�f�}��9anIH���Qs1���KtO��ll���O���X߬� �{�ŋ����œ�?o'�>PK�(2��PK-�q,-�[Content_Types].xmlPK-��z��I v_rels/.relsPK-�|wؑ��docProps/app.xmlPK-Z��qdocProps/core.xmlPK-p��&x��xl/sharedStrings.xmlPK-�1X@C� xl/styles.xmlPK- ���xl/workbook.xmlPK-�(2���xl/_rels/workbook.xml.relsPK�� +~�PK�|wؑ�PK-docProps/core.xmlm��J�0F_%依����.�,� �(ޅdl��I��ֵۛ� +�H�;s�L�=ꁼ��55eyA iUoښ>vن��Qb�kj,�6�t\Z�{o��c Ic���]��١!O�I��Z���-8!_E�P�9h�B�(`fn1ғR�E���0 �P��X�����u��aN����1W3�&b�t{s?��f��D�T'5�EDE����6�<�.�;ڔEy�1��́|�N繂_����n}s��!��]O�R��Ϛ�OPK���x�PK-xl/sharedStrings.xml=�A� ツ��.z0Ɣ�`� �����,�����q2��o�ԇ���N�E��x5�z>�W���(R�K���^4{�����ŀ�5��y�V����y�m�XV�\�.�j���� 8�PKp��&x�PK- xl/styles.xml���n� ��>bop2TQ��P)U�RWb�6*�����ӤS�Nw�s���3ߍ֐ ���t��(l��������ҝx�!N=@$ɀ��}��3c���ʰr`:i��2��w, � +�d �T��R#�voc �;c�iE��Û��E<|��4Iɣ����F#��n���B�z�F���y�j3y��yҥ�jt>���2��Lژ�!6��2F�OY��4@M�!���G��������1�t��y��p��" n����u�����a�ΦDi�9�&#��%I��9��}���cK��T��$?������`J������7���o��f��M|PK�1X@C�PK-xl/workbook.xmlM���0��>E�wi1ƨ����z/�HmI�_j��qf��)ʧٌ��w�LC��ָ��[u��T�b�a��؊;���8�9��G�)��5�|�:�2<8MuK=b�#� q�V�u ����K��H\)�\�&�t͌��%���?��B��T� PK ���PK-xl/_rels/workbook.xml.rels��ͪ1 �_�d�tt!"V7� n������LZ�(����r�� ��p����6�JY���U ����s����;[�E8D&a��h@- ��$� Xt�im���F�*&�41���̭M��ؒ]����WL�f�}��9anIH���Qs1���KtO��ll���O���X߬� �{�ŋ����œ�?o'�>PK�(2��PK-�q,-�[Content_Types].xmlPK-��z��I v_rels/.relsPK-�|wؑ��docProps/app.xmlPK-���x�qdocProps/core.xmlPK-p��&x��xl/sharedStrings.xmlPK-�1X@C� xl/styles.xmlPK- ���xl/workbook.xmlPK-�(2���xl/_rels/workbook.xml.relsPK�� @@ -4316,29 +4421,29 @@

      HTTP response

      "content" : "공지 사항 내용", "hitCount" : 0, "fixed" : true, - "createdAt" : "2024-11-13T23:55:20.918411", - "updatedAt" : "2024-11-13T23:55:20.918412", + "createdAt" : "2024-11-18T19:55:52.009219", + "updatedAt" : "2024-11-18T19:55:52.009221", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.918406", - "updatedAt" : "2024-11-13T23:55:20.918407" + "createdAt" : "2024-11-18T19:55:52.00921", + "updatedAt" : "2024-11-18T19:55:52.009213" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.918408", - "updatedAt" : "2024-11-13T23:55:20.918409" + "createdAt" : "2024-11-18T19:55:52.009214", + "updatedAt" : "2024-11-18T19:55:52.009215" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.918409", - "updatedAt" : "2024-11-13T23:55:20.91841" + "createdAt" : "2024-11-18T19:55:52.009218", + "updatedAt" : "2024-11-18T19:55:52.009218" } ] } @@ -4514,23 +4619,21 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, "title" : "공지 사항 1", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-11-13T23:55:20.867946", - "updatedAt" : "2024-11-13T23:55:20.867948" + "createdAt" : "2024-11-18T19:55:51.877105", + "updatedAt" : "2024-11-18T19:55:51.877107" }, { "id" : 2, "title" : "공지 사항 2", "hitCount" : 10, "fixed" : false, - "createdAt" : "2024-11-13T23:55:20.867963", - "updatedAt" : "2024-11-13T23:55:20.867963" + "createdAt" : "2024-11-18T19:55:51.877121", + "updatedAt" : "2024-11-18T19:55:51.877121" } ], "number" : 0, "sort" : { @@ -4538,7 +4641,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -4551,6 +4653,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -4781,7 +4886,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 949 +Content-Length: 947 { "id" : 1, @@ -4789,29 +4894,29 @@

      HTTP response

      "content" : "content", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-11-13T23:55:20.908975", - "updatedAt" : "2024-11-13T23:55:20.908975", + "createdAt" : "2024-11-18T19:55:51.982112", + "updatedAt" : "2024-11-18T19:55:51.982112", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.908968", - "updatedAt" : "2024-11-13T23:55:20.908971" + "createdAt" : "2024-11-18T19:55:51.982104", + "updatedAt" : "2024-11-18T19:55:51.982107" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.908972", - "updatedAt" : "2024-11-13T23:55:20.908972" + "createdAt" : "2024-11-18T19:55:51.982108", + "updatedAt" : "2024-11-18T19:55:51.982109" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.908973", - "updatedAt" : "2024-11-13T23:55:20.908974" + "createdAt" : "2024-11-18T19:55:51.98211", + "updatedAt" : "2024-11-18T19:55:51.98211" } ] } @@ -5034,28 +5139,28 @@

      HTTP response

      "hitCount" : 10, "fixed" : false, "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:20.882041", + "updatedAt" : "2024-11-18T19:55:51.921969", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:20.882011" + "updatedAt" : "2024-11-18T19:55:51.921919" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:20.882016" + "updatedAt" : "2024-11-18T19:55:51.921926" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:20.882018" + "updatedAt" : "2024-11-18T19:55:51.921929" } ] } @@ -5304,7 +5409,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 981 +Content-Length: 980 { "id" : 1, @@ -5312,29 +5417,29 @@

      HTTP response

      "content" : "이벤트 공지 사항 내용", "hitCount" : 0, "fixed" : true, - "createdAt" : "2024-11-13T23:55:19.135205", - "updatedAt" : "2024-11-13T23:55:19.135206", + "createdAt" : "2024-11-18T19:55:47.17606", + "updatedAt" : "2024-11-18T19:55:47.176061", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.135188", - "updatedAt" : "2024-11-13T23:55:19.135195" + "createdAt" : "2024-11-18T19:55:47.176039", + "updatedAt" : "2024-11-18T19:55:47.176047" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.135198", - "updatedAt" : "2024-11-13T23:55:19.135199" + "createdAt" : "2024-11-18T19:55:47.176051", + "updatedAt" : "2024-11-18T19:55:47.176053" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.135201", - "updatedAt" : "2024-11-13T23:55:19.135203" + "createdAt" : "2024-11-18T19:55:47.176055", + "updatedAt" : "2024-11-18T19:55:47.176057" } ] } @@ -5505,28 +5610,26 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 874 +Content-Length: 873 { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, "title" : "이벤트 공지 사항 1", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-11-13T23:55:19.148638", - "updatedAt" : "2024-11-13T23:55:19.148643" + "createdAt" : "2024-11-18T19:55:47.21455", + "updatedAt" : "2024-11-18T19:55:47.214557" }, { "id" : 2, "title" : "이벤트 공지 사항 2", "hitCount" : 10, "fixed" : false, - "createdAt" : "2024-11-13T23:55:19.148651", - "updatedAt" : "2024-11-13T23:55:19.148654" + "createdAt" : "2024-11-18T19:55:47.214576", + "updatedAt" : "2024-11-18T19:55:47.214578" } ], "number" : 0, "sort" : { @@ -5534,7 +5637,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -5547,6 +5649,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -5785,29 +5890,29 @@

      HTTP response

      "content" : "content", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-11-13T23:55:19.112756", - "updatedAt" : "2024-11-13T23:55:19.112758", + "createdAt" : "2024-11-18T19:55:47.117036", + "updatedAt" : "2024-11-18T19:55:47.117038", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.112736", - "updatedAt" : "2024-11-13T23:55:19.112746" + "createdAt" : "2024-11-18T19:55:47.117012", + "updatedAt" : "2024-11-18T19:55:47.117022" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.112749", - "updatedAt" : "2024-11-13T23:55:19.112751" + "createdAt" : "2024-11-18T19:55:47.117026", + "updatedAt" : "2024-11-18T19:55:47.117029" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:19.112753", - "updatedAt" : "2024-11-13T23:55:19.112754" + "createdAt" : "2024-11-18T19:55:47.117032", + "updatedAt" : "2024-11-18T19:55:47.117034" } ] } @@ -6021,7 +6126,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 974 +Content-Length: 975 { "id" : 1, @@ -6030,28 +6135,28 @@

      HTTP response

      "hitCount" : 10, "fixed" : false, "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:19.086333", + "updatedAt" : "2024-11-18T19:55:47.026018", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:19.08614" + "updatedAt" : "2024-11-18T19:55:47.025945" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:19.086157" + "updatedAt" : "2024-11-18T19:55:47.025971" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-11-13T23:55:19.086174" + "updatedAt" : "2024-11-18T19:55:47.025978" } ] } @@ -6239,8 +6344,8 @@

      HTTP request

      Cookie: refresh-token=refresh_token { - "start" : "2024-11-13T23:55:19.409069", - "end" : "2024-11-23T23:55:19.409073" + "start" : "2024-11-18T19:55:47.738113", + "end" : "2024-11-28T19:55:47.738129" } @@ -6292,10 +6397,10 @@

      HTTP response

      { "id" : 1, "year" : 2024, - "start" : "2024-11-13T23:55:19.409077", - "end" : "2024-11-23T23:55:19.409079", - "createdAt" : "2024-11-13T23:55:19.409081", - "updatedAt" : "2024-11-13T23:55:19.409082" + "start" : "2024-11-18T19:55:47.738137", + "end" : "2024-11-28T19:55:47.738139", + "createdAt" : "2024-11-18T19:55:47.738142", + "updatedAt" : "2024-11-18T19:55:47.738144" } @@ -6389,10 +6494,10 @@

      HTTP response

      { "id" : 1, "year" : 2024, - "start" : "2024-11-13T23:55:19.40019", - "end" : "2024-11-23T23:55:19.400192", - "createdAt" : "2024-11-13T23:55:19.400194", - "updatedAt" : "2024-11-13T23:55:19.400196" + "start" : "2024-11-18T19:55:47.71465", + "end" : "2024-11-28T19:55:47.714653", + "createdAt" : "2024-11-18T19:55:47.714657", + "updatedAt" : "2024-11-18T19:55:47.714659" } @@ -6481,22 +6586,22 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 415 +Content-Length: 414 [ { "id" : 1, "year" : 2024, - "start" : "2024-11-13T23:55:19.419422", - "end" : "2024-11-23T23:55:19.419427", - "createdAt" : "2024-11-13T23:55:19.41943", - "updatedAt" : "2024-11-13T23:55:19.419432" + "start" : "2024-11-18T19:55:47.776458", + "end" : "2024-11-28T19:55:47.77647", + "createdAt" : "2024-11-18T19:55:47.776475", + "updatedAt" : "2024-11-18T19:55:47.776477" }, { "id" : 2, "year" : 2025, - "start" : "2024-11-13T23:55:19.419434", - "end" : "2024-11-23T23:55:19.419436", - "createdAt" : "2024-11-13T23:55:19.419438", - "updatedAt" : "2024-11-13T23:55:19.419439" + "start" : "2024-11-18T19:55:47.77648", + "end" : "2024-11-28T19:55:47.776481", + "createdAt" : "2024-11-18T19:55:47.776483", + "updatedAt" : "2024-11-18T19:55:47.776485" } ] @@ -6577,8 +6682,8 @@

      HTTP request

      Cookie: refresh-token=refresh_token { - "start" : "2024-11-13T23:55:19.379086", - "end" : "2024-11-23T23:55:19.379094" + "start" : "2024-11-18T19:55:47.657836", + "end" : "2024-11-28T19:55:47.657846" } @@ -6630,10 +6735,10 @@

      HTTP response

      { "id" : 1, "year" : 2024, - "start" : "2024-11-13T23:55:19.379126", - "end" : "2024-11-23T23:55:19.379127", - "createdAt" : "2024-11-13T23:55:19.379129", - "updatedAt" : "2024-11-13T23:55:19.379131" + "start" : "2024-11-18T19:55:47.657891", + "end" : "2024-11-28T19:55:47.657893", + "createdAt" : "2024-11-18T19:55:47.657895", + "updatedAt" : "2024-11-18T19:55:47.657897" } @@ -6782,7 +6887,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 890 +Content-Length: 891 { "id" : 1, @@ -6790,29 +6895,29 @@

      HTTP response

      "year" : 2024, "month" : 4, "hitCount" : 1, - "createdAt" : "2024-11-13T23:55:20.13304", - "updatedAt" : "2024-11-13T23:55:20.133042", + "createdAt" : "2024-11-18T19:55:49.947753", + "updatedAt" : "2024-11-18T19:55:49.947755", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.133027", - "updatedAt" : "2024-11-13T23:55:20.133031" + "createdAt" : "2024-11-18T19:55:49.947735", + "updatedAt" : "2024-11-18T19:55:49.947743" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.133033", - "updatedAt" : "2024-11-13T23:55:20.133035" + "createdAt" : "2024-11-18T19:55:49.947746", + "updatedAt" : "2024-11-18T19:55:49.947747" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.133036", - "updatedAt" : "2024-11-13T23:55:20.133038" + "createdAt" : "2024-11-18T19:55:49.947749", + "updatedAt" : "2024-11-18T19:55:49.947751" } ] } @@ -6988,13 +7093,11 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 1232 +Content-Length: 1234 { "totalPages" : 1, "totalElements" : 1, - "first" : true, - "last" : true, "size" : 1, "content" : [ { "id" : 1, @@ -7002,29 +7105,29 @@

      HTTP response

      "year" : 2024, "month" : 4, "hitCount" : 0, - "createdAt" : "2024-11-13T23:55:20.10461", - "updatedAt" : "2024-11-13T23:55:20.104611", + "createdAt" : "2024-11-18T19:55:49.866951", + "updatedAt" : "2024-11-18T19:55:49.866952", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.104596", - "updatedAt" : "2024-11-13T23:55:20.1046" + "createdAt" : "2024-11-18T19:55:49.866926", + "updatedAt" : "2024-11-18T19:55:49.866935" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.104602", - "updatedAt" : "2024-11-13T23:55:20.104603" + "createdAt" : "2024-11-18T19:55:49.866938", + "updatedAt" : "2024-11-18T19:55:49.86694" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.104605", - "updatedAt" : "2024-11-13T23:55:20.104606" + "createdAt" : "2024-11-18T19:55:49.866942", + "updatedAt" : "2024-11-18T19:55:49.866944" } ] } ], "number" : 0, @@ -7033,8 +7136,10 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 1, "pageable" : "INSTANCE", + "numberOfElements" : 1, + "first" : true, + "last" : true, "empty" : false } @@ -7265,7 +7370,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 889 +Content-Length: 890 { "id" : 1, @@ -7273,29 +7378,29 @@

      HTTP response

      "year" : 2024, "month" : 4, "hitCount" : 1, - "createdAt" : "2024-11-13T23:55:20.122548", - "updatedAt" : "2024-11-13T23:55:20.12255", + "createdAt" : "2024-11-18T19:55:49.918362", + "updatedAt" : "2024-11-18T19:55:49.918364", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.122531", - "updatedAt" : "2024-11-13T23:55:20.122538" + "createdAt" : "2024-11-18T19:55:49.918345", + "updatedAt" : "2024-11-18T19:55:49.918351" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.12254", - "updatedAt" : "2024-11-13T23:55:20.122542" + "createdAt" : "2024-11-18T19:55:49.918355", + "updatedAt" : "2024-11-18T19:55:49.918356" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.122543", - "updatedAt" : "2024-11-13T23:55:20.122545" + "createdAt" : "2024-11-18T19:55:49.918358", + "updatedAt" : "2024-11-18T19:55:49.91836" } ] } @@ -7549,7 +7654,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 888 +Content-Length: 887 { "id" : 1, @@ -7557,29 +7662,29 @@

      HTTP response

      "year" : 2024, "month" : 5, "hitCount" : 1, - "createdAt" : "2024-11-13T23:55:20.076117", - "updatedAt" : "2024-11-13T23:55:20.076123", + "createdAt" : "2024-11-18T19:55:49.714135", + "updatedAt" : "2024-11-18T19:55:49.714137", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "사진1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.076027", - "updatedAt" : "2024-11-13T23:55:20.076031" + "createdAt" : "2024-11-18T19:55:49.714027", + "updatedAt" : "2024-11-18T19:55:49.714047" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "사진2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.076037", - "updatedAt" : "2024-11-13T23:55:20.076038" + "createdAt" : "2024-11-18T19:55:49.714057", + "updatedAt" : "2024-11-18T19:55:49.71406" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "사진3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-11-13T23:55:20.076041", - "updatedAt" : "2024-11-13T23:55:20.076044" + "createdAt" : "2024-11-18T19:55:49.714063", + "updatedAt" : "2024-11-18T19:55:49.714065" } ] } @@ -7752,13 +7857,11 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 1177 +Content-Length: 1178 { "totalPages" : 1, "totalElements" : 3, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -7766,24 +7869,24 @@

      HTTP response

      "division" : "배민", "position" : null, "userType" : "INACTIVE_COMPANY", - "createdAt" : "2024-11-13T23:55:21.390245", - "updatedAt" : "2024-11-13T23:55:21.390246" + "createdAt" : "2024-11-18T19:55:54.259219", + "updatedAt" : "2024-11-18T19:55:54.259222" }, { "id" : 2, "name" : "김교수", "division" : "솦융대", "position" : "교수", "userType" : "INACTIVE_PROFESSOR", - "createdAt" : "2024-11-13T23:55:21.390259", - "updatedAt" : "2024-11-13T23:55:21.39026" + "createdAt" : "2024-11-18T19:55:54.259235", + "updatedAt" : "2024-11-18T19:55:54.259235" }, { "id" : 3, "name" : "박교수", "division" : "정통대", "position" : "교수", "userType" : "INACTIVE_PROFESSOR", - "createdAt" : "2024-11-13T23:55:21.390263", - "updatedAt" : "2024-11-13T23:55:21.390264" + "createdAt" : "2024-11-18T19:55:54.259245", + "updatedAt" : "2024-11-18T19:55:54.259246" } ], "number" : 0, "sort" : { @@ -7791,7 +7894,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 3, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -7804,6 +7906,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 3, + "first" : true, + "last" : true, "empty" : false } @@ -8041,7 +8146,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 271 +Content-Length: 272 { "id" : 1, @@ -8051,8 +8156,8 @@

      HTTP response

      "division" : "배민", "position" : "CEO", "userType" : "INACTIVE_COMPANY", - "createdAt" : "2024-11-13T23:55:21.42166", - "updatedAt" : "2024-11-13T23:55:21.421661" + "createdAt" : "2024-11-18T19:55:54.344894", + "updatedAt" : "2024-11-18T19:55:54.344897" } @@ -8181,7 +8286,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 262 +Content-Length: 263 { "id" : 1, @@ -8191,8 +8296,8 @@

      HTTP response

      "division" : "배민", "position" : "CEO", "userType" : "COMPANY", - "createdAt" : "2024-11-13T23:55:21.413068", - "updatedAt" : "2024-11-13T23:55:21.41307" + "createdAt" : "2024-11-18T19:55:54.328644", + "updatedAt" : "2024-11-18T19:55:54.328648" } @@ -8406,8 +8511,8 @@

      HTTP response

      "title" : "문의 사항 제목", "content" : "문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.430076", - "updatedAt" : "2024-11-13T23:55:20.430079" + "createdAt" : "2024-11-18T19:55:50.786517", + "updatedAt" : "2024-11-18T19:55:50.786521" } @@ -8550,24 +8655,22 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 823 +Content-Length: 822 { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, "authorName" : "프로젝트 문의 사항 제목", "title" : "프로젝트 문의 사항 내용", - "createdAt" : "2024-11-13T23:55:20.395604" + "createdAt" : "2024-11-18T19:55:50.66564" }, { "id" : 2, "authorName" : "프로젝트 문의 사항 제목", "title" : "프로젝트 문의 사항 내용", - "createdAt" : "2024-11-13T23:55:20.395698" + "createdAt" : "2024-11-18T19:55:50.665696" } ], "number" : 0, "sort" : { @@ -8575,7 +8678,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -8588,6 +8690,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -8813,8 +8918,8 @@

      HTTP response

      "title" : "문의 사항 제목", "content" : "문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.417825", - "updatedAt" : "2024-11-13T23:55:20.417829" + "createdAt" : "2024-11-18T19:55:50.749487", + "updatedAt" : "2024-11-18T19:55:50.749493" } @@ -8994,8 +9099,8 @@

      HTTP response

      "title" : "수정된 문의 사항 제목", "content" : "수정된 문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.453119", - "updatedAt" : "2024-11-13T23:55:20.453122" + "createdAt" : "2024-11-18T19:55:50.848221", + "updatedAt" : "2024-11-18T19:55:50.848224" } @@ -9570,12 +9675,10 @@

      프로젝트 API


      프로젝트 조회 (GET /projects)

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects HTTP/1.1
      @@ -9586,8 +9689,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -9600,8 +9703,6 @@ 
      HTTP response
      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -9652,7 +9753,6 @@
      HTTP response
      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -9665,13 +9765,16 @@
      HTTP response
      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      -
      -
      Query parameters
      +
      +

      Query parameters

      @@ -9724,8 +9827,8 @@
      Query parameters
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -9982,15 +10085,12 @@
      Response fields
      -

      프로젝트 생성 (POST /projects)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects HTTP/1.1
      @@ -10026,8 +10126,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -10035,7 +10135,7 @@ 
      HTTP response
      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 1480 +Content-Length: 1481 { "id" : 1, @@ -10069,24 +10169,24 @@
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206867", - "updatedAt" : "2024-11-13T23:55:21.206868" + "createdAt" : "2024-11-18T19:55:52.832829", + "updatedAt" : "2024-11-18T19:55:52.832841" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206869", - "updatedAt" : "2024-11-13T23:55:21.20687" + "createdAt" : "2024-11-18T19:55:52.832843", + "updatedAt" : "2024-11-18T19:55:52.832844" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206871", - "updatedAt" : "2024-11-13T23:55:21.206871" + "createdAt" : "2024-11-18T19:55:52.832844", + "updatedAt" : "2024-11-18T19:55:52.832845" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -10094,8 +10194,8 @@
      HTTP response
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -10199,8 +10299,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -10421,15 +10521,121 @@
      Response fields
      +
      +

      프로젝트 엑셀 일괄등록 (POST /projects/excel)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      POST /projects/excel HTTP/1.1
      +Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=excel; filename=project_upload_form.xlsx
      +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
      +
      +[BINARY DATA]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=thumbnails; filename=thumbnails.json
      +Content-Type: application/json
      +
      +[{"id":1,"uuid":"c7fabd9b-eea0-48c9-b94d-8fab318b2c88","name":"썸네일1.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698466","updatedAt":"2024-11-18T19:55:53.698477"},{"id":1,"uuid":"989ca4f3-9b7b-4784-b842-64b2314903ca","name":"썸네일2.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698519","updatedAt":"2024-11-18T19:55:53.69852"}]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=posters; filename=thumbnails.json
      +Content-Type: application/json
      +
      +[{"id":1,"uuid":"cdf4712a-9d35-4c99-9ad3-e97036c7028c","name":"포스터1.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698555","updatedAt":"2024-11-18T19:55:53.698556"},{"id":1,"uuid":"eb4efbf9-9539-466b-a349-b56970cfad1b","name":"포스터2.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698561","updatedAt":"2024-11-18T19:55:53.698562"}]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
      +
      +
      +
      +
      +

      Request parts

      +
      ++++ + + + + + + + + + + + + + + + + + + + + +
      PartDescription

      excel

      업로드할 Excel 파일

      thumbnails

      썸네일 등록 응답 JSON 파일

      posters

      포스터 등록 응답 JSON 파일

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 201 Created
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 24
      +
      +{
      +  "successCount" : 2
      +}
      +
      +
      +
      +
      +

      Response fields

      + ++++++ + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      successCount

      Number

      true

      생성에 성공한 프로젝트 개수

      +
      +
      +

      프로젝트 조회 (GET /projects/{projectId})

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects/1 HTTP/1.1
      @@ -10440,8 +10646,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -10483,24 +10689,24 @@ 
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180036", - "updatedAt" : "2024-11-13T23:55:21.180037" + "createdAt" : "2024-11-18T19:55:52.750773", + "updatedAt" : "2024-11-18T19:55:52.750777" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180041", - "updatedAt" : "2024-11-13T23:55:21.180041" + "createdAt" : "2024-11-18T19:55:52.750782", + "updatedAt" : "2024-11-18T19:55:52.750783" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180042", - "updatedAt" : "2024-11-13T23:55:21.180043" + "createdAt" : "2024-11-18T19:55:52.750784", + "updatedAt" : "2024-11-18T19:55:52.750784" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -10508,8 +10714,8 @@
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -10530,8 +10736,8 @@
      Path parameters
      Table 1. /projects/{projectId}
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -10752,15 +10958,12 @@
      Response fields
      -

      프로젝트 수정 (PUT /projects/{projectId})

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      PUT /projects/1 HTTP/1.1
      @@ -10796,8 +10999,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -10805,7 +11008,7 @@ 
      HTTP response
      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 1476 +Content-Length: 1477 { "id" : 1, @@ -10839,24 +11042,24 @@
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.08522", - "updatedAt" : "2024-11-13T23:55:21.085222" + "createdAt" : "2024-11-18T19:55:52.387676", + "updatedAt" : "2024-11-18T19:55:52.387679" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.085225", - "updatedAt" : "2024-11-13T23:55:21.085226" + "createdAt" : "2024-11-18T19:55:52.387684", + "updatedAt" : "2024-11-18T19:55:52.387684" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.085227", - "updatedAt" : "2024-11-13T23:55:21.085227" + "createdAt" : "2024-11-18T19:55:52.387687", + "updatedAt" : "2024-11-18T19:55:52.387687" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -10864,8 +11067,8 @@
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -10886,8 +11089,8 @@
      Path parameters
      Table 1. /projects/{projectId}
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -10991,8 +11194,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -11213,15 +11416,12 @@
      Response fields
      -

      프로젝트 삭제 (DELETE /projects/{projectId})

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1 HTTP/1.1
      @@ -11232,8 +11432,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -11243,8 +11443,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -11268,15 +11468,12 @@
      Path parameters
      -

      관심 프로젝트 등록 (POST /projects/{projectId}/favorite)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/favorite HTTP/1.1
      @@ -11287,8 +11484,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -11298,8 +11495,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}
      @@ -11323,15 +11520,12 @@
      Path parameters
      -

      관심 프로젝트 삭제 (DELETE /projects/{projectId}/favorite)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/favorite HTTP/1.1
      @@ -11342,8 +11536,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -11353,8 +11547,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/favorite
      @@ -11378,15 +11572,12 @@
      Path parameters
      -

      프로젝트 좋아요 등록 (POST /projects/{projectId}/like)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/like HTTP/1.1
      @@ -11397,8 +11588,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -11408,8 +11599,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/favorite
      @@ -11433,15 +11624,12 @@
      Path parameters
      -

      프로젝트 좋아요 삭제 (DELETE /projects/{projectId}/like)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/like HTTP/1.1
      @@ -11452,8 +11640,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -11463,8 +11651,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/like
      @@ -11488,15 +11676,12 @@
      Path parameters
      -

      프로젝트 댓글 등록 (POST /projects/{projectId}/comment)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/comment HTTP/1.1
      @@ -11513,8 +11698,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -11530,14 +11715,14 @@ 
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.171022", - "updatedAt" : "2024-11-13T23:55:21.171023" + "createdAt" : "2024-11-18T19:55:52.720346", + "updatedAt" : "2024-11-18T19:55:52.720349" }
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/like
      @@ -11558,8 +11743,8 @@
      Path parameters
      Table 1. /projects/{projectId}/comment
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -11591,8 +11776,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -11657,15 +11842,12 @@
      Response fields
      -

      프로젝트 댓글 삭제 (DELETE /projects/{projectId}/comment)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/comment/1 HTTP/1.1
      @@ -11676,8 +11858,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -11687,8 +11869,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -11716,15 +11898,12 @@
      Path parameters
      -

      수상 프로젝트 조회 (GET /projects/award?year={year})

      -
      -

      200 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects/award?year=2024 HTTP/1.1
      @@ -11735,8 +11914,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -11749,8 +11928,6 @@ 
      HTTP response
      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -11801,7 +11978,6 @@
      HTTP response
      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -11814,13 +11990,16 @@
      HTTP response
      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      -
      -
      Query parameters
      +
      +

      Query parameters

      Table 1. /projects/{projectId}/comment/{commentId}
      @@ -11858,8 +12037,8 @@
      Query parameters
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -12118,7 +12297,6 @@
      Response fields
      -

      AI HUB API

      @@ -12247,8 +12425,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "title" : "title", @@ -12279,7 +12455,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -12292,6 +12467,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      @@ -12625,8 +12803,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "title" : "title", @@ -12657,7 +12833,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -12670,6 +12845,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      @@ -13009,8 +13187,6 @@

      HTTP response

      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "company" : "기업명 1", @@ -13045,7 +13221,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -13058,6 +13233,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -13285,7 +13463,7 @@

      Response fields

      diff --git a/src/main/resources/static/docs/inquiry.html b/src/main/resources/static/docs/inquiry.html index 7987e003..c095943c 100644 --- a/src/main/resources/static/docs/inquiry.html +++ b/src/main/resources/static/docs/inquiry.html @@ -518,8 +518,8 @@

      HTTP response

      "title" : "문의 사항 제목", "content" : "문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.430076", - "updatedAt" : "2024-11-13T23:55:20.430079" + "createdAt" : "2024-11-18T19:55:50.786517", + "updatedAt" : "2024-11-18T19:55:50.786521" } @@ -662,24 +662,22 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 823 +Content-Length: 822 { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, "authorName" : "프로젝트 문의 사항 제목", "title" : "프로젝트 문의 사항 내용", - "createdAt" : "2024-11-13T23:55:20.395604" + "createdAt" : "2024-11-18T19:55:50.66564" }, { "id" : 2, "authorName" : "프로젝트 문의 사항 제목", "title" : "프로젝트 문의 사항 내용", - "createdAt" : "2024-11-13T23:55:20.395698" + "createdAt" : "2024-11-18T19:55:50.665696" } ], "number" : 0, "sort" : { @@ -687,7 +685,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -700,6 +697,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -925,8 +925,8 @@

      HTTP response

      "title" : "문의 사항 제목", "content" : "문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.417825", - "updatedAt" : "2024-11-13T23:55:20.417829" + "createdAt" : "2024-11-18T19:55:50.749487", + "updatedAt" : "2024-11-18T19:55:50.749493" } @@ -1106,8 +1106,8 @@

      HTTP response

      "title" : "수정된 문의 사항 제목", "content" : "수정된 문의 사항 내용", "replied" : false, - "createdAt" : "2024-11-13T23:55:20.453119", - "updatedAt" : "2024-11-13T23:55:20.453122" + "createdAt" : "2024-11-18T19:55:50.848221", + "updatedAt" : "2024-11-18T19:55:50.848224" } @@ -1680,7 +1680,7 @@

      HTTP response

      diff --git a/src/main/resources/static/docs/jobInfo-controller-test.html b/src/main/resources/static/docs/jobInfo-controller-test.html index 9f9e79e1..cbbdb50d 100644 --- a/src/main/resources/static/docs/jobInfo-controller-test.html +++ b/src/main/resources/static/docs/jobInfo-controller-test.html @@ -566,10 +566,8 @@

      HTTP response

      Content-Length: 1295 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "company" : "기업명 1", @@ -604,7 +602,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -617,6 +614,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -844,7 +844,7 @@

      Response fields

      diff --git a/src/main/resources/static/docs/jobInterview.html b/src/main/resources/static/docs/jobInterview.html index cfd6a1d9..dfa3e71a 100644 --- a/src/main/resources/static/docs/jobInterview.html +++ b/src/main/resources/static/docs/jobInterview.html @@ -546,8 +546,8 @@

      HTTP response

      "talkerBelonging" : "대담자의 소속", "talkerName" : "대담자의 성명", "category" : "INTERN", - "createdAt" : "2024-10-29T22:38:57.366975", - "updatedAt" : "2024-10-29T22:38:57.366976" + "createdAt" : "2024-11-18T19:55:54.938534", + "updatedAt" : "2024-11-18T19:55:54.938537" } @@ -702,10 +702,8 @@

      HTTP response

      Content-Length: 1205 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "id" : 1, @@ -716,8 +714,8 @@

      HTTP response

      "talkerName" : "대담자의 성명1", "favorite" : false, "category" : "INTERN", - "createdAt" : "2024-10-29T22:38:57.350426", - "updatedAt" : "2024-10-29T22:38:57.350429" + "createdAt" : "2024-11-18T19:55:54.88224", + "updatedAt" : "2024-11-18T19:55:54.882242" }, { "id" : 2, "title" : "잡페어 인터뷰의 제목2", @@ -727,8 +725,8 @@

      HTTP response

      "talkerName" : "대담자의 성명2", "favorite" : true, "category" : "INTERN", - "createdAt" : "2024-10-29T22:38:57.35044", - "updatedAt" : "2024-10-29T22:38:57.350441" + "createdAt" : "2024-11-18T19:55:54.882264", + "updatedAt" : "2024-11-18T19:55:54.882265" } ], "number" : 0, "sort" : { @@ -736,7 +734,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -749,6 +746,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -1016,8 +1016,8 @@

      HTTP response

      "talkerName" : "대담자의 성명", "favorite" : false, "category" : "INTERN", - "createdAt" : "2024-10-29T22:38:57.360921", - "updatedAt" : "2024-10-29T22:38:57.360922" + "createdAt" : "2024-11-18T19:55:54.921774", + "updatedAt" : "2024-11-18T19:55:54.921776" } @@ -1231,7 +1231,7 @@

      HTTP response

      "talkerName" : "수정된 대담자 성명", "category" : "INTERN", "createdAt" : "2021-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:57.331715" + "updatedAt" : "2024-11-18T19:55:54.788456" } @@ -1476,7 +1476,7 @@

      HTTP response

      diff --git a/src/main/resources/static/docs/notice.html b/src/main/resources/static/docs/notice.html index aeb7025d..5f1e5c82 100644 --- a/src/main/resources/static/docs/notice.html +++ b/src/main/resources/static/docs/notice.html @@ -529,29 +529,29 @@

      HTTP response

      "content" : "공지 사항 내용", "hitCount" : 0, "fixed" : true, - "createdAt" : "2024-10-29T22:38:56.701497", - "updatedAt" : "2024-10-29T22:38:56.701498", + "createdAt" : "2024-11-18T19:55:52.009219", + "updatedAt" : "2024-11-18T19:55:52.009221", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.70149", - "updatedAt" : "2024-10-29T22:38:56.701491" + "createdAt" : "2024-11-18T19:55:52.00921", + "updatedAt" : "2024-11-18T19:55:52.009213" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.701493", - "updatedAt" : "2024-10-29T22:38:56.701493" + "createdAt" : "2024-11-18T19:55:52.009214", + "updatedAt" : "2024-11-18T19:55:52.009215" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.701494", - "updatedAt" : "2024-10-29T22:38:56.701495" + "createdAt" : "2024-11-18T19:55:52.009218", + "updatedAt" : "2024-11-18T19:55:52.009218" } ] } @@ -725,25 +725,23 @@

      HTTP response

      Content-Length: 854 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "id" : 1, "title" : "공지 사항 1", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-10-29T22:38:56.662802", - "updatedAt" : "2024-10-29T22:38:56.662804" + "createdAt" : "2024-11-18T19:55:51.877105", + "updatedAt" : "2024-11-18T19:55:51.877107" }, { "id" : 2, "title" : "공지 사항 2", "hitCount" : 10, "fixed" : false, - "createdAt" : "2024-10-29T22:38:56.662818", - "updatedAt" : "2024-10-29T22:38:56.662819" + "createdAt" : "2024-11-18T19:55:51.877121", + "updatedAt" : "2024-11-18T19:55:51.877121" } ], "number" : 0, "sort" : { @@ -751,7 +749,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -764,6 +761,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false } @@ -1002,29 +1002,29 @@

      HTTP response

      "content" : "content", "hitCount" : 10, "fixed" : true, - "createdAt" : "2024-10-29T22:38:56.694639", - "updatedAt" : "2024-10-29T22:38:56.69464", + "createdAt" : "2024-11-18T19:55:51.982112", + "updatedAt" : "2024-11-18T19:55:51.982112", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.69463", - "updatedAt" : "2024-10-29T22:38:56.694634" + "createdAt" : "2024-11-18T19:55:51.982104", + "updatedAt" : "2024-11-18T19:55:51.982107" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.694635", - "updatedAt" : "2024-10-29T22:38:56.694636" + "createdAt" : "2024-11-18T19:55:51.982108", + "updatedAt" : "2024-11-18T19:55:51.982109" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", - "createdAt" : "2024-10-29T22:38:56.694637", - "updatedAt" : "2024-10-29T22:38:56.694638" + "createdAt" : "2024-11-18T19:55:51.98211", + "updatedAt" : "2024-11-18T19:55:51.98211" } ] } @@ -1247,28 +1247,28 @@

      HTTP response

      "hitCount" : 10, "fixed" : false, "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:56.676945", + "updatedAt" : "2024-11-18T19:55:51.921969", "files" : [ { "id" : 1, "uuid" : "014eb8a0-d4a6-11ee-adac-117d766aca1d", "name" : "예시 첨부 파일 1.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:56.676908" + "updatedAt" : "2024-11-18T19:55:51.921919" }, { "id" : 2, "uuid" : "11a480c0-13fa-11ef-9047-570191b390ea", "name" : "예시 첨부 파일 2.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:56.676917" + "updatedAt" : "2024-11-18T19:55:51.921926" }, { "id" : 3, "uuid" : "1883fc70-cfb4-11ee-a387-e754bd392d45", "name" : "예시 첨부 파일 3.jpg", "mimeType" : "image/jpeg", "createdAt" : "2024-01-01T12:00:00", - "updatedAt" : "2024-10-29T22:38:56.676919" + "updatedAt" : "2024-11-18T19:55:51.921929" } ] } @@ -1440,7 +1440,7 @@

      HTTP response

      diff --git a/src/main/resources/static/docs/project.html b/src/main/resources/static/docs/project.html index 3f4d3977..1d8b255a 100644 --- a/src/main/resources/static/docs/project.html +++ b/src/main/resources/static/docs/project.html @@ -446,12 +446,10 @@

      프로젝트 API


      프로젝트 조회 (GET /projects)

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects HTTP/1.1
      @@ -462,8 +460,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -476,8 +474,6 @@ 
      HTTP response
      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -528,7 +524,6 @@
      HTTP response
      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -541,13 +536,16 @@
      HTTP response
      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      -
      -
      Query parameters
      +
      +

      Query parameters

      @@ -600,8 +598,8 @@
      Query parameters
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -858,15 +856,12 @@
      Response fields
      -

      프로젝트 생성 (POST /projects)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects HTTP/1.1
      @@ -902,8 +897,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -911,7 +906,7 @@ 
      HTTP response
      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 1480 +Content-Length: 1481 { "id" : 1, @@ -945,24 +940,24 @@
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206867", - "updatedAt" : "2024-11-13T23:55:21.206868" + "createdAt" : "2024-11-18T19:55:52.832829", + "updatedAt" : "2024-11-18T19:55:52.832841" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206869", - "updatedAt" : "2024-11-13T23:55:21.20687" + "createdAt" : "2024-11-18T19:55:52.832843", + "updatedAt" : "2024-11-18T19:55:52.832844" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.206871", - "updatedAt" : "2024-11-13T23:55:21.206871" + "createdAt" : "2024-11-18T19:55:52.832844", + "updatedAt" : "2024-11-18T19:55:52.832845" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -970,8 +965,8 @@
      HTTP response
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -1075,8 +1070,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -1297,15 +1292,121 @@
      Response fields
      +
      +

      프로젝트 엑셀 일괄등록 (POST /projects/excel)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      POST /projects/excel HTTP/1.1
      +Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=excel; filename=project_upload_form.xlsx
      +Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
      +
      +[BINARY DATA]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=thumbnails; filename=thumbnails.json
      +Content-Type: application/json
      +
      +[{"id":1,"uuid":"c7fabd9b-eea0-48c9-b94d-8fab318b2c88","name":"썸네일1.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698466","updatedAt":"2024-11-18T19:55:53.698477"},{"id":1,"uuid":"989ca4f3-9b7b-4784-b842-64b2314903ca","name":"썸네일2.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698519","updatedAt":"2024-11-18T19:55:53.69852"}]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
      +Content-Disposition: form-data; name=posters; filename=thumbnails.json
      +Content-Type: application/json
      +
      +[{"id":1,"uuid":"cdf4712a-9d35-4c99-9ad3-e97036c7028c","name":"포스터1.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698555","updatedAt":"2024-11-18T19:55:53.698556"},{"id":1,"uuid":"eb4efbf9-9539-466b-a349-b56970cfad1b","name":"포스터2.png","mimeType":"image/png","createdAt":"2024-11-18T19:55:53.698561","updatedAt":"2024-11-18T19:55:53.698562"}]
      +--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
      +
      +
      +
      +
      +

      Request parts

      +
      ++++ + + + + + + + + + + + + + + + + + + + + +
      PartDescription

      excel

      업로드할 Excel 파일

      thumbnails

      썸네일 등록 응답 JSON 파일

      posters

      포스터 등록 응답 JSON 파일

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 201 Created
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 24
      +
      +{
      +  "successCount" : 2
      +}
      +
      +
      +
      +
      +

      Response fields

      + ++++++ + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      successCount

      Number

      true

      생성에 성공한 프로젝트 개수

      +
      +
      +

      프로젝트 조회 (GET /projects/{projectId})

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects/1 HTTP/1.1
      @@ -1316,8 +1417,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -1359,24 +1460,24 @@ 
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180036", - "updatedAt" : "2024-11-13T23:55:21.180037" + "createdAt" : "2024-11-18T19:55:52.750773", + "updatedAt" : "2024-11-18T19:55:52.750777" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180041", - "updatedAt" : "2024-11-13T23:55:21.180041" + "createdAt" : "2024-11-18T19:55:52.750782", + "updatedAt" : "2024-11-18T19:55:52.750783" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.180042", - "updatedAt" : "2024-11-13T23:55:21.180043" + "createdAt" : "2024-11-18T19:55:52.750784", + "updatedAt" : "2024-11-18T19:55:52.750784" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -1384,8 +1485,8 @@
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -1406,8 +1507,8 @@
      Path parameters
      Table 1. /projects/{projectId}
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -1628,15 +1729,12 @@
      Response fields
      -

      프로젝트 수정 (PUT /projects/{projectId})

      -
      -

      200 OK

      -
      -
      HTTP request
      +
      +

      HTTP request

      PUT /projects/1 HTTP/1.1
      @@ -1672,8 +1770,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -1681,7 +1779,7 @@ 
      HTTP response
      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 1476 +Content-Length: 1477 { "id" : 1, @@ -1715,24 +1813,24 @@
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.08522", - "updatedAt" : "2024-11-13T23:55:21.085222" + "createdAt" : "2024-11-18T19:55:52.387676", + "updatedAt" : "2024-11-18T19:55:52.387679" }, { "id" : 2, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.085225", - "updatedAt" : "2024-11-13T23:55:21.085226" + "createdAt" : "2024-11-18T19:55:52.387684", + "updatedAt" : "2024-11-18T19:55:52.387684" }, { "id" : 3, "projectId" : 1, "userName" : "유저 이름", "isAnonymous" : false, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.085227", - "updatedAt" : "2024-11-13T23:55:21.085227" + "createdAt" : "2024-11-18T19:55:52.387687", + "updatedAt" : "2024-11-18T19:55:52.387687" } ], "url" : "프로젝트 URL", "description" : "프로젝트 설명" @@ -1740,8 +1838,8 @@
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -1762,8 +1860,8 @@
      Path parameters
      Table 1. /projects/{projectId}
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -1867,8 +1965,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -2089,15 +2187,12 @@
      Response fields
      -

      프로젝트 삭제 (DELETE /projects/{projectId})

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1 HTTP/1.1
      @@ -2108,8 +2203,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -2119,8 +2214,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -2144,15 +2239,12 @@
      Path parameters
      -

      관심 프로젝트 등록 (POST /projects/{projectId}/favorite)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/favorite HTTP/1.1
      @@ -2163,8 +2255,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -2174,8 +2266,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}
      @@ -2199,15 +2291,12 @@
      Path parameters
      -

      관심 프로젝트 삭제 (DELETE /projects/{projectId}/favorite)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/favorite HTTP/1.1
      @@ -2218,8 +2307,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -2229,8 +2318,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/favorite
      @@ -2254,15 +2343,12 @@
      Path parameters
      -

      프로젝트 좋아요 등록 (POST /projects/{projectId}/like)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/like HTTP/1.1
      @@ -2273,8 +2359,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -2284,8 +2370,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/favorite
      @@ -2309,15 +2395,12 @@
      Path parameters
      -

      프로젝트 좋아요 삭제 (DELETE /projects/{projectId}/like)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/like HTTP/1.1
      @@ -2328,8 +2411,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -2339,8 +2422,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/like
      @@ -2364,15 +2447,12 @@
      Path parameters
      -

      프로젝트 댓글 등록 (POST /projects/{projectId}/comment)

      -
      -

      201 Created

      -
      -
      HTTP request
      +
      +

      HTTP request

      POST /projects/1/comment HTTP/1.1
      @@ -2389,8 +2469,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 201 Created
      @@ -2406,14 +2486,14 @@ 
      HTTP response
      "userName" : "유저 이름", "isAnonymous" : true, "content" : "댓글 내용", - "createdAt" : "2024-11-13T23:55:21.171022", - "updatedAt" : "2024-11-13T23:55:21.171023" + "createdAt" : "2024-11-18T19:55:52.720346", + "updatedAt" : "2024-11-18T19:55:52.720349" }
      -
      -
      Path parameters
      +
      +

      Path parameters

      Table 1. /projects/{projectId}/like
      @@ -2434,8 +2514,8 @@
      Path parameters
      Table 1. /projects/{projectId}/comment
      -
      -
      Request fields
      +
      +

      Request fields

      @@ -2467,8 +2547,8 @@
      Request fields
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -2533,15 +2613,12 @@
      Response fields
      -

      프로젝트 댓글 삭제 (DELETE /projects/{projectId}/comment)

      -
      -

      204 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      DELETE /projects/1/comment/1 HTTP/1.1
      @@ -2552,8 +2629,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 204 No Content
      @@ -2563,8 +2640,8 @@ 
      HTTP response
      -
      -
      Path parameters
      +
      +

      Path parameters

      @@ -2592,15 +2669,12 @@
      Path parameters
      -

      수상 프로젝트 조회 (GET /projects/award?year={year})

      -
      -

      200 No Content

      -
      -
      HTTP request
      +
      +

      HTTP request

      GET /projects/award?year=2024 HTTP/1.1
      @@ -2611,8 +2685,8 @@ 
      HTTP request
      -
      -
      HTTP response
      +
      +

      HTTP response

      HTTP/1.1 200 OK
      @@ -2625,8 +2699,6 @@ 
      HTTP response
      { "totalPages" : 1, "totalElements" : 2, - "first" : true, - "last" : true, "size" : 10, "content" : [ { "id" : 1, @@ -2677,7 +2749,6 @@
      HTTP response
      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -2690,13 +2761,16 @@
      HTTP response
      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      -
      -
      Query parameters
      +
      +

      Query parameters

      Table 1. /projects/{projectId}/comment/{commentId}
      @@ -2734,8 +2808,8 @@
      Query parameters
      -
      -
      Response fields
      +
      +

      Response fields

      @@ -2995,11 +3069,10 @@
      Response fields
      - diff --git a/src/main/resources/static/docs/proposal.html b/src/main/resources/static/docs/proposal.html new file mode 100644 index 00000000..63a966aa --- /dev/null +++ b/src/main/resources/static/docs/proposal.html @@ -0,0 +1,1646 @@ + + + + + + + +과제 제안 API + + + + + +
      +
      +

      과제 제안 API

      +
      +
      +

      과제 제안 생성 (POST /proposals)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      POST /proposals HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Content-Length: 220
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "webSite" : "website.com",
      +  "title" : "과제제안제목",
      +  "email" : "이메일@email.com",
      +  "projectTypes" : [ "LAB", "CLUB" ],
      +  "content" : "과제제안내용",
      +  "isVisible" : true,
      +  "isAnonymous" : true
      +}
      +
      +
      +
      +
      +

      Request fields

      +
      ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      title

      String

      true

      과제제안 제목

      content

      String

      true

      과제제안 내용

      webSite

      String

      과제제안 사이트

      projectTypes

      Array

      true

      과제제안 프로젝트 유형들

      email

      String

      true

      과제제안 이메일

      isVisible

      Boolean

      true

      공개 여부

      isAnonymous

      Boolean

      true

      익명 여부

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 201 Created
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 237
      +
      +{
      +  "id" : 1,
      +  "authorName" : "작성자",
      +  "email" : "이메일@email.com",
      +  "webSite" : "website.com",
      +  "title" : "과제제안제목",
      +  "projectTypes" : [ "LAB", "CLUB" ],
      +  "content" : "과제제안내용",
      +  "replied" : false
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 ID

      authorName

      String

      과제 제안 작성자

      email

      String

      과제 제안 이메일

      webSite

      String

      과제 제안 사이트

      title

      String

      과제 제안 제목

      projectTypes

      Array

      과제 제안 프로젝트 유형들

      content

      String

      과제 제안 내용

      replied

      Boolean

      과제 제안 답변 유무

      +
      +
      +
      +
      +
      +

      과제 제안 리스트 조회 (GET /proposals)

      +
      +
      +
      +

      Query parameters

      + ++++ + + + + + + + + + + + + + + + + + + + + +
      ParameterDescription

      title

      찾고자 하는 과제제안 제목

      page

      페이지 번호 [default = 0]

      size

      페이지 크기 [default = 10]

      +
      +
      +

      HTTP request

      +
      +
      +
      GET /proposals HTTP/1.1
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 723
      +
      +{
      +  "totalPages" : 1,
      +  "totalElements" : 2,
      +  "size" : 10,
      +  "content" : [ {
      +    "id" : 1,
      +    "title" : "과제 제안1",
      +    "name" : "이름",
      +    "createdDate" : "2024-11-17T00:47:41.048136"
      +  }, {
      +    "id" : 2,
      +    "title" : "과제 제안2",
      +    "name" : "이름",
      +    "createdDate" : "2024-11-17T00:47:41.048213"
      +  } ],
      +  "number" : 0,
      +  "sort" : {
      +    "empty" : true,
      +    "sorted" : false,
      +    "unsorted" : true
      +  },
      +  "numberOfElements" : 2,
      +  "pageable" : {
      +    "pageNumber" : 0,
      +    "pageSize" : 10,
      +    "sort" : {
      +      "empty" : true,
      +      "sorted" : false,
      +      "unsorted" : true
      +    },
      +    "offset" : 0,
      +    "paged" : true,
      +    "unpaged" : false
      +  },
      +  "first" : true,
      +  "last" : true,
      +  "empty" : false
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      content[].id

      Number

      과제 제안 ID

      content[].title

      String

      과제 제안 제목

      content[].name

      String

      과제 제안 작성자

      content[].createdDate

      String

      과제 제안 생성일

      pageable

      Object

      페이지 정보

      pageable.pageNumber

      Number

      현재 페이지 번호

      pageable.pageSize

      Number

      페이지 당 요소 수

      pageable.sort.empty

      Boolean

      정렬 정보가 비어있는지 여부

      pageable.sort.sorted

      Boolean

      정렬된 상태인지 여부

      pageable.sort.unsorted

      Boolean

      정렬되지 않은 상태인지 여부

      pageable.offset

      Number

      오프셋

      pageable.paged

      Boolean

      페이징된 여부

      pageable.unpaged

      Boolean

      페이징되지 않은 여부

      totalElements

      Number

      전체 요소 수

      totalPages

      Number

      전체 페이지 수

      size

      Number

      페이지 당 요소 수

      number

      Number

      현재 페이지 번호

      numberOfElements

      Number

      현재 페이지 요소 수

      first

      Boolean

      첫 페이지 여부

      last

      Boolean

      마지막 페이지 여부

      sort.empty

      Boolean

      정렬 정보가 비어있는지 여부

      sort.unsorted

      Boolean

      정렬되지 않은 상태인지 여부

      sort.sorted

      Boolean

      정렬된 상태인지 여부

      empty

      Boolean

      비어있는 페이지 여부

      +
      +
      +
      +
      +
      +

      과제 제안 상세 조회 (GET /proposals/{proposalId})

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}
      ParameterDescription

      proposalId

      수정할 과제제안 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      GET /proposals/1 HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Host: localhost:8080
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 287
      +
      +{
      +  "id" : 1,
      +  "authorName" : "작성자",
      +  "email" : "작성자@email.com",
      +  "webSite" : "website.com",
      +  "title" : "과제 제안 제목",
      +  "projectTypes" : [ "LAB", "CLUB", "STARTUP", "RESEARCH_AND_BUSINESS_FOUNDATION" ],
      +  "content" : "과제제안 내용",
      +  "replied" : false
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 ID

      authorName

      String

      과제 제안 작성자

      email

      String

      과제 제안 이메일

      webSite

      String

      과제 제안 사이트

      title

      String

      과제 제안 제목

      projectTypes

      Array

      과제 제안 프로젝트 유형들

      content

      String

      과제 제안 내용

      replied

      Boolean

      과제 제안 답변 유무

      +
      +
      +
      +
      +
      +

      과제 제안 수정 (PUT /proposals/{proposalId})

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}
      ParameterDescription

      proposalId

      수정할 과제제안 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      PUT /proposals/1 HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Content-Length: 220
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "webSite" : "website.com",
      +  "title" : "과제제안제목",
      +  "email" : "이메일@email.com",
      +  "projectTypes" : [ "LAB", "CLUB" ],
      +  "content" : "과제제안내용",
      +  "isVisible" : true,
      +  "isAnonymous" : true
      +}
      +
      +
      +
      +
      +

      Request fields

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      title

      String

      true

      과제제안 제목

      content

      String

      true

      과제제안 내용

      webSite

      String

      과제제안 사이트

      projectTypes

      Array

      true

      과제제안 프로젝트 유형들

      email

      String

      true

      과제제안 이메일

      isVisible

      Boolean

      true

      공개 여부

      isAnonymous

      Boolean

      true

      익명 여부

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 237
      +
      +{
      +  "id" : 1,
      +  "authorName" : "작성자",
      +  "email" : "이메일@email.com",
      +  "webSite" : "website.com",
      +  "title" : "과제제안제목",
      +  "projectTypes" : [ "LAB", "CLUB" ],
      +  "content" : "과제제안내용",
      +  "replied" : false
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 ID

      authorName

      String

      과제 제안 작성자

      email

      String

      과제 제안 이메일

      webSite

      String

      과제 제안 사이트

      title

      String

      과제 제안 제목

      projectTypes

      Array

      과제 제안 프로젝트 유형들

      content

      String

      과제 제안 내용

      replied

      Boolean

      과제 제안 답변 유무

      +
      +
      +
      +
      +
      +

      과제 제안 삭제 (DELETE /proposals/{proposalId})

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}
      ParameterDescription

      proposalId

      삭제할 과제제안 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      DELETE /proposals/1 HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 204 No Content
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +
      +
      +
      +
      +
      +
      +
      +

      과제 제안 답변 조회 (GET /proposals/{proposalId}/reply)

      +
      +
      +
      +

      Query parameters

      +
      +

      Snippet query-parameters not found for operation::proposal-controller-test/get-proposal-replies

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /proposals/1/reply HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 100
      +
      +{
      +  "id" : 1,
      +  "title" : "과제제안 답변 제목",
      +  "content" : "과제제안 답변 내용"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 답변 ID

      title

      String

      과제 제안 답변 제목

      content

      String

      과제 제안 답변 내용

      +
      +
      +
      +
      +
      +

      과제 제안 답변 생성 (PUT /proposals/{proposalId}/reply/)

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}/reply
      ParameterDescription

      proposalId

      해당 과제제안 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      POST /proposals/1/reply HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Content-Length: 62
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "title" : "답변 제목",
      +  "content" : "답변 내용"
      +}
      +
      +
      +
      +
      +

      Request fields

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      title

      String

      true

      과제제안 답변 제목

      content

      String

      true

      과제제안 답변 내용

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 201 Created
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 74
      +
      +{
      +  "id" : 1,
      +  "title" : "답변 제목",
      +  "content" : "답변 내용"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 답변 ID

      title

      String

      과제 제안 답변 제목

      content

      String

      과제 제안 답변 내용

      +
      +
      +
      +
      +
      +

      과제 제안 답변 수정 (PUT /proposals/{proposalId}/reply/{replyId})

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}/reply/{replyId}
      ParameterDescription

      proposalId

      해당 과제제안 ID

      replyId

      과제 제안 답변 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      PUT /proposals/1/reply/1 HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Content-Length: 62
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "title" : "답변 제목",
      +  "content" : "답변 내용"
      +}
      +
      +
      +
      +
      +

      Request fields

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      title

      String

      true

      과제제안 답변 제목

      content

      String

      true

      과제제안 답변 내용

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json;charset=UTF-8
      +Content-Length: 74
      +
      +{
      +  "id" : 1,
      +  "title" : "답변 제목",
      +  "content" : "답변 내용"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      과제 제안 답변 ID

      title

      String

      과제 제안 답변 제목

      content

      String

      과제 제안 답변 내용

      +
      +
      +
      +
      +
      +

      과제 제안 답변 삭제 (DELETE /proposals/{proposalId}/reply/{replyId})

      +
      +
      +
      +

      Path parameters

      + + ++++ + + + + + + + + + + + + + + + + +
      Table 1. /proposals/{proposalId}/reply/{proposalReplyId}
      ParameterDescription

      proposalId

      해당 과제제안 ID

      proposalReplyId

      삭제할 과제제안 답변 ID

      +
      +
      +

      HTTP request

      +
      +
      +
      DELETE /proposals/1/reply/1 HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: admin_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 204 No Content
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/src/main/resources/static/docs/quiz.html b/src/main/resources/static/docs/quiz.html index 8161291b..044d2b30 100644 --- a/src/main/resources/static/docs/quiz.html +++ b/src/main/resources/static/docs/quiz.html @@ -506,10 +506,8 @@

      HTTP response

      Content-Length: 739 { - "totalElements" : 2, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 2, "size" : 10, "content" : [ { "userId" : 1, @@ -530,7 +528,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 2, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -543,6 +540,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 2, + "first" : true, + "last" : true, "empty" : false }
      @@ -772,15 +772,15 @@

      HTTP response

      Vary: Access-Control-Request-Headers Content-Type: application/octet-stream;charset=UTF-8 Content-Disposition: attachment; filename=excel.xlsx -Content-Length: 2822 +Content-Length: 2821 PK-[Content_Types].xml�S�n1 ��U��&����X8�ql�J?�M��y)1��^�RT�S��xfl%��ڻj���q+G� ���k����~U!\ ؈�t2�o��[CiDO��*�GEƄ��6f�e�T����ht�t ��j4�d��-,UO��A�����S�U0G��^Pft[N�m*7L�˚Uv�0Z�:��q�������E�mk5����[$�M�23Y��A�7�,��<c�(���x֢cƳ �E�GӖ�L��;Yz�h>(�c�b��/�s�Ɲ��`�\s|J6�r��y���௶�j�PK�q,-�PK- _rels/.rels���j�0 �_���8�`�Q��2�m��4[ILb��ږ���.[K �($}��v?�I�Q.���uӂ�h���x>=��@��p�H"�~�}� �n����*"�H�׺؁�����8�Z�^'�#��7m{��O�3���G�u�ܓ�'��y|a�����D� ��l_EYȾ����vql3�ML�eh���*���\3�Y0���oJ׏� :��^��}PK��z��IPK-docProps/app.xmlM�� �0D�~EȽ��ADҔ���A? ��6�lB�J?ߜ���0���ͯ�)�@��׍H6���V>��$;�SC ;̢(�ra�g�l�&�e��L!y�%��49��`_���4G���F��J��Wg �GS�b���� -~�PK�|wؑ�PK-docProps/core.xmlm��J�0E��=M�e mQ�gP| ɱ-6�hǿ7�c�-�^gq���A �;:�]��$A-��u[��n��H�גFcM�!�� �p�Ez�I�hτ�I�e^t���"�c�b��!^] ��W�"y~ -�<p���]�䨔bQ�77�)T���Q�a:�����<�~��q��r��F��n���^O_H��f�!(�(`���F�����z�!M�')���bGKV����s��'��ٸ�2�a�����幂?57�PK�_*X�PK-xl/sharedStrings.xml=�A� ツ��.z0Ɣ�`� �����,�����q2��o�ԇ���N�E��x5�z>�W���(R�K���^4{�����ŀ�5��y�V����y�m�XV�\�.�j���� 8�PKp��&x�PK- xl/styles.xml���n� ��>bop2TQ��P)U�RWb�6*�����ӤS�Nw�s���3ߍ֐ ���t��(l��������ҝx�!N=@$ɀ��}��3c���ʰr`:i��2��w, � -�d �T��R#�voc �;c�iE��Û��E<|��4Iɣ����F#��n���B�z�F���y�j3y��yҥ�jt>���2��Lژ�!6��2F�OY��4@M�!���G��������1�t��y��p��" n����u�����a�ΦDi�9�&#��%I��9��}���cK��T��$?������`J������7���o��f��M|PK�1X@C�PK-xl/workbook.xmlM���0��>E�wi1ƨ����z/�HmI�_j��qf��)ʧٌ��w�LC��ָ��[u��T�b�a��؊;���8�9��G�)��5�|�:�2<8MuK=b�#� q�V�u ����K��H\)�\�&�t͌��%���?��B��T� PK ���PK-xl/_rels/workbook.xml.rels��ͪ1 �_�d�tt!"V7� n������LZ�(����r�� ��p����6�JY���U ����s����;[�E8D&a��h@- ��$� Xt�im���F�*&�41���̭M��ؒ]����WL�f�}��9anIH���Qs1���KtO��ll���O���X߬� �{�ŋ����œ�?o'�>PK�(2��PK-�q,-�[Content_Types].xmlPK-��z��I v_rels/.relsPK-�|wؑ��docProps/app.xmlPK-�_*X�qdocProps/core.xmlPK-p��&x��xl/sharedStrings.xmlPK-�1X@C� �xl/styles.xmlPK- ���xl/workbook.xmlPK-�(2���xl/_rels/workbook.xml.relsPK��
      +~�PK�|wؑ�PK-docProps/core.xmlm��J�0F_%依����.�,� �(ޅdl��I��ֵۛ� +�H�;s�L�=ꁼ��55eyA iUoښ>vن��Qb�kj,�6�t\Z�{o��c Ic���]��١!O�I��Z���-8!_E�P�9h�B�(`fn1ғR�E���0 �P��X�����u��aN����1W3�&b�t{s?��f��D�T'5�EDE����6�<�.�;ڔEy�1��́|�N繂_����n}s��!��]O�R��Ϛ�OPK���x�PK-xl/sharedStrings.xml=�A� ツ��.z0Ɣ�`� �����,�����q2��o�ԇ���N�E��x5�z>�W���(R�K���^4{�����ŀ�5��y�V����y�m�XV�\�.�j���� 8�PKp��&x�PK- xl/styles.xml���n� ��>bop2TQ��P)U�RWb�6*�����ӤS�Nw�s���3ߍ֐ ���t��(l��������ҝx�!N=@$ɀ��}��3c���ʰr`:i��2��w, � +�d �T��R#�voc �;c�iE��Û��E<|��4Iɣ����F#��n���B�z�F���y�j3y��yҥ�jt>���2��Lژ�!6��2F�OY��4@M�!���G��������1�t��y��p��" n����u�����a�ΦDi�9�&#��%I��9��}���cK��T��$?������`J������7���o��f��M|PK�1X@C�PK-xl/workbook.xmlM���0��>E�wi1ƨ����z/�HmI�_j��qf��)ʧٌ��w�LC��ָ��[u��T�b�a��؊;���8�9��G�)��5�|�:�2<8MuK=b�#� q�V�u ����K��H\)�\�&�t͌��%���?��B��T� PK ���PK-xl/_rels/workbook.xml.rels��ͪ1 �_�d�tt!"V7� n������LZ�(����r�� ��p����6�JY���U ����s����;[�E8D&a��h@- ��$� Xt�im���F�*&�41���̭M��ؒ]����WL�f�}��9anIH���Qs1���KtO��ll���O���X߬� �{�ŋ����œ�?o'�>PK�(2��PK-�q,-�[Content_Types].xmlPK-��z��I v_rels/.relsPK-�|wؑ��docProps/app.xmlPK-���x�qdocProps/core.xmlPK-p��&x��xl/sharedStrings.xmlPK-�1X@C� xl/styles.xmlPK- ���xl/workbook.xmlPK-�(2���xl/_rels/workbook.xml.relsPK��
      @@ -793,7 +793,7 @@

      HTTP response

      diff --git a/src/main/resources/static/docs/talk.html b/src/main/resources/static/docs/talk.html index 402adee4..fd1793cf 100644 --- a/src/main/resources/static/docs/talk.html +++ b/src/main/resources/static/docs/talk.html @@ -562,7 +562,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 464 +Content-Length: 465 { "id" : 1, @@ -580,8 +580,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-10-29T22:38:57.956919", - "updatedAt" : "2024-10-29T22:38:57.95692" + "createdAt" : "2024-11-18T19:55:56.391775", + "updatedAt" : "2024-11-18T19:55:56.391777" }
      @@ -749,10 +749,8 @@

      HTTP response

      Content-Length: 999 { - "totalElements" : 1, "totalPages" : 1, - "first" : true, - "last" : true, + "totalElements" : 1, "size" : 10, "content" : [ { "id" : 1, @@ -771,8 +769,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-10-29T22:38:57.964821", - "updatedAt" : "2024-10-29T22:38:57.964822" + "createdAt" : "2024-11-18T19:55:56.416019", + "updatedAt" : "2024-11-18T19:55:56.416023" } ], "number" : 0, "sort" : { @@ -780,7 +778,6 @@

      HTTP response

      "sorted" : false, "unsorted" : true }, - "numberOfElements" : 1, "pageable" : { "pageNumber" : 0, "pageSize" : 10, @@ -793,6 +790,9 @@

      HTTP response

      "paged" : true, "unpaged" : false }, + "numberOfElements" : 1, + "first" : true, + "last" : true, "empty" : false }
      @@ -1067,7 +1067,7 @@

      HTTP response

      Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json;charset=UTF-8 -Content-Length: 485 +Content-Length: 486 { "id" : 1, @@ -1086,8 +1086,8 @@

      HTTP response

      "answer" : 0, "options" : [ "선지1", "선지2" ] } ], - "createdAt" : "2024-10-29T22:38:57.949768", - "updatedAt" : "2024-10-29T22:38:57.94977" + "createdAt" : "2024-11-18T19:55:56.373952", + "updatedAt" : "2024-11-18T19:55:56.373955" }
      @@ -1352,8 +1352,8 @@

      HTTP response

      "answer" : 0, "options" : [ "수정한 선지1", "수정한 선지2" ] } ], - "createdAt" : "2024-10-29T22:38:57.913428", - "updatedAt" : "2024-10-29T22:38:57.913431" + "createdAt" : "2024-11-18T19:55:56.226099", + "updatedAt" : "2024-11-18T19:55:56.226104" }
      @@ -1949,7 +1949,7 @@

      Response fields

      diff --git a/src/main/resources/static/docs/user-controller-test.html b/src/main/resources/static/docs/user-controller-test.html new file mode 100644 index 00000000..30efc3b2 --- /dev/null +++ b/src/main/resources/static/docs/user-controller-test.html @@ -0,0 +1,937 @@ + + + + + + + +유저 API + + + + + +
      +
      +

      유저 API

      +
      +
      +
      +

      로그인 유저 기본 정보 조회 (GET /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /users/me HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      Request cookies

      + ++++ + + + + + + + + + + + + +
      NameDescription

      refresh-token

      갱신 토큰

      +
      +
      +

      Request headers

      + ++++ + + + + + + + + + + + + +
      NameDescription

      Authorization

      access token

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 356
      +
      +{
      +  "id" : 1,
      +  "name" : "이름",
      +  "phone" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "socialLoginId" : "아이디",
      +  "userType" : "STUDENT",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "departmentName" : "학과",
      +  "createdAt" : "2024-08-21T15:21:47.871876",
      +  "updatedAt" : "2024-08-21T15:21:47.871886"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      사용자 ID

      name

      String

      사용자 이름

      phone

      String

      사용자 전화번호

      email

      String

      사용자 이메일

      socialLoginId

      String

      사용자 이메일

      userType

      String

      사용자 유형

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      departmentName

      String

      학과 이름

      createdAt

      String

      생성일

      updatedAt

      String

      수정일

      +
      +
      +
      +
      +
      +

      로그인 유저 기본 정보 수정 (PUT /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      PUT /users/me HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: user_access_token
      +Content-Length: 193
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "name" : "이름",
      +  "phone" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "departmentName" : "학과"
      +}
      +
      +
      +
      +
      +

      Request cookies

      + ++++ + + + + + + + + + + + + +
      NameDescription

      refresh-token

      갱신 토큰

      +
      +
      +

      Request headers

      + ++++ + + + + + + + + + + + + +
      NameDescription

      Authorization

      access token

      +
      +
      +

      Request fields

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      name

      String

      true

      이름

      phone

      String

      true

      전화번호

      email

      String

      true

      이메일

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      departmentName

      String

      학과

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 356
      +
      +{
      +  "id" : 1,
      +  "name" : "이름",
      +  "phone" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "socialLoginId" : "아이디",
      +  "userType" : "STUDENT",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "departmentName" : "학과",
      +  "createdAt" : "2024-08-21T15:21:47.966909",
      +  "updatedAt" : "2024-08-21T15:21:47.967104"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      사용자 ID

      name

      String

      사용자 이름

      phone

      String

      사용자 전화번호

      email

      String

      사용자 이메일

      socialLoginId

      String

      사용자 이메일

      userType

      String

      사용자 유형

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      departmentName

      String

      학과 이름

      createdAt

      String

      생성일

      updatedAt

      String

      수정일

      +
      +
      +
      +
      +
      +

      유저 탈퇴 (DELETE /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      DELETE /users/me HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      Request cookies

      + ++++ + + + + + + + + + + + + +
      NameDescription

      refresh-token

      갱신 토큰

      +
      +
      +

      Request headers

      + ++++ + + + + + + + + + + + + +
      NameDescription

      Authorization

      access token

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 204 No Content
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/src/main/resources/static/docs/user.html b/src/main/resources/static/docs/user.html new file mode 100644 index 00000000..53114208 --- /dev/null +++ b/src/main/resources/static/docs/user.html @@ -0,0 +1,1052 @@ + + + + + + + +유저 API + + + + + +
      +
      +

      유저 API

      +
      +
      +
      +

      로그인 유저 기본 정보 조회 (GET /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /users/me HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 323
      +
      +{
      +  "id" : 1,
      +  "name" : "이름",
      +  "phone" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "userType" : "STUDENT",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "departmentName" : "학과",
      +  "createdAt" : "2024-10-12T22:04:36.086629",
      +  "updatedAt" : "2024-10-12T22:04:36.086638"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      사용자 ID

      name

      String

      사용자 이름

      phone

      String

      사용자 전화번호

      email

      String

      사용자 이메일

      userType

      String

      사용자 유형

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      departmentName

      String

      학과 이름

      createdAt

      String

      생성일

      updatedAt

      String

      수정일

      +
      +
      +
      +
      +
      +

      로그인 유저 기본 정보 수정 (PUT /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      PUT /users/me HTTP/1.1
      +Content-Type: application/json;charset=UTF-8
      +Authorization: user_access_token
      +Content-Length: 195
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +{
      +  "name" : "이름",
      +  "phoneNumber" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "department" : "학과"
      +}
      +
      +
      +
      +
      +

      Request fields

      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeRequiredDescription

      name

      String

      true

      이름

      phoneNumber

      String

      true

      전화번호

      email

      String

      true

      이메일

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      department

      String

      학과

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 323
      +
      +{
      +  "id" : 1,
      +  "name" : "이름",
      +  "phone" : "010-1234-5678",
      +  "email" : "student@g.skku.edu",
      +  "userType" : "STUDENT",
      +  "division" : null,
      +  "position" : null,
      +  "studentNumber" : "2000123456",
      +  "departmentName" : "학과",
      +  "createdAt" : "2024-10-12T22:04:36.170473",
      +  "updatedAt" : "2024-10-12T22:04:36.170481"
      +}
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      id

      Number

      사용자 ID

      name

      String

      사용자 이름

      phone

      String

      사용자 전화번호

      email

      String

      사용자 이메일

      userType

      String

      사용자 유형

      division

      String

      소속

      position

      String

      직책

      studentNumber

      String

      학번

      departmentName

      String

      학과 이름

      createdAt

      String

      생성일

      updatedAt

      String

      수정일

      +
      +
      +
      +
      +
      +

      유저 탈퇴 (DELETE /users/me)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      DELETE /users/me HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 204 No Content
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +
      +
      +
      +
      +
      +
      +
      +

      유저 관심 리스트 조회 (GET /users/favorites)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /users/favorites?type=TALK HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      Query parameters

      + ++++ + + + + + + + + + + + + +
      ParameterDescription

      type

      관심 항목의 타입 (PROJECT, TALK, JOBINTERVIEW)

      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 142
      +
      +[ {
      +  "id" : 1,
      +  "title" : "Project 1",
      +  "youtubeId" : "youtube 1"
      +}, {
      +  "id" : 2,
      +  "title" : "Project 2",
      +  "youtubeId" : "youtube 2"
      +} ]
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      [].id

      Number

      ID

      [].title

      String

      제목

      [].youtubeId

      String

      유튜브 ID

      +
      +
      +
      +
      +
      +

      유저 문의 리스트 조회 (GET /users/inquiries)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /users/inquiries HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 214
      +
      +[ {
      +  "id" : 1,
      +  "title" : "Title 1",
      +  "projectId" : 1,
      +  "createdDate" : "2024-10-12T22:04:36.060407"
      +}, {
      +  "id" : 2,
      +  "title" : "Title 2",
      +  "projectId" : 2,
      +  "createdDate" : "2024-10-12T22:04:36.060452"
      +} ]
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      [].id

      Number

      문의 ID

      [].title

      String

      문의 제목

      [].projectId

      Number

      프로젝트 ID

      [].createdDate

      String

      문의 생성일

      +
      +
      +
      +
      +
      +

      유저 과제 제안 리스트 조회 (GET /users/proposals)

      +
      +
      +
      +

      HTTP request

      +
      +
      +
      GET /users/proposals HTTP/1.1
      +Authorization: user_access_token
      +Host: localhost:8080
      +Cookie: refresh-token=refresh_token
      +
      +
      +
      +
      +

      HTTP response

      +
      +
      +
      HTTP/1.1 200 OK
      +Vary: Origin
      +Vary: Access-Control-Request-Method
      +Vary: Access-Control-Request-Headers
      +Content-Type: application/json
      +Content-Length: 175
      +
      +[ {
      +  "id" : 1,
      +  "title" : "Title 1",
      +  "createdDate" : "2024-10-12T22:04:36.13273"
      +}, {
      +  "id" : 2,
      +  "title" : "Title 2",
      +  "createdDate" : "2024-10-12T22:04:36.132747"
      +} ]
      +
      +
      +
      +
      +

      Response fields

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      PathTypeDescription

      [].id

      Number

      과제 제안 ID

      [].title

      String

      프로젝트명

      [].createdDate

      String

      과제 제안 생성일

      +
      +
      +
      +
      +
      +
      +
      + + + \ No newline at end of file diff --git a/src/test/java/com/scg/stop/file/controller/FileControllerTest.java b/src/test/java/com/scg/stop/file/controller/FileControllerTest.java index bd640726..4ddabe2b 100644 --- a/src/test/java/com/scg/stop/file/controller/FileControllerTest.java +++ b/src/test/java/com/scg/stop/file/controller/FileControllerTest.java @@ -1,15 +1,15 @@ package com.scg.stop.file.controller; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; -import static org.mockito.Mockito.description; import static org.mockito.Mockito.when; +import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; +import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseBody; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.partWithName; @@ -22,6 +22,7 @@ import com.scg.stop.file.domain.File; import com.scg.stop.file.dto.response.FileResponse; import com.scg.stop.file.service.FileService; +import jakarta.servlet.http.Cookie; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -33,13 +34,14 @@ import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.core.io.InputStreamResource; +import org.springframework.core.io.Resource; import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.restdocs.payload.JsonFieldType; import org.springframework.test.web.servlet.ResultActions; -import org.springframework.web.multipart.MultipartFile; @WebMvcTest(FileController.class) @MockBean(JpaMetamodelMappingContext.class) @@ -49,6 +51,9 @@ class FileControllerTest extends AbstractControllerTest { @MockBean private FileService fileService; + private static final String ACCESS_TOKEN = "admin_access_token"; + private static final String REFRESH_TOKEN = "refresh_token"; + @Test @DisplayName("여러개의 파일을 업로드할 수 있다.") void uploadFiles() throws Exception { @@ -142,4 +147,37 @@ void getFile() throws Exception { ) )); } -} \ No newline at end of file + + @Test + @DisplayName("프로젝트 일괄등록 양식을 가져올 수 있다.") + void getProjectExcelForm() throws Exception { + // given + String directoryPath = "form/"; + String fileName = "project_upload_form.xlsx"; + byte[] content = "project_upload_form".getBytes(StandardCharsets.UTF_8); + ByteArrayInputStream inputStream = new ByteArrayInputStream(content); + Resource mockResource = new InputStreamResource(inputStream); + when(fileService.getLocalFile(directoryPath, fileName)).thenReturn(mockResource); + + // when + ResultActions result = mockMvc.perform( + get("/files/form/projects") + .header(HttpHeaders.AUTHORIZATION, ACCESS_TOKEN) + .cookie(new Cookie("refresh-token", REFRESH_TOKEN)) + ); + + // then + result.andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_OCTET_STREAM)) + .andDo(restDocs.document( + requestCookies( + cookieWithName("refresh-token") + .description("갱신 토큰") + ), + requestHeaders( + headerWithName("Authorization") + .description("access token") + ) + )); + } +} diff --git a/src/test/java/com/scg/stop/project/controller/ProjectControllerTest.java b/src/test/java/com/scg/stop/project/controller/ProjectControllerTest.java index e0aeb0ec..948cc9bc 100644 --- a/src/test/java/com/scg/stop/project/controller/ProjectControllerTest.java +++ b/src/test/java/com/scg/stop/project/controller/ProjectControllerTest.java @@ -1,23 +1,7 @@ package com.scg.stop.project.controller; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; -import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; -import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; -import static org.springframework.restdocs.request.RequestDocumentation.*; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import com.fasterxml.jackson.databind.ObjectMapper; import com.scg.stop.configuration.AbstractControllerTest; - -import com.scg.stop.project.controller.ProjectController; import com.scg.stop.project.domain.AwardStatus; import com.scg.stop.project.domain.ProjectCategory; import com.scg.stop.project.domain.ProjectType; @@ -49,6 +33,18 @@ import java.time.LocalDateTime; import java.util.List; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; +import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.request.RequestDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + @WebMvcTest(ProjectController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureRestDocs @@ -673,7 +669,7 @@ void createProjectComment() throws Exception { // given CommentRequest commentRequest = new CommentRequest("댓글 내용", true); - CommentResponse commentResponse = new CommentResponse(1L,1L, "유저 이름", true,"댓글 내용" , LocalDateTime.now(), LocalDateTime.now()); + CommentResponse commentResponse = new CommentResponse(1L, 1L, "유저 이름", true, "댓글 내용", LocalDateTime.now(), LocalDateTime.now()); when(projectService.createProjectComment(anyLong(), any(User.class), any(CommentRequest.class))).thenReturn(commentResponse); @@ -869,4 +865,4 @@ void getAwardProjects() throws Exception { ) )); } -} \ No newline at end of file +} diff --git a/src/test/java/com/scg/stop/project/controller/ProjectExcelControllerTest.java b/src/test/java/com/scg/stop/project/controller/ProjectExcelControllerTest.java new file mode 100644 index 00000000..67158592 --- /dev/null +++ b/src/test/java/com/scg/stop/project/controller/ProjectExcelControllerTest.java @@ -0,0 +1,112 @@ +package com.scg.stop.project.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.scg.stop.configuration.AbstractControllerTest; +import com.scg.stop.file.dto.response.FileResponse; +import com.scg.stop.project.dto.response.ProjectExcelResponse; +import com.scg.stop.project.service.ProjectExcelService; +import jakarta.servlet.http.Cookie; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.test.web.servlet.ResultActions; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.partWithName; +import static org.springframework.restdocs.request.RequestDocumentation.requestParts; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(ProjectExcelController.class) +@MockBean(JpaMetamodelMappingContext.class) +@AutoConfigureRestDocs +class ProjectExcelControllerTest extends AbstractControllerTest { + + @MockBean + private ProjectExcelService projectExcelService; + + @Autowired + private ObjectMapper objectMapper; + + private static final String ADMIN_ACCESS_TOKEN = "admin_access_token"; + private static final String REFRESH_TOKEN = "refresh_token"; + + @Test + @DisplayName("엑셀 양식으로 프로젝트를 일괄등록할 수 있다.") + void createProjectExcel() throws Exception { + // given + MockMultipartFile excelFile = new MockMultipartFile( + "excel", + "project_upload_form.xlsx", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "[BINARY DATA]".getBytes(StandardCharsets.UTF_8) + ); + List thumbnails = Arrays.asList(mockImageFileResponse("썸네일1.png"), mockImageFileResponse("썸네일2.png")); + List posters = Arrays.asList(mockImageFileResponse("포스터1.png"), mockImageFileResponse("포스터2.png")); + MockMultipartFile thumbnailsFile = new MockMultipartFile( + "thumbnails", + "thumbnails.json", + "application/json", + objectMapper.writeValueAsString(thumbnails).getBytes(StandardCharsets.UTF_8) + ); + MockMultipartFile postersFile = new MockMultipartFile( + "posters", + "thumbnails.json", + "application/json", + objectMapper.writeValueAsString(posters).getBytes(StandardCharsets.UTF_8) + ); + ProjectExcelResponse projectExcelResponse = new ProjectExcelResponse(2); + when(projectExcelService.createProjectExcel(any(), any(), any())).thenReturn(projectExcelResponse); + + // when + ResultActions result = mockMvc.perform( + multipart("/projects/excel") + .file(excelFile) + .file(thumbnailsFile) + .file(postersFile) + .header(HttpHeaders.AUTHORIZATION, ADMIN_ACCESS_TOKEN) + .cookie(new Cookie("refresh-token", REFRESH_TOKEN)) + .contentType(MediaType.MULTIPART_FORM_DATA) + ); + + // then + result.andExpect(status().isCreated()) + .andDo(restDocs.document( + requestParts( + partWithName("excel").description("업로드할 Excel 파일"), + partWithName("thumbnails").description("썸네일 등록 응답 JSON 파일"), + partWithName("posters").description("포스터 등록 응답 JSON 파일") + ), + responseFields( + fieldWithPath("successCount").type(JsonFieldType.NUMBER).description("생성에 성공한 프로젝트 개수") + ) + )); + } + + private FileResponse mockImageFileResponse(String fileName) { + return new FileResponse( + 1L, + UUID.randomUUID().toString(), + fileName, + "image/png", + LocalDateTime.now(), + LocalDateTime.now()); + } +}