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
121 changes: 74 additions & 47 deletions docs/getting-started/tutorial.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,24 @@ devslab:

---

## 4단계 — 실행
## 4단계 — 실행

```bash
./gradlew bootRun
```
평소 개발하던 방식으로 실행하세요:

=== "IntelliJ IDEA (일반적)"

`myapp` 폴더를 Gradle 프로젝트로 열고 import가 끝나면 `MyappApplication` 의 **Run**(▶) 실행.

!!! tip "kit 추가/버전 변경 직후 Run이 실패하면"
`ClassNotFoundException: kr.devslab.kit.*` 는 IntelliJ 프로젝트 모델이 옛것이라는 뜻 —
**Gradle 리로드**(Gradle 툴 윈도우 → ↻ *Reload*)로 새 jar를 잡게 한 뒤 다시 Run.
(Gradle `bootRun` 은 매번 새로 해소해서 항상 됨.)

=== "터미널"

```bash
./gradlew bootRun
```

첫 실행 시 kit은:

Expand All @@ -171,66 +184,80 @@ devslab:
3. 테넌트, 모든 `admin.*` 권한을 가진 `PLATFORM_ADMIN` 역할, `admin` 사용자를 **부트스트랩**,
4. `/admin/api/v1/**` 에 **관리자 REST API**, `/swagger-ui.html` 에 **Swagger UI** 제공.

이걸 띄워둔 채로 두 번째 터미널을 열어 다음 단계를 진행하세요.
이제 앱이 `http://localhost:8080` 에서 동작합니다.

---

## 5단계 — 로그인
## 5단계 — admin 콘솔 띄우기

모든 관리자 호출엔 토큰이 필요합니다. 부트스트랩 관리자로 로그인:
실무에서는 플랫폼을 curl이 아니라 **웹 콘솔**로 관리합니다. (앱과 별도 폴더에) 클론해서 실행:

```bash
curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}'
git clone https://github.com/devslab-kr/devslab-kit-admin-ui.git
cd devslab-kit-admin-ui
npm install
npm run dev
```

응답에 JWT가 들어있습니다. 다음 명령에서 재사용하도록 셸 변수에 담으세요:
**http://localhost:5173** 을 엽니다 — dev 서버가 `/admin/api` 를 `:8080` 의 앱으로 프록시합니다.
부트스트랩 관리자로 로그인: 테넌트 `default`, 로그인 `admin`, 비밀번호 `admin`. 이제 다음
단계들은 몇 번의 클릭으로 끝납니다 — [Admin 콘솔 가이드](../guides/admin-console.md)가 모든
화면을 안내합니다.

```bash
TOKEN=$(curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}' | sed -E 's/.*"token":"([^"]+)".*/\1/')
echo "$TOKEN"
```

!!! tip "UI가 편하시면"
[admin 콘솔](https://github.com/devslab-kr/devslab-kit-admin-ui)을 `http://localhost:8080`
에 연결하면 6단계를 curl 대신 클릭으로 할 수 있습니다.
!!! note "API / 스크립트가 편하면"
전부 REST로도 됩니다. 로그인해 JWT를 받아 `$TOKEN` 으로 재사용:
```bash
TOKEN=$(curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}' | sed -E 's/.*"token":"([^"]+)".*/\1/')
echo "$TOKEN"
```

---

## 6단계 — 권한·역할·사용자 만들기

**권한**은 문자열 코드(`resource.action`), **역할**은 권한 묶음, **사용자**는 역할을 가집니다.
새 사용자에게 "책 읽기" 권한을 줘봅시다.
새 사용자에게 "책 읽기" 권한을 줘봅시다 — 편한 방식으로:

```bash
# 1) 권한 생성 -> 응답의 "id" 기록
curl -s -X POST localhost:8080/admin/api/v1/permissions \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"code":"book.read","description":"책 읽기"}'

# 2) 역할 생성 -> "id" 기록
curl -s -X POST localhost:8080/admin/api/v1/roles \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","code":"LIBRARIAN","name":"사서"}'

# 3) 역할에 권한 부여 (1·2의 id 사용)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/permissions/<PERMISSION_ID>" \
-H "Authorization: Bearer $TOKEN"

# 4) 사용자 생성
curl -s -X POST localhost:8080/admin/api/v1/users \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"alice","rawPassword":"alice-password","email":"alice@example.com"}'

# 5) 사용자에게 역할 할당 (2·4의 id 사용)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/users/<USER_ID>?tenantId=default" \
-H "Authorization: Bearer $TOKEN"
```
=== "admin 콘솔에서 (클릭)"

1. **Permissions → Create** — resource `book`, action `read`; 코드가 `book.read` 로 미리보기. **Create**.
2. **Roles → Create** — code `LIBRARIAN`, 이름 `사서`. 그 행의 **권한 관리**(열쇠 아이콘) → `book.read` 를 *할당* 으로 옮기고 **저장**.
3. **Users → Create** — 로그인 `alice`, 비밀번호. 그 행의 **역할 관리**(신분증 아이콘) → `LIBRARIAN` 추가 → **저장**.

각 화면·버튼은 [Admin 콘솔 가이드](../guides/admin-console.md)에 자세히 있습니다.

=== "API로 (curl)"

5단계의 `$TOKEN` 사용.

```bash
# 1) 권한 생성 -> 응답의 "id" 기록
curl -s -X POST localhost:8080/admin/api/v1/permissions \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"code":"book.read","description":"책 읽기"}'

# 2) 역할 생성 -> "id" 기록
curl -s -X POST localhost:8080/admin/api/v1/roles \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","code":"LIBRARIAN","name":"사서"}'

# 3) 역할에 권한 부여 (1·2의 id 사용)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/permissions/<PERMISSION_ID>" \
-H "Authorization: Bearer $TOKEN"

# 4) 사용자 생성
curl -s -X POST localhost:8080/admin/api/v1/users \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"alice","rawPassword":"alice-password","email":"alice@example.com"}'

# 5) 사용자에게 역할 할당 (2·4의 id 사용)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/users/<USER_ID>?tenantId=default" \
-H "Authorization: Bearer $TOKEN"
```

이제 `alice`로 로그인(5단계, alice 자격증명)하면 `book.read` 권한을 가집니다.
이제 `alice`로 로그인(콘솔 또는 API)하면 `book.read` 권한을 가집니다.

---

Expand Down
127 changes: 79 additions & 48 deletions docs/getting-started/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,26 @@ devslab:

---

## Step 4 — Run it
## Step 4 — Run the app

```bash
./gradlew bootRun
```
Run it the way you normally develop:

=== "IntelliJ IDEA (typical)"

Open the `myapp` folder as a Gradle project, let the import finish, then **Run**
`MyappApplication` (the green ▶ by `main`).

!!! tip "If Run fails right after adding/bumping the kit"
A `ClassNotFoundException: kr.devslab.kit.*` means IntelliJ's project model is
stale — **reload Gradle** (Gradle tool window → the ↻ *Reload* button) so it
picks up the new jars, then Run again. (Gradle `bootRun` always works because it
resolves fresh.)

=== "Terminal"

```bash
./gradlew bootRun
```

On first start the kit:

Expand All @@ -177,66 +192,82 @@ On first start the kit:
4. serves the **admin REST API** at `/admin/api/v1/**` and **Swagger UI** at
`/swagger-ui.html`.

Leave it running and open a second terminal for the next steps.
The app is now listening on `http://localhost:8080`.

---

## Step 5 — Log in
## Step 5 — Open the admin console

Every admin call needs a token. Log in as the bootstrap admin:
Day to day you manage the platform from the **web console**, not curl. Clone and run it
(in its own folder, alongside your app):

```bash
curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}'
git clone https://github.com/devslab-kr/devslab-kit-admin-ui.git
cd devslab-kit-admin-ui
npm install
npm run dev
```

The response contains a JWT — copy it into a shell variable so the next commands can reuse it:
Open **http://localhost:5173** — the dev server proxies `/admin/api` to your app on
`:8080`. Sign in with the bootstrap admin: tenant `default`, login `admin`, password
`admin`. From here everything in the next steps is a few clicks — the
[Admin Console guide](../guides/admin-console.md) walks through every screen.

```bash
TOKEN=$(curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}' | sed -E 's/.*"token":"([^"]+)".*/\1/')
echo "$TOKEN"
```

!!! tip "Prefer a UI?"
Point the [admin console](https://github.com/devslab-kr/devslab-kit-admin-ui) at
`http://localhost:8080` and do all of Step 6 by clicking instead of curl.
!!! note "Prefer the API / scripting it?"
Everything also works over REST. Log in to get a JWT and reuse it as `$TOKEN`:
```bash
TOKEN=$(curl -s localhost:8080/admin/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}' | sed -E 's/.*"token":"([^"]+)".*/\1/')
echo "$TOKEN"
```

---

## Step 6 — Create a permission, a role, and a user

A **permission** is a string code (`resource.action`). A **role** is a bundle of
permissions. A **user** holds roles. Let's give a new user the ability to read books.
A **permission** is a string code (`resource.action`); a **role** bundles permissions; a
**user** holds roles. Let's give a new user the ability to read books — do it whichever way
suits you:

```bash
# 1) create a permission -> note its "id" in the response
curl -s -X POST localhost:8080/admin/api/v1/permissions \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"code":"book.read","description":"Read books"}'

# 2) create a role -> note its "id"
curl -s -X POST localhost:8080/admin/api/v1/roles \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","code":"LIBRARIAN","name":"Librarian"}'

# 3) grant the permission to the role (use the ids from steps 1 & 2)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/permissions/<PERMISSION_ID>" \
-H "Authorization: Bearer $TOKEN"

# 4) create a user
curl -s -X POST localhost:8080/admin/api/v1/users \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"alice","rawPassword":"alice-password","email":"alice@example.com"}'

# 5) assign the role to the user (ids from steps 2 & 4)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/users/<USER_ID>?tenantId=default" \
-H "Authorization: Bearer $TOKEN"
```
=== "In the admin console (clicks)"

1. **Permissions → Create** — resource `book`, action `read`; the code previews as `book.read`. **Create**.
2. **Roles → Create** — code `LIBRARIAN`, name `Librarian`. Then on its row click **Manage permissions** (key icon) and move `book.read` to *Assigned* → **Save**.
3. **Users → Create** — login `alice`, a password. Then on her row click **Manage roles** (id-card icon) and add `LIBRARIAN` → **Save**.

Every screen/button is detailed in the [Admin Console guide](../guides/admin-console.md).

=== "Via the API (curl)"

Uses the `$TOKEN` from Step 5.

```bash
# 1) create a permission -> note its "id" in the response
curl -s -X POST localhost:8080/admin/api/v1/permissions \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"code":"book.read","description":"Read books"}'

# 2) create a role -> note its "id"
curl -s -X POST localhost:8080/admin/api/v1/roles \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","code":"LIBRARIAN","name":"Librarian"}'

# 3) grant the permission to the role (use the ids from steps 1 & 2)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/permissions/<PERMISSION_ID>" \
-H "Authorization: Bearer $TOKEN"

# 4) create a user
curl -s -X POST localhost:8080/admin/api/v1/users \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"tenantId":"default","loginId":"alice","rawPassword":"alice-password","email":"alice@example.com"}'

# 5) assign the role to the user (ids from steps 2 & 4)
curl -s -X POST "localhost:8080/admin/api/v1/roles/<ROLE_ID>/users/<USER_ID>?tenantId=default" \
-H "Authorization: Bearer $TOKEN"
```

Now `alice` can log in (Step 5 with her credentials) and holds `book.read`.
Now `alice` can sign in (console or API) and holds `book.read`.

---

Expand Down
Loading