diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e76c3b0..603d67b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -65,18 +65,46 @@ jobs: runs-on: self-hosted steps: - # 1. 최신 이미지를 풀받습니다 - - name: docker pull - run: sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/jangburich2 + - uses: actions/checkout@v3 + + - name: Setup SSH key + uses: webfactory/ssh-agent@v0.5.4 + with: + ssh-private-key: ${{ secrets.EC2_SSH_KEY }} + + - name: Add EC2 to known_hosts + run: | + ssh-keyscan -H ip-172-31-3-107 >> ~/.ssh/known_hosts - # 2. 기존의 컨테이너를 중지시킵니다 - - name: docker stop container - run: sudo docker stop $(sudo docker ps -q) 2>/dev/null || true + - name: Copy docker-compose.yml to EC2 + run: | + scp docker-compose.yml ubuntu@ip-172-31-3-107:/home/ubuntu/ - # 3. 최신 이미지를 컨테이너화하여 실행시킵니다 - - name: docker run new container - run: sudo docker run --name jangburich2 --rm -d -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/jangburich2 + - name: Login to Docker Hub on EC2 + run: | + ssh ubuntu@ip-172-31-3-107 ' + echo "${{ secrets.DOCKERHUB_PASSWORD }}" | sudo docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin + ' - # 4. 미사용 이미지를 정리합니다 - - name: delete old docker image - run: sudo docker system prune -f \ No newline at end of file + - name: Stop existing Redis process + run: | + if pgrep redis-server; then + sudo systemctl stop redis || echo "Redis service not managed by systemctl" + pkill redis-server || echo "No Redis process to kill" + fi + + # 0. 최신 이미지를 풀받습니다 + - name: docker pull + run: sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/jangburich2 + + # 1. docker-compose 종료 + - name: docker-compose down + run: sudo docker-compose down + + # 2. docker-compose 실행 + - name: docker-compose up + run: sudo docker-compose up -d + + # 3. 안쓰는 이미지 제거 + - name: Remove unused Docker images + run: sudo docker image prune -f diff --git a/compose-prod.yml b/docker-compose.yml similarity index 73% rename from compose-prod.yml rename to docker-compose.yml index aac2ff8..3adc64d 100644 --- a/compose-prod.yml +++ b/docker-compose.yml @@ -1,8 +1,6 @@ services: - api-server: - build: - context: . - dockerfile: ./Dockerfile + app: + image: rookie97/jangburich2:latest ports: - 8080:8080 depends_on: @@ -15,4 +13,4 @@ services: healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 5s - retries: 10 \ No newline at end of file + retries: 10 diff --git a/src/main/java/com/jangburich/domain/store/domain/StoreTeam.java b/src/main/java/com/jangburich/domain/store/domain/StoreTeam.java index b546b88..e5d8f48 100644 --- a/src/main/java/com/jangburich/domain/store/domain/StoreTeam.java +++ b/src/main/java/com/jangburich/domain/store/domain/StoreTeam.java @@ -10,6 +10,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import java.time.LocalDate; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -44,6 +45,9 @@ public class StoreTeam extends BaseEntity { @Column(name = "remain_point") private Integer remainPoint; + @Column(name = "prepaid_expiration_date") + private LocalDate prepaidExpirationDate; + public void updatePersonalAllocatedPoint(Integer point) { this.personalAllocatedPoint = point; } @@ -71,13 +75,16 @@ public void subRemainPoint(Integer point) { this.remainPoint -= point; } + @Builder - public StoreTeam(Store store, Team team, Integer point, Integer personalAllocatedPoint, Integer remainPoint) { + public StoreTeam(Store store, Team team, Integer point, Integer personalAllocatedPoint, Integer remainPoint, + LocalDate prepaidExpirationDate) { this.store = store; this.team = team; this.point = point; this.personalAllocatedPoint = personalAllocatedPoint; this.remainPoint = remainPoint; + this.prepaidExpirationDate = prepaidExpirationDate; } public static StoreTeam create(Team team, Store store, Integer point) { diff --git a/src/main/java/com/jangburich/domain/store/service/PrepayService.java b/src/main/java/com/jangburich/domain/store/service/PrepayService.java index c1fc839..87e7cbe 100644 --- a/src/main/java/com/jangburich/domain/store/service/PrepayService.java +++ b/src/main/java/com/jangburich/domain/store/service/PrepayService.java @@ -15,6 +15,7 @@ import com.jangburich.global.error.DefaultNullPointerException; import com.jangburich.global.payload.ErrorCode; import com.jangburich.global.payload.Message; +import java.time.LocalDate; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -42,17 +43,9 @@ public Message prepay(String userId, PrepayRequest prepayRequest) { Store store = storeRepository.findById(prepayRequest.storeId()) .orElseThrow(() -> new IllegalArgumentException("유효하지 않은 가게 id 입니다.")); - if (!team.getTeamLeader().getUser_id().equals(user.getUserId())) { - return Message.builder() - .message("팀의 리더가 아닌 사람은 선결제를 할 수 없습니다.") - .build(); - } + team.validateIsTeamLeader(team.getTeamLeader().getUser_id(), user.getUserId()); - if (prepayRequest.prepayAmount() > user.getPoint()) { - return Message.builder() - .message("보유하고 있는 금액이 선결제 하려는 금액보다 적습니다.") - .build(); - } + user.validateHasPointWithPrepayAmount(prepayRequest.prepayAmount(), user.getPoint()); user.usePoint(prepayRequest.prepayAmount()); PointTransaction pointTransaction = PointTransaction @@ -65,6 +58,8 @@ public Message prepay(String userId, PrepayRequest prepayRequest) { pointTransactionRepository.save(pointTransaction); + LocalDate expirationDate = LocalDate.now().plusDays(store.getPrepaymentDuration()); + StoreTeam buildedStoreTeam = StoreTeam .builder() .team(team) @@ -72,6 +67,7 @@ public Message prepay(String userId, PrepayRequest prepayRequest) { .point(prepayRequest.prepayAmount()) .personalAllocatedPoint(prepayRequest.personalAllocatedAmount()) .remainPoint(prepayRequest.prepayAmount()) + .prepaidExpirationDate(expirationDate) .build(); Optional storeAndTeam = storeTeamRepository.findByStoreAndTeam(store, team); diff --git a/src/main/java/com/jangburich/domain/team/domain/Team.java b/src/main/java/com/jangburich/domain/team/domain/Team.java index 369d13f..79ef3ca 100644 --- a/src/main/java/com/jangburich/domain/team/domain/Team.java +++ b/src/main/java/com/jangburich/domain/team/domain/Team.java @@ -66,4 +66,10 @@ public Team(String name, String description, String secretCode, TeamLeader teamL this.point = point; this.teamType = teamType; } + + public void validateIsTeamLeader(Long userId, Long userId1) { + if (!userId.equals(userId1)) { + throw new IllegalArgumentException("팀의 리더가 아닌 사람은 선결제를 할 수 없습니다."); + } + } } diff --git a/src/main/java/com/jangburich/domain/user/domain/User.java b/src/main/java/com/jangburich/domain/user/domain/User.java index b609ff1..e2e9c18 100644 --- a/src/main/java/com/jangburich/domain/user/domain/User.java +++ b/src/main/java/com/jangburich/domain/user/domain/User.java @@ -80,4 +80,10 @@ public static User create(String userId, String nickname, String email, String i newUser.setPoint(0); return newUser; } + + public void validateHasPointWithPrepayAmount(int prepayAmount, Integer point) { + if (prepayAmount > point) { + throw new IllegalArgumentException("보유하고 있는 금액이 선결제 하려는 금액보다 적습니다."); + } + } } diff --git a/src/main/java/com/jangburich/domain/user/dto/response/TeamsResponse.java b/src/main/java/com/jangburich/domain/user/dto/response/TeamsResponse.java index 856f28c..5949054 100644 --- a/src/main/java/com/jangburich/domain/user/dto/response/TeamsResponse.java +++ b/src/main/java/com/jangburich/domain/user/dto/response/TeamsResponse.java @@ -5,6 +5,7 @@ public record TeamsResponse( Long teamId, Long storeId, + int dDay, String storeImgUrl, Boolean isLikedAtStore, String teamName, @@ -14,10 +15,12 @@ public record TeamsResponse( ) { @QueryProjection - public TeamsResponse(Long teamId, Long storeId, String storeImgUrl, Boolean isLikedAtStore, String teamName, + public TeamsResponse(Long teamId, Long storeId, int dDay, String storeImgUrl, Boolean isLikedAtStore, + String teamName, String storeName, int totalAmount, int currentAmount) { this.teamId = teamId; this.storeId = storeId; + this.dDay = dDay; this.storeImgUrl = storeImgUrl; this.isLikedAtStore = isLikedAtStore; this.teamName = teamName; diff --git a/src/main/java/com/jangburich/domain/user/repository/UserQueryDslRepositoryImpl.java b/src/main/java/com/jangburich/domain/user/repository/UserQueryDslRepositoryImpl.java index cdfe8cc..b76d8f9 100644 --- a/src/main/java/com/jangburich/domain/user/repository/UserQueryDslRepositoryImpl.java +++ b/src/main/java/com/jangburich/domain/user/repository/UserQueryDslRepositoryImpl.java @@ -33,8 +33,11 @@ public UserHomeResponse findUserHomeData(Long userId) { List teamsResponses = queryFactory .selectDistinct(new QTeamsResponse( - storeTeam.team.id, + userTeam.team.id, storeTeam.store.id, + Expressions.numberTemplate(Integer.class, + "DATEDIFF({0}, CURRENT_DATE)", + storeTeam.prepaidExpirationDate), storeTeam.store.representativeImage, Expressions.constant(false), storeTeam.team.name, @@ -42,15 +45,14 @@ public UserHomeResponse findUserHomeData(Long userId) { storeTeam.point, storeTeam.remainPoint )) - .from(storeTeam) - .leftJoin(team).on(team.id.eq(storeTeam.team.id)) - .leftJoin(userTeam).on(storeTeam.team.eq(team)) + .from(userTeam) + .leftJoin(team).on(team.id.eq(userTeam.team.id)) + .leftJoin(storeTeam).on(storeTeam.team.eq(team)) .where(storeTeam.status.eq(Status.ACTIVE), userTeam.user.userId.eq(userId)) .orderBy(storeTeam.createdAt.desc()) .fetch(); - UserHomeResponse userHomeResponse = queryFactory.select(new QUserHomeResponse( user.userId, Expressions.constant(formattedDate),