-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor: 프로젝트 구조 리팩토링 #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| # 📒 FlipNote — User Service | ||
|
|
||
| **FlipNote 서비스의 유저 도메인 백엔드 레포지토리입니다.** | ||
|
|
||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|
|
||
| --- | ||
|
|
||
| ## 📑 목차 | ||
|
|
||
| - [시작하기](#-시작하기) | ||
| - [환경 변수](#-환경-변수) | ||
| - [실행 및 배포](#-실행-및-배포) | ||
| - [프로젝트 구조](#-프로젝트-구조) | ||
|
|
||
| --- | ||
|
|
||
| ## 🚀 시작하기 | ||
|
|
||
| ### 사전 요구사항 | ||
|
|
||
| - **Java** 21 이상 | ||
| - **Gradle** 8 이상 | ||
| - **MySQL** 8 이상 | ||
| - **Redis** 6 이상 | ||
| - Google OAuth2 클라이언트 생성 및 API 키 발급 | ||
| - Resend 계정 생성 및 API 키 발급 | ||
|
|
||
| ### 설치 | ||
|
|
||
| ```bash | ||
| # 의존성 설치 및 빌드 | ||
| ./gradlew build -x test | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 🔐 환경 변수 | ||
|
|
||
| `application.yml`에서 참조하는 환경 변수 목록입니다. 로컬 실행 시 `.env` 또는 IDE 실행 구성에 아래 변수를 설정합니다. | ||
|
|
||
| ``` | ||
| # ─── Database ─────────────────────────────────────────── | ||
| DB_URL=jdbc:mysql://localhost:3306/flipnote_user | ||
| DB_USERNAME= | ||
| DB_PASSWORD= | ||
|
|
||
| # ─── Redis ────────────────────────────────────────────── | ||
| REDIS_HOST=localhost | ||
| REDIS_PORT=6379 | ||
| REDIS_PASSWORD= | ||
|
|
||
| # ─── JPA ──────────────────────────────────────────────── | ||
| # create | create-drop | update | validate | none | ||
| DDL_AUTO=update | ||
|
|
||
| # ─── gRPC ─────────────────────────────────────────────── | ||
| GRPC_PORT=9092 | ||
|
|
||
| # ─── JWT ──────────────────────────────────────────────── | ||
| JWT_SECRET= | ||
| # 액세스 토큰 만료 시간 (ms), 기본값 900000 (15분) | ||
| JWT_ACCESS_EXPIRATION=900000 | ||
| # 리프레시 토큰 만료 시간 (ms), 기본값 604800000 (7일) | ||
| JWT_REFRESH_EXPIRATION=604800000 | ||
|
|
||
| # ─── Email (Resend) ───────────────────────────────────── | ||
| APP_RESEND_API_KEY= | ||
|
|
||
| # ─── Client ───────────────────────────────────────────── | ||
| # 프론트엔드 URL (CORS, 리다이렉트에 사용) | ||
| APP_CLIENT_URL=http://localhost:3000 | ||
|
|
||
| # ─── Google OAuth2 ────────────────────────────────────── | ||
| GOOGLE_CLIENT_ID= | ||
| GOOGLE_CLIENT_SECRET= | ||
| ``` | ||
|
Comment on lines
+46
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 펜스 코드블록에 언어를 지정해 주세요. 현재 여러 코드블록에 language 지정이 없어 린트 경고(MD040)가 발생합니다. 최소 수정 예시- ```
+ ```bash
# ─── Database ───────────────────────────────────────────
...
- ```
+ ```
- ```
+ ```text
src/main/java/flipnote/user/
...
- ```
+ ```
- ```
+ ```text
FlipNote-User/
...
- ```
+ ```Also applies to: 148-154, 156-228 🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 46-46: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||
|
|
||
| > **⚠️ 주의**: 환경 변수 파일은 절대 git에 커밋하지 마세요. `.gitignore`에 포함되어 있는지 반드시 확인하세요. | ||
|
|
||
| --- | ||
|
|
||
| ## 🖥️ 실행 및 배포 | ||
|
|
||
| ### 로컬 개발 서버 실행 | ||
|
|
||
| ```bash | ||
| ./gradlew bootRun | ||
| ``` | ||
|
|
||
| 기본적으로 `http://localhost:8081`에서 실행됩니다. | ||
| Swagger UI는 `http://localhost:8081/users/swagger-ui.html`에서 확인할 수 있습니다. | ||
|
|
||
|
Comment on lines
+95
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 로컬 기본 포트 안내와 Docker 포트 매핑이 서로 다릅니다. 문서상 기본 실행 포트는 수정 예시 (앱이 8081로 뜨는 경우)-docker run -p 8081:8080 \
+docker run -p 8081:8081 \
-e DB_URL=... \
-e JWT_SECRET=... \
flipnote-userAlso applies to: 119-123 🤖 Prompt for AI Agents |
||
| ### 프로덕션 빌드 | ||
|
|
||
| ```bash | ||
| ./gradlew bootJar | ||
| ``` | ||
|
|
||
| `build/libs/user-0.0.1-SNAPSHOT.jar` 파일이 생성됩니다. | ||
|
|
||
| ### 테스트 실행 | ||
|
|
||
| ```bash | ||
| ./gradlew test | ||
| ``` | ||
|
|
||
| ### Docker 이미지 빌드 및 실행 | ||
|
|
||
| ```bash | ||
| # 이미지 빌드 | ||
| docker build -t flipnote-user . | ||
|
|
||
| # 컨테이너 실행 | ||
| docker run -p 8081:8080 \ | ||
| -e DB_URL=... \ | ||
| -e JWT_SECRET=... \ | ||
| flipnote-user | ||
| ``` | ||
|
|
||
| ### 배포 (GitHub Actions) | ||
|
|
||
| `main` 브랜치에 push 시 GitHub Actions가 자동으로 아래 과정을 실행합니다. | ||
|
|
||
| **CI** (`push` / `pull_request` → `main`) | ||
| 1. JDK 21 설치 | ||
| 2. `./gradlew build -x test` — 빌드 검증 | ||
| 3. `./gradlew test` — 테스트 실행 | ||
| 4. Dependency-Check — 취약점 분석 리포트 생성 | ||
|
|
||
| **CD** (`push` → `main`) | ||
| 1. GitHub Container Registry(GHCR) 로그인 | ||
| 2. Docker 이미지 빌드 | ||
| 3. `ghcr.io/dungbik/flipnote-user` 이미지 Push | ||
|
|
||
| > 배포에 필요한 시크릿(`ORG_PAT`)은 GitHub Repository → Settings → Secrets and variables → Actions에 등록해야 합니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 📁 프로젝트 구조 | ||
|
|
||
| - 간략화 버전 | ||
|
|
||
| ``` | ||
| src/main/java/flipnote/user/ | ||
| ├── domain/ # 도메인 레이어 (엔티티, 레포지토리, 에러코드, 이벤트) | ||
| ├── application/ # 애플리케이션 레이어 (서비스) | ||
| ├── infrastructure/ # 인프라 레이어 (JWT, Redis, 메일, OAuth, 설정) | ||
| └── interfaces/ # 인터페이스 레이어 (HTTP, gRPC 진입점) | ||
| ``` | ||
|
|
||
| ``` | ||
| FlipNote-User/ | ||
| ├── src/ | ||
| │ ├── main/ | ||
| │ │ ├── java/flipnote/user/ | ||
| │ │ │ ├── UserApplication.java | ||
| │ │ │ │ | ||
| │ │ │ ├── domain/ # 도메인 레이어 | ||
| │ │ │ │ ├── common/ # 도메인 공통 | ||
| │ │ │ │ │ ├── ErrorCode.java | ||
| │ │ │ │ │ ├── BizException.java | ||
| │ │ │ │ │ └── EmailSendException.java | ||
| │ │ │ │ ├── entity/ # JPA 엔티티 | ||
| │ │ │ │ │ ├── User.java | ||
| │ │ │ │ │ ├── OAuthLink.java | ||
| │ │ │ │ │ └── BaseEntity.java | ||
| │ │ │ │ ├── repository/ # 레포지토리 인터페이스 | ||
| │ │ │ │ │ ├── UserRepository.java | ||
| │ │ │ │ │ └── OAuthLinkRepository.java | ||
| │ │ │ │ ├── event/ # 도메인 이벤트 | ||
| │ │ │ │ │ ├── EmailVerificationSendEvent.java | ||
| │ │ │ │ │ └── PasswordResetCreateEvent.java | ||
| │ │ │ │ ├── AuthErrorCode.java | ||
| │ │ │ │ ├── UserErrorCode.java | ||
| │ │ │ │ ├── ImageErrorCode.java | ||
| │ │ │ │ ├── TokenClaims.java | ||
| │ │ │ │ ├── TokenPair.java | ||
| │ │ │ │ ├── PasswordResetConstants.java | ||
| │ │ │ │ └── VerificationConstants.java | ||
| │ │ │ │ | ||
| │ │ │ ├── application/ # 애플리케이션 레이어 | ||
| │ │ │ │ ├── AuthService.java | ||
| │ │ │ │ ├── OAuthService.java | ||
| │ │ │ │ └── UserService.java | ||
| │ │ │ │ | ||
| │ │ │ ├── infrastructure/ # 인프라 레이어 | ||
| │ │ │ │ ├── config/ # 범용 설정 (App, JPA, Swagger, gRPC 클라이언트) | ||
| │ │ │ │ ├── jwt/ # JWT 발급/검증 + 설정 | ||
| │ │ │ │ ├── mail/ # 메일 발송 서비스 + 설정 | ||
| │ │ │ │ ├── oauth/ # Google OAuth2 클라이언트 + 설정 | ||
| │ │ │ │ ├── redis/ # Redis 저장소 (토큰, 인증코드 등) | ||
| │ │ │ │ └── listener/ # 도메인 이벤트 리스너 | ||
| │ │ │ │ | ||
| │ │ │ └── interfaces/ # 인터페이스 레이어 | ||
| │ │ │ ├── http/ # HTTP 진입점 | ||
| │ │ │ │ ├── AuthController.java # 인증 (회원가입, 로그인, 비밀번호 등) | ||
| │ │ │ │ ├── OAuthController.java # 소셜 로그인 (Google OAuth2) | ||
| │ │ │ │ ├── UserController.java # 유저 정보 조회/수정 | ||
| │ │ │ │ ├── dto/ | ||
| │ │ │ │ │ ├── request/ # Request DTO | ||
| │ │ │ │ │ └── response/ # Response DTO | ||
| │ │ │ │ └── common/ # ApiResponse, 예외 처리, 쿠키 유틸 | ||
| │ │ │ └── grpc/ # gRPC 진입점 | ||
| │ │ │ ├── GrpcUserQueryService.java # 유저 조회 gRPC 서비스 | ||
| │ │ │ └── GrpcExceptionHandlerImpl.java # gRPC 전역 예외 처리 | ||
| │ │ │ | ||
| │ │ ├── proto/ # gRPC proto 파일 | ||
| │ │ │ ├── user_query.proto | ||
| │ │ │ └── image.proto | ||
| │ │ │ | ||
| │ │ └── resources/ | ||
| │ │ ├── application.yml | ||
| │ │ └── templates/email/ # 이메일 HTML 템플릿 (Thymeleaf) | ||
| │ │ ├── email-verification.html | ||
| │ │ └── password-reset.html | ||
| │ │ | ||
| │ └── test/ | ||
| │ └── java/flipnote/user/ | ||
| │ | ||
| ├── Dockerfile | ||
| ├── build.gradle.kts | ||
| └── settings.gradle.kts | ||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TOC 앵커(fragment) 깨짐 가능성이 있습니다.
이모지가 포함된 제목(
## 🖥️ 실행 및 배포)을#-실행-및-배포로 직접 참조하면 GitHub slug와 불일치할 수 있어 목차 링크가 동작하지 않을 수 있습니다. 명시적 HTML 앵커를 두고 그 앵커를 링크하도록 고정하는 방식이 안전합니다.수정 예시
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 17-17: Link fragments should be valid
(MD051, link-fragments)
🤖 Prompt for AI Agents