Skip to content

docs: Quick Start Guide と Keycloak 自動セットアップスクリプト追加 - #37

Merged
susumutomita merged 2 commits into
mainfrom
docs/quickstart-guide
Nov 14, 2025
Merged

susumutomita merged 2 commits into
mainfrom
docs/quickstart-guide

Conversation

@susumutomita

@susumutomita susumutomita commented Nov 14, 2025 •

Copy link
Copy Markdown
Owner

概要

TenkaCloud Control Plane UI を 5〜10 分で起動できる Quick Start Guide と Keycloak の自動セットアップスクリプトを追加しました。

変更内容

1. Quick Start Guide (docs/QUICKSTART.md)

含まれる内容:

  • ✅ Docker Desktop の起動手順
  • ✅ Keycloak の起動と初期設定(手動)
  • ✅ 環境変数ファイルの作成手順
  • ✅ Control Plane UI の起動手順
  • ✅ ログイン/ログアウトフローの確認方法
  • ✅ トラブルシューティング(よくあるエラーと解決策)
  • ✅ 環境のクリーンアップ手順

対象ユーザー: 初めて TenkaCloud を動かす開発者

所要時間: 約 5〜10 分

2. Keycloak 自動セットアップスクリプト

ファイル: infrastructure/docker/keycloak/scripts/setup-keycloak.sh

機能:

  • ✅ Keycloak の起動を自動で待機
  • ✅ TenkaCloud Realm を自動作成
  • ✅ control-plane-ui Client を自動作成
  • ✅ Client Secret を自動生成・表示
  • ✅ .env.local に設定すべき環境変数を出力

使い方:

cd infrastructure/docker/keycloak
docker compose up -d
./scripts/setup-keycloak.sh

出力例:

✨ Keycloak セットアップが完了しました!

📋 以下の情報を .env.local に設定してください:

AUTH_KEYCLOAK_ID=control-plane-ui
AUTH_KEYCLOAK_SECRET=xxxxxxxxxxxxx
AUTH_KEYCLOAK_ISSUER=http://localhost:8080/realms/tenkacloud

3. Keycloak README の更新

変更点:

  • 自動セットアップ手順を追記(推奨方法)
  • Quick Start Guide へのリンク追加
  • 手動セットアップは Quick Start Guide を参照

テスト

  • ✅ スクリプトの実行権限を確認(chmod +x)
  • ✅ Markdown のフォーマット確認
  • ✅ リンクの整合性確認

利用シーン

新規開発者のオンボーディング

# 1. リポジトリをクローン
git clone https://github.com/susumutomita/TenkaCloud.git
cd TenkaCloud

# 2. Quick Start Guide を開く
open docs/QUICKSTART.md

# 3. 手順に従って起動(5〜10分)

CI/CD での自動テスト

# Keycloak を起動して自動設定
docker compose up -d
./scripts/setup-keycloak.sh
# E2E テストを実行

スクリーンショット

(オプション)後で追加予定:

  • ログイン画面のスクリーンショット
  • ダッシュボードのスクリーンショット
  • Keycloak 管理コンソールのスクリーンショット

参照

次のステップ

  • スクリプトのテストを追加(bats など)
  • CI/CD パイプラインに統合
  • ビデオチュートリアルの作成(オプション)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added a Quick Start Guide covering local Control Plane UI setup, prerequisites, configuration, troubleshooting, and next steps.
  • New Features

    • Added an automated Keycloak setup workflow with a fallback manual method and instructions to integrate results into local env.
  • Style

    • Normalized string quoting and minor formatting across the frontend codebase for consistency.

- Quick Start Guide (docs/QUICKSTART.md) を追加
  - Docker Desktop の起動手順
  - Keycloak の起動と設定手順
  - Control Plane UI の起動手順
  - トラブルシューティング
- Keycloak 自動セットアップスクリプト (scripts/setup-keycloak.sh) を追加
  - Realm と Client の自動作成
  - Client Secret の自動生成と表示
  - 環境変数設定の自動出力
- Keycloak README を更新
  - 自動セットアップ手順を追記
  - Quick Start Guide へのリンク追加

所要時間: 5〜10分で起動可能

Refs: Plan.md "NextAuth.js + Keycloak 認証統合 - 2025-11-13"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 14, 2025 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Walkthrough

Adds local Quick Start documentation and an automated Keycloak setup script; updates Keycloak README to prefer the automated flow and adds a manual fallback; applies stylistic string-quote normalizations across the control-plane frontend and introduces an explicit API early-return in middleware.

Changes

Cohort / File(s) Summary
Documentation
docs/QUICKSTART.md, infrastructure/docker/keycloak/README.md
New Quick Start guide for running the Control Plane UI locally; Keycloak README reorganized to recommend the automated setup, adds manual setup fallback and updated teardown instructions.
Keycloak automation script
infrastructure/docker/keycloak/scripts/setup-keycloak.sh
New Bash script that waits for Keycloak, obtains admin token, creates realm and OIDC client (with redirect URIs and web origins) if missing, retrieves client secret, and prints .env.local integration instructions; includes error handling and retries.
Frontend — control-plane (styling/strings)
frontend/control-plane/..., frontend/control-plane/src/..., frontend/control-plane/types/next-auth.d.ts, frontend/control-plane/app/**/*.tsx, frontend/control-plane/next.config.ts, frontend/control-plane/app/api/auth/[...nextauth]/route.ts, frontend/control-plane/app/globals.css, frontend/control-plane/src/app/globals.css
Widespread non-functional string literal/quoting normalization from double quotes to single quotes across imports, literals, and type declarations; minor JSX/formatting tweaks.
Frontend — middleware
frontend/control-plane/middleware.ts
Same quoting normalization plus an explicit early-return branch for API authentication routes (NextResponse.next()), preserving existing redirect targets and route matching.

Sequence Diagram(s)

sequenceDiagram
    actor Developer
    participant Script as setup-keycloak.sh
    participant Keycloak as Keycloak API

    Developer->>Script: run script
    Script->>Keycloak: poll /health (retry loop)
    alt healthy
        Keycloak-->>Script: 200 OK
    end
    Script->>Keycloak: POST token (master realm)
    Keycloak-->>Script: admin access token

    Script->>Keycloak: GET /realms/{name}
    alt realm missing
        Script->>Keycloak: POST create realm
        Keycloak-->>Script: realm created
    end

    Script->>Keycloak: GET /clients?clientId={id}
    alt client missing
        Script->>Keycloak: POST create client (OIDC, redirects, webOrigins)
        Keycloak-->>Script: client created (id)
    end

    Script->>Keycloak: GET /clients/{id}/client-secret
    Keycloak-->>Script: client secret
    Script->>Developer: print credentials + .env.local instructions
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay extra attention to:
    • infrastructure/docker/keycloak/scripts/setup-keycloak.sh: polling/retry logic, token handling, API payload shapes and error exits.
    • infrastructure/docker/keycloak/README.md and docs/QUICKSTART.md: accuracy of commands and values to follow the script outputs.
    • frontend/control-plane/middleware.ts: ensure the new early-return does not change auth behavior for API routes.

Possibly related PRs

Poem

🐰 Hop, hop — keys and realms in cheer,

scripts hum, the UI draws near.
One small script, secrets to show,
devs sprint in springtime flow.
🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly summarizes the main changes: adding a Quick Start Guide and an automated Keycloak setup script, which aligns with the actual changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88092e4 and 2b479ea.

📒 Files selected for processing (15)
  • docs/QUICKSTART.md (1 hunks)
  • frontend/control-plane/app/api/auth/[...nextauth]/route.ts (1 hunks)
  • frontend/control-plane/app/dashboard/page.tsx (2 hunks)
  • frontend/control-plane/app/globals.css (1 hunks)
  • frontend/control-plane/app/layout.tsx (1 hunks)
  • frontend/control-plane/app/login/page.tsx (2 hunks)
  • frontend/control-plane/app/page.tsx (1 hunks)
  • frontend/control-plane/auth.ts (2 hunks)
  • frontend/control-plane/middleware.ts (2 hunks)
  • frontend/control-plane/next.config.ts (1 hunks)
  • frontend/control-plane/src/app/globals.css (1 hunks)
  • frontend/control-plane/src/app/layout.tsx (1 hunks)
  • frontend/control-plane/src/app/page.tsx (2 hunks)
  • frontend/control-plane/types/next-auth.d.ts (2 hunks)
  • infrastructure/docker/keycloak/README.md (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@susumutomita
susumutomita enabled auto-merge (squash) November 14, 2025 00:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
docs/QUICKSTART.md (1)

45-90: Consider referencing the automated setup script in this guide.

The QUICKSTART guide details manual Keycloak setup (realm and client creation), but infrastructure/docker/keycloak/scripts/setup-keycloak.sh is available to automate these steps. To reduce user confusion and encourage the recommended workflow, consider:

  1. Adding a note at the start of section 3 suggesting users run the automated setup script first (reference: ./scripts/setup-keycloak.sh from infrastructure/docker/keycloak).
  2. Positioning manual steps as a fallback or troubleshooting reference.

This aligns with the PR objective to promote automated setup as the primary method.

Also applies to: 180-184

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b158653 and 88092e4.

📒 Files selected for processing (3)
  • docs/QUICKSTART.md (1 hunks)
  • infrastructure/docker/keycloak/README.md (1 hunks)
  • infrastructure/docker/keycloak/scripts/setup-keycloak.sh (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: claude-review
🔇 Additional comments (11)
infrastructure/docker/keycloak/scripts/setup-keycloak.sh (3)

1-14: Script initialization and error handling look solid.

The use of set -e, appropriate defaults, and hardcoded development-friendly values are well-suited for this automated setup context.


19-37: Retry logic and health check are appropriate for local development.

The 30-attempt retry with 2-second intervals provides ~60 seconds of wait time, which is reasonable for Keycloak startup. Using the /health/ready endpoint is correct.


137-156: Output and user guidance are clear and helpful.

The formatted output section provides all necessary credentials and next-step instructions. Users have clear guidance on populating .env.local and generating AUTH_SECRET.

docs/QUICKSTART.md (5)

94-94: Verify relative path references are correct.

The path references need verification against actual repository structure:

  • Line 94: cd ../../frontend/control-plane (from docs/)
  • Line 151: cd ../../../frontend/control-plane (from script output, assuming execution location)

Confirm these paths align with the actual directory structure. If the repository layout differs, these paths may fail for users following the guide.

Can you verify the actual repository structure and confirm the correct relative paths? Alternatively, I can generate a verification script to check the paths.

Also applies to: 151-151


91-119: Environment configuration section is well-structured and complete.

The .env.local setup instructions are clear, with proper variable names and values. The security reminder about not committing .env.local is appropriate and well-placed.


143-162: Verification steps are clear and follow a realistic user journey.

The login/logout flow testing provides good coverage of the happy path.


164-223: Troubleshooting section provides practical guidance.

Comprehensive coverage of common issues with diagnostic commands and solutions. Port conflict resolution and error message explanations are helpful.


245-248: Verify consistency of path conventions in links.

Path references for internal links (e.g., ../frontend/control-plane/README.md on line 246) should be verified to match the directory structure. Also ensure consistency with the navigation paths mentioned in earlier sections (e.g., line 94).

infrastructure/docker/keycloak/README.md (3)

13-30: Automated setup section clearly prioritizes the recommended workflow.

Positioning the automated setup as "Method 1" with the "(推奨)" recommendation is effective. The integration flow is clear: docker compose up → script execution → populate environment variables.


32-34: Manual setup appropriately documented as secondary option.

Directing users to the QUICKSTART guide for manual setup avoids duplication and clearly marks this as the fallback method.


36-51: Cleanup section provides helpful options for different scenarios.

Documenting docker compose down, stop, and down -v variants helps users manage development environment state effectively.

Comment on lines +43 to +56
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=${ADMIN_USER}" \
-d "password=${ADMIN_PASSWORD}" \
-d "grant_type=password" \
-d "client_id=admin-cli")

ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | sed 's/"access_token":"//')

if [ -z "$ACCESS_TOKEN" ]; then
echo "❌ 管理者トークンの取得に失敗しました"
echo "レスポンス: $TOKEN_RESPONSE"
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace grep/sed JSON parsing with jq for robustness.

Using grep/sed to extract JSON values (line 50) is fragile and may fail if the response contains escaped characters, line breaks, or unexpected formatting. This could silently produce an empty or incorrect token, causing misleading errors downstream.

Apply this diff to use jq for reliable JSON parsing:

-ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | sed 's/"access_token":"//')
+ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token // empty')

Verify that jq is available in your execution environment (it's typically pre-installed on most systems or easily added to Docker images).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=${ADMIN_USER}" \
-d "password=${ADMIN_PASSWORD}" \
-d "grant_type=password" \
-d "client_id=admin-cli")
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | sed 's/"access_token":"//')
if [ -z "$ACCESS_TOKEN" ]; then
echo "❌ 管理者トークンの取得に失敗しました"
echo "レスポンス: $TOKEN_RESPONSE"
exit 1
fi
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=${ADMIN_USER}" \
-d "password=${ADMIN_PASSWORD}" \
-d "grant_type=password" \
-d "client_id=admin-cli")
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token // empty')
if [ -z "$ACCESS_TOKEN" ]; then
echo "❌ 管理者トークンの取得に失敗しました"
echo "レスポンス: $TOKEN_RESPONSE"
exit 1
fi
🤖 Prompt for AI Agents
in infrastructure/docker/keycloak/scripts/setup-keycloak.sh around lines 43 to
56, the script uses grep/sed to extract the access_token from the JSON response
which is fragile; replace that extraction with jq (e.g., TOKEN_RESPONSE stored,
then ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token') ), add a
check that jq is available before use (exit with a clear message if not), and
preserve the existing failure branch by checking for empty ACCESS_TOKEN and
printing TOKEN_RESPONSE on error; ensure jq -r is used so null/empty results
produce an empty string rather than "null".

Comment on lines +71 to +80
curl -s -X POST "${KEYCLOAK_URL}/admin/realms" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"realm\": \"${REALM_NAME}\",
\"enabled\": true,
\"displayName\": \"TenkaCloud\",
\"loginTheme\": \"keycloak\",
\"sslRequired\": \"none\"
}" > /dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add error checking to realm and client creation requests.

The realm (line 71) and client creation (line 97) curl commands pipe output to /dev/null without checking for HTTP errors. If these POST requests fail (e.g., 400, 403), the script continues silently and may fail later with confusing errors.

Add error checking to catch failed creations early:

  # Realm を作成
  echo "📝 Realm '${REALM_NAME}' を作成しています..."
- curl -s -X POST "${KEYCLOAK_URL}/admin/realms" \
+ REALM_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms" \
    -H "Authorization: Bearer ${ACCESS_TOKEN}" \
    -H "Content-Type: application/json" \
    -d "{
      \"realm\": \"${REALM_NAME}\",
      \"enabled\": true,
      \"displayName\": \"TenkaCloud\",
      \"loginTheme\": \"keycloak\",
      \"sslRequired\": \"none\"
-   }" > /dev/null
+   }")
+ HTTP_CODE=$(echo "$REALM_RESPONSE" | tail -1)
+ if [ "$HTTP_CODE" != "201" ]; then
+   echo "❌ Realm 作成に失敗しました (HTTP $HTTP_CODE)"
+   exit 1
+ fi

Apply similar checks to the client creation section.

Also applies to: 97-113

🤖 Prompt for AI Agents
in infrastructure/docker/keycloak/scripts/setup-keycloak.sh around lines 71-80
(and similarly for client creation around 97-113), the curl POSTs send output to
/dev/null and don't check HTTP status so failures are silent; change each curl
invocation to capture both response body and HTTP status (for example using -w
'%{http_code}' and storing output), check that the status is a 2xx value, and if
not log the response and an error message to stderr and exit with a non-zero
code to stop the script; apply the same pattern to the client creation block so
any 4xx/5xx responses are detected and cause an immediate, informative failure.

Comment on lines +89 to +90
CLIENT_UUID=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients?clientId=${CLIENT_ID}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"id":"[^"]*' | head -1 | sed 's/"id":"//')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace grep/sed JSON parsing with jq for client UUID extraction.

Client UUID extraction (lines 90, 117) suffers from the same fragility as the token parsing issue. JSON parsing via grep/sed is error-prone.

Apply this diff to both occurrences:

-CLIENT_UUID=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients?clientId=${CLIENT_ID}" \
-  -H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"id":"[^"]*' | head -1 | sed 's/"id":"//')
+CLIENT_UUID=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients?clientId=${CLIENT_ID}" \
+  -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq -r '.[0].id // empty')

This is cleaner and handles the array response directly without needing head and sed.

Also applies to: 116-117

🤖 Prompt for AI Agents
in infrastructure/docker/keycloak/scripts/setup-keycloak.sh around lines 89-90
(and similarly 116-117), the client UUID is being extracted using fragile
grep/sed parsing of JSON; replace those pipelines with jq to parse the JSON
array and extract the first object's id field reliably (use jq -r '.[0].id' on
the curl output or pipe through jq to select the matching client then .id),
ensuring the curl response is passed into jq and still authenticated with the
same Authorization header; update both occurrences accordingly and handle
empty/null results if jq returns no id.

Comment on lines +125 to +132
echo "🔐 Client Secret を取得しています..."
CLIENT_SECRET=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${CLIENT_UUID}/client-secret" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"value":"[^"]*' | sed 's/"value":"//')

if [ -z "$CLIENT_SECRET" ]; then
echo "❌ Client Secret の取得に失敗しました"
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace grep/sed JSON parsing with jq for client secret extraction.

Line 127 uses the same fragile grep/sed pattern for JSON parsing.

Apply this diff:

-CLIENT_SECRET=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${CLIENT_UUID}/client-secret" \
-  -H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"value":"[^"]*' | sed 's/"value":"//')
+CLIENT_SECRET=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${CLIENT_UUID}/client-secret" \
+  -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq -r '.value // empty')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "🔐 Client Secret を取得しています..."
CLIENT_SECRET=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${CLIENT_UUID}/client-secret" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"value":"[^"]*' | sed 's/"value":"//')
if [ -z "$CLIENT_SECRET" ]; then
echo "❌ Client Secret の取得に失敗しました"
exit 1
fi
echo "🔐 Client Secret を取得しています..."
CLIENT_SECRET=$(curl -s "${KEYCLOAK_URL}/admin/realms/${REALM_NAME}/clients/${CLIENT_UUID}/client-secret" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" | jq -r '.value // empty')
if [ -z "$CLIENT_SECRET" ]; then
echo "❌ Client Secret の取得に失敗しました"
exit 1
fi
🤖 Prompt for AI Agents
in infrastructure/docker/keycloak/scripts/setup-keycloak.sh around lines 125 to
132, the client secret is extracted using fragile grep/sed; replace that
pipeline with jq to robustly parse the JSON response: call curl as before and
pipe to jq -r '.value' to extract the client secret, assign that to
CLIENT_SECRET, and keep the subsequent empty-check/exit behavior unchanged so
failure still logs and exits with code 1.

@claude

claude Bot commented Nov 14, 2025

Copy link
Copy Markdown

PR Review: Quick Start Guide と Keycloak 自動セットアップスクリプト

こんにちは! PR 37 のレビューを実施しました。全体的に非常に良い実装です。

良い点

1. ドキュメントの質が高い

  • QUICKSTART.md が初心者にも分かりやすく、5〜10分で起動できる構成
  • トラブルシューティングが充実
  • セキュリティ注意事項が明記

2. 自動化スクリプトが堅牢

  • エラーハンドリングが適切(set -e)
  • Keycloak の起動待機ロジックを実装
  • 冪等性を考慮した設計

3. ユーザー体験の向上

  • 手動/自動セットアップの両方を提供
  • 出力メッセージが視認性が高く、次のステップが明確

改善提案

1. Critical: JSON パース処理の脆弱性

ファイル: infrastructure/docker/keycloak/scripts/setup-keycloak.sh:50, 90, 127

問題: grep + sed による JSON パースは脆弱で、予期しない形式のレスポンスに対応できません

推奨修正: jq を使用した堅牢な JSON パース

理由:

  • jq は JSON パースの標準ツールで、エラーハンドリングが確実
  • 可読性とメンテナンス性が向上

依存関係: docs/QUICKSTART.md の前提条件に jq を追加してください

2. Medium: エラーメッセージの標準エラー出力

すべてのエラーメッセージに >&2 を追加してください。

3. Medium: ShellCheck 導入

シェルスクリプトの品質保証のため ShellCheck を導入し、CI に統合してください。

4. Medium: リンク切れの確認

docs/QUICKSTART.md:246 の frontend/control-plane/README.md へのリンクが存在するか確認してください。

テストカバレッジ

不足している項目

  • スクリプトの単体テスト(bats)
  • ShellCheck による静的解析
  • E2E テスト

総合評価

カテゴリ 評価 コメント
コード品質 ⭐⭐⭐⭐☆ JSON パースの改善が必要
セキュリティ ⭐⭐⭐⭐☆ 注意事項が適切に記載
ドキュメント ⭐⭐⭐⭐⭐ 非常に充実
テストカバレッジ ⭐⭐☆☆☆ スクリプトテストが不足
ユーザー体験 ⭐⭐⭐⭐⭐ 優れたオンボーディング

承認条件

以下の修正を実施後、承認可能です:

  1. JSON パース処理を jq に移行(セキュリティ)
  2. エラーメッセージを標準エラー出力に変更(>&2)
  3. リンク切れの確認・修正

その他の推奨事項は、マージ後の別 PR で対応しても問題ありません。


素晴らしい実装です!特に初心者向けドキュメントの充実度が高く、TenkaCloud のオンボーディング体験を大幅に向上させるPRです 🎉

🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com

@susumutomita
susumutomita merged commit 71828dc into main Nov 14, 2025
6 of 7 checks passed
@susumutomita
susumutomita deleted the docs/quickstart-guide branch November 14, 2025 21:46
@claude

claude Bot commented Nov 14, 2025

Copy link
Copy Markdown

PR Review - Quick Start Guide と Keycloak 自動セットアップスクリプト

全体として、開発者体験を大幅に向上させる素晴らしい PR です!CLAUDE.md のコンセプトに沿った、実用的で親切なドキュメントとツールの追加になっています。以下、詳細なレビューフィードバックをお送りします。


✅ 強み・評価ポイント

1. 優れた開発者体験 (Developer Experience)

  • Quick Start Guide が非常に丁寧: ステップバイステップで、初めての開発者でも迷わず進められる構成
  • 自動化スクリプトの提供: 手動セットアップの煩わしさを解消し、5-10分で起動できる点が秀逸
  • トラブルシューティングが充実: よくあるエラーと解決策が網羅されており、実践的

2. コードの一貫性向上

  • TypeScript ファイルのクォート統一(ダブル→シングル)は、プロジェクト全体の一貫性を保つ良い改善
  • Prettier/ESLint のルールに従った変更と思われる

3. セキュリティ意識

  • docs/QUICKSTART.md:282-286 でセキュリティ注意事項を明記
  • 本番環境での使用を警告し、デフォルトパスワードのリスクを説明

4. スクリプトの堅牢性

  • infrastructure/docker/keycloak/scripts/setup-keycloak.sh:24-37: リトライロジックによる起動待機
  • setup-keycloak.sh:52-56: エラーハンドリングとメッセージ表示
  • setup-keycloak.sh:66-67, 92-93: 冪等性の確保(Realm/Client が既に存在する場合のチェック)

🔍 改善提案

1. Bash スクリプトのセキュリティと堅牢性

🔴 Critical: JSON パース処理の脆弱性

場所: infrastructure/docker/keycloak/scripts/setup-keycloak.sh:50, 90, 117, 127

問題:
grep と sed によるパースは、JSON 構造の変化に弱く、エスケープされた引用符やネストした JSON に対応できない可能性があります。

推奨: jq を使用したパース(より堅牢でメンテナンス性が高い)

代替案 (jq を必須にしたくない場合):

  • 現状のアプローチを維持しつつ、README に「jq のインストールを推奨」と記載
  • または Python の json モジュールを使用(macOS/Linux に標準搭載)

🟡 Medium: エラーメッセージの改善

場所: setup-keycloak.sh:129-132

問題: Client が存在しない場合、CLIENT_UUID が空になり、API リクエストが失敗しますが、エラーメッセージには具体的な原因が示されません。

推奨: CLIENT_UUID の存在チェックを追加し、より詳細なエラーメッセージを表示


🟡 Medium: シェルスクリプトのベストプラクティス

推奨: より厳格なエラーハンドリング

  • set -euo pipefail を使用(-u: 未定義変数でエラー, -o pipefail: パイプの途中でエラー)
  • デバッグモードのサポート追加

2. ドキュメントの改善

🟡 Medium: Quick Start Guide のパス問題

場所: docs/QUICKSTART.md:94

問題: 相対パス cd ../../frontend/control-plane は、ユーザーが現在どのディレクトリにいるかに依存します。

推奨: リポジトリルートからの絶対的な手順として統一するか、両方のパターンを明記


🟢 Nice-to-Have: スクリーンショットの追加

PR 説明に「スクリーンショット追加予定」とありますが、以下があると更に良いです:

  • Keycloak 管理コンソールのログイン画面
  • Realm 作成画面
  • Client 設定画面
  • Next.js ログインページ
  • ダッシュボード画面

後続の PR で追加予定であれば問題ありません。


3. テストカバレッジ

🟡 Medium: スクリプトの自動テスト

場所: infrastructure/docker/keycloak/scripts/setup-keycloak.sh

現状: スクリプトの動作確認は手動のみで、CI/CD での自動テストがありません。

推奨: bats-core を使用した自動テスト、または簡易的な smoke test スクリプトの追加

PR 説明の「次のステップ」に記載あり: 「スクリプトのテストを追加(bats など)」 → これで OK です。Issue 化して追跡することを推奨します。


4. CI/CD 統合

🟢 Nice-to-Have: GitHub Actions での検証

Quick Start Guide の手順が実際に動作することを CI で検証することを推奨します。


📝 細かい指摘

1. タイポ・表記ゆれ

docs/QUICKSTART.md

  • L11: 「5分で起動」→ Quick Start なら 5 分、PR 説明では「5〜10分」。統一推奨(「5〜10分」が現実的)

infrastructure/docker/keycloak/README.md

  • L42-46: 段落間に空行を追加すると読みやすくなります

2. TypeScript フォーマット変更

場所: 複数ファイル(ダブルクォート → シングルクォート)

評価: ✅ Good

  • プロジェクトの一貫性向上
  • Prettier/ESLint ルールに従っている(と推測)

確認事項: .prettierrc または eslint.config.js で singleQuote: true が設定されているか確認してください。


🎯 次のステップ(推奨)

CLAUDE.md の「振り返り & 改善プロトコル」に従い、以下を推奨します:

  1. Issue 作成:

    • スクリプトのテスト追加(bats-core)
    • CI/CD パイプラインへの統合
    • スクリーンショットの追加
    • jq を使用した JSON パースのリファクタリング
  2. Plan.md への記録:

    • このレビューで指摘された問題と対応方針を記録
    • 特に Critical/Medium 項目の対応予定
  3. CLAUDE.md の更新:

    • スクリプト開発のベストプラクティスを追記

🏁 結論

マージ可否: ✅ Approve with Minor Suggestions

  • Critical な問題はなく、現状でもマージ可能
  • 上記の改善提案は、後続の PR で対応可能
  • Quick Start Guide と自動化スクリプトは、開発者体験を大幅に向上させる素晴らしい追加

特に setup-keycloak.sh は、Keycloak の初期設定の煩わしさを解消し、新規開発者のオンボーディングを劇的に改善します。CLAUDE.md のコンセプト「動くものをイテレーティブに作る」に忠実で、実用性の高い PR です。

お疲れ様でした!🎉


レビュアー: Claude Code (Sonnet 4.5)
レビュー日時: 2025-11-14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant