From bde16436ae648de4272bf277892db729f064d19f Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:30:12 +0900 Subject: [PATCH 1/7] =?UTF-8?q?:sparkles:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moment/scheduler/controller/AiController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/AiController.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/AiController.java index 581e36d462..c91213cde3 100644 --- a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/AiController.java +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/AiController.java @@ -17,8 +17,8 @@ public class AiController { private final AiService aiService; - @PostMapping("/run") - public AiModelRunResponseDTO.RunModel runAi(@RequestBody AiModelRunRequestDTO.RunModel request) { - return aiService.runAi(request.getFile_name()); - } +// @PostMapping("/run") +// public AiModelRunResponseDTO.RunModel runAi(@RequestBody AiModelRunRequestDTO.RunModel request) { +// return aiService.runAi(request.getFile_name()); +// } } From 8b1b749db4a9f47bf3091d39a14fdafb5862e1e6 Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:32:22 +0900 Subject: [PATCH 2/7] =?UTF-8?q?:sparkles:=20S3=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/moment/core/config/S3Config.java | 34 ++++++ .../core/controller/RootController.java | 42 ++++++- .../moment/core/service/CardViewService.java | 11 +- .../com/moment/core/service/S3Service.java | 110 ++++++++++++++++++ .../controller/SchedulerController.java | 8 +- .../dto/response/SchedulerResponseDTO.java | 17 +++ .../moment/scheduler/service/AiService.java | 6 +- .../scheduler/service/CardViewService.java | 44 ++++++- 8 files changed, 256 insertions(+), 16 deletions(-) create mode 100644 backend/moment/moment-server/core/src/main/java/com/moment/core/config/S3Config.java create mode 100644 backend/moment/moment-server/core/src/main/java/com/moment/core/service/S3Service.java create mode 100644 backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/response/SchedulerResponseDTO.java diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/config/S3Config.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/config/S3Config.java new file mode 100644 index 0000000000..6b21f0bf03 --- /dev/null +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/config/S3Config.java @@ -0,0 +1,34 @@ +package com.moment.core.config; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class S3Config { + + @Value("${cloud.aws.s3.credentials.access-key}") + private String accessKey; + + @Value("${cloud.aws.s3.credentials.secret-key}") + private String secretKey; + + @Value("${cloud.aws.s3.region.static}") + private String region; + + @Bean + public AmazonS3Client amazonS3Client() { + BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); + + return (AmazonS3Client) AmazonS3ClientBuilder + .standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .build(); + } +} \ No newline at end of file diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/RootController.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/RootController.java index 4495446ef4..b1cf2823ef 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/RootController.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/RootController.java @@ -1,12 +1,15 @@ package com.moment.core.controller; +import com.moment.core.service.S3Service; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties; import org.springframework.core.env.Environment; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.time.LocalDateTime; @RestController @AllArgsConstructor @@ -14,6 +17,7 @@ public class RootController { private final Environment env; + private final S3Service s3Service; @GetMapping("/health-check") public ResponseEntity healthCheck() { @@ -21,4 +25,36 @@ public ResponseEntity healthCheck() { log.info("health-check called" ); return ResponseEntity.ok("I'm alive : " + env.getProperty("server.port")); } + + @PostMapping("/test/s3") + public ResponseEntity testS3( + @RequestHeader Long userId, + @RequestPart MultipartFile recordFile + ) { + try { + return ResponseEntity.ok(s3Service.uploadFile(recordFile, userId, LocalDateTime.now().toString(), true)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @PostMapping("/test/s3/folder") + public ResponseEntity testS3Folder( + @RequestHeader Long userId, + @RequestParam String folderName + ) { + s3Service.createFolder(userId.toString()); + return ResponseEntity.ok("test-s3-folder called"); + } + + @DeleteMapping("/test/s3") + public ResponseEntity deleteS3( + @RequestHeader Long userId, + @RequestParam String fileName + ) { +// fileName = "users/" + userId.toString() + "/" + fileName; + fileName = "users/" + userId.toString(); + s3Service.deleteFile(fileName); + return ResponseEntity.ok("delete-s3 called"); + } } diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/service/CardViewService.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/CardViewService.java index 74fcfee5c5..5237a5a563 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/service/CardViewService.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/CardViewService.java @@ -17,6 +17,7 @@ import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -30,18 +31,20 @@ public class CardViewService { private final TripService tripService; private final TripFileService tripFileService; private final ImageFileService imageFileService; + private final S3Service s3Service; @Value("${file.path}") private String filePath; @Autowired - public CardViewService(CardViewRepository cardViewRepository, UserRepository userRepository, TripService tripService, TripFileService tripFileService, ImageFileService imageFileService) { + public CardViewService(CardViewRepository cardViewRepository, UserRepository userRepository, TripService tripService, TripFileService tripFileService, ImageFileService imageFileService, S3Service s3Service) { this.cardViewRepository = cardViewRepository; this.userRepository = userRepository; this.tripService = tripService; this.tripFileService = tripFileService; this.imageFileService = imageFileService; + this.s3Service = s3Service; } @@ -69,7 +72,7 @@ public CardViewResponseDTO.GetCardView uploadRecord(CardViewRequestDTO.UploadRec String fileName = createFileName(recordFile.getOriginalFilename()); // 로컬 저장소에 파일 저장 - recordFile.transferTo(new File(getFullPath(fileName))); + String url = s3Service.uploadToS3(recordFile, userId, fileName, true); CardView cardView = CardView.builder() .recordedAt(uploadRecord.getRecordedAt()) @@ -83,7 +86,7 @@ public CardViewResponseDTO.GetCardView uploadRecord(CardViewRequestDTO.UploadRec .location(uploadRecord.getLocation()) .recordFileStatus("WAIT") .recordFileLength(length) - .recordFileUrl("") + .recordFileUrl(url) .recordFileName(fileName) // .user(user) .tripFile(tripFile) @@ -100,7 +103,7 @@ public CardViewResponseDTO.GetCardView uploadRecord(CardViewRequestDTO.UploadRec private String createFileName(String originalFilename) { String ext = extractExt(originalFilename); - String uuid = UUID.randomUUID().toString(); + String uuid = LocalDateTime.now().toString(); return uuid + "." + ext; } diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/service/S3Service.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/S3Service.java new file mode 100644 index 0000000000..a73e2b72fc --- /dev/null +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/S3Service.java @@ -0,0 +1,110 @@ +package com.moment.core.service; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.util.IOUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.UrlResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +@Service +@RequiredArgsConstructor +@Slf4j +public class S3Service { + private final AmazonS3 amazonS3; + + @Value("${cloud.aws.s3.bucket}") + private String bucket; + + public String uploadFile(MultipartFile image, Long userId, String fileName, boolean isRecord) throws IOException { + this.validateImageFileExtention(image.getOriginalFilename()); + try { + return this.uploadToS3(image, userId, fileName, isRecord); + } catch (IOException e) { + throw new IOException("S3에 이미지를 업로드하는데 실패했습니다."); + } + } + public String uploadToS3(MultipartFile image, Long userId, String fileName, boolean isRecord) throws IOException { + String s3FileName = "users/" + userId.toString() + "/" + fileName; //S3에 저장될 파일 명 + String extention = Objects.requireNonNull(image.getOriginalFilename()).substring(image.getOriginalFilename().lastIndexOf(".")); + + InputStream is = image.getInputStream(); + byte[] bytes = IOUtils.toByteArray(is); //image를 byte[]로 변환 + + ObjectMetadata metadata = new ObjectMetadata(); //metadata 생성 + if (isRecord) { + metadata.setContentType("audio/" + extention); + } else { + metadata.setContentType("image/" + extention); + } + metadata.setContentLength(bytes.length); + + //S3에 요청할 때 사용할 byteInputStream 생성 + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + + try{ + //S3로 putObject 할 때 사용할 요청 객체 + //생성자 : bucket 이름, 파일 명, byteInputStream, metadata + PutObjectRequest putObjectRequest = + new PutObjectRequest(bucket, s3FileName + extention, byteArrayInputStream, metadata) + .withCannedAcl(CannedAccessControlList.PublicRead); + + //실제로 S3에 이미지 데이터를 넣는 부분이다. + amazonS3.putObject(putObjectRequest); // put image to S3 + }catch (Exception e){ + log.error(e.getMessage()); + throw new IOException("S3에 이미지를 업로드하는데 실패했습니다."); + }finally { + byteArrayInputStream.close(); + is.close(); + } + + return amazonS3.getUrl(bucket, s3FileName).toString(); + } + + public ResponseEntity downloadImage(String originalFilename) { + UrlResource urlResource = new UrlResource(amazonS3.getUrl(bucket, originalFilename)); + + String contentDisposition = "attachment; filename=\"" + originalFilename + "\""; + + // header에 CONTENT_DISPOSITION 설정을 통해 클릭 시 다운로드 진행 + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) + .body(urlResource); + + } + + public void deleteFile(String originalFilename) { + amazonS3.deleteObject(bucket, originalFilename); + } + + public void createFolder(String folderName) { + amazonS3.putObject(bucket, folderName + "/", new ByteArrayInputStream(new byte[0]), new ObjectMetadata()); + } + + public void validateImageFileExtention(String filename) throws IOException { + int lastDotIndex = filename.lastIndexOf("."); + if (lastDotIndex == -1) { + throw new IOException("파일에 확장자가 없습니다."); + } + + String extention = filename.substring(lastDotIndex + 1).toLowerCase(); + List allowedExtentionList = Arrays.asList("jpg", "jpeg", "png", "gif", "m4a", "mp4", "wav"); + + if (!allowedExtentionList.contains(extention)) { + throw new IOException("허용되지 않는 확장자입니다."); + } + } +} diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/SchedulerController.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/SchedulerController.java index fd33c2c1a0..3569ff6e82 100644 --- a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/SchedulerController.java +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/controller/SchedulerController.java @@ -1,8 +1,12 @@ package com.moment.scheduler.controller; +import com.moment.scheduler.common.APIResponse; +import com.moment.scheduler.common.code.SuccessCode; +import com.moment.scheduler.dto.response.SchedulerResponseDTO; import com.moment.scheduler.service.AiService; import com.moment.scheduler.service.CardViewService; import lombok.AllArgsConstructor; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -14,7 +18,7 @@ public class SchedulerController { private final CardViewService cardViewService; @PatchMapping("/run") - public void runScheduler() { - cardViewService.getIncompleteCardViews(); + public ResponseEntity> runScheduler() throws InterruptedException { + return ResponseEntity.ok(APIResponse.of(SuccessCode.EXECUTE_SUCCESS, cardViewService.getIncompleteCardViews())); } } diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/response/SchedulerResponseDTO.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/response/SchedulerResponseDTO.java new file mode 100644 index 0000000000..fa64d5a691 --- /dev/null +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/response/SchedulerResponseDTO.java @@ -0,0 +1,17 @@ +package com.moment.scheduler.dto.response; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +public class SchedulerResponseDTO { + @Getter + @Setter + @Builder + public static class AIModelRunResponseDTO { + private final Integer totalRecordNum; + private final Integer successRecordNum; + private final Integer failRecordNum; + private final Long totalElapsedTime; + } +} diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/AiService.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/AiService.java index 0e1df7efd4..6604c9be8b 100644 --- a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/AiService.java +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/AiService.java @@ -12,13 +12,13 @@ @AllArgsConstructor public class AiService { private final AiClient aiClient; - private final static String file_path = ""; + private final static String file_path = "users/"; - public AiModelRunResponseDTO.RunModel runAi(String fileName) { + public AiModelRunResponseDTO.RunModel runAi(String fileName, Long userId) { return aiClient.runAi( AiModelRunRequestDTO.RunModel.builder() .file_name(fileName) - .file_path(file_path) + .file_path(file_path + userId + "/") .build() ); } diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/CardViewService.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/CardViewService.java index 96466ba814..faa41ec5fc 100644 --- a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/CardViewService.java +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/CardViewService.java @@ -10,6 +10,8 @@ import com.moment.scheduler.domain.user.UserRepository; import com.moment.scheduler.dto.response.AiModelRunResponseDTO; +import com.moment.scheduler.dto.response.SchedulerResponseDTO; +import jakarta.persistence.criteria.CriteriaBuilder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; @@ -18,6 +20,8 @@ import java.util.List; import java.util.Objects; +import static java.lang.Thread.sleep; + @Service @RequiredArgsConstructor @@ -27,12 +31,27 @@ public class CardViewService { private final AiService aiService; private final TripRepository tripRepository; private final TripFileRepository tripFileRepository; + private final AwsService awsService; - @Async - public void getIncompleteCardViews() { + public SchedulerResponseDTO.AIModelRunResponseDTO getIncompleteCardViews() throws InterruptedException { + // ec2가 켜져있는지 확인 +// if (awsService.isEc2Running()){ +// throw new RuntimeException("EC2 is already running"); +// } +// awsService.turnOnOrOff("moment-ai", true); +// while (!awsService.isEc2Running()){ +// sleep(3000); +// } + // 경과 시간 체크를 위한 시작 시간 + long startTime = System.currentTimeMillis(); List cards = cardViewRepository.findAllByRecordFileStatusIn(List.of("WAIT", "FAIL")); + Integer totalCardNum = cards.size(); + Integer failRecordNum = 0; + Integer successRecordNum = 0; + + log.info("cards.size : " + cards.size()); for (CardView card : cards) { - AiModelRunResponseDTO.RunModel ret = aiService.runAi(card.getRecordFileName()); + AiModelRunResponseDTO.RunModel ret = aiService.runAi(card.getRecordFileName(), card.getTripFile().getTrip().getUser().getId()); log.info("ret.status : " + ret.getStatus()); log.info("ret.text : " + ret.getText()); log.info("ret.happy : " + ret.getEmotions().getHappy()); @@ -42,7 +61,7 @@ public void getIncompleteCardViews() { log.info("ret.error : " + ret.getError()); log.info("ret.file_name : " + ret.getFile_name()); log.info("ret.file_path : " + ret.getFile_path()); - if (Objects.equals(ret.getStatus(), "wait")){ + if (Objects.equals(ret.getStatus(), "200")){ card.setRecordFileStatus("DONE"); card.setStt(ret.getText()); card.setHappy(ret.getEmotions().getHappy()); @@ -57,13 +76,30 @@ public void getIncompleteCardViews() { tripRepository.save(trip); tripFileRepository.save(tripFile); cardViewRepository.save(card); + successRecordNum++; } else { + log.info("AI model run failed"); + log.info("status : " + ret.getStatus()); + log.info("error : " + ret.getError()); card.setRecordFileStatus("FAIL"); cardViewRepository.save(card); + failRecordNum++; } } + long endTime = System.currentTimeMillis(); + log.info("AI model run time : " + (endTime - startTime) + "ms"); +// awsService.turnOnOrOff("moment-ai", false); +// while (awsService.isEc2Running()){ +// sleep(3000); +// } + return SchedulerResponseDTO.AIModelRunResponseDTO.builder() + .failRecordNum(failRecordNum) + .successRecordNum(successRecordNum) + .totalRecordNum(totalCardNum) + .totalElapsedTime(endTime - startTime) + .build(); } From f7aeab9ea01a3cff1d3b9c9c1ea35503287a6f29 Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:33:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?:sparkles:=20=EC=9D=B8=EC=A6=9D=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moment/auth/controller/AuthController.java | 5 ++--- .../java/com/moment/auth/service/AuthService.java | 5 ++--- .../moment/auth/controller/AuthControllerTest.java | 14 +++++++++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/controller/AuthController.java b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/controller/AuthController.java index 6fe26402e8..b599c3012d 100644 --- a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/controller/AuthController.java +++ b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/controller/AuthController.java @@ -50,12 +50,11 @@ public ResponseEntity> sendCode( // 인증코드 검증 @PatchMapping("/verify") - public ResponseEntity verifyCode( + public ResponseEntity> verifyCode( @RequestBody AuthRequest.VerifyCode verifyCode, @RequestHeader Long userId ) { - authService.verifyCode(verifyCode, userId); - return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS)); + return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS, authService.verifyCode(verifyCode, userId))); } // 비밀번호 변경 diff --git a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/AuthService.java b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/AuthService.java index 37248191b7..326193bd4f 100644 --- a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/AuthService.java +++ b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/AuthService.java @@ -103,16 +103,15 @@ public TokenResponseDTO.GetTempToken sendCode(AuthRequest.SendCode sendCode) { } - public void verifyCode(AuthRequest.VerifyCode verifyCode, Long userId) { + public TokenResponseDTO.GetToken verifyCode(AuthRequest.VerifyCode verifyCode, Long userId) { User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("잘못된 유저 정보")); if(!Objects.equals(user.getVerificationCode(), verifyCode.getCode())) throw new IllegalArgumentException("잘못된 인증코드"); if (user.getRole() == Role.ROLE_TEMP_USER) { userService.registerUserToCoreServer(user); user.setRole(Role.ROLE_AUTH_USER); } - - userService.save(user); + return jwtTokenUtils.generateToken(provider, iss, user.getId(), user.getRole()); } public void changePassword(AuthRequest.ChangePassword changePassword, Long userId) { diff --git a/backend/moment/moment-server/auth/src/test/java/com/moment/auth/controller/AuthControllerTest.java b/backend/moment/moment-server/auth/src/test/java/com/moment/auth/controller/AuthControllerTest.java index efb9afeabf..d712bc3ef4 100644 --- a/backend/moment/moment-server/auth/src/test/java/com/moment/auth/controller/AuthControllerTest.java +++ b/backend/moment/moment-server/auth/src/test/java/com/moment/auth/controller/AuthControllerTest.java @@ -79,7 +79,6 @@ void login() throws Exception { fieldWithPath("data.accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), fieldWithPath("data.refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰"), fieldWithPath("data.role").type(JsonFieldType.STRING).description("사용자 권한") - ) )) .andDo(print()); @@ -129,11 +128,17 @@ void sendCode() throws Exception { @Test void verifyCode() throws Exception { + TokenResponseDTO.GetToken responseDTO = TokenResponseDTO.GetToken.builder() + .accessToken("accessToken") + .refreshToken("refresh") + .grantType("Bearer") + .role(Role.ROLE_AUTH_USER) + .build(); AuthRequest.VerifyCode verifyCode = AuthRequest.VerifyCode.builder() .code("1234") .build(); - Mockito.doNothing().when(authService).verifyCode(any(AuthRequest.VerifyCode.class), any()); + Mockito.when(authService.verifyCode(any(AuthRequest.VerifyCode.class), any())).thenReturn(responseDTO); mockMvc.perform(RestDocumentationRequestBuilders.patch("/auth/verify") .contentType(MediaType.APPLICATION_JSON) @@ -154,7 +159,10 @@ void verifyCode() throws Exception { fieldWithPath("code").type(JsonFieldType.STRING).description("응답 코드"), fieldWithPath("msg").type(JsonFieldType.STRING).description("응답 메시지"), fieldWithPath("detailMsg").type(JsonFieldType.STRING).description("상세 메시지"), - fieldWithPath("data").type(JsonFieldType.OBJECT).description("데이터 없음") + fieldWithPath("data.grantType").type(JsonFieldType.STRING).description("토큰 타입"), + fieldWithPath("data.accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), + fieldWithPath("data.refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰"), + fieldWithPath("data.role").type(JsonFieldType.STRING).description("사용자 권한") ) )) .andDo(print()); From 0c13e170e61d91ac12ffc9a310586f0fe90ed128 Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:34:54 +0900 Subject: [PATCH 4/7] =?UTF-8?q?:sparkles:=20Noti=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scheduler/dto/request/FcmSendDto.java | 21 +++++++++++++++++++ .../moment/scheduler/service/NotiService.java | 17 +++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/request/FcmSendDto.java create mode 100644 backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/NotiService.java diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/request/FcmSendDto.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/request/FcmSendDto.java new file mode 100644 index 0000000000..21c2e6acc9 --- /dev/null +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/dto/request/FcmSendDto.java @@ -0,0 +1,21 @@ +package com.moment.scheduler.dto.request; + +import lombok.*; + +@Getter +@ToString +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class FcmSendDto { + private String token; + + private String title; + + private String body; + + @Builder(toBuilder = true) + public FcmSendDto(String token, String title, String body) { + this.token = token; + this.title = title; + this.body = body; + } +} diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/NotiService.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/NotiService.java new file mode 100644 index 0000000000..7643bdc0e5 --- /dev/null +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/service/NotiService.java @@ -0,0 +1,17 @@ +package com.moment.scheduler.service; + +import com.moment.scheduler.domain.user.UserRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class NotiService { + private final UserRepository userRepository; + + public void sendNoti() { + log.info("send noti"); + } +} From fa15b30ef2668e1ae690667651683f78d59c2045 Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:35:11 +0900 Subject: [PATCH 5/7] =?UTF-8?q?:sparkles:=20=EC=9C=A0=EC=A0=80=EC=97=90=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=EA=B0=92=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/dto/request/UserRequestDTO.java | 5 +++++ .../com/moment/auth/service/UserService.java | 3 +++ .../core/controller/UserController.java | 13 +++++++++++++ .../com/moment/core/domain/user/User.java | 12 ++++++++++++ .../core/dto/request/UserRequestDTO.java | 19 +++++++++++++++++++ .../com/moment/core/service/UserService.java | 11 +++++++++++ .../moment/scheduler/domain/user/User.java | 11 +++++++++++ 7 files changed, 74 insertions(+) diff --git a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/dto/request/UserRequestDTO.java b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/dto/request/UserRequestDTO.java index d9048290f4..df0031f4d3 100644 --- a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/dto/request/UserRequestDTO.java +++ b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/dto/request/UserRequestDTO.java @@ -15,6 +15,11 @@ public static class registerUser { private Long id; + private boolean notification; + + private boolean dataUsage; + + private String firebaseToken; } } diff --git a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/UserService.java b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/UserService.java index 5108efde58..183fa92cc2 100644 --- a/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/UserService.java +++ b/backend/moment/moment-server/auth/src/main/java/com/moment/auth/service/UserService.java @@ -24,6 +24,9 @@ public void registerUserToCoreServer(User user) { .builder() .email(user.getEmail()) .id(user.getId()) + .notification(false) + .dataUsage(false) + .firebaseToken("") .build() ); }catch (Exception e){ diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/UserController.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/UserController.java index 2d4a8b2a67..a8ded17d62 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/UserController.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/controller/UserController.java @@ -4,6 +4,7 @@ import com.moment.core.common.code.SuccessCode; import com.moment.core.domain.user.User; import com.moment.core.dto.request.UserRequestDTO; +import com.moment.core.service.S3Service; import com.moment.core.service.UserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -23,6 +24,7 @@ @RequestMapping("/core/user") public class UserController { private final UserService userService; + private final S3Service s3Service; // 유저 등록 @PostMapping("/register") @@ -34,7 +36,18 @@ public class UserController { public ResponseEntity registerUser( @RequestBody UserRequestDTO.registerUser request ) { + s3Service.createFolder(request.getId().toString()); userService.save(request); return ResponseEntity.ok(APIResponse.of(SuccessCode.INSERT_SUCCESS)); } + + // 유저 설정 업데이트 + @PatchMapping("/setting") + public ResponseEntity updateUserSetting( + @RequestBody UserRequestDTO.updateUser request, + @RequestHeader Long userId + ) { + userService.updateUserSetting(request, userId); + return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS)); + } } diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/domain/user/User.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/domain/user/User.java index 037748f6e8..0d29948864 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/domain/user/User.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/domain/user/User.java @@ -21,5 +21,17 @@ public class User extends BaseEntity{ @Column(name = "email", nullable = false, unique = true) private String email; + // 알림설정 유무 + @Column(name = "notification", nullable = false) + private boolean notification; + + // 데이터 사용 유무 + @Column(name = "data_usage", nullable = false) + private boolean dataUsage; + + // firebase token + @Column(name = "firebase_token") + private String firebaseToken; + } diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/dto/request/UserRequestDTO.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/dto/request/UserRequestDTO.java index ef164d6ee5..95f169008c 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/dto/request/UserRequestDTO.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/dto/request/UserRequestDTO.java @@ -1,5 +1,6 @@ package com.moment.core.dto.request; +import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -13,6 +14,24 @@ public static class registerUser { private Long id; + private boolean notification; + private boolean dataUsage; + + private String firebaseToken; + } + + @Getter + @Setter + @Builder + public static class updateUser { + + private String email; + + private boolean notification; + + private boolean dataUsage; + + private String firebaseToken; } } diff --git a/backend/moment/moment-server/core/src/main/java/com/moment/core/service/UserService.java b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/UserService.java index 537b851af5..25ea1b2b1b 100644 --- a/backend/moment/moment-server/core/src/main/java/com/moment/core/service/UserService.java +++ b/backend/moment/moment-server/core/src/main/java/com/moment/core/service/UserService.java @@ -35,6 +35,9 @@ public User save(UserRequestDTO.registerUser request) { User user = User.builder() .id(request.getId()) .email(request.getEmail()) + .notification(request.isNotification()) + .dataUsage(request.isDataUsage()) + .firebaseToken(request.getFirebaseToken()) .build(); // em.persist(user); User managedUser = em.merge(user); @@ -73,4 +76,12 @@ public void validateUserWithCardView(Long userId, Long cardViewId) { throw new UserNotValidException("해당 카드뷰는 유저의 카드뷰가 아닙니다."); } } + + public void updateUserSetting(UserRequestDTO.updateUser request, Long userId) { + User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다.")); + user.setNotification(request.isNotification()); + user.setDataUsage(request.isDataUsage()); + user.setFirebaseToken(request.getFirebaseToken()); + userRepository.save(user); + } } diff --git a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/domain/user/User.java b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/domain/user/User.java index 4616baa098..0b86872bcf 100644 --- a/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/domain/user/User.java +++ b/backend/moment/moment-server/scheduler/src/main/java/com/moment/scheduler/domain/user/User.java @@ -25,5 +25,16 @@ public class User extends BaseEntity { @Column(name = "email", nullable = false, unique = true) private String email; + // 알림설정 유무 + @Column(name = "notification", nullable = false) + private boolean notification; + + // 데이터 사용 유무 + @Column(name = "data_usage", nullable = false) + private boolean dataUsage; + + // firebase token + @Column(name = "firebase_token") + private String firebaseToken; } From 914514c5afb3ca870164fa2f3086c5ac369d157a Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:35:57 +0900 Subject: [PATCH 6/7] =?UTF-8?q?:sparkles:=20API=20=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=EC=B5=9C=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/static/docs/index.html | 1067 +++++++++++++++-- 1 file changed, 977 insertions(+), 90 deletions(-) diff --git a/backend/moment/moment-server/gateway/src/main/resources/static/docs/index.html b/backend/moment/moment-server/gateway/src/main/resources/static/docs/index.html index 2f66b1edd9..d2ac911743 100644 --- a/backend/moment/moment-server/gateway/src/main/resources/static/docs/index.html +++ b/backend/moment/moment-server/gateway/src/main/resources/static/docs/index.html @@ -523,39 +523,51 @@

Moment Application API Document

+
  • TripFile + +
  • +
  • User + +
  • @@ -699,7 +757,7 @@

    Auth

    로그인

    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/auth/login' -i -X POST \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -d '{
    +  "email" : "alexj99@naver.com",
    +  "password" : "1234"
    +}'
    +
    +
    +
    +

    HTTP request

    @@ -1929,6 +2000,41 @@

    +

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 229
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "grantType" : "Bearer",
    +    "accessToken" : "accessToken",
    +    "refreshToken" : "refresh",
    +    "role" : "ROLE_AUTH_USER"
    +  }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ echo '{
    +  "email" : "alexj99@naver.com",
    +  "password" : "1234"
    +}' | http POST 'http://localhost:8080/auth/login' \
    +    'Content-Type:application/json;charset=UTF-8'
    +
    +
    +
    +

    Request body

    @@ -1977,14 +2083,10 @@

    -

    HTTP response

    +

    Response body

    -
    HTTP/1.1 200 OK
    -Content-Type: application/json
    -Content-Length: 229
    -
    -{
    +
    {
       "status" : 200,
       "code" : "200",
       "msg" : "SELECT SUCCESS",
    @@ -2062,6 +2164,20 @@ 

    비밀번호 변경

    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/auth/password' -i -X PATCH \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1' \
    +    -d '{
    +  "code" : "1234",
    +  "newPassword" : "12345"
    +}'
    +
    +
    +
    +

    HTTP request

    @@ -2079,25 +2195,35 @@

    -

    Request headers

    - ---- - - - - - - - - - - - - -
    NameDescription

    userId

    Bearer Token

    +

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 102
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "UPDATE SUCCESS",
    +  "detailMsg" : "",
    +  "data" : { }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ echo '{
    +  "code" : "1234",
    +  "newPassword" : "12345"
    +}' | http PATCH 'http://localhost:8080/auth/password' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +

    Request body

    @@ -2148,14 +2274,31 @@

    -

    HTTP response

    +

    Request headers

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

    userId

    Bearer Token

    +
    +
    +

    Response body

    -
    HTTP/1.1 200 OK
    -Content-Type: application/json
    -Content-Length: 102
    -
    -{
    +
    {
       "status" : 200,
       "code" : "200",
       "msg" : "UPDATE SUCCESS",
    @@ -2213,11 +2356,26 @@ 

    인증코드 요청

    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/auth/code' -i -X POST \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1' \
    +    -d '{
    +  "email" : "alexj99@naver.com",
    +  "isSignUp" : "true"
    +}'
    +
    +
    +
    +

    HTTP request

    POST /auth/code HTTP/1.1
     Content-Type: application/json;charset=UTF-8
    +userId: 1
     Content-Length: 58
     Host: localhost:8080
     
    @@ -2229,6 +2387,42 @@ 

    +

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 215
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "grantType" : "Bearer",
    +    "accessToken" : "accessToken",
    +    "role" : "ROLE_AUTH_USER",
    +    "userId" : 1
    +  }
    +}
    +
    +
    +

    +
    +

    HTTPie request

    +
    +
    +
    $ echo '{
    +  "email" : "alexj99@naver.com",
    +  "isSignUp" : "true"
    +}' | http POST 'http://localhost:8080/auth/code' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +
    +
    +

    Request body

    @@ -2277,14 +2471,10 @@

    -

    HTTP response

    +

    Response body

    -
    HTTP/1.1 200 OK
    -Content-Type: application/json
    -Content-Length: 215
    -
    -{
    +
    {
       "status" : 200,
       "code" : "200",
       "msg" : "SELECT SUCCESS",
    @@ -2362,6 +2552,19 @@ 

    인증코드 확인

    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/auth/verify' -i -X PATCH \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1' \
    +    -d '{
    +  "code" : "1234"
    +}'
    +
    +
    +
    +

    HTTP request

    @@ -2378,25 +2581,39 @@

    -

    Request headers

    - ---- - - - - - - - - - - - - -
    NameDescription

    userId

    Bearer Token

    +

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 229
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "UPDATE SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "grantType" : "Bearer",
    +    "accessToken" : "accessToken",
    +    "refreshToken" : "refresh",
    +    "role" : "ROLE_AUTH_USER"
    +  }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ echo '{
    +  "code" : "1234"
    +}' | http PATCH 'http://localhost:8080/auth/verify' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +

    Request body

    @@ -2439,19 +2656,41 @@

    -

    HTTP response

    -
    -
    -
    HTTP/1.1 200 OK
    -Content-Type: application/json
    -Content-Length: 102
    -
    -{
    +

    Request headers

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

    userId

    Bearer Token

    +
    +
    +

    Response body

    +
    +
    +
    {
       "status" : 200,
       "code" : "200",
       "msg" : "UPDATE SUCCESS",
       "detailMsg" : "",
    -  "data" : { }
    +  "data" : {
    +    "grantType" : "Bearer",
    +    "accessToken" : "accessToken",
    +    "refreshToken" : "refresh",
    +    "role" : "ROLE_AUTH_USER"
    +  }
     }
    @@ -2493,9 +2732,24 @@

    상세 메시지

    -

    data

    -

    Object

    -

    데이터 없음

    +

    data.grantType

    +

    String

    +

    토큰 타입

    + + +

    data.accessToken

    +

    String

    +

    액세스 토큰

    + + +

    data.refreshToken

    +

    String

    +

    리프레시 토큰

    + + +

    data.role

    +

    String

    +

    사용자 권한

    @@ -2520,8 +2774,8 @@

    @@ -2553,8 +2807,8 @@

    {
    -  "startDate" : "2024-04-19",
    -  "endDate" : "2024-04-20",
    +  "startDate" : "2024-04-27",
    +  "endDate" : "2024-04-28",
       "tripName" : "test"
     }
    @@ -2719,22 +2973,22 @@

    @@ -2862,8 +3116,8 @@

    {
       "tripId" : 1,
    -  "startDate" : "2024-04-19",
    -  "endDate" : "2024-04-20",
    +  "startDate" : "2024-04-27",
    +  "endDate" : "2024-04-28",
       "tripName" : "test"
     }

    @@ -3851,11 +4105,644 @@

    +

    TripFile

    +
    +
    +

    여행의 모든 파일 조회

    +
    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/core/tripfile/1' -i -X GET \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1'
    +
    +
    +
    +
    +

    HTTP request

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

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 512
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "tripFiles" : [ {
    +      "id" : 1,
    +      "tripId" : 1,
    +      "email" : "test",
    +      "yearDate" : "2024-04-27",
    +      "analyzingCount" : 1
    +    }, {
    +      "id" : 2,
    +      "tripId" : 2,
    +      "email" : "test",
    +      "yearDate" : "2024-04-28",
    +      "analyzingCount" : 2
    +    }, {
    +      "id" : 3,
    +      "tripId" : 3,
    +      "email" : "test",
    +      "yearDate" : "2024-04-29",
    +      "analyzingCount" : 1
    +    } ]
    +  }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ http GET 'http://localhost:8080/core/tripfile/1' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +
    +
    +
    +

    Path parameters

    + + ++++ + + + + + + + + + + + + +
    Table 1. /core/tripfile/{tripId}
    ParameterDescription

    tripId

    여행 ID

    +
    +
    +

    Request body

    +
    +
    +
    +
    +
    +
    +
    +

    Request headers

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

    userId

    Bearer Token

    +
    +
    +

    Response body

    +
    +
    +
    {
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "tripFiles" : [ {
    +      "id" : 1,
    +      "tripId" : 1,
    +      "email" : "test",
    +      "yearDate" : "2024-04-27",
    +      "analyzingCount" : 1
    +    }, {
    +      "id" : 2,
    +      "tripId" : 2,
    +      "email" : "test",
    +      "yearDate" : "2024-04-28",
    +      "analyzingCount" : 2
    +    }, {
    +      "id" : 3,
    +      "tripId" : 3,
    +      "email" : "test",
    +      "yearDate" : "2024-04-29",
    +      "analyzingCount" : 1
    +    } ]
    +  }
    +}
    +
    +
    +
    +
    +

    Response fields

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

    status

    Number

    응답 상태 코드

    code

    String

    응답 코드

    msg

    String

    응답 메시지

    detailMsg

    String

    상세 메시지

    data.tripFiles[].id

    Number

    파일 ID

    data.tripFiles[].tripId

    Number

    여행 ID

    data.tripFiles[].email

    String

    유저 email

    data.tripFiles[].yearDate

    String

    연월일

    data.tripFiles[].analyzingCount

    Number

    분석 중 파일 개수

    +
    +
    +
    +

    일상기록 조회

    +
    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/core/tripfile/untitled' -i -X GET \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1'
    +
    +
    +
    +
    +

    HTTP request

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

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 512
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "tripFiles" : [ {
    +      "id" : 1,
    +      "tripId" : 1,
    +      "email" : "test",
    +      "yearDate" : "2024-04-27",
    +      "analyzingCount" : 1
    +    }, {
    +      "id" : 2,
    +      "tripId" : 2,
    +      "email" : "test",
    +      "yearDate" : "2024-04-28",
    +      "analyzingCount" : 2
    +    }, {
    +      "id" : 3,
    +      "tripId" : 3,
    +      "email" : "test",
    +      "yearDate" : "2024-04-29",
    +      "analyzingCount" : 1
    +    } ]
    +  }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ http GET 'http://localhost:8080/core/tripfile/untitled' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +
    +
    +
    +

    Request body

    +
    +
    +
    +
    +
    +
    +
    +

    Request headers

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

    userId

    Bearer Token

    +
    +
    +

    Response body

    +
    +
    +
    {
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "SELECT SUCCESS",
    +  "detailMsg" : "",
    +  "data" : {
    +    "tripFiles" : [ {
    +      "id" : 1,
    +      "tripId" : 1,
    +      "email" : "test",
    +      "yearDate" : "2024-04-27",
    +      "analyzingCount" : 1
    +    }, {
    +      "id" : 2,
    +      "tripId" : 2,
    +      "email" : "test",
    +      "yearDate" : "2024-04-28",
    +      "analyzingCount" : 2
    +    }, {
    +      "id" : 3,
    +      "tripId" : 3,
    +      "email" : "test",
    +      "yearDate" : "2024-04-29",
    +      "analyzingCount" : 1
    +    } ]
    +  }
    +}
    +
    +
    +
    +
    +

    Response fields

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

    status

    Number

    응답 상태 코드

    code

    String

    응답 코드

    msg

    String

    응답 메시지

    detailMsg

    String

    상세 메시지

    data.tripFiles[].id

    Number

    파일 ID

    data.tripFiles[].tripId

    Number

    여행 ID

    data.tripFiles[].email

    String

    유저 email

    data.tripFiles[].yearDate

    String

    연월일

    data.tripFiles[].analyzingCount

    Number

    분석 중 파일 개수

    +
    +
    +
    +

    +
    +

    User

    +
    +
    +

    유저 설정값 변경 및 FCM 토큰 등록

    +
    +

    Curl request

    +
    +
    +
    $ curl 'http://localhost:8080/core/user/setting' -i -X PATCH \
    +    -H 'Content-Type: application/json;charset=UTF-8' \
    +    -H 'userId: 1' \
    +    -d '{
    +  "notification" : true,
    +  "dataUsage" : true,
    +  "firebaseToken" : "firebaseToken"
    +}'
    +
    +
    +
    +
    +

    HTTP request

    +
    +
    +
    PATCH /core/user/setting HTTP/1.1
    +Content-Type: application/json;charset=UTF-8
    +userId: 1
    +Content-Length: 86
    +Host: localhost:8080
    +
    +{
    +  "notification" : true,
    +  "dataUsage" : true,
    +  "firebaseToken" : "firebaseToken"
    +}
    +
    +
    +
    +
    +

    HTTP response

    +
    +
    +
    HTTP/1.1 200 OK
    +Content-Type: application/json
    +Content-Length: 102
    +
    +{
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "UPDATE SUCCESS",
    +  "detailMsg" : "",
    +  "data" : { }
    +}
    +
    +
    +
    +
    +

    HTTPie request

    +
    +
    +
    $ echo '{
    +  "notification" : true,
    +  "dataUsage" : true,
    +  "firebaseToken" : "firebaseToken"
    +}' | http PATCH 'http://localhost:8080/core/user/setting' \
    +    'Content-Type:application/json;charset=UTF-8' \
    +    'userId:1'
    +
    +
    +
    +
    +

    Request body

    +
    +
    +
    {
    +  "notification" : true,
    +  "dataUsage" : true,
    +  "firebaseToken" : "firebaseToken"
    +}
    +
    +
    +
    +
    +

    Request fields

    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    필드명타입필수값양식설명

    firebaseToken

    String

    true

    firebaseToken

    notification

    Boolean

    true

    notification

    dataUsage

    Boolean

    true

    dataUsage

    +
    +
    +

    Request headers

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

    userId

    Bearer Token

    +
    +
    +

    Response body

    +
    +
    +
    {
    +  "status" : 200,
    +  "code" : "200",
    +  "msg" : "UPDATE SUCCESS",
    +  "detailMsg" : "",
    +  "data" : { }
    +}
    +
    +
    +
    +
    +

    Response fields

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

    status

    Number

    응답 상태 코드

    code

    String

    응답 코드

    msg

    String

    응답 메시지

    detailMsg

    String

    상세 메시지

    data

    Object

    응답 데이터

    +
    +
    +
    +
    From c5d505726ccd2b0b809d81b90371afcf6be89c68 Mon Sep 17 00:00:00 2001 From: j-yong99 Date: Sat, 27 Apr 2024 19:37:18 +0900 Subject: [PATCH 7/7] =?UTF-8?q?:sparkles:=20=EB=94=94=ED=8E=9C=EB=8D=98?= =?UTF-8?q?=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/moment/moment-server/core/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/moment/moment-server/core/build.gradle b/backend/moment/moment-server/core/build.gradle index 0dee708175..77bc1dd995 100644 --- a/backend/moment/moment-server/core/build.gradle +++ b/backend/moment/moment-server/core/build.gradle @@ -37,6 +37,7 @@ dependencies { asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor' // asciidoctorExt에 spring-restdocs-asciidoctor 의존성 추가 testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' // mockMvc 사용 implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.12.4' + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' } ext {