From 269109a73d4e52bd0ff2b22068caa91bf439dac4 Mon Sep 17 00:00:00 2001 From: Parkjihun Date: Mon, 15 Dec 2025 00:30:30 +0900 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20SonarCloud=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B6=84=EC=84=9D=20=EB=8F=84=EC=9E=85=20?= =?UTF-8?q?(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: sonarcloud 추가설정 및 yml추가 #2 * chore: sonarcloud.yml 워크플로우 브랜치 이름 변경 #2 * chore: sonarcloud 버전이 gradle 8버전과 맞지않아 변경 #2 * chore: Gradle 8.10으로 다운그레이드 #2 --- .github/workflows/sonarcloud.yml | 43 ++++++++++++++++++++++++ build.gradle | 9 +++++ gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/sonarcloud.yml diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 0000000..10c34fe --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,43 @@ +name: SonarCloud Analysis + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: + - master + - dev + +jobs: + sonarcloud: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: ./gradlew sonar --info \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2c73181..215358d 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'org.springframework.boot' version '3.5.7' id 'io.spring.dependency-management' version '1.1.7' id 'com.diffplug.spotless' version '6.22.0' + id 'org.sonarqube' version '5.1.0.4882' } group = 'org.hanseiro' @@ -15,6 +16,14 @@ java { } } +sonar { + properties { + property 'sonar.projectKey', 'Hansei-ro_hanseiro-server' + property 'sonar.organization', 'hansei-ro' + property 'sonar.host.url', 'https://sonarcloud.io' + } +} + repositories { mavenCentral() } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 23449a2..9355b41 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 70ec18cae635e7e5ffac3e51c4710d9760a29236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=A7=80=ED=9B=88?= Date: Sat, 20 Dec 2025 18:56:39 +0900 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20docs=20=EA=B8=B0=EC=A0=9C=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20=EC=B6=94=EA=B0=80=20#5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Documentation_Guide.md | 269 ++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 docs/Documentation_Guide.md diff --git a/docs/Documentation_Guide.md b/docs/Documentation_Guide.md new file mode 100644 index 0000000..c598eb2 --- /dev/null +++ b/docs/Documentation_Guide.md @@ -0,0 +1,269 @@ +# API Documentation Convention Guide + +> 이 문서는 한세로 프로젝트의 API 문서 작성 컨벤션입니다. +> 모든 API 문서는 이 형식을 따라 작성해주세요. + +--- + +## 문서 구조 +``` +docs/ +├── API_DOCS_EXAMPLE.md # 이 파일 (컨벤션 가이드) +├── USER_API.md # 사용자 관련 API +├── MATCHING_API.md # 매칭 관련 API +├── MATCHING_ROOM_API.md # 매칭룸 관련 API +├── BUS_ROUTE_API.md # 버스 노선 관련 API +└── CHAT_API.md # 채팅 관련 API (P2) +``` + +--- + +## API 문서 작성 템플릿 + +### 기본 정보 +```markdown +# [도메인명] API + +> Base URL: `/api/v1/[도메인]` +> 담당자: [이름] +> 최종 수정일: YYYY.MM.DD +``` + +--- + +### 엔드포인트 작성 형식 + +각 엔드포인트는 아래 형식을 따릅니다. + +--- + +## `[METHOD]` /api/v1/[resource] + +### 개요 +| 항목 | 내용 | +|------|------| +| **설명** | 이 API가 하는 일을 한 줄로 설명 | +| **인증** | Required / Optional / None | +| **권한** | USER / ADMIN / ALL | + +### Method 선택 이유 +> 왜 이 HTTP Method를 선택했는지 간단히 설명 +> 예: POST - 새로운 리소스(매칭 요청)를 생성하기 때문 + +--- + +### Request + +#### Headers +| Key | Value | Required | Description | +|-----|-------|----------|-------------| +| Authorization | Bearer {token} | O | JWT 액세스 토큰 | +| Content-Type | application/json | O | - | + +#### Path Parameters +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| id | Long | O | 리소스 고유 ID | + +#### Query Parameters +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| page | Integer | X | 0 | 페이지 번호 | +| size | Integer | X | 10 | 페이지 크기 | + +#### Request Body +```json +{ + "field1": "string", + "field2": 0, + "field3": true +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| field1 | String | O | 필드 설명 | +| field2 | Integer | O | 필드 설명 | +| field3 | Boolean | X | 필드 설명 (기본값: false) | + +--- + +### Response + +#### 성공 (200 OK) +```json +{ + "code": "SUCCESS", + "message": "요청이 성공했습니다.", + "data": { + "id": 1, + "field1": "value", + "createdAt": "2025-01-01T12:00:00" + } +} +``` + +#### 실패 케이스 + +| Status | Code | Message | Description | +|--------|------|---------|-------------| +| 400 | INVALID_INPUT | 입력값이 올바르지 않습니다 | 필수 필드 누락 또는 형식 오류 | +| 401 | UNAUTHORIZED | 인증이 필요합니다 | 토큰 없음 또는 만료 | +| 404 | NOT_FOUND | 리소스를 찾을 수 없습니다 | 존재하지 않는 ID | +| 409 | CONFLICT | 이미 존재하는 리소스입니다 | 중복 요청 | +```json +{ + "code": "INVALID_INPUT", + "message": "입력값이 올바르지 않습니다", + "errors": [ + { + "field": "email", + "message": "이메일 형식이 올바르지 않습니다" + } + ] +} +``` + +--- + +## 실제 예시: 매칭 요청 API + +## `POST` /api/v1/matching + +### 개요 +| 항목 | 내용 | +|------|------| +| **설명** | 택시 카풀 매칭 대기열에 등록 | +| **인증** | Required | +| **권한** | USER | + +### Method 선택 이유 +> POST - 매칭 대기열에 새로운 요청(리소스)을 생성하는 행위이므로 POST 사용. +> 동일한 요청을 여러 번 보내면 중복 등록될 수 있으므로 멱등성이 없음. + +--- + +### Request + +#### Headers +| Key | Value | Required | Description | +|-----|-------|----------|-------------| +| Authorization | Bearer {token} | O | JWT 액세스 토큰 | +| Content-Type | application/json | O | - | + +#### Request Body +```json +{ + "departureStation": "SANBON", + "expectedDepartureTime": "2025-01-15T09:00:00" +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| departureStation | String | O | 출발역 (SANBON / GEUMJEONG) | +| expectedDepartureTime | DateTime | X | 예상 출발 시간 (미입력 시 즉시 매칭) | + +--- + +### Response + +#### 성공 (201 Created) +```json +{ + "code": "SUCCESS", + "message": "매칭 대기열에 등록되었습니다.", + "data": { + "matchingRequestId": 123, + "departureStation": "SANBON", + "status": "WAITING", + "queuePosition": 3, + "estimatedWaitTime": 5, + "createdAt": "2025-01-15T08:55:00" + } +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| matchingRequestId | Long | 매칭 요청 ID | +| departureStation | String | 출발역 | +| status | String | 상태 (WAITING / MATCHED / CANCELLED) | +| queuePosition | Integer | 대기열 순서 | +| estimatedWaitTime | Integer | 예상 대기 시간 (분) | +| createdAt | DateTime | 요청 생성 시간 | + +#### 실패 케이스 + +| Status | Code | Message | Description | +|--------|------|---------|-------------| +| 400 | INVALID_STATION | 올바르지 않은 출발역입니다 | SANBON, GEUMJEONG 외 값 | +| 401 | UNAUTHORIZED | 인증이 필요합니다 | 토큰 없음 또는 만료 | +| 409 | ALREADY_IN_QUEUE | 이미 대기열에 등록되어 있습니다 | 중복 매칭 요청 | + +--- + +## 작성 시 체크리스트 + +- [ ] 엔드포인트 URL이 RESTful 규칙을 따르는가? +- [ ] HTTP Method 선택 이유가 명확한가? +- [ ] Request/Response 예시가 실제 데이터와 유사한가? +- [ ] 모든 필수/선택 필드가 명시되어 있는가? +- [ ] 에러 케이스가 충분히 정의되어 있는가? +- [ ] 인증/권한 정보가 명시되어 있는가? + +--- + +## HTTP Method 가이드 + +| Method | 용도 | 멱등성 | 예시 | +|--------|------|--------|------| +| GET | 리소스 조회 | O | 매칭 상태 조회 | +| POST | 리소스 생성 | X | 매칭 요청, 회원가입 | +| PUT | 리소스 전체 수정 | O | 프로필 전체 수정 | +| PATCH | 리소스 부분 수정 | O | 프로필 일부 수정 | +| DELETE | 리소스 삭제 | O | 매칭 취소 | + +--- + +## 공통 Response 형식 + +### 성공 응답 +```json +{ + "code": "SUCCESS", + "message": "성공 메시지", + "data": { ... } +} +``` + +### 에러 응답 +```json +{ + "code": "ERROR_CODE", + "message": "에러 메시지", + "errors": [ + { + "field": "필드명", + "message": "상세 에러 메시지" + } + ] +} +``` + +### 페이징 응답 +```json +{ + "code": "SUCCESS", + "message": "성공", + "data": { + "content": [ ... ], + "page": 0, + "size": 10, + "totalElements": 100, + "totalPages": 10, + "first": true, + "last": false + } +} +``` \ No newline at end of file