Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions CHANGELOG.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ English: [CHANGELOG.md](CHANGELOG.md)

## [Unreleased]

## [0.2.1] — 2026-06-02

### 변경됨 (Changed)
- **OpenAPI / Swagger UI를 이제 스타터에 포함** — `0.2.0`은 springdoc을 `compileOnly`로
배포해, 소비자가 직접 springdoc을 추가해야만 Swagger UI가 떴습니다. 이제 스타터가
`springdoc-openapi-starter-webmvc-ui`를 `api`로 의존하므로 스타터만으로
`/swagger-ui`와 `/v3/api-docs`가 올라옵니다 — "스타터만 추가하면 다 됨" 약속에 부합.
`devslab.kit.openapi.enabled=false`로 끄거나 `org.springdoc` 의존성을 `exclude`해
jar를 제거할 수 있습니다(설정 레퍼런스에 문서화).

## [0.2.0] — 2026-06-02

### 추가됨 (Added)
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ The library major aligns with the Spring Boot major: `4.x.y` targets Spring Boot

## [Unreleased]

## [0.2.1] — 2026-06-02

### Changed
- **OpenAPI / Swagger UI is now bundled in the starter** — `0.2.0` shipped springdoc
as `compileOnly`, so Swagger UI only appeared if the consumer added springdoc
themselves. The starter now depends on `springdoc-openapi-starter-webmvc-ui`
(`api`), so `/swagger-ui` and `/v3/api-docs` come up from the starter alone —
matching the kit's "add the starter, nothing else" promise. Turn it off with
`devslab.kit.openapi.enabled=false`, or `exclude` the `org.springdoc` dependency to
drop the jar (both documented in the configuration reference).

## [0.2.0] — 2026-06-02

### Added
Expand Down
8 changes: 4 additions & 4 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
| **캐시** | 플러그형 캐시 — `in-memory` · `redis` · `none`. Redis 백엔드가 JSON 직렬화를 직접 책임지므로 `Serializable` 구현이나 직렬화기 배선이 필요 없습니다(ADR 0002). 사용자별 메뉴 캐시도 이 공유 매니저를 사용합니다. |
| **최초 관리자 부트스트랩** | 첫 부팅 시 테넌트, `PLATFORM_ADMIN` 역할, `admin.*` 권한, 관리자 사용자를 멱등하게 생성 — opt-in, 프로퍼티 기반(ADR 0001). |
| **관리자 REST API** | 위 모든 엔티티 + 진단 + 실시간 설정 뷰를 위한 `/admin/api/v1/**`. |
| **OpenAPI / Swagger UI** | springdoc만 추가하면 `/swagger-ui`가 관리자 API 그룹과 함께 자동으로 뜸설정 불필요. `openapi.enabled=false`로 . |
| **OpenAPI / Swagger UI** | 스타터에 포함 — `/swagger-ui`가 관리자 API 그룹과 함께 자동으로 뜸, 설정 불필요. `openapi.enabled=false`로 끄거나, springdoc 의존성을 `exclude`해 jar 자체를 제거. |
| **Override 친화적** | 모든 기본 빈이 `@ConditionalOnMissingBean` — 직접 선언하면 어느 조각이든 교체 가능. |
| **GraalVM Native** | 리플렉션 중심 설계를 피하고, 샘플 앱이 `nativeCompile`을 검증. |

Expand All @@ -62,7 +62,7 @@
**Gradle (Kotlin DSL)**

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1")
```

**Maven**
Expand All @@ -71,7 +71,7 @@ implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
</dependency>
```

Expand Down Expand Up @@ -146,7 +146,7 @@ Docker Compose(Postgres + Redis)와 Testcontainers 기반 테스트까지 갖춘
| `bootstrap.admin-login-id` | `admin` | 최초 관리자 로그인 id. |
| `bootstrap.admin-password` | — | 비우면 강력한 랜덤 비밀번호를 한 번 로깅. |
| `bootstrap.must-change-password` | `true` | 첫 로그인 시 변경 강제. |
| `openapi.enabled` | `true` | springdoc이 classpath에 있으면 Swagger UI / OpenAPI 노출. `false`로 비활성화(예: 프로덕션). |
| `openapi.enabled` | `true` | Swagger UI / OpenAPI 노출(springdoc은 스타터에 포함됨). `false`로 비활성화(예: 프로덕션). |
| `openapi.title` | `devslab-kit Admin API` | OpenAPI 문서 / Swagger UI에 표시될 제목. |

런타임의 실제 적용값은 `GET /admin/api/v1/settings`에서도 볼 수 있습니다(시크릿 마스킹).
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ specific product's domain.
| **Cache** | A pluggable cache — `in-memory`, `redis`, or `none`. The Redis backend owns JSON serialization, so you never implement `Serializable` or wire a serializer (ADR 0002). The per-user menu cache rides this shared manager. |
| **First-admin bootstrap** | Idempotently provisions a tenant, a `PLATFORM_ADMIN` role, the `admin.*` permissions, and an admin user on first boot — opt-in and property-driven (ADR 0001). |
| **Admin REST API** | `/admin/api/v1/**` for every entity above, plus diagnostics and a live settings view. |
| **OpenAPI / Swagger UI** | Add springdoc and `/swagger-ui` comes up with the admin API groupedno wiring. Toggle off with `openapi.enabled=false`. |
| **OpenAPI / Swagger UI** | Bundled in the starter — `/swagger-ui` comes up with the admin API grouped, no wiring. Toggle off with `openapi.enabled=false`, or `exclude` the springdoc dependency to drop the jar. |
| **Override-friendly** | Every default bean is `@ConditionalOnMissingBean` — replace any piece by declaring your own. |
| **GraalVM Native** | Reflection-heavy patterns are avoided; the sample app verifies `nativeCompile`. |

Expand All @@ -64,7 +64,7 @@ specific product's domain.
**Gradle (Kotlin DSL)**

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1")
```

**Maven**
Expand All @@ -73,7 +73,7 @@ implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
</dependency>
```

Expand Down Expand Up @@ -149,7 +149,7 @@ All keys are under the `devslab.kit.*` prefix. Defaults shown.
| `bootstrap.admin-login-id` | `admin` | First admin login id. |
| `bootstrap.admin-password` | — | Blank → a strong random one is logged once. |
| `bootstrap.must-change-password` | `true` | Force a rotation on first login. |
| `openapi.enabled` | `true` | Expose Swagger UI / OpenAPI when springdoc is on the classpath. Set `false` to disable (e.g. in production). |
| `openapi.enabled` | `true` | Expose Swagger UI / OpenAPI (springdoc is bundled in the starter). Set `false` to disable (e.g. in production). |
| `openapi.title` | `devslab-kit Admin API` | Title shown in the OpenAPI doc / Swagger UI. |

The live, effective values are also viewable at runtime via
Expand Down
8 changes: 3 additions & 5 deletions devslab-kit-sample-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.flywaydb:flyway-database-postgresql")

// Swagger UI / OpenAPI. The kit's OpenApiAutoConfiguration activates only when
// springdoc is on the classpath (a consumer opts in by adding this); it then
// exposes /swagger-ui and groups the admin API. Version pinned in gradle.properties
// (the Spring Boot BOM doesn't manage springdoc).
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:${property("SPRINGDOC_VERSION")}")
// No springdoc declared here on purpose: the starter bundles it, so Swagger UI
// comes up from the starter alone. The OpenApi*Tests prove /swagger-ui and
// /v3/api-docs work without the sample app adding springdoc itself.

compileOnly("org.projectlombok:lombok")
developmentOnly("org.springframework.boot:spring-boot-devtools")
Expand Down
8 changes: 8 additions & 0 deletions devslab-kit-spring-boot-starter/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ description = "devslab-kit :: Spring Boot starter (dependency bundle)"
dependencies {
api(project(":devslab-kit-autoconfigure"))
api(project(":devslab-kit-tenant-core"))

// Bundle springdoc so a consumer gets Swagger UI just by adding the starter —
// OpenApiAutoConfiguration (in -autoconfigure, @ConditionalOnClass(GroupedOpenApi))
// then activates and serves /swagger-ui + /v3/api-docs with the admin API grouped.
// Turn it off with devslab.kit.openapi.enabled=false (the bean stays dormant), or
// exclude this dependency if you don't want the jar at all. Version pinned in
// gradle.properties (the Spring Boot BOM doesn't manage springdoc).
api("org.springdoc:springdoc-openapi-starter-webmvc-ui:${property("SPRINGDOC_VERSION")}")
}

mavenPublishing {
Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started/installation.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
=== "Gradle (Kotlin DSL)"

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1")
```

=== "Gradle (Groovy)"

```groovy
implementation 'kr.devslab:devslab-kit-spring-boot-starter:0.2.0'
implementation 'kr.devslab:devslab-kit-spring-boot-starter:0.2.1'
```

=== "Maven"
Expand All @@ -32,7 +32,7 @@
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
</dependency>
```

Expand All @@ -43,10 +43,10 @@
물러납니다(`@ConditionalOnMissingBean`).

```kotlin
implementation("kr.devslab:devslab-kit-access-core:0.2.0") // RBAC + 그룹 + ABAC
implementation("kr.devslab:devslab-kit-cache-core:0.2.0") // 플러그형 캐시
implementation("kr.devslab:devslab-kit-access-core:0.2.1") // RBAC + 그룹 + ABAC
implementation("kr.devslab:devslab-kit-cache-core:0.2.1") // 플러그형 캐시
// …또는 계약만:
implementation("kr.devslab:devslab-kit-access-api:0.2.0")
implementation("kr.devslab:devslab-kit-access-api:0.2.1")
```

동작하는 앱을 부팅하려면 [빠른 시작](quick-start.md)을 참고하세요.
Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ whole platform; depend on individual modules only if you want à la carte.
=== "Gradle (Kotlin DSL)"

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.0")
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1")
```

=== "Gradle (Groovy)"

```groovy
implementation 'kr.devslab:devslab-kit-spring-boot-starter:0.2.0'
implementation 'kr.devslab:devslab-kit-spring-boot-starter:0.2.1'
```

=== "Maven"
Expand All @@ -32,7 +32,7 @@ whole platform; depend on individual modules only if you want à la carte.
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.0</version>
<version>0.2.1</version>
</dependency>
```

Expand All @@ -44,10 +44,10 @@ your own — the auto-configuration backs off (`@ConditionalOnMissingBean`) when
do.

```kotlin
implementation("kr.devslab:devslab-kit-access-core:0.2.0") // RBAC + groups + ABAC
implementation("kr.devslab:devslab-kit-cache-core:0.2.0") // pluggable cache
implementation("kr.devslab:devslab-kit-access-core:0.2.1") // RBAC + groups + ABAC
implementation("kr.devslab:devslab-kit-cache-core:0.2.1") // pluggable cache
// …or just the contract:
implementation("kr.devslab:devslab-kit-access-api:0.2.0")
implementation("kr.devslab:devslab-kit-access-api:0.2.1")
```

See [Quick Start](quick-start.md) to boot a working app.
Expand Down
50 changes: 37 additions & 13 deletions docs/reference/configuration.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,44 @@

## OpenAPI / Swagger UI — `devslab.kit.openapi.*` { #openapi }

킷은 **springdoc이 classpath에 있을 때** OpenAPI와 Swagger UI를 자동 구성합니다 —
springdoc을 `compileOnly`로 가지고 있으므로, 의존성을 추가해 opt-in 합니다:

```kotlin
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3")
```

추가하면 추가 설정 없이 `/swagger-ui.html`과 `/v3/api-docs`가 올라오고, 킷의
`/admin/api/v1/**` 엔드포인트가 하나의 그룹(`/v3/api-docs/admin`)으로 묶입니다.
springdoc `3.0.x`가 Spring Boot 4 라인입니다(`2.8.x`는 Spring Boot 3 대상).
스타터가 **springdoc을 포함**하므로, 추가 의존성·설정 없이 스타터만으로
`/swagger-ui.html`과 `/v3/api-docs`가 올라오고, 킷의 `/admin/api/v1/**` 엔드포인트가
하나의 그룹(`/v3/api-docs/admin`)으로 묶입니다. springdoc `3.0.x`가 Spring Boot 4
라인입니다(`2.8.x`는 Spring Boot 3 대상).

끄는 방법 두 가지:

1. **jar는 두고 표면만 끔** — `devslab.kit.openapi.enabled=false`. 자동 구성이
비활성 상태로 남아 아무것도 노출되지 않습니다. 프로덕션의 일반적 선택.
2. **jar 자체를 제거** — 스타터 의존성에서 springdoc을 exclude:

=== "Gradle (Kotlin DSL)"

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1") {
exclude(group = "org.springdoc")
}
```

=== "Maven"

```xml
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.1</version>
<exclusions>
<exclusion>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</exclusion>
</exclusions>
</dependency>
```

| 프로퍼티 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| `enabled` | boolean | `true` | 마스터 스위치. `false`로 두면 의존성을 제거하지 않고도 킷의 OpenAPI 구성을 끕니다. |
| `enabled` | boolean | `true` | 마스터 스위치. `false`로 두면 (포함된) 의존성을 그대로 둔 채 킷의 OpenAPI 구성만 끕니다. |
| `admin-group` | string | `admin` | 관리자 API의 Swagger UI 그룹 이름. |
| `title` | string | `devslab-kit Admin API` | OpenAPI 문서 / Swagger UI에 표시될 제목. |
| `version` | string | `v1` | OpenAPI 문서의 버전 문자열. |
Expand All @@ -130,5 +154,5 @@ springdoc `3.0.x`가 Spring Boot 4 라인입니다(`2.8.x`는 Spring Boot 3 대

!!! tip "프로덕션"
API 문서는 보통 프로덕션에 노출하지 않습니다.
`devslab.kit.openapi.enabled=false`로 끄거나(또는 프로덕션 빌드에서 springdoc
의존성을 빼서) 해당 표면을 비활성화하세요.
`devslab.kit.openapi.enabled=false`로 표면을 끄거나(위 1번), springdoc을
`exclude`해 jar를 제거하세요(2번).
53 changes: 38 additions & 15 deletions docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,45 @@ See the [First-admin Bootstrap guide](../guides/bootstrap.md) and

## OpenAPI / Swagger UI — `devslab.kit.openapi.*` { #openapi }

The kit auto-configures OpenAPI and Swagger UI **when springdoc is on the
classpath** — it ships springdoc as `compileOnly`, so you opt in by adding the
dependency:

```kotlin
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3")
```

With that present, `/swagger-ui.html` and `/v3/api-docs` come up with no further
wiring, and the kit's `/admin/api/v1/**` endpoints are collected into one group
(`/v3/api-docs/admin`). springdoc `3.0.x` is the Spring Boot 4 line (`2.8.x`
targets Spring Boot 3).
The starter **bundles springdoc**, so `/swagger-ui.html` and `/v3/api-docs` come up
from the starter alone — no extra dependency, no wiring — and the kit's
`/admin/api/v1/**` endpoints are collected into one group (`/v3/api-docs/admin`).
springdoc `3.0.x` is the Spring Boot 4 line (`2.8.x` targets Spring Boot 3).

Two ways to turn it off:

1. **Keep the jar, disable the surface** — `devslab.kit.openapi.enabled=false`. The
auto-configuration stays dormant; nothing is served. This is the usual production
choice.
2. **Drop the jar entirely** — exclude springdoc from the starter dependency:

=== "Gradle (Kotlin DSL)"

```kotlin
implementation("kr.devslab:devslab-kit-spring-boot-starter:0.2.1") {
exclude(group = "org.springdoc")
}
```

=== "Maven"

```xml
<dependency>
<groupId>kr.devslab</groupId>
<artifactId>devslab-kit-spring-boot-starter</artifactId>
<version>0.2.1</version>
<exclusions>
<exclusion>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</exclusion>
</exclusions>
</dependency>
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `enabled` | boolean | `true` | Master switch. Set `false` to disable the kit's OpenAPI wiring without removing the dependency. |
| `enabled` | boolean | `true` | Master switch. Set `false` to disable the kit's OpenAPI wiring while leaving the (bundled) dependency in place. |
| `admin-group` | string | `admin` | Swagger UI group name for the admin API. |
| `title` | string | `devslab-kit Admin API` | Title shown in the OpenAPI document / Swagger UI. |
| `version` | string | `v1` | Version string in the OpenAPI document. |
Expand All @@ -139,5 +162,5 @@ schemes or servers) and the kit backs off.

!!! tip "Production"
API docs are usually not exposed in production. Set
`devslab.kit.openapi.enabled=false` (or omit the springdoc dependency from the
production build) to turn the surface off.
`devslab.kit.openapi.enabled=false` to turn the surface off (option 1 above), or
`exclude` springdoc to drop the jar (option 2).
Loading