Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3034352
chore : commit before change branch
kdfasdf Jul 14, 2025
ffbdb82
chore : commit before change branch
kdfasdf Jul 14, 2025
d3a2f05
chore : commit
kdfasdf Jun 19, 2025
c8cd04b
Merge branch 'beforeMerge' into sprint5
kdfasdf Jul 14, 2025
12bdb46
chore : adapt swagger
kdfasdf Jul 14, 2025
6904229
refactor : adapt custom exception
kdfasdf Jul 20, 2025
b40067a
refactor : adapt ErrorResponse Object to GlobalExceptionHandler
kdfasdf Jul 20, 2025
13e534f
chore : clean up code
kdfasdf Jul 20, 2025
f75c5ff
chore : update jar file
kdfasdf Jul 20, 2025
545f1fd
chore : add exception handler to handle unexpected errors
kdfasdf Jul 20, 2025
9e8e3c2
chore : edit method name
kdfasdf Jul 20, 2025
8b43111
-ammend
kdfasdf Jul 27, 2025
293fde4
feat : 커서기반 페이징 구현
kdfasdf Jul 28, 2025
d43ca24
chore : 트랜잭션 메서드 레벨로 수정
kdfasdf Aug 3, 2025
845fe48
chore : separate yaml configuration by environment profiles
kdfasdf Aug 11, 2025
e5c8487
chore : add logback-spring.xml
kdfasdf Aug 11, 2025
0aba451
feat: apply method logging aop to service layer
kdfasdf Aug 12, 2025
a8b3027
feat : add logging for service layer
kdfasdf Aug 12, 2025
a3010be
feat : add additional bean validation and exception handling
kdfasdf Aug 13, 2025
919a55c
chore : set actuator
kdfasdf Aug 13, 2025
1660c98
test : add service unit test
kdfasdf Aug 17, 2025
9b39254
test : add Repository slice test
kdfasdf Aug 18, 2025
057e075
test : add controller test
kdfasdf Aug 22, 2025
b2d8739
test : add integration test
kdfasdf Aug 24, 2025
0c3d108
commit before checkout
kdfasdf Aug 25, 2025
ab69031
commit before checkout
kdfasdf Aug 25, 2025
77db84f
hotfix : edit MessageMapper and UserMapper
kdfasdf Aug 25, 2025
b099f80
feat : add MDC Logging
kdfasdf Aug 25, 2025
de04f8a
test : add AWSS3 test
kdfasdf Aug 26, 2025
e01c6f3
before checkout
kdfasdf Aug 26, 2025
e833322
commit brefore change (doing admin)
kdfasdf Aug 27, 2025
5f29f4d
before checkout
kdfasdf Aug 27, 2025
2c1eccb
before merge
kdfasdf Aug 27, 2025
e865f3f
test: add S3BinatyContentStorageTest
kdfasdf Aug 31, 2025
7a61998
chore : add test.yml
kdfasdf Sep 1, 2025
4d2c575
chore : add test.yml
kdfasdf Sep 1, 2025
b10c136
document : add readme
kdfasdf Sep 1, 2025
23b1289
docs : readme 수정
kdfasdf Sep 7, 2025
666054a
chore : add deploy.yml
kdfasdf Sep 8, 2025
27bb1ea
chore : cleanup local files
kdfasdf Sep 8, 2025
5f972af
chore : edit gitignore
kdfasdf Sep 8, 2025
84e22af
chore : edit yaml and gitignore
kdfasdf Sep 24, 2025
f3c39bd
chore : edit deploy.yml
kdfasdf Aug 25, 2025
e7399a4
chore : edit deploy.yml and README.md
kdfasdf Sep 26, 2025
40493a7
feat : implment SignIn
kdfasdf Sep 30, 2025
50bf28e
feat: implement logout
kdfasdf Sep 30, 2025
f39fc7a
feat : assign authority
kdfasdf Oct 1, 2025
fa0af38
feat : session management
kdfasdf Oct 2, 2025
47f33da
feat : add rememberMe
kdfasdf Oct 2, 2025
36e7de2
refactor : add SpEL expression at PreAuthorize
kdfasdf Oct 2, 2025
ec3d6e8
feat : 토큰기반 인증 방식 구현
kdfasdf Oct 22, 2025
4d096ef
feat : 파일 업로드 로직 분리
kdfasdf Oct 26, 2025
9ef3327
feat : 비동기 적용 및 실패처리 적용
kdfasdf Oct 27, 2025
6a364b3
feat : 캐시 적용
kdfasdf Oct 27, 2025
0720b8b
feat : 카프카 도입
kdfasdf Oct 28, 2025
1aa7d17
feat : 레디스 적용
kdfasdf Oct 28, 2025
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
94 changes: 94 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
name: deploy

on:
pull_request:
branches: ["main", "cherry-pick-sprint8"]

jobs:
build-and-push:
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: 소스 체크 아웃
uses: actions/checkout@v3

- name: gradlew 실행 권한 부여
run: chmod +x gradlew

- name: JDK 17 설정
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Gradle 캐시 (선택)
uses: gradle/actions/setup-gradle@v4

- name: 애플리케이션 빌드
run: ./gradlew clean bootJar

- name: AWS 자격 증명 설정
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}

- name: ECR 로그인
run: |
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} \
| docker login --username AWS --password-stdin \
${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

- name: 태그 구성 - 커밋 해시 7자리 + latest
id: prep
run: |
echo "IMAGE_TAG=${GITHUB_SHA::7}" >> $GITHUB_ENV
echo "REPO_URI=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/discodeit/discodeit" >> $GITHUB_ENV

- name: 도커 빌드
run: |
docker build -t "$REPO_URI:$IMAGE_TAG" -t "$REPO_URI:latest" .

- name: ECR 푸시
run: |
docker push "$REPO_URI:$IMAGE_TAG"
docker push "$REPO_URI:latest"

- name: 작업 정의 템플릿 렌더링
run: |
sudo apt-get update -y && sudo apt-get install -y gettext-base
export AWS_ACCOUNT_ID=${{ secrets.AWS_ACCOUNT_ID }}
export AWS_REGION=${{ secrets.AWS_REGION }}
export IMAGE_TAG=${{ env.IMAGE_TAG }}
envsubst < ecs-task-def.json > task-def.rendered.json
echo "=== Rendered task def ==="
cat task-def.rendered.json

- name: 작업 정의 업데이트
run: |
aws ecs register-task-definition \
--cli-input-json file://task-def.rendered.json

- name: ECS 서비스 업데이트
run: |
aws ecs update-service \
--cluster ${{ secrets.ECS_CLUSTER }} \
--service ${{ secrets.ECS_SERVICE }} \
--force-new-deployment

- name: ECS 배포 완료 대기
run: |
aws ecs wait services-stable \
--cluster ${{ secrets.ECS_CLUSTER }} \
--services ${{ secrets.ECS_SERVICE }}

- name: ECS 배포 상태 확인
run: |
aws ecs describe-services \
--cluster ${{ secrets.ECS_CLUSTER }} \
--services ${{ secrets.ECS_SERVICE }} \
--query "services[0].deployments"
35 changes: 35 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
on:
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

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

- name: Grant execute permission for gradlew
run: chmod +x gradlew

# Gradle 캐싱 설정
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
cache-read-only: false

- name: Build with Gradle
run: ./gradlew build test

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ bin/
out/
!**/src/main/**/out/
!**/src/test/**/out/
.env
.discoedit/**
src/main/resources/static/**
src/main/generated/**
logs/**
{discodeit.storage.local.root-path}
/build/generated/**


### NetBeans ###
/nbproject/private/
Expand Down
49 changes: 49 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ARG는 값을 외부에서 덮어쓸 수 있으므로 사용x
# =========== (1) Build =============
FROM gradle:7.6.0-jdk17 AS build

# 루트 권한으로 변경 (권한 설정/ 폴더 생성작업을 위해)
USER root
# 애플리케이션 작업 디렉토리 설정
WORKDIR /app
# Gradle 캐시 디토리와 앱 디렉토리 소유자를 gradle 유저로 변경
RUN mkdir -p /home/gradle/.gradle && chown -R gradle:gradle /home/gradle /app
# gradle 유저로 변경(보안 및 권한 문제 방지)
User gradle

# Gradle Wrapper 스크립트 복사 (빌드 실행에 필요)
COPY --chown=gradle:gradle gradlew ./
# gradle 폴더 복사 (wrapper 설정 및 실행 환경)
COPY --chown=gradle:gradle gradle ./gradle
# Gradle 설정 파일 복사 (빌드 스크립트)
COPY --chown=gradle:gradle settings.gradle build.gradle ./
# gradlew 실행 권한 부여
RUN chmod +x ./gradlew
# 의존성만 먼저 다운로드하여 캐시 활용 (코드 변경 없이 재사용 가능)
RUN ./gradlew --no-daemon --refresh-dependencies dependencies || true
# 실제 소스코드 복사 (이 시점 이후 변경 시 빌드 다시 수행됨)
COPY --chown=gradle:gradle src ./src
# 애플리케이션 빌드
RUN ./gradlew clean build


# ============ (2) Runtime ============
# 런타임 스테이지: 빌드 결과 실행에 필요한 최소한의 경량 이미지 사용
FROM amazoncorretto:17
# 앱 실행 디렉토리 지정
WORKDIR /app

# 빌드 스테이지에서 생성한 JAR 파일만 복사
COPY --from=build /app/build/libs/*.jar app.jar
# 애플리케이션이 사용하는 포트 노출
EXPOSE 80
# 프로젝트 정보 환경변수 설정
ENV PROJECT_VERSION=1.2-M8
ENV PROJECT_NAME=discodeit
#JVM_OPTS: JVM 옵션
ENV JVM_OPTS=""
# Spring Boot 프로필을 운영(prod)으로 설정
ENV SPRING_PROFILES_ACTIVE=prod
# 컨테이너 시작 시 JAR 실행
#CMD["sh", "-c", "exec", "java", "${JVM_OPTS}", "-jar", "${PROJECT_NAME}-${PROJECT_VERSION}.jar"]
ENTRYPOINT ["java", "-jar", "app.jar"]
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

[![codecov](https://codecov.io/github/kdfasdf/4-sprint-mission/branch/sprint8/graph/badge.svg?token=Z4ZWRVXB5J)](https://codecov.io/github/kdfasdf/4-sprint-mission)
### REST API 설계원칙 준수
- 리소스 중심의 URI 설계
- GET /api/users/{userId}
- 명확한 상태코드 응답 제공
- request : DELETE /api/users/{userId}
- response : ResponseEntity.noContent().build()
- 필터링, 정렬, 페이징에 쿼리 파라미터 사용
- request : /channels?userId=d3ee2929-212b-4077-af84-694a0e69b8e1

### 예외 처리
- Global
- GlobalHandlerExceptionResolver를 통한 전역 예외 처리
- ErrorResponse(String message, String code, ins status, List\<FieldError> errors, List\<ConstraintViolationError> violationErrors) 형식으로 응답형식 통일
- 커스텀 예외를 발생시키는 경우 상황에 맞는 오류 메시지를 전달하여 서버 내부 오류 메시지 노출 최소화
- Controller
- bean validation을 통한 요청 검증
- Service
- 도메인과 비즈니스 로직 상황에 맞는 커스텀 예외 발생

### OOP
- 무분별한 @Setter 방지를 통한 캡슐화 원칙 준수
- 수정 가능한 필드에 대해서 비즈니스적인 의미를 가지는 setter 메서드 구현

### Test Code
- 슬라이스 테스트
- mockito 라이브러리를 사용하여 controller, repository계층 슬라이스 테스트, 서비스 계층 단위테스트를 통한 계층 별 동작 검증
- 통합 테스트
- controller 계층 통합테스트를 진행하여 프로덕션 코드 안정성 보장

### Logging
- MDC Interceptor
- 요청별 고유 ID(requestId) 요청 생성 및 HTTP 메서드, 요청 경로 정보 자동 수집
- afterCompletion에서 MDC 정리를 통한 메모리 누수 방지
- AOP
- MethodLoggingAspect를 통한 비즈니스 로직 요청 응답 추적
- LogParameterFormatter를 통한 로그 출력 형식 표준화
- 리플렉션을 통한 요청 필드 상세 분석
- 민감정보 마스킹

### API 문서화
- swagger를 통한 API 문서화
- 인터페이스로 추상화하여 controller 계층에 non-invasive하도록 문서화

### Docker
- 멀티스테이지 빌드: Build와 Runtime 스테이지 분리로 최종 이미지 크기 최적화
- Build 스테이지: Gradle 기반 애플리케이션 컴파일 및 의존성 관리
- Runtime 스테이지: Amazon Corretto JDK17 경량 런타임 환경
- 레이어 캐싱 최적화: 의존성과 소스코드 복사 단계 분리로 빌드 성능 향상
- Gradle 설정 파일 우선 복사 후 의존성 다운로드
- 소스코드 변경 시에도 의존성 레이어 캐시 재사용

### CI/CD
- GitHub Actions를 통한 자동화된 빌드 및 배포 파이프라인 구성
- Pull Request 시 자동 테스트 실행 및 코드 커버리지 측정
- CI
- JDK 17 (Amazon Corretto) 기반 빌드 환경 구성
- Gradle 캐싱을 통한 빌드 성능 최적화
- CD
- Docker 기반 컨테이너화된 애플리케이션 배포
- AWS ECR를 통한 컨테이너 이미지 저장 및 ECS를 정의를 통한 배포

3 changes: 3 additions & 0 deletions admin/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/gradlew text eol=lf
*.bat text eol=crlf
*.jar binary
37 changes: 37 additions & 0 deletions admin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
39 changes: 39 additions & 0 deletions admin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.5'
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.codeit'
version = '0.0.1-SNAPSHOT'
description = 'admin'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

repositories {
mavenCentral()
}

ext {
set('springBootAdminVersion', "3.5.0")
}

dependencies {
implementation 'de.codecentric:spring-boot-admin-starter-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

dependencyManagement {
imports {
mavenBom "de.codecentric:spring-boot-admin-dependencies:${springBootAdminVersion}"
}
}

tasks.named('test') {
useJUnitPlatform()
}
Binary file added admin/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions admin/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading