Files
api2/CLAUDE.md
T
sdw086 43d3f8947e [api] swagger 셋팅중
- cors 화이트리스트 허용방식 변경
2026-02-26 09:35:21 +09:00

155 lines
5.9 KiB
Markdown

# CLAUDE.md - alist API 프로젝트
## Claude 작업 규칙 (중요!)
### 코드 수정 시 반드시 따를 것
1. **절대로 바로 파일을 수정하지 말 것**
2. **먼저 수정 방향과 계획을 설명**
3. **수정할 코드를 먼저 보여주기** (사용자가 직접 수정할 수도 있도록)
4. **사용자 확인 후 자동 작성 진행** 또는 사용자가 요청 시에만 작성
### 작업 순서 예시
```
1. "CORS 설정을 yml로 분리하겠습니다."
2. "다음과 같이 수정됩니다:"
- CorsProperties.java 생성 (코드 보여주기)
- CorsConfig.java 수정 (코드 보여주기)
- application-local.yaml 수정 (코드 보여주기)
3. "직접 수정하시겠습니까? 아니면 제가 작성할까요?"
4. (사용자 확인 후) 파일 수정 진행
```
## 프로젝트 개요
- **프로젝트명**: alist API
- **그룹**: com.alist
- **포트**: 8106
- **빌드 결과물**: `api.jar`
## 기술 스택
- **Java**: 21
- **Framework**: Spring Boot 3.5.10
- **빌드 도구**: Gradle
- **DB**: MariaDB
- **ORM**: MyBatis (mapper XML: `classpath:mapper/**/*.xml`)
- **인증**: JWT (jjwt 0.11.5) + Spring Security
- **API 문서**: Swagger (springdoc-openapi 2.6.0)
- **기타**: Lombok, Validation, Actuator, log4jdbc
## 패키지 구조
```
com.alist.api
├── common
│ ├── response/ # ApiResponse, ApiResponseCode
│ └── utils/ # 공통 유틸리티
├── config
│ ├── jwt/ # JWT 필터, 핸들러, Provider
│ ├── exception/ # GlobalExceptionHandler
│ ├── properties/ # JwtProperties 등
│ ├── SecurityConfig.java
│ └── OpenApiConfig.java
└── modules
└── {도메인}/ # Controller, Service, Mapper, DTO
```
## 프로파일
| 프로파일 | 설명 |
|---------|------|
| `local` | 로컬 개발 환경 |
| `pjt` | 프로젝트(개발) 환경 |
## 보안 구조
- **Swagger**: `/v3/api-docs/**`, `/swagger-ui/**` → HTTP Basic 인증 (InMemory)
- **API**: JWT Bearer 토큰 인증 (Stateless)
- **공개 경로**: `/`, `/actuator/health`, `/auth/**`, `/api/user/signup`
## 응답 코드 규칙
`ApiResponseCode` enum으로 관리. 주요 코드:
| 코드 | 메시지 | HTTP Status | 용도 |
|------|--------|-------------|------|
| `CODE_200` | 성공 | 200 OK | 일반 성공 |
| `CODE_400` | 잘못된 요청 | 400 Bad Request | 일반 클라이언트 오류 |
| `CODE_401` | 인증 필요 합니다. | 401 Unauthorized | 인증 없음 |
| `CODE_403` | 접근 권한 필요 합니다. | 403 Forbidden | 권한 없음 |
| `CODE_404` | 페이지를 찾을 수 없습니다. | 404 Not Found | 리소스 없음 |
| `CODE_405` | 잘못된 요청입니다. 요청 방식을 확인해 주세요. | 405 Method Not Allowed | 메서드 불일치 |
| `CODE_500` | 요청을 처리하는 중 오류가 발생했습니다. | 500 Internal Server Error | 서버 오류 |
| `CODE_2001` | {0} 정보 조회에 성공하였습니다. | 200 OK | 단건 조회 성공 |
| `CODE_2002` | {0} 등록 되었습니다. | 201 Created | 등록 성공 |
| `CODE_2003` | 조회된 정보가 없습니다. | 200 OK | 조회 결과 없음 |
| `CODE_2004` | 중복된 {0} 정보 입니다. | 409 Conflict | 중복 데이터 |
| `CODE_4001` | 입력값을 확인해주세요. | 400 Bad Request | `@Valid` / 바인딩 / 타입오류 / JSON 파싱 실패 |
| `CODE_4003` | 필수 요청 파라미터가 누락되었습니다. | 400 Bad Request | 필수 파라미터 누락 |
- `{0}` 자리에 대상명 삽입 (예: `CODE_2001` → "회원 정보 조회에 성공하였습니다.")
## 빌드 및 실행
```bash
# 빌드
./gradlew bootJar
# 로컬 실행
./gradlew bootRun --args='--spring.profiles.active=local'
# JAR 실행
java -jar build/libs/api.jar --spring.profiles.active=local
```
## Swagger 접속
- URL: `http://localhost:8106/swagger-ui.html`
- 인증: `swagger.login.id` / `swagger.login.password` (환경별 yaml에 설정)
## 코드 작성 규칙
- 응답은 `ApiResponse<T>` 래퍼 사용
- 응답 코드는 `ApiResponseCode` enum 사용
- MyBatis Mapper XML은 `src/main/resources/mapper/` 하위에 작성
- 카멜케이스 자동 변환 활성화 (`map-underscore-to-camel-case: true`)
- 새 모듈 추가 시: `modules/{moduleName}/` 하위에 Controller, Service, Mapper, dto/, vo/ 구조로 생성
- Mapper XML은 `resources/mapper/{moduleName}/` 에 위치
## MyBatis 규칙
- Mapper XML 위치: `src/main/resources/mapper/**/*.xml`
- `map-underscore-to-camel-case: true` 설정 → DB 컬럼 `user_idx` → Java 필드 `userIdx` 자동 매핑
- Mapper 인터페이스와 XML의 namespace, id 반드시 일치시킬 것
- VO: DB 조회 결과 매핑용 / DTO: 서비스 레이어 간 데이터 전달용 / Form: 컨트롤러 입력 검증용
## CI/CD
- **Jenkins**: `Jenkinsfile.pjt`
- **Docker**: `Dockerfile`
- **배포 스크립트**: `deploy/` 디렉토리
## 개발 서버 (pjt)
### 도메인
- **API**: `api-alist.pjt.kr`
- **파일(업로드)**: `file-alist.pjt.kr`
- **Swagger**: `https://api-alist.pjt.kr/swagger-ui/index.html`
### Docker
- **레지스트리**: `registry.pjt.kr`
- **이미지**: `registry.pjt.kr/alist/api`
- **컨테이너명**: `alist-api`
- **포트**: `127.0.0.1:8106->8106/tcp`
### 서버 디렉토리 (`/srv/project/alist/`)
```
/srv/project/alist/
├── compose/ # docker-compose 파일
├── data/ # 데이터
├── env/ # 환경변수 파일
├── logs/ # 로그
├── scripts/ # 배포/운영 스크립트
└── uploads/ # 업로드 파일 (file-alist.pjt.kr 루트)
```
### Nginx
- `file-alist.pjt.kr``/srv/project/alist/uploads` (정적 파일 서빙)
- HTTP(80) → HTTPS(301) 리다이렉트
- SSL: Let's Encrypt
- 직접 접근 차단 (`allow 127.0.0.1; deny all;`)
### 파일 업로드
- 업로드 저장 경로: `/srv/project/alist/uploads/`
- 업로드 파일 접근 URL: `https://file-alist.pjt.kr/{파일경로}`