Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d22fcb7
[refactor] 큐레이션 상세 응답에서 alcoholIds를 alcohols 객체 목록으로 변경
Whale0928 Feb 6, 2026
1b2ed77
chore: pre-commit 설정 파일 제거
Whale0928 Feb 6, 2026
7b5672f
feat: 어드민 배너 CRUD 기능 설계 및 구현 계획 추가
Whale0928 Feb 6, 2026
0678132
feat: 배너 도메인 엔티티 및 리포지토리 Admin용 확장
Whale0928 Feb 9, 2026
251e137
feat: 배너 Admin API 요청/응답 DTO 추가
Whale0928 Feb 9, 2026
8fbd653
feat: 배너 Admin 서비스 및 예외 처리 추가
Whale0928 Feb 9, 2026
b371adc
docs: 어드민 배너 CRUD 구현 계획 상세화
Whale0928 Feb 9, 2026
abf97c2
deps: version update
Whale0928 Feb 9, 2026
307ac91
feat: 배너 Admin API 컨트롤러 추가
Whale0928 Feb 9, 2026
c9c2162
test: 배너 Admin API 통합 테스트 및 RestDocs 문서화 추가
Whale0928 Feb 9, 2026
b922267
docs: 배너 Admin API RestDocs 문서 추가
Whale0928 Feb 9, 2026
b80f603
docs: 배너 API 문서에 BannerType, TextPosition enum 참조 추가
Whale0928 Feb 9, 2026
a82c53f
docs: 어드민 배너 구현 계획 완료 처리
Whale0928 Feb 9, 2026
93b6c31
docs: Admin API 구현 가이드 보강
Whale0928 Feb 9, 2026
97487ae
fix: TestFactory generateRandomSuffix 충돌로 인한 flaky test 수정
Whale0928 Feb 9, 2026
88f07f4
feat: 조회 기록 동기화 성능 및 안정성 개선
Whale0928 Feb 9, 2026
86a9963
chore: 버전 정보 업데이트
Whale0928 Feb 9, 2026
54e68d9
chore: version update @v1.0.6
hgkim-openerd Feb 10, 2026
5fd93e1
refactor: remove unused rating joins in CustomReviewRepositoryImpl
hgkim-openerd Feb 10, 2026
2d6d36b
chore: update version to 1.0.7 and add git tag creation step
hgkim-openerd Feb 10, 2026
28f8ac6
chore: add Version Tag Sync workflow and refactor version-check logic
hgkim-openerd Feb 10, 2026
aff91c4
deps: version patch
hgkim-openerd Feb 10, 2026
4a0ae38
chore: merge Version Tag Sync workflow with version-check logic and r…
hgkim-openerd Feb 10, 2026
58862ca
deps: version sync
hgkim-openerd Feb 10, 2026
ac7982c
deps: update version to 1.0.7-3 and enhance version parsing in workflow
hgkim-openerd Feb 10, 2026
0479812
refactor: update validation messages in AdminBanner request classes
Whale0928 Feb 11, 2026
ef5e193
chore: update environment variables and increment version to 1.0.8
Whale0928 Feb 11, 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
69 changes: 56 additions & 13 deletions .claude/docs/ADMIN-API-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ admin-api (Kotlin) → mono (Java)

| 순서 | 작업 | 모듈 | 위치 |
|------|------|------|------|
| 1 | Request/Response DTO | mono | `{domain}/dto/request/`, `{domain}/dto/response/` |
| 2 | ExceptionCode 추가 | mono | `{domain}/exception/{Domain}ExceptionCode.java` |
| 3 | ResultCode 추가 | mono | `global/dto/response/AdminResultResponse.java` |
| 4 | Repository 확장 (필요 시) | mono | `{domain}/repository/` |
| 5 | Service 작성 | mono | `{domain}/service/Admin{Domain}Service.java` |
| 6 | Controller 작성 | admin-api | `{domain}/presentation/Admin{Domain}Controller.kt` |
| 1 | 엔티티 수정 메서드 추가 (필요 시) | mono | `{domain}/domain/{Domain}.java` |
| 2 | Repository 확장 (필요 시) | mono | `{domain}/repository/` |
| 3 | Request/Response DTO | mono | `{domain}/dto/request/`, `{domain}/dto/response/` |
| 4 | ExceptionCode + Exception 추가 | mono | `{domain}/exception/{Domain}ExceptionCode.java`, `{Domain}Exception.java` |
| 5 | ResultCode 추가 | mono | `global/dto/response/AdminResultResponse.java` |
| 6 | Service 작성 | mono | `{domain}/service/Admin{Domain}Service.java` |
| 7 | Controller 작성 | admin-api | `{domain}/presentation/Admin{Domain}Controller.kt` |

> [주의] Repository 인터페이스에 메서드를 추가하면 `InMemory{Domain}Repository` 테스트 픽스처도 반드시 동기화해야 한다.

### Phase 2: 테스트

Expand All @@ -46,7 +49,12 @@ admin-api (Kotlin) → mono (Java)
| 순서 | 작업 | 위치 |
|------|------|------|
| 1 | RestDocs Test | `app/docs/{domain}/Admin{Domain}ControllerDocsTest.kt` |
| 2 | AsciiDoc | `src/docs/asciidoc/api/{domain}/` |
| 2 | Enum adoc 생성 | `src/docs/asciidoc/api/common/enums/{enum-name}.adoc` |
| 3 | Domain adoc 생성 | `src/docs/asciidoc/api/admin-{domain}/{domain}.adoc` |
| 4 | 메인 문서에 include 추가 | `src/docs/asciidoc/admin-api.adoc` |
| 5 | asciidoctor 빌드 검증 | `./gradlew :bottlenote-admin-api:asciidoctor` |

> Domain adoc에서 enum adoc을 include할 때 상대 경로 사용: `include::../common/enums/{enum-name}.adoc[]`

---

Expand All @@ -57,7 +65,7 @@ admin-api (Kotlin) → mono (Java)
| 규칙 | 설명 |
|------|------|
| **DTO-Entity 분리** | Response DTO는 Entity를 직접 참조하면 안 됨 (아키텍처 규칙 위반) |
| **팩토리 메서드** | `from(Entity)` 금지 → `of(...)` 사용, 변환 로직은 Service에서 처리 |
| **변환 로직** | `from(Entity)` 금지 → Service에서 직접 생성자 호출 또는 `of(...)` 팩토리 사용 |
| **record 사용** | Java record로 작성, `@Builder` 생성자에서 기본값 설정 |
| **Validation** | `@NotBlank`, `@NotNull` 등 Bean Validation 사용 |

Expand All @@ -66,7 +74,7 @@ admin-api (Kotlin) → mono (Java)
| 규칙 | 설명 |
|------|------|
| **목록 조회 반환** | `Page<T>` 직접 반환 금지 → `GlobalResponse.fromPage()` 사용 |
| **상세 조회 반환** | Response DTO 반환, `of()` 팩토리로 변환 |
| **상세 조회 반환** | Response DTO 반환, Service에서 변환 (직접 생성자 또는 `of()`) |
| **CUD 반환** | `AdminResultResponse.of(ResultCode, targetId)` 통일 |
| **트랜잭션** | 조회는 `@Transactional(readOnly = true)`, CUD는 `@Transactional` |

Expand Down Expand Up @@ -104,6 +112,20 @@ admin-api (Kotlin) → mono (Java)

---

## 예외 계층 구조

```
RuntimeException
→ AbstractCustomException (ExceptionCode 보유)
→ {Domain}Exception ({Domain}ExceptionCode)
```

- `{Domain}ExceptionCode`: `ExceptionCode` 인터페이스 구현 (`getMessage()`, `getHttpStatus()`)
- `{Domain}Exception`: `AbstractCustomException` 상속, 생성자에서 `ExceptionCode` 전달
- 참고: `AlcoholExceptionCode.java`, `BannerExceptionCode.java`

---

## 테스트 규칙

### Integration Test
Expand Down Expand Up @@ -138,6 +160,8 @@ admin-api (Kotlin) → mono (Java)

## 참고 구현 파일

### Curation (큐레이션) - 하위 리소스 관리 포함

| 항목 | 파일 경로 |
|------|----------|
| Controller | `admin-api/.../alcohols/presentation/AdminCurationController.kt` |
Expand All @@ -148,6 +172,22 @@ admin-api (Kotlin) → mono (Java)
| RestDocs Test | `admin-api/.../docs/curation/AdminCurationControllerDocsTest.kt` |
| Helper | `admin-api/.../helper/curation/CurationHelper.kt` |

### Banner (배너) - QueryDSL 검색, 비즈니스 검증, sortOrder 리오더링 포함

| 항목 | 파일 경로 |
|------|----------|
| Controller | `admin-api/.../banner/presentation/AdminBannerController.kt` |
| Service | `mono/.../banner/service/AdminBannerService.java` |
| Response DTO | `mono/.../banner/dto/response/AdminBanner*Response.java` |
| Request DTO | `mono/.../banner/dto/request/AdminBanner*Request.java` |
| Exception | `mono/.../banner/exception/BannerException.java`, `BannerExceptionCode.java` |
| QueryDSL | `mono/.../banner/repository/CustomBannerRepository*.java` |
| Integration Test | `admin-api/.../integration/banner/AdminBannerIntegrationTest.kt` |
| RestDocs Test | `admin-api/.../docs/banner/AdminBannerControllerDocsTest.kt` |
| Helper | `admin-api/.../helper/banner/BannerHelper.kt` |
| AsciiDoc | `admin-api/src/docs/asciidoc/api/admin-banners/banners.adoc` |
| Enum adoc | `admin-api/src/docs/asciidoc/api/common/enums/banner-type.adoc`, `text-position.adoc` |

---

## 검증 절차
Expand All @@ -158,12 +198,15 @@ Admin API 구현 완료 후 아래 순서대로 검증:
|------|----------|--------|-----------|
| 1 | 컴파일 | `./gradlew :bottlenote-admin-api:compileKotlin` | - |
| 2 | 코드 포맷팅 | `./gradlew :bottlenote-mono:spotlessCheck` | mono만 적용 |
| 3 | 아키텍처 규칙 | `./gradlew :bottlenote-mono:check_rule_test` | `@Tag("rule")` |
| 3 | 아키텍처 규칙 | `./gradlew check_rule_test` | `@Tag("rule")` |
| 4 | 단위 테스트 | `./gradlew unit_test` | `@Tag("unit")` |
| 5 | 어드민 통합 테스트 | `./gradlew admin_integration_test` | `@Tag("admin_integration")` |
| 6 | REST Docs 생성 | `./gradlew :bottlenote-admin-api:restDocsTest` | `app.docs.*` |
| 5 | Product 통합 테스트 | `./gradlew integration_test` | `@Tag("integration")` |
| 6 | Admin 통합 테스트 | `./gradlew admin_integration_test` | `@Tag("admin_integration")` |
| 7 | REST Docs 빌드 | `./gradlew :bottlenote-admin-api:asciidoctor` | 문서화 시 |

> CI 파이프라인은 3~6번을 병렬 실행한다. mono 모듈 변경이 product-api에 영향을 줄 수 있으므로 `integration_test`도 반드시 확인해야 한다.

**전체 검증 (위 1-5 포함):**
**전체 검증 (위 1-6 포함):**
```bash
./gradlew :bottlenote-admin-api:build
```
66 changes: 59 additions & 7 deletions .github/workflows/version-check.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,71 @@
name: Version Check & Release PR
name: Version Tag Sync

on:
push:
branches: [main]
paths:
- '**/VERSION'

concurrency:
group: version-check
group: version-tag-sync
cancel-in-progress: true

permissions:
contents: write
pull-requests: write

jobs:
check-and-create-pr:
create-tag:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- module: product
version_file: bottlenote-product-api/VERSION
- module: admin
version_file: bottlenote-admin-api/VERSION
- module: batch
version_file: bottlenote-batch/VERSION

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Check VERSION file changed
id: version-change
run: |
if git diff --name-only HEAD~1 HEAD | grep -q "${{ matrix.version_file }}"; then
VERSION=$(cat "${{ matrix.version_file }}" | tr -d '[:space:]')
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "${{ matrix.module }} VERSION changed: $VERSION"
else
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "${{ matrix.module }} VERSION not changed, skipping"
fi

- name: Create and push tag
if: steps.version-change.outputs.changed == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

VERSION="${{ steps.version-change.outputs.version }}"
MODULE="${{ matrix.module }}"
TAG_NAME="${MODULE}/v${VERSION}"

if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
echo "Tag $TAG_NAME already exists, skipping"
else
git tag -a "$TAG_NAME" -m "Release ${MODULE} v${VERSION}"
git push origin "$TAG_NAME"
echo "Created and pushed tag: $TAG_NAME"
fi

create-release-pr:
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -82,7 +134,7 @@ jobs:
id: existing-version
run: |
PR_TITLE="${{ steps.existing-pr.outputs.pr_title }}"
EXISTING_VERSION=$(echo "$PR_TITLE" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+' || echo "0.0.0")
EXISTING_VERSION=$(echo "$PR_TITLE" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?' || echo "0.0.0")
echo "version=$EXISTING_VERSION" >> "$GITHUB_OUTPUT"
echo "Existing PR version: $EXISTING_VERSION"

Expand All @@ -94,7 +146,7 @@ jobs:
OLD_VERSION="${{ steps.existing-version.outputs.version }}"

version_to_int() {
echo "$1" | awk -F. '{ printf("%d%03d%03d", $1, $2, $3) }'
echo "$1" | awk -F'[-.]' '{ printf("%d%03d%03d%03d", $1, $2, $3, (NF>=4 ? $4 : 0)) }'
}

NEW_INT=$(version_to_int "$NEW_VERSION")
Expand Down Expand Up @@ -142,7 +194,7 @@ jobs:
- **Auto-generated release PR**

---
This PR was automatically created by version-check workflow.
This PR was automatically created by version-tag-sync workflow.
EOF
)

Expand Down Expand Up @@ -173,7 +225,7 @@ jobs:
- **Auto-generated release PR**

---
This PR was automatically created by version-check workflow.
This PR was automatically created by version-tag-sync workflow.
EOF
)

Expand Down
22 changes: 0 additions & 22 deletions .pre-commit-config.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion bottlenote-admin-api/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.7-3
1.0.8
6 changes: 6 additions & 0 deletions bottlenote-admin-api/src/docs/asciidoc/admin-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ include::api/admin-reference/reference.adoc[]
== Curation API

include::api/admin-curations/curations.adoc[]

'''

== Banner API

include::api/admin-banners/banners.adoc[]
Loading
Loading