UMC 10기 프로젝트 '투겟 (Toget)'의 백엔드 저장소입니다.
- Language: Java 21
- Framework: Spring Boot 4.1.0
- Database: MySQL
- ORM / JPA: Spring Data JPA (Hibernate)
- Security: Spring Security 7.1.0
- Build Tool: Gradle 9.5.1
- Libraries:
- Lombok (1.18.46)
- Springdoc OpenAPI / Swagger (v3.0.1)
- MySQL Connector/J (v9.7.0)
- AWS SDK v2 S3 (v2.25.20)
main: 실제 서비스로 출시될 수 있는 안정된 상태의 코드만 관리합니다.develop: 다음 출시 버전을 개발하는 통합 브랜치입니다. 모든 기능 개발의 시작점이며, 항상 빌드 오류가 없는 상태를 유지해야 합니다.feat: 새로운 기능을 개발할 때 사용합니다. 작업이 완료되면develop브랜치에 Pull Request(PR)를 보냅니다.fix: 버그 및 예외 사항을 수정할 때 사용합니다.refac: 기능 변경 없이 코드의 가독성을 높이거나 구조를 개선할 때 사용합니다.chore: 패키지 매니저 설정, 빌드 스크립트 수정,.gitignore등 소스 코드 로직과 무관한 환경 설정을 수정할 때 사용합니다.docs: 문서를 생성하거나 수정할 때 사용합니다. (README, API 명세서, 주석 등)task: 어느 태그로도 분류하기 어려운 작업이나 하위 태스크를 포함하는 상위 작업에 사용합니다. (사용을 최소화하고, 가능하면 다른 태그로 세분화하여 사용합니다.)
이슈 번호와 명확한 작업 명을 포함하여 구성합니다.
- 형식:
전략/#이슈번호-제목 - 예시:
feat/#5-userfix/#43-funding-apichore/#10-setupdocs/#15-readmetask/#2-db-design
- 이슈 생성: 기능을 개발하기 전 GitHub Issues에 작업 내용을 등록하고 이슈 번호를 할당받습니다.
- 브랜치 생성:
- 브랜치를 생성하기 전 반드시
develop브랜치를 최신 상태로 pull 받습니다. develop브랜치로부터전략/#이슈번호-제목형식으로 브랜치를 생성합니다.
- 브랜치를 생성하기 전 반드시
- 작업 및 커밋: 작업 단위별로 아래 커밋 컨벤션에 맞춰 커밋을 진행합니다.
- Pull Request (PR):
- 본인의 브랜치 작업을 마친 후, GitHub에서
develop브랜치로 PR을 보냅니다. - PR 작성 시 템플릿의 자가 검증 항목을 모두 점검합니다.
- AI 리뷰어 외에 최소 1명 이상의 인간 리뷰어에게 승인(approve)을 받은 후
develop에 머지합니다.
- 본인의 브랜치 작업을 마친 후, GitHub에서
커밋 메시지는 작업의 성격을 한눈에 알 수 있도록 아래의 태그를 사용합니다.
- 형식:
태그: 설명 - 예시:
feat: User 도메인 DTO 설정
| 태그 | 설명 |
|---|---|
| feat | 새로운 기능 추가 또는 기존 기능의 요구사항 수정 |
| fix | 버그 수정 |
| refactor | 기능 변화 없이 코드의 가독성이나 구조를 개선 (변수명 변경 등) |
| chore | 빌드 설정, 패키지 매니저, 환경 설정 등 기타 코드 이외의 작업 |
| docs | 문서 수정 (README, 주석, API 명세 등) |
| style | 코드 로직 변경 없는 스타일 수정 (들여쓰기, 포맷팅 등) |
| test | 테스트 코드 추가 및 수정 |
| build | 빌드 관련 파일 수정 (build.gradle 등) |
| release | 버전 릴리즈 및 배포 관련 작업 |
협업 효율성과 코드 유지보수성을 극대화하기 위해 다음 스타일 가이드를 준수합니다.
- 도메인 기반 구조를 채택합니다.
- 패키지는 업무 도메인을 기준으로 분류하며, 도메인 패키지 내부에
controller,service,repository,dto등을 위치시켜 응집도를 높이고 관심사를 분리합니다.
- Java 16+
record타입을 사용하여 DTO를 정의합니다. - 이를 통해 데이터 전달 객체의 불변성을 보장하고 불필요한 보일러플레이트 코드(Getter, equals, hashCode 등)를 방지합니다.
- DTO와 엔티티 간 변환 시 단일 책임 원칙(SRP)을 준수하기 위해 별도의 Converter 클래스를 정의하여 빌더 패턴으로 응답 DTO를 생성합니다. (DTO 내부에 변환 로직을 섞는 것을 지양합니다.)
- 엔티티 클래스 명명 규칙: PascalCase를 사용합니다. (ex.
UserEntity) - DB 테이블 및 컬럼 명명 규칙: 소문자
snake_case를 사용합니다. (ex.user_id,created_at) - Audit 필드 분리: 생성일시(
createdAt)와 수정일시(updatedAt) 필드는BaseEntity로 분리하여 정의하고, 모든 Entity가 이를 상속받도록 설계합니다. - PK 생성 전략: PK 생성은 데이터베이스에 전적으로 위임하는 IDENTITY 전략 (
@GeneratedValue(strategy = GenerationType.IDENTITY))을 사용합니다. - 엔티티 생성 및 데이터 수정: 엔티티 객체 생성 시에는
@Builder패턴을 사용하여 객체를 생성하며, 무분별한 데이터 변경 대신 비즈니스 의미가 담긴 명확한 메서드(수정용 메서드 등)를 엔티티에 별도로 정의하여 사용합니다. 기본 생성자는 지연 로딩을 위해access = AccessLevel.PROTECTED로 제한합니다. - 지연 로딩: 불필요한 조회 및 N+1 문제 방지를 위해 모든 연관 관계(ManyToOne, OneToOne 등)는 지연 로딩 (
FetchType.LAZY)을 기본으로 설정합니다. - 연관관계 매핑: 단방향 매핑을 우선 적용하고, 도메인 간 양방향 참조가 반드시 필요한 경우에만 신중하게 양방향 매핑을 추가합니다.
- 모든 API 응답은 프론트엔드와의 원활한 소통을 위해 일관된 공통 응답 구조(
ApiResponse) 포맷을 반환합니다.
{
"isSuccess": true,
"code": "COMMON200",
"message": "요청에 성공하였습니다.",
"result": { ...데이터 DTO... }
}@RestControllerAdvice와@ExceptionHandler를 이용해 전역 예외 처리 체계를 구축합니다. 예외 발생 시 원시 예외 정보(500 에러, Stack Trace)가 외부로 유출되지 않도록 하며, 항상 정의된 공통 에러 포맷으로 가공하여 전달합니다.- 컨트롤러 단에서
@Valid어노테이션을 사용하여 요청 바디를 검증하고, 검증 실패 시 발생하는MethodArgumentNotValidException을 캐치하여 구체적인 예외 필드와 원인을 공통 응답 포맷으로 응답합니다.
- 자원의 표현: URI 경로에는 자원을 나타내는 복수형 명사를 사용하며, 단수형은 지양합니다. (ex.
/api/v1/wishlists) - 동사 사용 배제: 경로에 행위를 나타내는 동사(ex.
get,create,delete,update)를 쓰지 않고, HTTP Method (GET,POST,PUT/PATCH,DELETE)로 행위를 명시합니다. - 표기법: 경로 작성 시 소문자와 하이픈(-)을 사용하는 kebab-case를 사용합니다. (ex.
/api/v1/user-accounts)