Skip to content

Commit

Permalink
[#100] Feat: Sync Data 저장 (#108)
Browse files Browse the repository at this point in the history
* feat: sync content done

* feat: sync_data done
  • Loading branch information
jalju0804 authored Jun 6, 2024
1 parent 4fff4fb commit 5058d0b
Show file tree
Hide file tree
Showing 17 changed files with 307 additions and 49 deletions.
16 changes: 10 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,24 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v2
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
distribution: 'temurin'

- name: Decode application.yml
run: |
echo "${{ secrets.ENCODED_APPLICATION_YML }}" | base64 --decode > ./src/main/resources/application.yml
cat ./src/main/resources/application.yml
- name: Grant execute permission for Gradlew
run: chmod +x ./gradlew

- name: Cache Gradle packages
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
Expand All @@ -43,7 +44,7 @@ jobs:
run: docker build -t ${{ secrets.DOCKERHUB_URL }}:${{ github.sha }} .

- name: Log in to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand All @@ -67,15 +68,17 @@ jobs:
environment: production
steps:
- name: Checkout the repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: ${{ secrets.MANIFEST_REPO }}
ref: ${{ secrets.MANIFEST_REPO_BRANCH }}
token: ${{ secrets.MY_PAT }}

- name: Configure git
run: |
git config user.email ${{ secrets.GIT_USER_EMAIL }}
git config user.name ${{ secrets.GIT_USER_NAME }}
- name: Make changes
run: |
cd ${{ secrets.MANIFEST_FOLDER_NAME }}
Expand Down Expand Up @@ -107,6 +110,7 @@ jobs:
yq eval -i ".spec.template.spec.containers[0].image = \"$IMAGE_TAG\"" $FILENAME
yq eval -i ".spec.replicas = ${{ secrets.POD_REPLICAS }}" $FILENAME
fi
- name: Commit and Push
run: |
SHORT_SHA="${{ github.sha }}"
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/com/syncd/adapter/in/web/ProjectController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -79,9 +80,19 @@ public UpdateProjectResponseDto updateProject(HttpServletRequest request, @Valid
}

@PostMapping("/sync")
public SyncProjectResponseDto syncProject(HttpServletRequest request, @Valid @RequestBody SyncProjectRequestDto requestDto){
public SyncProjectResponseDto syncProject(HttpServletRequest request,
@Valid @ModelAttribute SyncProjectRequestDto requestDto){
String token = jwtService.resolveToken(request);
return syncProjectUsecase.syncProject(jwtService.getUserIdFromToken(token), requestDto.projectId(), requestDto.projectStage());
return syncProjectUsecase.syncProject(jwtService.getUserIdFromToken(token),
requestDto.projectId(),
requestDto.projectStage(),
requestDto.problem(),
requestDto.personaImage(),
requestDto.whyWhatHowImage(),
requestDto.coreDetails(),
requestDto.businessModelImage(),
requestDto.epics(),
requestDto.menuTreeImage());
}

@PostMapping("/userstory")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,42 @@ public class ProjectEntity {
private String lastModifiedDate;
private int leftChanceForUserstory;

// 추가 필드
private String problem;
private String personaImage;
private String whyImage;
private String whatImage;
private String howImage;
private CoreDetails coreDetails;
private String businessModelImage;
private List<String> scenarios;
private List<Epic> epics;

@Data
public static class UserInProjectEntity {
private String userId;
private Role role;
}

@Data
public static class CoreDetails {
private String coreTarget;
private String coreProblem;
private String coreCause;
private String solution;
private String coreValue;
}

@Data
public static class Epic {
private String id;
private String name;
private List<UserStory> userStories;
}

@Data
public static class UserStory {
private String id;
private String name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ record ProjectForGetAllInfoAboutRoomsByUserIdResponseDto(
Role role,
List<String> userEmails,
int progress,
String lastModifiedDate
String lastModifiedDate,
String projectImg
){}

record GetAllRoomsByUserIdRequestDto(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
package com.syncd.application.port.in;

import com.syncd.domain.project.CoreDetails;
import com.syncd.domain.project.Epic;
import com.syncd.exceptions.ValidationMessages;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public interface SyncProjectUsecase {
// ======================================
// METHOD
// ======================================
SyncProjectResponseDto syncProject(String userId, String projectId, int projectStage);
SyncProjectResponseDto syncProject(String userId, String projectId, int projectStage,
String problem,
MultipartFile personaImage,
MultipartFile whyWhatHowImage,
String coreDetails,
MultipartFile businessModelImage,
String epics,
MultipartFile menuTreeImage
);
// ======================================
// DTO
// ======================================
Expand All @@ -17,7 +30,16 @@ record SyncProjectRequestDto(
@NotBlank(message = ValidationMessages.PROJECT_ID_NOT_BLANK)
String projectId,
@NotNull(message = ValidationMessages.PROJECT_PROGRESS_NOT_NULL)
Integer projectStage
Integer projectStage,
// Sync 내용, projectStage 마다 필요한 요소들이 존재
String problem,
String coreDetails,
String epics,

MultipartFile personaImage,
MultipartFile whyWhatHowImage,
MultipartFile businessModelImage,
MultipartFile menuTreeImage
){}

record SyncProjectResponseDto(
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/com/syncd/application/port/out/s3/S3Port.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;

public interface S3Port {

public Optional<String> uploadMultipartFileToS3(MultipartFile multipartFile);
public Optional<Boolean> deleteFileFromS3(String filename);
Optional<String> uploadMultipartFileToS3(MultipartFile multipartFile);
Optional<Boolean> deleteFileFromS3(String filename);
}
82 changes: 73 additions & 9 deletions src/main/java/com/syncd/application/service/ProjectService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.syncd.application.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.syncd.application.port.in.*;
import com.syncd.application.port.out.gmail.SendMailPort;
import com.syncd.application.port.out.liveblock.LiveblocksPort;
Expand All @@ -8,6 +9,8 @@
import com.syncd.application.port.out.persistence.project.WriteProjectPort;
import com.syncd.application.port.out.persistence.user.ReadUserPort;
import com.syncd.application.port.out.s3.S3Port;
import com.syncd.domain.project.CoreDetails;
import com.syncd.domain.project.Epic;
import com.syncd.domain.project.Project;
import com.syncd.domain.project.UserInProject;
import com.syncd.domain.user.User;
Expand All @@ -27,7 +30,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.type.TypeReference;


@Service
Expand All @@ -47,12 +50,11 @@ public class ProjectService implements CreateProjectUsecase, GetAllRoomsByUserId

@Override
public CreateProjectResponseDto createProject(String hostId, String hostName, String projectName, String description, MultipartFile img, List<String> userEmails){
String imgURL = "";
System.out.println(hostName);
if (img != null && !img.isEmpty()) {
Optional<String> optionalImgURL = s3Port.uploadMultipartFileToS3(img);
imgURL = optionalImgURL.orElseThrow(() -> new IllegalStateException("Failed to upload image to S3"));
List<User> users = new ArrayList<>();
if(userEmails!=null){
users = readUserPort.usersFromEmails(userEmails);
}
String imgURL = uploadFileToS3(img);

Project project = new Project();
project = project.createProjectDomain(projectName, description, imgURL, hostId);
Expand Down Expand Up @@ -177,13 +179,65 @@ public WithdrawUserInProjectResponseDto withdrawUserInProject(String userId, Str
}

@Override
public SyncProjectResponseDto syncProject(String userId, String projectId, int projectStage) {
public SyncProjectResponseDto syncProject(String userId, String projectId, int projectStage,
String problem,
MultipartFile personaImage,
MultipartFile whyWhatHowImage,
String coreDetailsJson,
MultipartFile businessModelImage,
String epicsJson,
MultipartFile menuTreeImage) {
ObjectMapper objectMapper = new ObjectMapper();
CoreDetails coreDetails;
List<Epic> epics;

try {
coreDetails = objectMapper.readValue(coreDetailsJson, CoreDetails.class);
epics = objectMapper.readValue(epicsJson, new TypeReference<List<Epic>>() {});
} catch (Exception e) {
throw new CustomException(ErrorInfo.JSON_PARSE_ERROR, "Failed to parse JSON for coreDetails or epics: " + e.getMessage());
}

Project project = readProjectPort.findProjectByProjectId(projectId);
switch (projectStage) {
case 1:
case 2:
break;
case 3:
project.setProblem(problem);
break;
case 4:
project.setPersonaImage(uploadFileToS3(personaImage));
break;
case 5:
case 6:
break;
case 7:
project.setWhyWhatHowImage(uploadFileToS3(whyWhatHowImage));
break;
case 8:
project.setCoreDetails(coreDetails);
break;
case 9:
project.setBusinessModelImage(uploadFileToS3(businessModelImage));
break;
case 10:
break;
case 11:
project.setEpics(epics);
break;
case 12:
project.setMenuTreeImage(uploadFileToS3(menuTreeImage));
break;
default:
throw new IllegalArgumentException("Invalid project stage: " + projectStage);
}
writeProjectPort.AddProgress(projectId, projectStage);
writeProjectPort.updateLastModifiedDate(projectId);

writeProjectPort.UpdateProject(project);
return new SyncProjectResponseDto(projectId);
}

@Override
@Transactional
public MakeUserStoryResponseDto makeUserstory(String userId, String projectId, List<String> senarios){
Expand All @@ -199,6 +253,7 @@ public MakeUserStoryResponseDto makeUserstory(String userId, String projectId, L
System.out.println(project);
throw new CustomException(ErrorInfo.NOT_INCLUDE_PROJECT, "project id" + projectId);
}
project.setScenarios(senarios);
project.subLeftChanceForUserstory();
writeProjectPort.UpdateProject(project);
System.out.println(senarios);
Expand Down Expand Up @@ -259,11 +314,20 @@ private ProjectForGetAllInfoAboutRoomsByUserIdResponseDto convertProjectToDto(St
userRole,
userEmails,
project.getProgress(),
project.getLastModifiedDate()
project.getLastModifiedDate(),
project.getImg()
);
}

private UserRoleDto convertUserToUserRoleDto(String projectId, UserInProject user) {
return new UserRoleDto(projectId, user.getUserId(), user.getRole());
}

private String uploadFileToS3(MultipartFile file) {
if (file != null && !file.isEmpty()) {
Optional<String> optionalFileUrl = s3Port.uploadMultipartFileToS3(file);
return optionalFileUrl.orElseThrow(() -> new IllegalStateException("Failed to upload file to S3"));
}
return "";
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/syncd/domain/project/CoreDetails.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.syncd.domain.project;

import lombok.Data;

@Data
public class CoreDetails {
private String coreTarget;
private String coreProblem;
private String coreCause;
private String solution;
private String coreValue;
}
12 changes: 12 additions & 0 deletions src/main/java/com/syncd/domain/project/Epic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.syncd.domain.project;

import lombok.Data;

import java.util.List;

@Data
public class Epic {
private String id;
private String name;
private List<UserStory> userStories;
}
Loading

0 comments on commit 5058d0b

Please sign in to comment.