Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c54d3a4
✨ Feat: Configure Eureka and Config client connection
mimimya Apr 23, 2026
99d17d0
✨ Feat: API 명세서 반영한 라우팅 규칙 추가
mimimya Apr 23, 2026
bf6cbbc
Chore: modify settings.gradle project name
mimimya Apr 23, 2026
84c0d4f
Merge pull request #2 from Pagely-wisely/feat/1-gateway-init
mimimya Apr 25, 2026
d369ba6
Chore: jjwt 의존성 추가 (jjwtVersion 변수로 버전 관리)
mimimya Apr 26, 2026
4fdb06d
🩹 Fix: jjwt BOM 이름 수정
mimimya Apr 27, 2026
1506b94
🩹 Fix: jjwt BOM 제거 (버전 명시)
mimimya Apr 27, 2026
64149ae
✨ Feat: JWT_SECRET 추가 (env 파일 import)
mimimya Apr 27, 2026
702df37
✨ Feat: JwtTokenProvider 구현 (HMAC HS256 검증)
mimimya Apr 27, 2026
dff7a24
✨ Feat: JwtProperties 사용 (ConfigurationProperties 패턴 적용)
mimimya Apr 27, 2026
0a8aa7b
✨ Feat: AuthenticationFilter 구현 (Reactive GlobalFilter)
mimimya Apr 27, 2026
7db6170
Chore: CI 설정 (레포 secret 사용 - JWT-SECRET)
mimimya Apr 27, 2026
247d1c5
Fix: .gitignore
mimimya Apr 27, 2026
c807288
Merge pull request #13 from Pagely-wisely/feat/2-jwt-authentication
mimimya Apr 27, 2026
2fb67ac
♻️ Refactor: 프로젝트 패키지 오타 수정
mimimya Apr 27, 2026
ccc9e04
Merge pull request #14 from Pagely-wisely/refactor/11-package-name
mimimya Apr 29, 2026
b78e439
🐛 Fix: 잘못된 public path 수정
mimimya May 4, 2026
238aa06
♻️ Refactor: 에러 응답 형태 수정
mimimya May 4, 2026
172689a
🔨Script: pr 브렌치 네이밍 bug 타입 추가
mimimya May 4, 2026
4256039
Merge pull request #16 from Pagely-wisely/bug/15-user-service-public-…
mimimya May 4, 2026
e85d0ea
Chore: 주석 정리
mimimya May 6, 2026
b1e9541
✨ Feat: Auth Service 라우팅
mimimya May 14, 2026
01a4a5c
Merge pull request #18 from Pagely-wisely/feat/17-auth-service-routing
mimimya May 17, 2026
6348ef4
✨ Feat: Dockerfile 추가
mimimya May 17, 2026
29bdbd1
✨ Feat: Prod 환경의 application 파일 추가
mimimya May 17, 2026
293e099
🩹 Fix: Prod 환경의 application 파일
mimimya May 17, 2026
8af841a
🩹 Fix: Dockerfile 빌드 옵션 수정
mimimya May 17, 2026
d5ca0c0
✨ Feat: Git actions cd 플로우 추가
mimimya May 17, 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
18 changes: 18 additions & 0 deletions .github/auto_assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
addReviewers: true

addAssignees: author

reviewers:
- M1Nj1M
- soo96
- jsh9057
- gnoesnooj
- hhegi
- mimimya

numberOfReviewers: 6

numberOfAssignees: 1

skipKeywords:
- wip
18 changes: 18 additions & 0 deletions .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Auto Assign Reviewers

on:
pull_request:
types: [ opened, ready_for_review ]

jobs:
assign:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read

steps:
- name: Auto Assign Action
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: ".github/auto_assign.yml"
27 changes: 27 additions & 0 deletions .github/workflows/branch-name-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Branch Naming Check

on:
push:
branches-ignore:
- main
- dev
- init
- release

jobs:
check-branch-name:
runs-on: ubuntu-latest

steps:
- name: Check branch name format
run: |
BRANCH_NAME=${GITHUB_REF#refs/heads/}
REGEX="^(feat|fix|refactor|docs|chore|test|bug)\/[0-9]+-.+$"

if [[ ! $BRANCH_NAME =~ $REGEX ]]; then
echo "❌ ERROR: 브랜치 이름 형식이 틀렸습니다!"
echo "형식: 타입/이슈번호-설명 (예: feat/12-login)"
exit 1
fi

echo "✅ 브랜치 이름 형식이 올바릅니다: $BRANCH_NAME"
77 changes: 77 additions & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Continuous Deployment

on:
push:
branches:
- prod

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: 1. 코드가져오기 (Checkout)
uses: actions/checkout@v4

- name: 2. JDK 21 설정
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: 3. .env 파일 생성
run: |
cat << EOF > .env
${{ secrets.PROD_ENV_FILE }}
EOF

- name: 4. Docker Hub 로그인
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: 5. Docker 이미지 빌드 및 푸시
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
build-args: |
GPR_USER=${{ secrets.GPR_USER }}
GPR_KEY=${{ secrets.GPR_KEY }}
tags: ${{ secrets.DOCKER_USERNAME }}/gateway-service:latest

- name: 6. SSH를 통해 배포 서버 접속 및 컨테이너 실행
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.APP_EC2_IP }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
# 서버 내부의 배포 디렉토리 이동 (없으면 생성)
mkdir -p ~/app/gateway
cd ~/app/gateway

# 서버 호스트에 .env 파일 작성
cat << 'EOF' > .env
${{ secrets.PROD_ENV_FILE }}
EOF

# 최신 Docker 이미지 다운로드
docker pull ${{ secrets.DOCKER_USERNAME }}/gateway-service:latest

# 기존에 돌고 있는 게이트웨이 컨테이너 중지 및 삭제
docker stop gateway || true
docker rm gateway || true

# 불필요한 구버전 이미지 정리
docker image prune -f

# 새 컨테이너 실행 (--env-file 옵션으로 뭉텅이 .env 주입)
docker run -d \
--name gateway \
-p 8080:8080 \
--env-file .env \
--restart always \
${{ secrets.DOCKER_USERNAME }}/gateway-service:latest
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: build

on:
pull_request:
branches:
- dev
- main

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read

env:
JWT_SECRET: ${{secrets.JWT_SECRET}}

steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: temurin

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

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

- name: Build with Gradle
run: ./gradlew clean build --stacktrace
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.env
src/main/resources/.env

HELP.md
.gradle
build/
Expand Down
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /workspace
COPY . .

# [나중에 공통모듈 쓸 때 주석 해제]
# ARG GPR_USER
# ARG GPR_KEY
# ENV GPR_USER=${GPR_USER}
# ENV GPR_KEY=${GPR_KEY}

RUN chmod +x gradlew

# 현재는 순수하게 빌드만 진행 (공통모듈 미사용 버전)
RUN ./gradlew bootJar --no-daemon

# [나중에 공통모듈 쓸 때 주석 해제할 라인]
# RUN ./gradlew bootJar --no-daemon -Pgpr.user="${GPR_USER}" -Pgpr.key="${GPR_KEY}"

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /workspace/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
47 changes: 26 additions & 21 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.13'
id 'io.spring.dependency-management' version '1.1.7'
id 'java'
id 'org.springframework.boot' version '3.5.13'
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.pagley'
group = 'com.pagely'
version = '0.0.1-SNAPSHOT'

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

repositories {
mavenCentral()
mavenCentral()
}

ext {
set('springCloudVersion', "2025.0.2")
set('springCloudVersion', "2025.0.2")
jjwtVersion = '0.12.6'
}

dependencies {
Expand All @@ -34,22 +35,26 @@ dependencies {
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testCompileOnly 'org.projectlombok:lombok'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testAnnotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// jjwt - 직접 버전 명시
implementation "io.jsonwebtoken:jjwt-api:${jjwtVersion}"
runtimeOnly "io.jsonwebtoken:jjwt-impl:${jjwtVersion}"
runtimeOnly "io.jsonwebtoken:jjwt-jackson:${jjwtVersion}"

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
testCompileOnly 'org.projectlombok:lombok'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testAnnotationProcessor 'org.projectlombok:lombok'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1 @@
rootProject.name = 'gateway'
rootProject.name = 'gatewayserver'
16 changes: 16 additions & 0 deletions src/main/java/com/pagely/gateway/GatewayApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.pagely.gateway;

import com.pagely.gateway.infrastructure.security.JwtProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
@EnableConfigurationProperties(JwtProperties.class)
public class GatewayApplication {

public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.pagely.gateway.domain.exception;

import lombok.Getter;

@Getter
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;

public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}

public BusinessException(ErrorCode errorCode, String detailMessage) {
super(detailMessage);
this.errorCode = errorCode;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.pagely.gateway.domain.exception;

import lombok.Getter;
import org.springframework.http.HttpStatus;

/**
* 공통 에러 코드.
*/
@Getter
public enum CommonErrorCode implements ErrorCode {

// 4xx
INVALID_INPUT("입력값이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
RESOURCE_NOT_FOUND("요청한 리소스를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
UNAUTHORIZED("인증이 필요합니다.", HttpStatus.UNAUTHORIZED),
FORBIDDEN("접근 권한이 없습니다.", HttpStatus.FORBIDDEN),
CONFLICT("요청이 현재 상태와 충돌합니다.", HttpStatus.CONFLICT),
UNSUPPORTED_MEDIA_TYPE("지원하지 않는 미디어 타입입니다.", HttpStatus.UNSUPPORTED_MEDIA_TYPE),
TOO_MANY_REQUESTS("요청이 너무 많습니다. 잠시 후 다시 시도해 주세요.", HttpStatus.TOO_MANY_REQUESTS),

// 5xx
INTERNAL_SERVER_ERROR("서버 내부 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
SERVICE_UNAVAILABLE("서비스를 일시적으로 사용할 수 없습니다.", HttpStatus.SERVICE_UNAVAILABLE),
EVENT_PUBLISH_FAILURE("이벤트 발행에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);


private final String code;
private final String message;
private final HttpStatus httpStatus;

CommonErrorCode(String message, HttpStatus httpStatus) {
this.code = this.name();
this.message = message;
this.httpStatus = httpStatus;
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/pagely/gateway/domain/exception/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.pagely.gateway.domain.exception;

import org.springframework.http.HttpStatus;

public interface ErrorCode {
String getCode();

String getMessage();

HttpStatus getHttpStatus();
}
Loading
Loading