Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ae374a8
feat : 게시물 공개 여부 변경 기능 개발
venus-y Jan 31, 2026
ce91497
Merge pull request #14 from ReviewStore/feat/open-publication
venus-y Jan 31, 2026
2042222
feat : 자신의 회고 목록 반환 API 개발
venus-y Feb 5, 2026
7678d6a
Merge pull request #15 from ReviewStore/feat/read-my-retros
venus-y Feb 5, 2026
fec2ea4
fix : 회고 저장 테스트 오류 수정
venus-y Feb 5, 2026
ff8f0e5
feat : 회원 닉네임 변경 기능 개발
venus-y Feb 6, 2026
c64e84c
feat : 회원 탈퇴 시 관련 데이터 삭제 처리
venus-y Feb 7, 2026
86afc0e
Merge pull request #16 from ReviewStore/feat/with-draw-member
venus-y Feb 7, 2026
b924079
feat : 마케팅/서비스 알림 동의여부 변경 API 개발
venus-y Feb 7, 2026
9ec5211
Merge pull request #17 from ReviewStore/feat/update-term-agreements
venus-y Feb 7, 2026
b7f7ced
feat : 공지사항 작성/조회 API 개발
venus-y Feb 7, 2026
837e9a6
Merge pull request #18 from ReviewStore/feat/notices
venus-y Feb 7, 2026
34fd7cc
feat : 스웨거 API 갱신
venus-y Feb 8, 2026
b1eb45f
Merge pull request #19 from ReviewStore/feat/update-swagger-config
venus-y Feb 8, 2026
3308503
Add GitHub Actions workflow for dev-be deployment
venus-y Feb 10, 2026
2f71230
Run Gradle build with sudo
venus-y Feb 10, 2026
4722c01
Update Gradle build step in deployment workflow
venus-y Feb 10, 2026
e47eed2
Simplify Gradle build step in deployment workflow
venus-y Feb 10, 2026
2863503
Exclude tests from Gradle build step
venus-y Feb 10, 2026
a9851db
Add port configuration to deployment workflow
venus-y Feb 10, 2026
aa9e3f2
Update deployment configuration to specify port
venus-y Feb 10, 2026
248b45b
Enable overwrite for file transfer in deploy workflow
venus-y Feb 10, 2026
a673cfe
Update deploy-dev-be.yml
venus-y Feb 10, 2026
d009df8
Refactor deployment workflow for clarity and steps
venus-y Feb 10, 2026
8f686ea
Update deploy-dev-be.yml
venus-y Feb 10, 2026
7d5f538
Update deploy-dev-be.yml
venus-y Feb 10, 2026
bc5fa7f
Update deploy-dev-be.yml
venus-y Feb 10, 2026
cc96199
test : 깃헙 액션 테스트
venus-y Feb 10, 2026
438c038
test : 깃헙 액션 테스트
venus-y Feb 10, 2026
99da33b
test : 깃헙 액션 테스트
venus-y Feb 10, 2026
4970f36
Update JDK version from 17 to 21 in workflow
venus-y Feb 11, 2026
79d24ac
Update .gitkeep
venus-y Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/deploy-dev-be.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Deploy dev-be to GCP VM

on:
push:
branches:
- dev-be

jobs:
deploy:
runs-on: ubuntu-latest

steps:
# 1. 코드 체크아웃
- name: Checkout dev-be branch
uses: actions/checkout@v4

# 2. JDK 21 설치
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21

# 3. application-secret.yaml 생성
- name: Create application-secret.yaml
run: |
echo "${{ secrets.APPLICATION_SECRET_YAML }}" \
> src/main/resources/application-secret.yaml

# 4. Gradle 빌드
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew clean build -x test

# 5. JAR 이름 통일
- name: Rename jar
run: |
mv build/libs/*SNAPSHOT.jar build/libs/app.jar

# 6. 원격 서버 사전 점검 (디렉터리/디스크)
- name: Pre-check remote server
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.GCP_HOST }}
username: ${{ secrets.GCP_USERNAME }}
key: ${{ secrets.GCP_PRIVATE_KEY }}
port: 2222
script_stop: true
script: |
echo "[CHECK] Disk space"
df -h /
echo "[CHECK] Ensure directories"
mkdir -p /home/retrospection1234/spring-boot/review_store_backend/build/libs

# 7. JAR 전송 (임시 파일명)
- name: Copy jar to GCP VM
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.GCP_HOST }}
username: ${{ secrets.GCP_USERNAME }}
key: ${{ secrets.GCP_PRIVATE_KEY }}
port: 2222
source: build/libs/app.jar
target: /home/***/spring-boot/review_store_backend
overwrite: true

# 8. 원격 서버 배포 (교체 + 재시작)
- name: Deploy & Restart on GCP VM
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.GCP_HOST }}
username: ${{ secrets.GCP_USERNAME }}
key: ${{ secrets.GCP_PRIVATE_KEY }}
port: 2222
script_stop: true
script: |
cd /home/***/spring-boot/review_store_backend

echo "[DEPLOY] Stop existing process (by port)"
fuser -k -n tcp 8080 || true
sleep 2

echo "[DEPLOY] Start new process"
nohup java -jar build/libs/app.jar > output.log 2>&1 &

echo "[VERIFY] Process running"
sleep 5
ps -ef | grep "java -jar build/libs/app.jar" | grep -v grep || true

1 change: 1 addition & 0 deletions .gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d2 222
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ dependencies {
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.retro.domain.auth.application.dto.request.GoogleLoginRequest;
import com.retro.domain.auth.application.dto.request.RefreshRequest;
import com.retro.domain.auth.application.dto.response.AppleAuthCodeDto;
import com.retro.global.UserAgentHeader;
import com.retro.global.common.dto.ApiResponse;
import com.retro.global.common.dto.MemberDevice;
import com.retro.global.common.jwt.JwtToken;
Expand Down Expand Up @@ -57,6 +58,7 @@ public ApiResponse<AppleAuthCodeDto> appleRedirect(
}

@Operation(summary = "애플 로그인 처리", description = "인증 코드로 JWT 토큰을 발급합니다.")
@UserAgentHeader
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "성공",
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
examples = @ExampleObject(value = """
Expand All @@ -75,7 +77,7 @@ public ApiResponse<AppleAuthCodeDto> appleRedirect(
@PostMapping("/oauth2/login/apple")
public ApiResponse<JwtToken> appleLogin(
@Parameter(description = "애플 인증 코드", example = "c7e.apple.auth.code")
@RequestParam String code, MemberDevice memberDevice
@RequestParam String code, @Parameter(hidden = true) MemberDevice memberDevice
) throws Exception {
ApiResponse<JwtToken> success = ApiResponse.success(authService.appleLogin(code, memberDevice));
return success;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.retro.domain.member.domain.MemberRepository;
import com.retro.domain.member.domain.entity.Member;
import com.retro.domain.member.domain.event.MemberEventPublisher;
import com.retro.global.common.exception.BusinessException;
import com.retro.global.common.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
Expand All @@ -16,6 +17,7 @@
public class MemberService {

private final MemberRepository memberRepository;
private final MemberEventPublisher memberEventPublisher;

public Member getMember(Long memberId) {
return memberRepository.findById(memberId)
Expand All @@ -26,4 +28,39 @@ public Member getMember(Long memberId) {
public void grantUnlimitedPostReadPermissionToMember(Member member) {
member.grantPostReadPermission();
}

@Transactional
public void updatePostPublicStatus(Long memberId, boolean isPublic) {
Member member = getMember(memberId);
if (isPublic) {
member.openOwnPublication();
return;
}
member.closeOwnPublication();
}

@Transactional
public void updateNickname(Long memberId, String nickname) {
Member member = getMember(memberId);
member.updateNickname(nickname);
}

@Transactional
public void withdrawMember(Long memberId) {
Member member = getMember(memberId);
memberEventPublisher.publishMemberWithdrawnEvent(member);
memberRepository.delete(member);
}

@Transactional
public void updateMarketingAgreed(Long memberId, boolean marketingAgreed) {
Member member = getMember(memberId);
member.updateMarketingTermAgreed(marketingAgreed);
}

@Transactional
public void updateServiceTermAgreed(Long memberId, boolean serviceTermAgreed) {
Member member = getMember(memberId);
member.updateServiceTermAgreed(serviceTermAgreed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.retro.domain.member.application.dto;

import jakarta.validation.constraints.NotNull;

public record MemberMarketingAgreedUpdateRequest(@NotNull Boolean marketingAgreed) {

public static MemberMarketingAgreedUpdateRequest of(Boolean marketingAgreed) {
return new MemberMarketingAgreedUpdateRequest(marketingAgreed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.retro.domain.member.application.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

public record MemberNicknameUpdateRequest(
@NotBlank(message = "닉네임은 필수입니다.")
@Size(min = 2, max = 12, message = "닉네임은 2자 이상 12자 이하로 입력해주세요.")
@Pattern(regexp = "^[A-Za-z0-9가-힣]+$",
message = "닉네임은 한글/영문/숫자만 입력 가능합니다.")
String nickname
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.retro.domain.member.application.dto;

import jakarta.validation.constraints.NotNull;

public record MemberPublicUpdateRequest(@NotNull boolean isPublic) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.retro.domain.member.application.dto;

import jakarta.validation.constraints.NotNull;

public record MemberServiceTermAgreedUpdateRequest(@NotNull Boolean serviceTermAgreed) {

public static MemberServiceTermAgreedUpdateRequest of(Boolean serviceTermAgreed) {
return new MemberServiceTermAgreedUpdateRequest(serviceTermAgreed);
}
}
15 changes: 11 additions & 4 deletions src/main/java/com/retro/domain/member/domain/MemberRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
import java.util.Optional;

public interface MemberRepository {
Member save(Member member);
Optional<Member> findById(Long id);
boolean existsByProviderAndProviderId(Provider provider, String providerId);
Optional<Member> findByProviderAndProviderId(Provider provider, String providerId);

Member save(Member member);

Optional<Member> findById(Long id);

boolean existsByProviderAndProviderId(Provider provider, String providerId);

Optional<Member> findByProviderAndProviderId(Provider provider, String providerId);

void delete(Member member);

}
28 changes: 23 additions & 5 deletions src/main/java/com/retro/domain/member/domain/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
})
public class Member extends BaseEntity {

public static final Long DELETED_MEMBER_ID = -1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down Expand Up @@ -94,11 +96,6 @@ public void grantPostReadPermission() {
this.postReadPermission = PostReadPermission.UNLIMITED;
}

public void closePublicAccessToPost() {
this.isPublic = false;
this.postReadPermission = PostReadPermission.LIMITED;
}

public boolean hasLimitedPostReadPermission() {
return this.postReadPermission.equals(PostReadPermission.LIMITED);
}
Expand All @@ -107,6 +104,13 @@ public void openOwnPublication() {
this.isPublic = true;
}

public void closeOwnPublication() {
this.isPublic = false;
if (this.postReadPermission.equals(PostReadPermission.UNLIMITED)) {
this.postReadPermission = PostReadPermission.LIMITED;
}
}

public boolean hasLimitedPermissionAndOpenedOwnPublication() {
return this.hasLimitedPostReadPermission()
&& this.isPublic;
Expand All @@ -117,5 +121,19 @@ public boolean isPostReadCountExceeded() {
&& this.remainingPostReadCount == 0;
}

public void updateNickname(String nickname) {
this.nickname = nickname;
}

public void updateMarketingTermAgreed(
boolean marketingTermAgreed) {
this.term.updateMarketingAgreed(marketingTermAgreed);
}

public void updateServiceTermAgreed(
boolean serviceTermAgreed) {
this.term.updateServiceTermAgreed(serviceTermAgreed);
}


}
18 changes: 11 additions & 7 deletions src/main/java/com/retro/domain/member/domain/entity/Term.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Term {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -34,10 +32,6 @@ public class Term {

private boolean marketingAgreed;

public void addMember(Member member) {
this.member = member;
}

public static Term from(boolean marketingAgreed) {
Term term = new Term();
term.isAgeOver14 = true;
Expand All @@ -47,5 +41,15 @@ public static Term from(boolean marketingAgreed) {
return term;
}

public void addMember(Member member) {
this.member = member;
}

public void updateMarketingAgreed(boolean marketingAgreed) {
this.marketingAgreed = marketingAgreed;
}

public void updateServiceTermAgreed(boolean serviceTermAgreed) {
this.serviceTermAgreed = serviceTermAgreed;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.retro.domain.member.domain.event;

import com.retro.domain.member.domain.entity.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class MemberEventPublisher {

private final ApplicationEventPublisher applicationEventPublisher;

public void publishMemberWithdrawnEvent(Member member) {
MemberWithdrawnEvent memberWithdrawnEvent = MemberWithdrawnEvent.of(member.getId());
applicationEventPublisher.publishEvent(memberWithdrawnEvent);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.retro.domain.member.domain.event;

public record MemberWithdrawnEvent(Long memberId) {

public static MemberWithdrawnEvent of(Long memberId) {
return new MemberWithdrawnEvent(memberId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ public boolean existsByProviderAndProviderId(Provider provider, String providerI
public Optional<Member> findByProviderAndProviderId(Provider provider, String providerId) {
return memberJPARepository.findByProviderAndProviderId(provider, providerId);
}

@Override
public void delete(Member member) {
memberJPARepository.delete(member);
}
}
Loading