Skip to content

Commit

Permalink
refactor: 충돌 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
sangwonsheep committed Jan 9, 2025
2 parents 0bb0e93 + 0de04cf commit cc5d5b5
Show file tree
Hide file tree
Showing 825 changed files with 54,873 additions and 33 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/baguni.test.client.deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Baguni Test Client CI/CD

# *****************************************
# NOTE: 추후 도커 허브 레포를 baguni로 변경할 예정
# *****************************************

on:
push:
branches:
- 'fe-develop'
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
env:
docker-hub-username: 'minkyeu'
docker-hub-repo: 'baguni' # TODO: change to baguni
module-name: 'baguni-client'
steps:
- # 저장소 Checkout
name: Checkout source code
uses: actions/checkout@v4

- # .env 파일 설정
name: Create .env.production
run: |
cd ./frontend/techpick
touch .env.production
echo "NEXT_PUBLIC_API=${{ secrets.FRONT_NEXT_PUBLIC_API }}" >> .env.production
echo "NEXT_PUBLIC_DOMAIN=${{ secrets.FRONT_NEXT_PUBLIC_DOMAIN }}" >> .env.production
echo "NEXT_PUBLIC_REDIRECT_URL=${{secrets.FRONT_NEXT_PUBLIC_REDIRECT_URL}}" >> .env.production
echo "NEXT_PUBLIC_MIXPANEL_TOKEN=${{secrets.FRONT_NEXT_PUBLIC_MIXPANEL_TOKEN}}" >> .env.production
echo "NEXT_PUBLIC_IMAGE_URL=${{secrets.FRONT_NEXT_PUBLIC_IMAGE_URL}}" >> .env.production
- # .env.sentry-build-plugin 설정
name: Create .env.sentry-build-plugin
run: |
cd ./frontend/techpick
touch .env.sentry-build-plugin
echo "SENTRY_AUTH_TOKEN=${{secrets.FRONT_SENTRY_AUTH_TOKEN}}" >> .env.sentry-build-plugin
- # Docker image 빌드
name: Build docker image
run: |
docker build -t ${{ env.docker-hub-username }}/${{ env.docker-hub-repo }}:${{ env.module-name }}-${{ github.sha }} frontend
- # Docker hub 로그인
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.docker-hub-username }}
password: ${{ secrets.DOCKERHUB_REPO_BAGUNI_TOKEN }}
- # Docker hub 업로드
name: Publish to docker hub
run: docker push ${{ env.docker-hub-username }}/${{ env.docker-hub-repo }}:${{ env.module-name }}-${{ github.sha }}
- # 서버 ssh 접속 후 방금 올린 이미지 pull 받고 실행
name: Deploy on Test-Server
uses: appleboy/ssh-action@master
with:
host: minlife.me # test home server
port: 4242
username: root # root user
password: ${{ secrets.SSH_TEST_SERVER_KYEU_PASSWORD }}
script: |
echo "login docker hub for private repository access ..."
echo ${{ secrets.DOCKERHUB_REPO_BAGUNI_TOKEN }} | docker login -u ${{ env.docker-hub-username }} --password-stdin
echo "docker - pulling..."
docker pull ${{ env.docker-hub-username }}/${{ env.docker-hub-repo }}:${{ env.module-name }}-${{ github.sha }}
echo "docker - changing image name and tag ..."
docker tag ${{ env.docker-hub-username }}/${{ env.docker-hub-repo }}:${{ env.module-name }}-${{ github.sha }} ${{ env.docker-hub-repo }}:${{ env.module-name }}-staging
echo "moving to project directory..."
cd /home/project/baguni/develop
docker compose down ${{ env.module-name }}
docker compose up ${{ env.module-name }} -d
echo "docker - pruning images that passed 24h ..."
docker image prune -af --filter "until=24h"
- name: Discord Webhook Notification
uses: sarisia/[email protected]
if: always()
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_URL }}
status: ${{ job.status }}
title: 'TEST CLIENT DEPLOY'
color: 0xff91a4
url: 'https://github.com/sarisia/actions-status-discord'
username: GitHub Actions
39 changes: 39 additions & 0 deletions .github/workflows/playwright.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Playwright Tests
on:
pull_request:
branches: [fe-develop]
workflow_dispatch:
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend/techpick
steps:
- uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable

- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'yarn'
cache-dependency-path: frontend/yarn.lock

- name: Install dependencies
run: yarn

- name: Install Playwright Browsers
run: yarn playwright install --with-deps

- name: Run Playwright tests
run: yarn playwright test

- name: 'Upload Playwright Report'
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: frontend/techpick/playwright-report/
retention-days: 10
6 changes: 0 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
.vscode
.DS_Store
.vscode/extensions.json
.vscode/settings.json
.idea
frontend/techpick/.env.production
frontend/techpick/.env.development
frontend/techpick-extension/.env.development
frontend/techpick-extension/.env.production
11 changes: 11 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
if git diff --cached --name-only | grep -q '^frontend/techpick-extension'; then
echo "frontend/techpick-extension lint or tsc error"
cd "frontend/techpick-extension"
yarn lint
yarn tsc -b
elif git diff --cached --name-only | grep -q '^frontend/techpick'; then
echo "frontend/techpick lint or tsc error"
cd frontend/techpick
yarn lint
yarn tsc
fi
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@
## 팀 소개 페이지 [🔗 Notion](https://positive-airboat-4de.notion.site/Baguni-15841a7fba6580c59591e2d5d1c2414b)
[<img width="1464" alt="스크린샷 2024-12-18 오후 12 19 13" src="https://github.com/user-attachments/assets/2d1f8c70-fd90-4f4b-9494-3cf1e2f5813a" />](https://app.baguni.kr/)



## 팀원 소개
| **[팀장 : 김민규](https://github.com/kimminkyeu)** | **[팀원 : 김승태](https://github.com/dmdgpdi)** | **[팀원 : 오송민](https://github.com/obvoso)** | **[팀원 : 박수형](https://github.com/Gyaak)** | **[팀원 : 양상원](https://github.com/sangwonsheep)** |
| :-: | :-: | :-: | :-: | :-: |
| <a href="https://github.com/kimminkyeu"><img src="https://avatars.githubusercontent.com/kimminkyeu" width=200px /> | <a href="https://github.com/dmdgpdi"><img src="https://avatars.githubusercontent.com/dmdgpdi" width=200px /> | <a href="https://github.com/obvoso"><img src="https://avatars.githubusercontent.com/obvoso" width=200px /> | <a href="https://github.com/Gyaak"><img src="https://avatars.githubusercontent.com/Gyaak" width=200px /> | <a href="https://github.com/sangwonsheep"><img src="https://avatars.githubusercontent.com/sangwonsheep" width=200px /> |
| Backend | Frontend | Frontend | Backend | Backend |



## 프로젝트 소개
### 만들게 된 계기
<img width="785" alt="스크린샷 2024-12-19 오전 11 52 34" src="https://github.com/user-attachments/assets/125acbeb-312d-4cdd-ada9-108b237d8593" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package baguni.api.infrastructure.folder;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import baguni.entity.model.folder.Folder;
import baguni.entity.model.folder.FolderRepository;
import baguni.entity.model.user.User;
import baguni.entity.model.user.UserRepository;
import lombok.RequiredArgsConstructor;
import baguni.api.service.folder.dto.FolderCommand;
import baguni.api.service.folder.exception.ApiFolderException;
import baguni.api.service.user.exception.ApiUserException;

@Component
@RequiredArgsConstructor
public class FolderDataHandler {

private final FolderRepository folderRepository;
private final UserRepository userRepository;

@Transactional
public void createMandatoryFolder(User user) {
folderRepository.save(Folder.createEmptyUnclassifiedFolder(user));
folderRepository.save(Folder.createEmptyRecycleBinFolder(user));
folderRepository.save(Folder.createEmptyRootFolder(user));
}

@Transactional(readOnly = true)
public Folder getFolder(Long folderId) {
return folderRepository.findById(folderId).orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);
}

// idList에 포함된 모든 ID에 해당하는 폴더 리스트 조회, 순서를 보장하지 않음
@Transactional(readOnly = true)
public List<Folder> getFolderList(List<Long> folderIdList) {
List<Folder> folderList = folderRepository.findAllById(folderIdList);
// 조회리스트에 존재하지 않는 태그id가 존재하면 예외 발생
if (folderList.size() != folderIdList.size()) {
throw ApiFolderException.FOLDER_NOT_FOUND();
}
return folderList;
}

// idList에 포함된 모든 ID에 해당하는 폴더 리스트 조회, 순서는 idList의 순서를 따름
@Transactional(readOnly = true)
public List<Folder> getFolderListPreservingOrder(List<Long> folderIdList) {
List<Folder> folderList = folderRepository.findAllById(folderIdList);
// 조회리스트에 존재하지 않는 태그id가 존재하면 예외 발생
if (folderList.size() != folderIdList.size()) {
throw ApiFolderException.FOLDER_NOT_FOUND();
}
folderList.sort(Comparator.comparing(folder -> folderIdList.indexOf(folder.getId())));
return folderList;
}

@Transactional(readOnly = true)
public List<Folder> getFolderListByUserId(Long userId) {
return folderRepository.findByUserId(userId);
}

@Transactional(readOnly = true)
public Folder getRootFolder(Long userId) {
return folderRepository.findRootByUserId(userId);
}

@Transactional(readOnly = true)
public Folder getRecycleBin(Long userId) {
return folderRepository.findRecycleBinByUserId(userId);
}

@Transactional(readOnly = true)
public Folder getUnclassifiedFolder(Long userId) {
return folderRepository.findUnclassifiedByUserId(userId);
}

@Transactional
public Folder saveFolder(FolderCommand.Create command) {
User user = userRepository.findById(command.userId()).orElseThrow(ApiUserException::USER_NOT_FOUND);
Folder parentFolder = folderRepository.findById(command.parentFolderId())
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);

Folder folder = folderRepository.save(Folder.createEmptyGeneralFolder(user, parentFolder, command.name()));
folder.getParentFolder().addChildFolderIdOrdered(folder.getId());
return folder;
}

@Transactional
public Folder updateFolder(FolderCommand.Update command) {
Folder folder = folderRepository.findById(command.id())
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);
folder.updateFolderName(command.name());

return folder;
}

@Transactional
public List<Long> moveFolderWithinParent(FolderCommand.Move command) {
Folder parentFolder = folderRepository.findById(command.parentFolderId())
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);

parentFolder.updateChildFolderIdOrderedList(command.idList(), command.orderIdx());
return parentFolder.getChildFolderIdOrderedList();
}

@Transactional
public List<Long> moveFolderToDifferentParent(FolderCommand.Move command) {
Folder folder = folderRepository.findById(command.idList().get(0))
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);

Folder oldParent = folder.getParentFolder();
oldParent.getChildFolderIdOrderedList().removeAll(command.idList());

Folder newParent = folderRepository.findById(command.destinationFolderId())
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);
newParent.addChildFolderIdOrderedList(command.idList(), command.orderIdx());

List<Folder> folderList = getFolderList(command.idList());
for (Folder moveFolder : folderList) {
moveFolder.updateParentFolder(newParent);
}

return newParent.getChildFolderIdOrderedList();
}

@Transactional
public void deleteFolderList(FolderCommand.Delete command) {

List<Folder> deleteList = new ArrayList<>();

for (Long id : command.idList()) {
Folder folder = folderRepository.findById(id)
.orElseThrow(ApiFolderException::FOLDER_NOT_FOUND);

Folder parentFolder = folder.getParentFolder();
parentFolder.removeChildFolderIdOrdered(folder.getId());

deleteList.add(folder);
}

folderRepository.deleteAllInBatch(deleteList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package baguni.api.infrastructure.link;

import java.util.Optional;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import baguni.entity.model.link.Link;
import baguni.entity.model.link.LinkRepository;
import lombok.RequiredArgsConstructor;
import baguni.api.service.link.exception.ApiLinkException;

@Component
@RequiredArgsConstructor
public class LinkDataHandler {
private final LinkRepository linkRepository;

@Transactional(readOnly = true)
public Link getLink(String url) {
return linkRepository.findByUrl(url).orElseThrow(ApiLinkException::LINK_NOT_FOUND);
}

@Transactional(readOnly = true)
public Optional<Link> getOptionalLink(String url) {
return linkRepository.findByUrl(url);
}

@Transactional
public Link saveLink(Link link) {
return linkRepository.save(link);
}

@Transactional(readOnly = true)
public boolean existsByUrl(String url) {
return linkRepository.existsByUrl(url);
}
}
Loading

0 comments on commit cc5d5b5

Please sign in to comment.