From 9f014a1eb5b5310ba94648ce04b1ca721ef5acd8 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:11:52 +0900 Subject: [PATCH 01/89] =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E4=BD=9C=E6=A5=AD=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=82=92=E9=99=A4=E5=A4=96=E3=81=99=E3=82=8B.gitignor?= =?UTF-8?q?e=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..624a51e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Local work directory +.lw/ From 9b6514d26588c35360e41143a31dce734979b995 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:12:02 +0900 Subject: [PATCH 02/89] =?UTF-8?q?Claude=20Code=E8=A8=AD=E5=AE=9A=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=97=E3=80=81gitignore=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 許可・拒否操作の権限設定を追加 - 危険なコマンド(rm -rf、dd、mkfsなど)を拒否 - 環境変数アクセス(env、exportなど)を拒否 - WSLからのWindowsホストアクセスを拒否 - セキュリティのため.envファイルへのアクセスを拒否 - git、ファイル操作、Claude Codeツールを許可 - settings.local.jsonを除外するようgitignoreを更新 Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 82 +++++++++++++++++++++++++++++++++++++++++++ .gitignore | 3 ++ 2 files changed, 85 insertions(+) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..fbb1da7 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,82 @@ +{ + "permissions": { + "allow": [ + "Read(*)", + "Write(*)", + "WebSearch(*)", + "WebFetch(*)", + "Bash(ls:*)", + "Bash(cp:*)", + "Bash(mv:*)", + "Bash(rm:*)", + "Bash(mkdir:*)", + "Bash(touch:*)", + "Bash(chmod:*)", + "Bash(chown:*)", + "Bash(git status:*)", + "Bash(git add:*)", + "Bash(git commit:*)", + "Bash(git push:*)", + "Bash(git pull:*)", + "Bash(git fetch:*)", + "Bash(git branch:*)", + "Bash(git checkout:*)", + "Bash(git merge:*)", + "Bash(git rebase:*)", + "Bash(git log:*)", + "Bash(git diff:*)", + "Bash(git stash:*)", + "Bash(git reset:*)", + "Bash(git tag:*)", + "Bash(gh pr:*)", + "Bash(gh issue:*)", + "Bash(gh api:*)" + ], + "deny": [ + "Read(*.env)", + "Read(.env*)", + "Write(*.env)", + "Write(.env*)", + "Bash(rm -rf /:*)", + "Bash(rm -rf /*:*)", + "Bash(rm -rf ~:*)", + "Bash(sudo rm -rf:*)", + "Bash(chmod -R 777 /:*)", + "Bash(dd:*)", + "Bash(sudo dd:*)", + "Bash(mkfs:*)", + "Bash(sudo mkfs:*)", + "Bash(fdisk:*)", + "Bash(sudo fdisk:*)", + "Bash(parted:*)", + "Bash(* > /dev/sd*:*)", + "Bash(* > /dev/nvme*:*)", + "Bash(curl * | bash:*)", + "Bash(wget * | bash:*)", + "Bash(curl * | sh:*)", + "Bash(wget * | sh:*)", + "Bash(export *:*)", + "Bash(unset *:*)", + "Bash(env:*)", + "Bash(printenv:*)", + "Bash(powershell.exe:*)", + "Bash(pwsh.exe:*)", + "Bash(cmd.exe:*)", + "Bash(*.exe:*)", + "Bash(wsl.exe:*)", + "Bash(wslpath:*)", + "Read(/mnt/c/*)", + "Read(/mnt/d/*)", + "Read(/mnt/e/*)", + "Read(/mnt/f/*)", + "Write(/mnt/c/*)", + "Write(/mnt/d/*)", + "Write(/mnt/e/*)", + "Write(/mnt/f/*)", + "Bash(* /mnt/c/*:*)", + "Bash(* /mnt/d/*:*)", + "Bash(* /mnt/e/*:*)", + "Bash(* /mnt/f/*:*)" + ] + } +} diff --git a/.gitignore b/.gitignore index 624a51e..e1c030a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # Local work directory .lw/ + +# Claude Code local settings +.claude/settings.local.json From 3b05d9f1ddd5b0aabe2d04b50206e6dfefdf9aa8 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:12:07 +0900 Subject: [PATCH 03/89] =?UTF-8?q?=E3=82=BB=E3=83=83=E3=83=88=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=82=B9=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88?= =?UTF-8?q?=E3=81=A8=E3=83=89=E3=82=AD=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code統合を含む開発環境の自動セットアップスクリプトと、 READMEに包括的なセットアップ手順を追加 Co-Authored-By: Claude Opus 4.6 --- .env.example | 17 +++ README.md | 29 ++++++ setup.sh | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 .env.example create mode 100755 setup.sh diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..694ec53 --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# 注意: これらのキーは機密情報ですので、他人と共有しないでください。 + +# AWS +export AWS_ACCESS_KEY_ID="TODO" +export AWS_SECRET_ACCESS_KEY="TODO" +export AWS_DEFAULT_REGION="ap-northeast-1" + +# Claude Code +export CLAUDE_CODE_USE_BEDROCK="1" +export ANTHROPIC_MODEL="jp.anthropic.claude-sonnet-4-5-20250929-v1:0" +export ANTHROPIC_DEFAULT_SONNET_MODEL="jp.anthropic.claude-sonnet-4-5-20250929-v1:0" +export ANTHROPIC_DEFAULT_HAIKU_MODEL="jp.anthropic.claude-haiku-4-5-20251001-v1:0" +export CLAUDE_CODE_SUBAGENT_MODEL="jp.anthropic.claude-sonnet-4-5-20250929-v1:0" +export AWS_REGION="ap-northeast-1" + +# GitHub +export GH_TOKEN="TODO" diff --git a/README.md b/README.md index dd83d77..ca59f7d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,31 @@ # nabledge-dev Nablarch knowledge development + +## 前提条件 + +- WSL2 / Ubuntu +- 社内プロキシ環境の場合: CA証明書 + +## セットアップ + +### 1. CA証明書の配置(プロキシ環境の場合) + +```bash +sudo cp /path/to/your/ca.crt /usr/local/share/ca-certificates/ca.crt +sudo update-ca-certificates +``` + +### 2. 環境構築 + +```bash +./setup.sh +cp .env.example .env +# Edit .env and set your credentials +``` + +## 作業開始 + +```bash +source .env +claude +``` diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..eae320b --- /dev/null +++ b/setup.sh @@ -0,0 +1,284 @@ +#!/bin/bash + +set -euo pipefail + +# Color codes +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo "========================================" +echo "Nabledge Development Setup" +echo "========================================" +echo "" + +# Print status function +print_status() { + local status="$1" + local message="$2" + + case "$status" in + ok) + echo -e "${GREEN}✓${NC} $message" + ;; + error) + echo -e "${RED}✗${NC} $message" + ;; + warning) + echo -e "${YELLOW}⚠${NC} $message" + ;; + info) + echo -e "${BLUE}ℹ${NC} $message" + ;; + esac +} + +print_header() { + echo "" + echo "==========================================" + echo "$1" + echo "==========================================" + echo "" +} + +# Check prerequisites +print_header "1. Checking Prerequisites" + +# Check if running on WSL/Ubuntu +if ! grep -qi microsoft /proc/version && ! grep -qi ubuntu /etc/os-release; then + print_status warning "This script is designed for WSL/Ubuntu environment" + read -p "Continue anyway? [y/N] " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +fi + +# Check CA certificate +CA_CERT_PATH="/usr/local/share/ca-certificates/ca.crt" +if [ -f "$CA_CERT_PATH" ]; then + print_status ok "CA certificate found at $CA_CERT_PATH" +else + print_status warning "CA certificate not found at $CA_CERT_PATH" + echo "" + echo " If you are in a corporate proxy environment, please install CA certificate first:" + echo " sudo cp /path/to/your/ca.crt $CA_CERT_PATH" + echo " sudo update-ca-certificates" + echo "" + read -p "Continue without CA certificate? [y/N] " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +fi + +# Check bash version +if [ "${BASH_VERSINFO[0]}" -ge 4 ]; then + print_status ok "Bash ${BASH_VERSION}" +else + print_status error "Bash ${BASH_VERSION} (>= 4.0 required)" + exit 1 +fi + +# Check sudo access +if sudo -n true 2>/dev/null; then + print_status ok "sudo access available" +else + print_status info "sudo may require password" +fi + +# Install system tools +print_header "2. Installing System Tools" + +# Update package list +print_status info "Updating package list..." +sudo apt-get update + +# Check if tools are already installed +TOOLS_MISSING=0 +for tool in libreoffice pdftoppm pandoc jq python3 gh; do + if ! command -v "$tool" &> /dev/null; then + TOOLS_MISSING=1 + break + fi +done + +if [ $TOOLS_MISSING -eq 0 ]; then + print_status ok "System tools already installed" +else + print_status info "Installing LibreOffice, Poppler, Pandoc, jq, Python3..." + if sudo apt-get install -y libreoffice poppler-utils pandoc jq python3 python3-venv; then + print_status ok "System tools installed" + else + print_status error "Failed to install system tools" + exit 1 + fi +fi + +# Install GitHub CLI +print_status info "Installing GitHub CLI (gh)..." +if command -v gh &> /dev/null; then + print_status ok "gh is already installed ($(gh --version | head -n 1))" +else + # Install from official repository + if (type -p wget >/dev/null || (sudo apt-get update && sudo apt-get install -y wget)) \ + && sudo mkdir -p -m 755 /etc/apt/keyrings \ + && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ + && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ + && sudo apt-get update \ + && sudo apt-get install -y gh; then + print_status ok "gh installed successfully" + else + print_status error "Failed to install gh" + exit 1 + fi +fi + +# Setup environment variables +print_header "3. Setting Up Environment Variables" + +BASHRC="$HOME/.bashrc" +ENV_VARS_MARKER="# Nabledge environment variables" + +if grep -q "$ENV_VARS_MARKER" "$BASHRC"; then + print_status ok "Environment variables already configured" +else + print_status info "Adding environment variables to $BASHRC..." + cat >> "$BASHRC" << 'EOF' + +# Nabledge environment variables +export UV_CA_BUNDLE="/usr/local/share/ca-certificates/ca.crt" +export SSL_CERT_FILE="/usr/local/share/ca-certificates/ca.crt" +export NODE_EXTRA_CA_CERTS="/usr/local/share/ca-certificates/ca.crt" +export PATH="$HOME/venv/bin:$PATH" +EOF + print_status ok "Environment variables added" + print_status info "Sourcing $BASHRC..." + source "$BASHRC" || true +fi + +# Install uv if not present +print_header "4. Installing uv (Python Package Manager)" + +if command -v uv &> /dev/null; then + print_status ok "uv already installed" +else + print_status info "Installing uv..." + if curl -LsSf https://astral.sh/uv/install.sh | sh; then + source "$HOME/.cargo/env" || true + print_status ok "uv installed" + else + print_status error "Failed to install uv" + exit 1 + fi +fi + +# Setup Python venv and install libraries +print_header "5. Setting Up Python Virtual Environment" + +VENV_DIR="$HOME/venv" + +if [ -d "$VENV_DIR" ]; then + print_status ok "Python venv already exists at $VENV_DIR" +else + print_status info "Creating Python venv at $VENV_DIR..." + if uv venv "$VENV_DIR"; then + print_status ok "Python venv created" + else + print_status error "Failed to create Python venv" + exit 1 + fi +fi + +print_status info "Installing Python libraries..." +if uv pip install --python "$VENV_DIR/bin/python" \ + pdfplumber reportlab pypdf pymupdf \ + python-pptx Pillow markitdown \ + openpyxl python-docx lxml pandas; then + print_status ok "Python libraries installed" +else + print_status error "Failed to install Python libraries" + exit 1 +fi + +# Verify document tools installation +print_header "6. Verifying Document Tools" + +if "$VENV_DIR/bin/python" -c "import pdfplumber, reportlab, pptx, openpyxl, docx; print('OK')" 2>/dev/null; then + print_status ok "Python libraries verified" +else + print_status error "Python library verification failed" + exit 1 +fi + +if soffice --version &>/dev/null && pdftoppm -v &>/dev/null && pandoc --version &>/dev/null && jq --version &>/dev/null; then + print_status ok "System tools verified" +else + print_status error "System tools verification failed" + exit 1 +fi + +# Setup Node.js and npm +print_header "7. Setting Up Node.js" + +if command -v node &> /dev/null; then + print_status ok "Node.js $(node --version) already installed" +else + print_status info "Installing Node.js via nvm..." + + # Install nvm + if [ ! -d "$HOME/.nvm" ]; then + if curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash; then + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + print_status ok "nvm installed" + else + print_status error "Failed to install nvm" + exit 1 + fi + else + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + print_status ok "nvm already installed" + fi + + # Install Node.js LTS + if nvm install --lts; then + print_status ok "Node.js LTS installed" + else + print_status error "Failed to install Node.js" + exit 1 + fi +fi + +# Install ajv-cli +print_header "8. Installing JSON Schema Validator (ajv-cli)" + +if command -v ajv &> /dev/null; then + print_status ok "ajv-cli already installed" +else + print_status info "Installing ajv-cli and ajv-formats..." + if npm install -g ajv-cli ajv-formats; then + print_status ok "ajv-cli installed" + else + print_status error "Failed to install ajv-cli" + exit 1 + fi +fi + +# Final summary +print_header "Setup Completed Successfully!" + +echo "Next steps:" +echo " 1. Restart your shell or run: source ~/.bashrc" +echo " 2. Copy and edit .env file:" +echo " cp .env.example .env" +echo " # Edit .env and set your credentials" +echo "" +echo " 3. Load environment and start Claude Code:" +echo " source .env" +echo " claude" +echo "" From ca5eb1e658598039331ddd4845ae695b92415e64 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:12:14 +0900 Subject: [PATCH 04/89] =?UTF-8?q?Claude=20Code=E3=82=AC=E3=82=A4=E3=83=89?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E3=82=92=E7=B0=A1=E7=B4=A0=E5=8C=96?= =?UTF-8?q?=E3=81=97=E3=80=81Nablarch=E3=83=AA=E3=83=9D=E3=82=B8=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=B3=E6=A9=9F=E8=83=BD?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CLAUDE.mdをシンプルなルールのみの記述に変更 - setup.shにNablarch公式リポジトリのクローン機能を追加 Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 1 + setup.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..22dd64b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +言語は日本語 diff --git a/setup.sh b/setup.sh index eae320b..798d72f 100755 --- a/setup.sh +++ b/setup.sh @@ -269,6 +269,47 @@ else fi fi +# Clone Nablarch official repositories +print_header "9. Cloning Nablarch Official Repositories" + +NAB_OFFICIAL_DIR=".lw/nab-official" + +# Create directory if it doesn't exist +if [ ! -d "$NAB_OFFICIAL_DIR" ]; then + print_status info "Creating $NAB_OFFICIAL_DIR directory..." + mkdir -p "$NAB_OFFICIAL_DIR" + print_status ok "Directory created" +fi + +# Function to clone or update repository +clone_or_update_repo() { + local repo_url="$1" + local repo_name=$(basename "$repo_url" .git) + local repo_path="$NAB_OFFICIAL_DIR/$repo_name" + + if [ -d "$repo_path" ]; then + print_status info "Repository $repo_name already exists, updating..." + if git -C "$repo_path" pull; then + print_status ok "$repo_name updated" + else + print_status warning "Failed to update $repo_name" + fi + else + print_status info "Cloning $repo_name..." + if git clone "$repo_url" "$repo_path"; then + print_status ok "$repo_name cloned" + else + print_status error "Failed to clone $repo_name" + exit 1 + fi + fi +} + +# Clone repositories +clone_or_update_repo "https://github.com/nablarch/nablarch-document.git" +clone_or_update_repo "https://github.com/nablarch/nablarch-single-module-archetype.git" +clone_or_update_repo "https://github.com/Fintan-contents/nablarch-system-development-guide.git" + # Final summary print_header "Setup Completed Successfully!" From 6940ab6f962c538841bfcab7965a8222fa2a0e5d Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:12:22 +0900 Subject: [PATCH 05/89] =?UTF-8?q?Claude=20Code=E3=82=B9=E3=83=86=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=82=B9=E3=83=A9=E3=82=A4=E3=83=B3=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - シェルスクリプトを使用したカスタムステータスラインを設定 - document-skillsプラグインを有効化 - カレントディレクトリ、gitブランチ、モデル、コンテキスト使用率を表示 Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 10 +++++++++- .claude/statusline.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100755 .claude/statusline.sh diff --git a/.claude/settings.json b/.claude/settings.json index fbb1da7..aea572d 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -78,5 +78,13 @@ "Bash(* /mnt/e/*:*)", "Bash(* /mnt/f/*:*)" ] + }, + "statusLine": { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/statusline.sh", + "padding": 0 + }, + "enabledPlugins": { + "document-skills@anthropic-agent-skills": true } -} +} \ No newline at end of file diff --git a/.claude/statusline.sh b/.claude/statusline.sh new file mode 100755 index 0000000..012e684 --- /dev/null +++ b/.claude/statusline.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +input=$(cat) + +cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd') +model=$(echo "$input" | jq -r '.model.display_name // empty') +context_used=$(echo "$input" | jq -r '.context_window.used_percentage // empty') + +# Git branch +git_branch="" +if git -C "$cwd" rev-parse --git-dir > /dev/null 2>&1; then + branch=$(git -C "$cwd" -c core.useBuiltinFSMonitor=false -c core.fsmonitor=false branch --show-current 2>/dev/null) + [ -n "$branch" ] && git_branch=" ($branch)" +fi + +# Context info +context_info="" +[ -n "$context_used" ] && context_info=" [ctx: ${context_used}%]" + +# Model info +model_info="" +[ -n "$model" ] && model_info=" [${model}]" + +# Output +cwd_name=$(basename "$cwd") +printf "\033[01;34m%s\033[00m%s%s%s" "$cwd_name" "$git_branch" "$model_info" "$context_info" From dded1522ba104d9cc8f3bd2b1fbeaa4c0f534cc4 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:19:08 +0900 Subject: [PATCH 06/89] =?UTF-8?q?feat:=20Git=E6=93=8D=E4=BD=9C=E3=82=B9?= =?UTF-8?q?=E3=82=AD=E3=83=AB=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit エージェントから実行可能な構造で、ブランチ作成、コミット、ブランチ削除、ワークツリー作成/削除の5つの操作をサポート Co-Authored-By: Claude Opus 4.6 --- .claude/skills/git/SKILL.md | 249 ++++++++ .claude/skills/git/assets/examples.md | 506 +++++++++++++++ .claude/skills/git/assets/reference.md | 579 ++++++++++++++++++ .claude/skills/git/workflows/branch-create.md | 173 ++++++ .claude/skills/git/workflows/branch-delete.md | 157 +++++ .claude/skills/git/workflows/commit.md | 188 ++++++ .../skills/git/workflows/worktree-create.md | 203 ++++++ .../skills/git/workflows/worktree-delete.md | 219 +++++++ 8 files changed, 2274 insertions(+) create mode 100644 .claude/skills/git/SKILL.md create mode 100644 .claude/skills/git/assets/examples.md create mode 100644 .claude/skills/git/assets/reference.md create mode 100644 .claude/skills/git/workflows/branch-create.md create mode 100644 .claude/skills/git/workflows/branch-delete.md create mode 100644 .claude/skills/git/workflows/commit.md create mode 100644 .claude/skills/git/workflows/worktree-create.md create mode 100644 .claude/skills/git/workflows/worktree-delete.md diff --git a/.claude/skills/git/SKILL.md b/.claude/skills/git/SKILL.md new file mode 100644 index 0000000..bd09c4c --- /dev/null +++ b/.claude/skills/git/SKILL.md @@ -0,0 +1,249 @@ +--- +name: git +description: Git操作を実行する。使い方:/git(対話選択)、/git commit(コミット)、/git branch-create(ブランチ作成)、/git branch-delete(ブランチ削除)、/git worktree-create(ワークツリー作成)、/git worktree-delete(ワークツリー削除) +argument-hint: [commit|branch-create|branch-delete|worktree-create|worktree-delete] +allowed-tools: Bash, Task, AskUserQuestion, Read +--- + +# Git操作スキル + +このスキルは、Git操作を統合的に実行するオーケストレーターです。 +各操作は専用のワークフローを別コンテキストで実行します。 + +## 実行手順 + +以下の手順に従って、このスキルを実行してください。 + +### ステップ1: 引数解析とモード決定 + +$ARGUMENTSを確認し、モードを決定します。 + +**$ARGUMENTSの形式**: +- 引数なし(空文字列): `/git` のみが実行された +- 引数あり: `/git commit` や `/git branch-delete feature-branch` のように引数が渡される + - 最初の単語がサブコマンド + - 2番目以降の単語が追加パラメータ + +**引数解析の手順**: + +1. $ARGUMENTSが空または空白のみの場合、AskUserQuestionツールで操作を選択: + +``` +AskUserQuestion + questions: + - question: "どのGit操作を実行しますか?" + header: "Git操作" + multiSelect: false + options: + - label: "コミット&プッシュ (commit)" + description: "変更をコミットしてリモートにプッシュ" + - label: "ブランチ作成 (branch-create)" + description: "mainから作業ブランチを作成" + - label: "ブランチ削除 (branch-delete)" + description: "マージ済みブランチを削除" + - label: "ワークツリー操作 (worktree)" + description: "ワークツリーの作成または削除" +``` + +ユーザーの回答から、カッコ内の単語(commit、branch-create等)を抽出してモードとします。 +「ワークツリー操作」が選択された場合、さらにAskUserQuestionでサブモードを選択: + +``` +AskUserQuestion + questions: + - question: "ワークツリー操作を選択してください" + header: "操作種別" + multiSelect: false + options: + - label: "作成 (worktree-create)" + description: "新しいワークツリーを作成" + - label: "削除 (worktree-delete)" + description: "ワークツリーを削除" +``` + +2. $ARGUMENTSに文字列がある場合、スペースで分割して解析: + - 最初の単語がサブコマンド(モード) + - `commit` → mode="commit" + - `branch-create` → mode="branch-create" + - `branch-delete` → mode="branch-delete" + - `worktree-create` → mode="worktree-create" + - `worktree-delete` → mode="worktree-delete" + - `worktree` → AskUserQuestionでサブモード選択(上記と同じ) + - その他 → 無効なサブコマンドとしてAskUserQuestionでモード選択 + + - 2番目以降の単語がある場合: + - `branch-delete`の場合: target_branchとして保存 + - `worktree-delete`の場合: target_pathとして保存 + +### ステップ2: 現在のGit状態を確認 + +Bashツールで以下のコマンドを実行し、現在の状態を取得します: + +```bash +git branch --show-current && pwd +``` + +**結果の解析**: +- 1行目: カレントブランチ名を保存 (例: "main" または "feature/new-feature") +- 2行目: カレントディレクトリパスを保存 (例: "/home/user/project") + +これらの情報は変数として保持し、ステップ3-2でTaskツールのpromptに含めます。 + +**gitリポジトリチェック**: +もしgit branch --show-currentが失敗した場合(終了コード0でない)、カレントディレクトリはgitリポジトリではありません。以下のメッセージを表示して終了: + +``` +エラー: カレントディレクトリはgitリポジトリではありません。 +gitリポジトリのディレクトリで実行してください。 +``` + +### ステップ3: ワークフローの読み込みと実行 + +決定したモードに応じて、対応するワークフローファイルを読み込み、Taskツールで実行します。 + +#### 3-1. ワークフローファイルの読み込み + +Readツールで対応するワークフローファイルを読み込みます: + +- `commit` → `.claude/skills/git/workflows/commit.md` +- `branch-create` → `.claude/skills/git/workflows/branch-create.md` +- `branch-delete` → `.claude/skills/git/workflows/branch-delete.md` +- `worktree-create` → `.claude/skills/git/workflows/worktree-create.md` +- `worktree-delete` → `.claude/skills/git/workflows/worktree-delete.md` + +#### 3-2. Taskツールでワークフロー実行 + +3-1で読み込んだワークフローの内容を、Taskツールのpromptパラメータに含めて実行します。 + +**重要**: promptには以下の構造で文字列を構築してください: +``` +以下のワークフローに従って、{操作内容}してください。 + +{Readツールで読み込んだワークフローファイルの全内容(1行目から最後の行まで全て)} + +## 追加の入力情報 +- {ステップ2で取得した情報} +``` + +**各モードの実装**: + +**commit モード**: +``` +Task + subagent_type: "general-purpose" + description: "コミット実行" + prompt: 文字列を以下のように構築: + - 1行目: "以下のワークフローに従って、変更をコミットしてプッシュしてください。" + - 2行目: 空行 + - 3行目以降: Readツールで取得した.claude/skills/git/workflows/commit.mdの全内容 + - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}" +``` + +**branch-create モード**: +``` +Task + subagent_type: "general-purpose" + description: "ブランチ作成" + prompt: 文字列を以下のように構築: + - 1行目: "以下のワークフローに従って、作業ブランチを作成してください。" + - 2行目: 空行 + - 3行目以降: Readツールで取得した.claude/skills/git/workflows/branch-create.mdの全内容 + - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}" +``` + +**branch-delete モード**: +``` +Task + subagent_type: "general-purpose" + description: "ブランチ削除" + prompt: 文字列を以下のように構築: + - 1行目: "以下のワークフローに従って、ブランチを削除してください。" + - 2行目: 空行 + - 3行目以降: Readツールで取得した.claude/skills/git/workflows/branch-delete.mdの全内容 + - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}\n- 削除対象ブランチ: {ステップ1で取得したtarget_branch(ある場合、なければ「指定なし」)}" +``` + +**worktree-create モード**: +``` +Task + subagent_type: "general-purpose" + description: "ワークツリー作成" + prompt: 文字列を以下のように構築: + - 1行目: "以下のワークフローに従って、ワークツリーを作成してください。" + - 2行目: 空行 + - 3行目以降: Readツールで取得した.claude/skills/git/workflows/worktree-create.mdの全内容 + - 最後に追加: "## 追加の入力情報\n- カレントディレクトリ: {ステップ2で取得したディレクトリ}" +``` + +**worktree-delete モード**: +``` +Task + subagent_type: "general-purpose" + description: "ワークツリー削除" + prompt: 文字列を以下のように構築: + - 1行目: "以下のワークフローに従って、ワークツリーを削除してください。" + - 2行目: 空行 + - 3行目以降: Readツールで取得した.claude/skills/git/workflows/worktree-delete.mdの全内容 + - 最後に追加: "## 追加の入力情報\n- 削除対象パス: {ステップ1で取得したtarget_path(ある場合、なければ「指定なし」)}" +``` + +### ステップ4: 結果の確認と報告 + +Taskツールが完了したら、その結果をユーザーに報告します。 + +**報告の方針**: +- ワークフロー内で詳細な結果(ブランチ名、ファイル数等)が既に表示されています +- オーケストレーター側では、Taskツールの結果を見て、成功したか失敗したかを簡潔に報告するだけで十分です + +**成功時の報告例**: +- "コミット処理が完了しました。" +- "ブランチ作成が完了しました。" +- "ブランチ削除が完了しました。" +- "ワークツリー作成が完了しました。" +- "ワークツリー削除が完了しました。" + +**失敗時の対応**: +- Taskツールからエラーメッセージが返された場合、そのエラーメッセージをユーザーに伝えます +- ワークフロー内に対処方法が記載されているため、追加の説明は不要です + +## 重要な注意事項 + +### 1. ワークフローの全内容を必ず渡す + +**最重要**: Readツールで読み込んだワークフローファイルの内容は、1文字も省略せず、要約もせず、そのまま全てTaskツールのpromptに含めてください。 + +- ✅ 正しい: ワークフローファイルの内容を全て(1行目から最後の行まで)promptに含める +- ❌ 間違い: ワークフローを要約したり、一部だけを含めたりする +- ❌ 間違い: 「workflows/commit.mdを参照してください」とだけ書く(Taskツールは別コンテキストなので参照できない) + +### 2. 別コンテキストでの実行 + +Taskツールは完全に別のコンテキストで実行されます。そのため: +- このスキル(オーケストレーター)側では、ステップ2の状態確認以外のBashコマンドは実行不要 +- ワークフロー内の全てのBashコマンドは、Taskツール側で実行される +- Taskツールは、promptに含まれる情報のみを使用する(このスキル側の変数や状態にアクセスできない) + +### 3. 引数解析の柔軟性 + +ユーザーが引数を指定しなくても、AskUserQuestionで対話的にモードを選択できるようにします。これにより、コマンドに不慣れなユーザーでも使いやすくなります。 + +### 4. エラーハンドリングの分担 + +- **オーケストレーター側**: gitリポジトリチェックのみ +- **ワークフロー側**: 各操作固有のエラーハンドリング(各ワークフローファイルに記載済み) + +## トラブルシューティング + +### gitリポジトリではない +カレントディレクトリがgitリポジトリでない場合: +``` +エラー: カレントディレクトリはgitリポジトリではありません。 +gitリポジトリのディレクトリで実行してください。 +``` + +### 無効なサブコマンド +$ARGUMENTSに無効なサブコマンドが指定された場合、AskUserQuestionでモードを選択します。 + +## 参考情報 + +詳細な使用例は `assets/examples.md`、技術リファレンスは `assets/reference.md` を参照してください。 diff --git a/.claude/skills/git/assets/examples.md b/.claude/skills/git/assets/examples.md new file mode 100644 index 0000000..dea3e0e --- /dev/null +++ b/.claude/skills/git/assets/examples.md @@ -0,0 +1,506 @@ +# Gitスキル - 使用例 + +このドキュメントでは、gitスキルの実際の使用例を紹介します。 + +## 基本的な使用例 + +### 1. 作業ブランチ作成 + +#### シナリオ: mainブランチから新機能開発用のブランチを作成 + +```bash +# mainブランチにいることを確認 +git branch --show-current +# main + +# 作業ブランチを作成 +/git branch-create +``` + +**実行内容**: +1. mainブランチであることを確認 +2. 作業ツリーがクリーンであることを確認 +3. 作業目的をヒアリング(新機能、バグ修正等) +4. ブランチ名を3つ提案 +5. ユーザーが選択したブランチ名で作成 + +**対話例**: +``` +質問: このブランチで何を実装・修正しますか? +→ 「新機能の追加」を選択 + +詳細を教えてください。 +→ 「ユーザー認証機能」と入力 + +ブランチ名を選択してください。 +→ 「add-user-auth」を選択(推奨) +``` + +**出力例**: +``` +## 作業ブランチ作成完了 + +**ブランチ名**: add-user-auth +**ベースブランチ**: main + +作業を開始できます。 +変更をコミットする際は `/git commit` を使用してください。 +``` + +### 2. コミット・プッシュ + +#### シナリオ: 変更をConventional Commits形式でコミットしてプッシュ + +```bash +# 作業ブランチで変更を加える +# (コードを書く) + +# コミット +/git commit +``` + +**実行内容**: +1. 変更を分析(git status、git diff) +2. Conventional Commits形式のメッセージを自動生成 +3. ユーザーに確認 +4. 機密ファイルを除外してステージング +5. コミット・プッシュ + +**対話例**: +``` +以下のメッセージでコミットします。よろしいですか? + +feat: ユーザー認証機能を追加 + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) + +変更ファイル: +- src/auth/login.ts +- src/auth/register.ts +- src/types/user.ts + +→ 「はい、コミットする」を選択 +``` + +**出力例**: +``` +## コミット完了 + +**ブランチ**: add-user-auth +**コミットメッセージ**: feat: ユーザー認証機能を追加 +**変更ファイル**: 3件 + +変更がリモートにプッシュされました。 +``` + +### 3. ブランチ削除 + +#### シナリオ: マージ済みブランチを削除 + +```bash +# 任意のブランチから実行 +/git branch-delete +``` + +**実行内容**: +1. マージ済みブランチの一覧を取得 +2. ユーザーに削除対象を選択させる +3. mainブランチに切り替え +4. リモートとローカルのブランチを削除 + +**対話例**: +``` +削除するブランチを選択してください。 +→ 「add-user-auth」を選択(マージ済み) +``` + +**出力例**: +``` +## ブランチ削除完了 + +**削除したブランチ**: add-user-auth + +### 実行内容 +- リモートブランチ 'origin/add-user-auth' を削除しました +- ローカルブランチ 'add-user-auth' を削除しました +- mainブランチに切り替えました +- 最新のコードを取得しました +``` + +#### シナリオ: 特定のブランチを指定して削除 + +```bash +# ブランチ名を指定 +/git branch-delete old-feature +``` + +**実行内容**: +1. 指定されたブランチがマージ済みか確認 +2. マージ済みの場合のみ削除 + +### 4. ワークツリー作成 + +#### シナリオ: 緊急バグ修正のためのワークツリーを作成 + +```bash +# メインリポジトリで実行 +/git worktree-create +``` + +**実行内容**: +1. 作業目的をヒアリング +2. ブランチ名を3つ提案 +3. ワークツリーパスを決定(`{親ディレクトリ}/{リポジトリ名}-{ブランチ名}`) +4. ユーザーに確認してワークツリーを作成 + +**対話例**: +``` +このワークツリーで何を実装・修正しますか? +→ 「バグ修正」を選択 + +詳細を教えてください。 +→ 「ログイン画面のバグ」と入力 + +ブランチ名を選択してください。 +→ 「fix-login-page」を選択 + +以下のパスにワークツリーを作成します。よろしいですか? +パス: /nab-agents- +ブランチ: fix-login-page +ベース: main +→ 「はい、作成する」を選択 +``` + +**出力例**: +``` +## ワークツリー作成完了 + +**パス**: /nab-agents- +**ブランチ**: fix-login-page +**ベースブランチ**: main + +### 移動コマンド +cd /nab-agents- + +移動後、作業を開始できます。 +変更をコミットする際は `/git commit` を使用してください。 +``` + +### 5. ワークツリー削除 + +#### シナリオ: 作業完了後のワークツリーを削除 + +```bash +# 任意の場所から実行 +/git worktree-delete +``` + +**実行内容**: +1. 既存のワークツリー一覧を表示 +2. ユーザーに削除対象を選択させる +3. 未コミット変更がある場合は警告 +4. ワークツリーを削除 +5. マージ済みブランチの削除を提案 + +**対話例**: +``` +削除するワークツリーを選択してください。 +→ 「/nab-agents-」を選択 + +ブランチ「fix-login-page」はマージ済みです。 +このブランチも削除しますか? +→ 「はい、削除する」を選択(ローカルとリモートから削除) +``` + +**出力例**: +``` +## ワークツリー削除完了 + +**削除したワークツリー**: /nab-agents- +**ブランチ**: fix-login-page + +### 実行内容 +- ワークツリー '/nab-agents-' を削除しました +- ローカルブランチ 'fix-login-page' を削除しました +- リモートブランチ 'origin/fix-login-page' を削除しました +``` + +#### シナリオ: 特定のワークツリーを指定して削除 + +```bash +# ワークツリーパスを指定 +/git worktree-delete /nab-agents- +``` + +## 高度な使用例 + +### 6. 機密ファイルの自動除外 + +#### シナリオ: .envファイルが含まれる変更をコミット + +```bash +# .envファイルを含む変更 +/git commit +``` + +**実行内容**: +1. 機密ファイル(.env)を検出 +2. 警告を表示 +3. 機密ファイルを除外してコミット + +**出力例**: +``` +警告: 以下の機密ファイルが含まれています: +- .env +- config/secrets.yml + +これらのファイルはコミットから除外されます。 + +## コミット完了 + +**ブランチ**: add-feature +**コミットメッセージ**: feat: 新機能を追加 +**変更ファイル**: 5件(機密ファイル2件を除外) +``` + +### 7. 未コミット変更があるワークツリーの削除 + +#### シナリオ: 変更を保存せずにワークツリーを削除 + +```bash +/git worktree-delete /nab-agents- +``` + +**実行内容**: +1. 未コミット変更を検出 +2. 警告を表示してユーザーに確認 + +**対話例**: +``` +ワークツリー「/nab-agents-」に未コミットの変更があります。 +削除すると、これらの変更は失われます。本当に削除しますか? + +変更一覧: +M src/experimental.ts +?? src/test.ts + +→ 「はい、削除する」または「いいえ、キャンセル」を選択 +``` + +### 8. プッシュ失敗時の自動リカバリ + +#### シナリオ: リモートに新しいコミットがありプッシュが失敗 + +```bash +/git commit +``` + +**実行内容**: +1. コミット成功 +2. プッシュ失敗(rejected) +3. 自動的にrebaseして再プッシュ + +**出力例**: +``` +コミット完了。リモートにプッシュ中... +リモートに新しいコミットがあります。rebaseして再プッシュします... + +## コミット完了 + +**ブランチ**: add-feature +**コミットメッセージ**: feat: 新機能を追加 +**変更ファイル**: 3件 + +変更がリモートにプッシュされました。 +``` + +## エラー時の対応例 + +### ケース1: main以外から作業ブランチを作成しようとした + +```bash +git checkout feature-branch +/git branch-create +``` + +**出力**: +``` +エラー: 作業ブランチはmainブランチから作成してください。 +現在のブランチ: feature-branch + +mainブランチに切り替えるには: +git checkout main +``` + +### ケース2: 未マージブランチを削除しようとした + +```bash +/git branch-delete unmerged-branch +``` + +**出力**: +``` +エラー: ブランチ「unmerged-branch」はまだマージされていません。 + +マージされていないブランチを削除する場合は、手動で強制削除してください: +git branch -D unmerged-branch + +注意: 強制削除すると、マージされていない変更が失われます。 +``` + +### ケース3: 変更がない状態でコミットしようとした + +```bash +/git commit +``` + +**出力**: +``` +エラー: コミットする変更がありません。 + +現在の状態を確認: +git status +``` + +### ケース4: ブランチ名が既に存在 + +```bash +/git branch-create +# → ブランチ名「add-feature」を選択 +``` + +**出力**: +``` +エラー: ブランチ「add-feature」は既に存在します。 + +別のブランチ名を使用するか、既存ブランチを削除してください: +git branch -d add-feature +``` + +## 実際のワークフロー例 + +### フルサイクル: 機能開発からマージまで + +```bash +# 1. 作業ブランチを作成 +/git branch-create +# → 「新機能の追加」→「ユーザープロフィール機能」→「add-user-profile」 + +# 2. 機能を実装 +# (コードを書く) + +# 3. コミット +/git commit +# → コミット完了、自動プッシュ + +# 4. MRを作成 +/mr create +# → MR作成完了 + +# 5. レビューコメントに対応 +/mr resolve +# → 修正完了、リプライ送信 + +# 6. マージ +/mr merge +# → マージ完了 + +# 7. ブランチを削除 +/git branch-delete +# → ブランチ削除完了 +``` + +### ワークツリーを使った並行作業 + +```bash +# メインリポジトリで機能A開発中 +cd /nab-agents +# ブランチ: add-feature-a + +# 緊急バグ修正のためワークツリー作成 +/git worktree-create +# → fix-critical-bug ワークツリー作成 + +# ワークツリーに移動してバグ修正 +cd /nab-agents- +# (バグを修正) +/git commit +/mr create +/mr merge + +# ワークツリーを削除 +/git worktree-delete +# → ワークツリー削除完了 + +# メインリポジトリに戻って機能A開発を続行 +cd /nab-agents +# (機能Aの開発を続ける) +``` + +### 複数ブランチの並行開発 + +```bash +# メインリポジトリ: feature-a開発 +cd /nab-agents +git checkout add-feature-a + +# ワークツリー1: feature-b開発 +/git worktree-create +# → /nab-agents- + +# ワークツリー2: feature-c開発 +/git worktree-create +# → /nab-agents- + +# それぞれで独立して作業 +# 各ワークツリーで /git commit, /mr create を実行 + +# 作業完了後、ワークツリーを削除 +/git worktree-delete +# → feature-b, feature-c のワークツリーを順次削除 +``` + +## チーム開発でのヒント + +1. **ブランチ命名規則**: + - `add-`: 新機能追加 + - `fix-`: バグ修正 + - `refactor-`: リファクタリング + - `docs-`: ドキュメント更新 + +2. **コミットの粒度**: + - 目的単位でコミット + - 大きな変更は複数のコミットに分割 + - `/git commit` で自動的に適切なメッセージが生成される + +3. **ワークツリーの活用**: + - 緊急バグ修正: 作業中のブランチを残してワークツリーで修正 + - 並行開発: 複数の機能を同時進行 + - レビュー対応: メインの作業を残してワークツリーでレビュー対応 + +4. **ブランチのクリーンアップ**: + - MRマージ後は `/git branch-delete` で定期的にクリーンアップ + - マージ済みブランチのみ削除される(安全) + +## カスタマイズ例 + +### プロジェクト固有のワークフロー + +プロジェクトによっては、SKILL.mdをフォークして以下のようなカスタマイズが可能です: + +1. **ブランチ命名規則のカスタマイズ**: + - チケット番号を含める(例: `PROJ-123-add-feature`) + - チーム名をプレフィックスに追加 + +2. **コミットメッセージテンプレート**: + - プロジェクト固有のルールを追加 + - Jiraチケット番号の自動挿入 + +3. **自動テスト実行**: + - コミット前に自動的にテストを実行 + - テストが失敗した場合はコミットを中断 + +4. **通知の追加**: + - Slack等への通知をフックで実装 + +詳細なカスタマイズ方法は、Claude Codeの公式ドキュメントを参照してください。 diff --git a/.claude/skills/git/assets/reference.md b/.claude/skills/git/assets/reference.md new file mode 100644 index 0000000..6b731b9 --- /dev/null +++ b/.claude/skills/git/assets/reference.md @@ -0,0 +1,579 @@ +# Gitスキル - 詳細リファレンス + +このドキュメントは、gitスキルの詳細な技術仕様とワークフローを記載します。 + +## 目次 + +1. [Git用語説明](#git用語説明) +2. [ブランチ命名規則](#ブランチ命名規則) +3. [Conventional Commits形式](#conventional-commits形式) +4. [機密ファイルの検出ロジック](#機密ファイルの検出ロジック) +5. [ワークツリーの仕組み](#ワークツリーの仕組み) +6. [エラーハンドリング詳細](#エラーハンドリング詳細) +7. [トラブルシューティング](#トラブルシューティング) +8. [ベストプラクティス](#ベストプラクティス) + +## Git用語説明 + +### ブランチ関連 +- **作業ブランチ**: 機能開発やバグ修正のために作成するブランチ +- **mainブランチ**: メインの開発ブランチ(masterとも呼ばれる) +- **マージ済みブランチ**: mainブランチにマージされたブランチ +- **未マージブランチ**: mainブランチにマージされていないブランチ + +### コミット関連 +- **ステージング**: コミット対象のファイルを選択する操作 +- **コミット**: 変更をローカルリポジトリに記録する操作 +- **プッシュ**: ローカルの変更をリモートリポジトリに送信する操作 +- **HEREDOC**: シェルスクリプトで複数行の文字列を扱う記法 + +### ワークツリー関連 +- **メインワークツリー**: 元のリポジトリディレクトリ +- **ワークツリー**: 同じリポジトリの別ディレクトリ(並行作業用) +- **ワークツリーパス**: ワークツリーが作成されるディレクトリのパス + +## ブランチ命名規則 + +### プレフィックス + +| プレフィックス | 用途 | 例 | +|--------------|------|-----| +| `add-` | 新機能の追加 | `add-user-auth` | +| `fix-` | バグ修正 | `fix-login-page` | +| `refactor-` | リファクタリング | `refactor-api-layer` | +| `update-` | 既存機能の更新・改善 | `update-user-settings` | +| `docs-` | ドキュメント更新 | `docs-setup-guide` | +| `test-` | テストの追加・修正 | `test-auth-logic` | +| `chore-` | ビルド、設定等の変更 | `chore-update-deps` | + +### 命名ルール + +1. **小文字のみ**: すべて小文字で記述 +2. **英数字とハイフン**: 使用可能な文字は`a-z`, `0-9`, `-`のみ +3. **プレフィックス必須**: 作業内容を表すプレフィックスを付ける +4. **簡潔に**: 3-5単語程度、最大50文字以内 +5. **説明的**: ブランチの目的が分かる名前にする + +### 良い例・悪い例 + +**良い例**: +- `add-user-profile` - 明確で簡潔 +- `fix-login-timeout` - バグの内容が分かる +- `refactor-database-layer` - リファクタリング対象が明確 + +**悪い例**: +- `feature` - 内容が不明 +- `Add-User-Profile` - 大文字を使用している +- `add_user_profile` - アンダースコアを使用している +- `add-a-new-feature-for-user-profile-management` - 長すぎる + +## Conventional Commits形式 + +### コミットタイプ + +| タイプ | 説明 | 例 | +|--------|------|-----| +| `feat` | 新機能の追加 | `feat: ユーザー認証機能を追加` | +| `fix` | バグ修正 | `fix: ログイン時のセッションタイムアウトを修正` | +| `refactor` | リファクタリング | `refactor: API層のエラーハンドリングを改善` | +| `update` | 既存機能の更新・改善 | `update: ユーザー設定画面のUIを改善` | +| `docs` | ドキュメント更新 | `docs: READMEにセットアップ手順を追加` | +| `test` | テストの追加・修正 | `test: ユーザー認証のテストを追加` | +| `chore` | ビルド、設定等の変更 | `chore: 依存パッケージを最新化` | + +### メッセージ形式 + +``` +{type}: {目的・意図を表す簡潔な説明} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +``` + +### メッセージ生成ルール + +1. **1行目(タイトル)**: + - 50文字以内を目標(最大70文字) + - 日本語で記述 + - 目的または意図が伝わる内容にする + - 「〜を追加」「〜を修正」など、動作を明確に + +2. **Co-Authored-By**: + - 2行目は空行 + - 3行目にClaude署名を追加 + +### 生成例 + +**変更内容**: ユーザー認証機能の実装 +``` +feat: ユーザー認証機能を追加 + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +``` + +**変更内容**: ログインバグ修正 +``` +fix: ログイン時のセッションタイムアウトを修正 + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +``` + +**変更内容**: API層のリファクタリング +``` +refactor: API層のエラーハンドリングを改善 + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +``` + +## 機密ファイルの検出ロジック + +### 検出パターン + +gitスキルは以下のパターンに一致するファイルを自動的に機密ファイルとして検出します: + +#### 環境変数ファイル +``` +.env +.env.* +.env.local +.env.production +.env.development +``` + +#### 認証情報ファイル +``` +*credentials* +*secret* +*password* +config/credentials.yml.enc +config/secrets.yml +``` + +#### 鍵ファイル +``` +*.key +*.pem +*.p12 +*.pfx +id_rsa +id_rsa.pub +``` + +#### データベース設定 +``` +config/database.yml +database.yml +``` + +#### その他 +``` +.npmrc (認証トークンを含む場合) +.pypirc +.dockercfg +.docker/config.json +``` + +### 検出時の動作 + +1. **警告表示**: 機密ファイルが検出されたことをユーザーに通知 +2. **自動除外**: コミット対象から自動的に除外 +3. **処理継続**: 他のファイルは通常通りコミット + +### 例外処理 + +機密ファイルを意図的にコミットしたい場合は、手動でコミットしてください: + +```bash +git add .env.example # サンプルファイルは問題ない +git commit -m "chore: 環境変数のサンプルを追加" +``` + +## ワークツリーの仕組み + +### ワークツリーとは + +ワークツリーは、同じGitリポジトリの異なるブランチを別のディレクトリで操作できる機能です。 + +### メリット + +1. **並行作業**: 複数の機能を同時に開発できる +2. **緊急対応**: 作業中のブランチを保持したまま、別ブランチで緊急バグ修正 +3. **レビュー対応**: メインの作業を中断せずに、レビュー対応を行える + +### ディレクトリ構造 + +``` +/home/user/work/ +├── nab-agents/ # メインワークツリー (mainブランチ) +├── nab-agents-add-feature/ # ワークツリー1 (add-featureブランチ) +└── nab-agents-fix-bug/ # ワークツリー2 (fix-bugブランチ) +``` + +### パス命名規則 + +```bash +{親ディレクトリ}/{リポジトリ名}-{ブランチ名} +``` + +例: +- メインリポジトリ: `/home/user/work/nab-agents` +- ワークツリー: `/home/user/work/nab-agents-add-user-auth` + +### ワークツリーのライフサイクル + +1. **作成**: `/git worktree-create` + - mainブランチから新しいブランチを作成 + - 指定パスにワークツリーを作成 + +2. **作業**: 通常のGit操作が可能 + - `/git commit` でコミット + - `/mr create` でMR作成 + +3. **削除**: `/git worktree-delete` + - ワークツリーディレクトリを削除 + - 必要に応じてブランチも削除 + +### ワークツリーの制限 + +1. **同じブランチを複数のワークツリーで使用不可** +2. **ディスク容量**: ワークツリーごとにファイルが複製される +3. **.gitディレクトリ**: メインリポジトリと共有される + +## エラーハンドリング詳細 + +### ブランチ作成時のエラー + +#### main以外のブランチから実行 + +```bash +# エラー +/git branch-create +# 現在: feature-branch + +# 対応 +git checkout main +/git branch-create +``` + +#### 未コミット変更がある + +```bash +# エラー +/git branch-create +# 変更あり + +# 対応方法1: コミット +/git commit + +# 対応方法2: stash +git stash +/git branch-create +git stash pop +``` + +#### ブランチ名が既に存在 + +```bash +# エラー +/git branch-create +# ブランチ名「add-feature」選択 → 既に存在 + +# 対応方法1: 別の名前を使用 +/git branch-create +# → "Other"で別の名前を入力 + +# 対応方法2: 既存ブランチを削除 +git branch -d add-feature +/git branch-create +``` + +### コミット時のエラー + +#### 変更がない + +```bash +# エラー +/git commit +# 変更なし + +# 対応 +# ファイルを編集してから実行 +``` + +#### プッシュ失敗(rejected) + +```bash +# エラー +/git commit +# プッシュ失敗: リモートに新しいコミットがある + +# 自動対応 +# → rebaseして再プッシュ +``` + +#### プッシュ失敗(コンフリクト) + +```bash +# エラー +/git commit +# rebase失敗: コンフリクト + +# 対応 +git status # コンフリクトファイルを確認 +# コンフリクトを手動で解決 +git add {resolved_files} +git rebase --continue +git push +``` + +### ブランチ削除時のエラー + +#### 未マージブランチの削除試行 + +```bash +# エラー +/git branch-delete unmerged-branch + +# 対応方法1: マージしてから削除 +git checkout main +git merge unmerged-branch +/git branch-delete unmerged-branch + +# 対応方法2: 強制削除(注意) +git branch -D unmerged-branch +``` + +#### mainブランチの削除試行 + +```bash +# エラー +/git branch-delete main + +# 対応 +# mainブランチは削除できません +``` + +### ワークツリー削除時のエラー + +#### 未コミット変更がある + +```bash +# 警告 +/git worktree-delete /path/to/worktree +# 未コミット変更あり + +# 対応方法1: キャンセルしてコミット +cd /path/to/worktree +/git commit +/git worktree-delete /path/to/worktree + +# 対応方法2: 変更を破棄して削除 +# → AskUserQuestionで「はい、削除する」を選択 +``` + +#### ワークツリーが見つからない + +```bash +# エラー +/git worktree-delete /invalid/path + +# 対応 +git worktree list # 一覧を確認 +/git worktree-delete # 引数なしで選択 +``` + +## トラブルシューティング + +### スキルが起動しない + +1. **gitリポジトリか確認**: + ```bash + git status + # Not a git repository → gitリポジトリではない + ``` + +2. **サブコマンドの確認**: + ```bash + /git branch-create # 正しい + /git create # 間違い(無効なサブコマンド) + ``` + +### ブランチが作成できない + +1. **カレントブランチを確認**: + ```bash + git branch --show-current + # main以外 → mainに切り替える + ``` + +2. **作業ツリーの状態を確認**: + ```bash + git status + # 変更あり → コミットまたはstash + ``` + +3. **リモートの状態を確認**: + ```bash + git fetch origin main + git status + # behind → pullが必要 + ``` + +### コミットができない + +1. **変更があるか確認**: + ```bash + git status + # nothing to commit → 変更なし + ``` + +2. **機密ファイルが含まれている**: + - 自動的に除外される + - 意図的にコミットしたい場合は手動で実行 + +3. **プッシュが失敗する**: + ```bash + git pull --rebase origin {branch} + # コンフリクトを解決 + git push + ``` + +### ブランチが削除できない + +1. **マージ済みか確認**: + ```bash + git branch --merged main + # リストに含まれない → 未マージ + ``` + +2. **mainブランチではないか確認**: + ```bash + # mainブランチは削除不可 + ``` + +3. **リモートブランチが削除できない**: + ```bash + # 権限を確認 + # リポジトリへの書き込み権限が必要 + ``` + +### ワークツリーが作成できない + +1. **パスが既に存在する**: + ```bash + ls /home/user/work/nab-agents-add-feature + # 既に存在 → 別の名前を使用 + ``` + +2. **ブランチ名が既に存在する**: + ```bash + git branch --list add-feature + # 既に存在 → 別の名前を使用 + ``` + +3. **ディスク容量不足**: + ```bash + df -h + # ディスク容量を確認 + ``` + +### ワークツリーが削除できない + +1. **メインワークツリーではないか確認**: + ```bash + git worktree list + # 最初の行はメインワークツリー(削除不可) + ``` + +2. **削除に失敗する**: + ```bash + git worktree remove --force {path} + # それでも失敗する場合 + rm -rf {path} + git worktree prune + ``` + +## ベストプラクティス + +### ブランチ管理 + +1. **命名規則を統一**: チーム全体で統一したプレフィックスを使用 +2. **定期的なクリーンアップ**: マージ済みブランチは定期的に削除 +3. **mainから分岐**: 作業ブランチは常にmainから分岐 +4. **小さなブランチ**: 1つのブランチで1つの目的を達成 + +### コミット管理 + +1. **目的単位でコミット**: 複数の目的を1つのコミットにしない +2. **頻繁にコミット**: 作業の節目ごとにコミット +3. **プッシュを忘れずに**: コミット後は忘れずにプッシュ +4. **機密情報の除外**: .envファイル等は.gitignoreに追加 + +### ワークツリー管理 + +1. **用途を明確に**: 緊急バグ修正、並行開発など、目的を明確に +2. **作業完了後は削除**: 不要なワークツリーは残さない +3. **ディスク容量を考慮**: 大規模プロジェクトでは容量に注意 +4. **ブランチの整理**: ワークツリー削除時にブランチも整理 + +### チーム開発 + +1. **ブランチ戦略の共有**: チームで統一した運用ルールを決める +2. **コミットメッセージの品質**: 他のメンバーが理解できる内容に +3. **レビュー前のセルフチェック**: `/git commit`後、diffを確認 +4. **定期的なmainへのマージ**: 長期間放置しない + +### 安全性 + +1. **強制操作は慎重に**: `-D`, `--force`等は使用しない(スキルも使わない) +2. **バックアップの取得**: 重要な変更前はバックアップブランチを作成 +3. **テストの実行**: コミット前に関連テストを実行 +4. **段階的な変更**: 大きな変更は複数のコミットに分割 + +### パフォーマンス + +1. **不要なファイルを除外**: .gitignoreを適切に設定 +2. **大きなファイルを避ける**: バイナリファイルはGit LFSを使用 +3. **ワークツリーの数を制限**: 同時に使用するワークツリーは3-4個まで +4. **定期的なgc**: `git gc`でリポジトリを最適化 + +## 高度な使用例 + +### フック活用 + +プロジェクトのニーズに応じて、gitフックを活用できます: + +```bash +# .git/hooks/pre-commit +# コミット前にテストを実行 +npm test || exit 1 +``` + +### エイリアス設定 + +よく使うコマンドをエイリアスに設定: + +```bash +# ~/.bashrc または ~/.zshrc +alias gbc='/git branch-create' +alias gc='/git commit' +alias gbd='/git branch-delete' +alias gwc='/git worktree-create' +alias gwd='/git worktree-delete' +``` + +### CI/CD連携 + +GitLab CI/CDと連携して、自動テスト・デプロイを実現: + +```yaml +# .gitlab-ci.yml +test: + script: + - npm test + +deploy: + script: + - npm run deploy + only: + - main +``` diff --git a/.claude/skills/git/workflows/branch-create.md b/.claude/skills/git/workflows/branch-create.md new file mode 100644 index 0000000..b50a6d7 --- /dev/null +++ b/.claude/skills/git/workflows/branch-create.md @@ -0,0 +1,173 @@ +# 作業ブランチ作成ワークフロー + +このワークフローは、mainブランチから作業ブランチを作成します。 + +## 必要なツール + +- Bash +- AskUserQuestion + +## 実行ステップ + +### 1. 事前確認 + +**1.1 カレントブランチの確認** + +```bash +git branch --show-current +``` + +カレントブランチが`main`でない場合はエラー終了: +``` +エラー: 作業ブランチはmainブランチから作成してください。 +現在のブランチ: {current_branch} + +mainブランチに切り替えるには: +git checkout main +``` + +**1.2 ワーキングツリーの確認** + +```bash +git status --porcelain +``` + +未コミットの変更がある場合はエラー終了: +``` +エラー: 未コミットの変更があります。 +変更をコミットまたはstashしてから実行してください。 + +変更を確認: +git status + +変更をstash: +git stash +``` + +**1.3 リモートの最新化** + +```bash +git fetch origin main +git pull origin main +``` + +pullが失敗(conflict)した場合: +``` +エラー: mainブランチの更新に失敗しました。 +コンフリクトを解決してから実行してください。 +``` + +### 2. ブランチ名の提案 + +**2.1 作業目的のヒアリング** + +AskUserQuestionで作業目的をヒアリング: + +``` +質問: このブランチで何を実装・修正しますか? +header: "作業内容" +options: + - label: "新機能の追加" + description: "新しい機能を実装する" + - label: "バグ修正" + description: "既存のバグを修正する" + - label: "リファクタリング" + description: "コードの構造を改善する" + - label: "ドキュメント更新" + description: "ドキュメントを更新する" +``` + +**2.2 詳細のヒアリング** + +選択された作業内容に応じて、詳細をヒアリング(自由入力): +``` +「{作業内容}」の詳細を教えてください。 +例: ユーザー認証機能、ログイン画面のバグ、API層のリファクタリング等 +``` + +**2.3 ブランチ名の生成** + +ヒアリングした内容から、3つのブランチ名候補を生成: + +**生成ルール**: +- プレフィックス: `add-`(新機能), `fix-`(バグ修正), `refactor-`(リファクタリング), `docs-`(ドキュメント) +- 本体: 詳細から抽出したキーワードを`-`で連結 +- 全て小文字、英数字とハイフンのみ + +**例**: +- 詳細: "ユーザー認証機能を追加" + - 候補1: `add-user-auth` + - 候補2: `add-authentication` + - 候補3: `user-auth-feature` + +- 詳細: "ログイン画面のバグ修正" + - 候補1: `fix-login-page` + - 候補2: `fix-login-bug` + - 候補3: `login-page-fix` + +**2.4 ブランチ名の選択** + +AskUserQuestionで候補から選択: + +``` +質問: ブランチ名を選択してください。 +header: "ブランチ名" +options: + - label: "{候補1}" + description: "推奨" + - label: "{候補2}" + description: "" + - label: "{候補3}" + description: "" +``` + +ユーザーが"Other"を選択した場合、自由入力を受け付ける。 + +**2.5 ブランチ名の重複確認** + +```bash +git branch --list "{branch_name}" +``` + +既に存在する場合はエラー終了: +``` +エラー: ブランチ「{branch_name}」は既に存在します。 + +別のブランチ名を使用するか、既存ブランチを削除してください: +git branch -d {branch_name} +``` + +### 3. ブランチ作成 + +選択されたブランチ名でブランチを作成: + +```bash +git checkout -b {branch_name} +``` + +### 4. 結果表示 + +``` +## 作業ブランチ作成完了 + +**ブランチ名**: {branch_name} +**ベースブランチ**: main + +作業を開始できます。 +変更をコミットする際は `/git commit` を使用してください。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| main以外のブランチから実行 | mainブランチに切り替えるよう案内 | +| 未コミットの変更がある | コミットまたはstashするよう案内 | +| mainの更新に失敗 | コンフリクトを解決するよう案内 | +| ブランチ名が既に存在 | 別の名前を使用するか、既存ブランチを削除するよう案内 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **ブランチ名の品質**: ユーザーの入力から適切なブランチ名を生成する +3. **安全性**: mainブランチの保護、重複チェック、作業ツリーのクリーン確認 diff --git a/.claude/skills/git/workflows/branch-delete.md b/.claude/skills/git/workflows/branch-delete.md new file mode 100644 index 0000000..476be2e --- /dev/null +++ b/.claude/skills/git/workflows/branch-delete.md @@ -0,0 +1,157 @@ +# ブランチ削除ワークフロー + +このワークフローは、マージ済みブランチをローカルとリモートから削除します。 + +## 必要なツール + +- Bash +- AskUserQuestion + +## 実行ステップ + +### 1. 削除対象ブランチの決定 + +**1.1 引数の確認** + +引数が指定されている場合、それを削除対象とする。 +引数がない場合、次のステップでユーザーに選択させる。 + +**1.2 削除可能なブランチの取得** + +```bash +git branch --merged main +``` + +結果からmainブランチを除外し、削除可能なブランチのリストを作成。 + +ブランチがない場合: +``` +情報: 削除可能なマージ済みブランチがありません。 + +マージ済みブランチの一覧を確認: +git branch --merged main +``` + +**1.3 削除対象の選択(引数がない場合)** + +AskUserQuestionでブランチを選択: + +``` +質問: 削除するブランチを選択してください。 +header: "ブランチ削除" +options: + - label: "{branch1}" + description: "マージ済み" + - label: "{branch2}" + description: "マージ済み" + - label: "{branch3}" + description: "マージ済み" +``` + +### 2. 削除前チェック + +**2.1 mainブランチの保護** + +削除対象が`main`または`master`の場合はエラー終了: +``` +エラー: mainブランチは削除できません。 +``` + +**2.2 マージ済み確認** + +```bash +git branch --merged main | grep "^ {branch_name}$" +``` + +マージされていない場合はエラー終了: +``` +エラー: ブランチ「{branch_name}」はまだマージされていません。 + +マージされていないブランチを削除する場合は、手動で強制削除してください: +git branch -D {branch_name} + +注意: 強制削除すると、マージされていない変更が失われます。 +``` + +**2.3 カレントブランチの確認** + +```bash +git branch --show-current +``` + +カレントブランチが削除対象の場合、mainブランチに切り替え: +```bash +git checkout main +``` + +### 3. mainブランチの更新 + +```bash +git fetch origin main +git pull origin main +``` + +### 4. ブランチの削除 + +**4.1 リモートブランチの削除** + +```bash +git push origin --delete {branch_name} +``` + +リモートブランチが存在しない場合のエラーは無視(警告のみ表示): +``` +警告: リモートブランチ「{branch_name}」は既に削除されています。 +``` + +権限エラーの場合: +``` +エラー: リモートブランチの削除に失敗しました。 +リポジトリへの書き込み権限を確認してください。 + +ローカルブランチのみ削除する場合: +git branch -d {branch_name} +``` + +**4.2 ローカルブランチの削除** + +```bash +git branch -d {branch_name} +``` + +### 5. リモートブランチ情報の更新 + +```bash +git fetch --prune +``` + +### 6. 結果表示 + +``` +## ブランチ削除完了 + +**削除したブランチ**: {branch_name} + +### 実行内容 +- リモートブランチ 'origin/{branch_name}' を削除しました +- ローカルブランチ '{branch_name}' を削除しました +- mainブランチに切り替えました +- 最新のコードを取得しました +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| 削除可能なブランチがない | マージ済みブランチを確認 | +| mainブランチの削除試行 | エラーメッセージを表示して終了 | +| 未マージブランチ | 手動での強制削除を案内 | +| リモートブランチが存在しない | 警告のみ表示してローカル削除を継続 | +| 権限不足 | リポジトリの権限を確認するよう案内 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **安全性優先**: マージ済みブランチのみ削除、未マージは強制削除を案内 +3. **mainブランチの保護**: mainブランチは削除を拒否 +4. **リモート優先**: リモートブランチを先に削除してから、ローカルブランチを削除 diff --git a/.claude/skills/git/workflows/commit.md b/.claude/skills/git/workflows/commit.md new file mode 100644 index 0000000..98bab27 --- /dev/null +++ b/.claude/skills/git/workflows/commit.md @@ -0,0 +1,188 @@ +# コミット・プッシュワークフロー + +このワークフローは、変更をコミットしてリモートにプッシュします。 + +## 必要なツール + +- Bash +- AskUserQuestion + +## 実行ステップ + +### 1. 事前確認 + +**1.1 カレントブランチの確認** + +```bash +git branch --show-current +``` + +カレントブランチが`main`または`master`の場合は警告表示(エラーではない): +``` +警告: mainブランチに直接コミットしようとしています。 +作業ブランチで作業することを推奨します。 + +続行しますか? +``` + +**1.2 変更の確認** + +```bash +git status --porcelain +``` + +変更がない場合はエラー終了: +``` +エラー: コミットする変更がありません。 + +現在の状態を確認: +git status +``` + +### 2. 変更の分析 + +**2.1 ステージングされていない変更とステージング済み変更の取得** + +```bash +git status +git diff HEAD --stat +git diff HEAD +``` + +**2.2 機密ファイルのチェック** + +変更ファイルリストから以下のパターンを検出: +- `.env`, `.env.*` +- `*credentials*`, `*secret*`, `*password*` +- `*.key`, `*.pem` +- `config/database.yml`, `config/secrets.yml` + +機密ファイルが含まれる場合は警告: +``` +警告: 以下の機密ファイルが含まれています: +- {file1} +- {file2} + +これらのファイルはコミットから除外されます。 +``` + +**2.3 コミット対象ファイルの決定** + +機密ファイルを除外したファイルリストを作成。 + +### 3. コミットメッセージの生成 + +**3.1 変更内容の分析** + +diffとファイル名から以下を判定: +- **変更タイプ**: feat, fix, refactor, update, docs, test, chore +- **変更対象**: 主要な変更対象(ファイル名やdiffから抽出) +- **変更の目的**: diffの内容から推測 + +**3.2 メッセージの生成** + +Claude.mdのルール「目的または意図が伝わるタイトル」に従い、以下の形式で生成: + +``` +{type}: {目的・意図を表す簡潔な説明} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +``` + +**タイプ別の例**: +- `feat: ユーザー認証機能を追加` +- `fix: ログイン時のセッションタイムアウトを修正` +- `refactor: API層のエラーハンドリングを改善` +- `update: ユーザー設定画面のUIを改善` +- `docs: READMEにセットアップ手順を追加` + +**生成ルール**: +- 1行目は50文字以内を目標(最大70文字) +- 日本語で記述 +- 「〜を追加」「〜を修正」など、動作を明確に +- 技術的な詳細は不要(タイトルのみ) + +### 4. コミットの実行 + +**4.1 ファイルのステージング** + +機密ファイルを除外してステージング: + +```bash +git add {file1} {file2} {file3} ... +``` + +**重要**: `git add -A` や `git add .` は使用しない(機密ファイルの誤コミット防止) + +**4.2 コミット** + +HEREDOC形式でコミット: + +```bash +git commit -m "$(cat <<'EOF' +{commit_message} +EOF +)" +``` + +### 5. リモートへのプッシュ + +**5.1 プッシュ** + +```bash +git push -u origin {current_branch} +``` + +**5.2 プッシュ失敗時の対応** + +rejected(リモートに新しいコミットがある)場合: + +```bash +git pull --rebase origin {current_branch} +``` + +rebase中にコンフリクトが発生した場合: +``` +エラー: コンフリクトが発生しました。 +以下のファイルを手動で解決してください: +{conflict_files} + +解決後: +git add {resolved_files} +git rebase --continue +git push +``` + +rebaseが成功した場合、再度プッシュ: +```bash +git push +``` + +### 6. 結果表示 + +``` +## コミット完了 + +**ブランチ**: {current_branch} +**コミットメッセージ**: {commit_message_first_line} +**変更ファイル**: {file_count}件 + +変更がリモートにプッシュされました。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| 変更がない | ファイルを編集してから実行するよう案内 | +| 機密ファイル検出 | 自動除外して続行(警告表示) | +| コンフリクト発生 | 手動解決の手順を案内 | +| プッシュ失敗 | rebaseして再プッシュ | +| rebase失敗 | 手動解決の手順を案内 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **機密ファイルの保護**: 自動検出して除外、警告を表示 +3. **コミットメッセージの品質**: Claude.mdのルールに従い、目的・意図が伝わるタイトルを生成 +4. **安全なステージング**: `git add .` は使用せず、ファイルを個別に指定 diff --git a/.claude/skills/git/workflows/worktree-create.md b/.claude/skills/git/workflows/worktree-create.md new file mode 100644 index 0000000..947cea3 --- /dev/null +++ b/.claude/skills/git/workflows/worktree-create.md @@ -0,0 +1,203 @@ +# ワークツリー作成ワークフロー + +このワークフローは、新しいワークツリーを作成します。 + +## 必要なツール + +- Bash +- AskUserQuestion + +## 実行ステップ + +### 1. 現在のディレクトリ情報を取得 + +**1.1 カレントディレクトリとリポジトリ名を取得** + +```bash +pwd +basename $(pwd) +``` + +- カレントディレクトリ: `/nab-agents` +- リポジトリ名: `nab-agents` + +**1.2 親ディレクトリを取得** + +```bash +dirname $(pwd) +``` + +- 親ディレクトリ: `` + +### 2. ブランチ名の提案 + +**2.1 作業目的のヒアリング** + +AskUserQuestionで作業目的をヒアリング: + +``` +質問: このワークツリーで何を実装・修正しますか? +header: "作業内容" +options: + - label: "新機能の追加" + description: "新しい機能を実装する" + - label: "バグ修正" + description: "既存のバグを修正する" + - label: "リファクタリング" + description: "コードの構造を改善する" + - label: "ドキュメント更新" + description: "ドキュメントを更新する" +``` + +**2.2 詳細のヒアリング** + +選択された作業内容に応じて、詳細をヒアリング(自由入力): +``` +「{作業内容}」の詳細を教えてください。 +例: ユーザー認証機能、ログイン画面のバグ、API層のリファクタリング等 +``` + +**2.3 ブランチ名の生成** + +ヒアリングした内容から、3つのブランチ名候補を生成: + +**生成ルール**: +- プレフィックス: `add-`(新機能), `fix-`(バグ修正), `refactor-`(リファクタリング), `docs-`(ドキュメント) +- 本体: 詳細から抽出したキーワードを`-`で連結 +- 全て小文字、英数字とハイフンのみ + +**2.4 ブランチ名の選択** + +AskUserQuestionで候補から選択: + +``` +質問: ブランチ名を選択してください。 +header: "ブランチ名" +options: + - label: "{候補1}" + description: "推奨" + - label: "{候補2}" + description: "" + - label: "{候補3}" + description: "" +``` + +ユーザーが"Other"を選択した場合、自由入力を受け付ける。 + +**2.5 ブランチ名の重複確認** + +```bash +git branch --list "{branch_name}" +``` + +既に存在する場合はエラー終了: +``` +エラー: ブランチ「{branch_name}」は既に存在します。 + +別のブランチ名を使用するか、既存ブランチを削除してください: +git branch -d {branch_name} +``` + +### 3. ワークツリーパスの決定 + +**3.1 パスの生成** + +```bash +parent_dir=$(dirname $(pwd)) +repo_name=$(basename $(pwd)) +worktree_path="${parent_dir}/${repo_name}-${branch_name}" +``` + +例: +- 現在: `/nab-agents` +- ワークツリー: `/nab-agents-` + +**3.2 パスの存在確認** + +```bash +test -e {worktree_path} +``` + +既に存在する場合はエラー終了: +``` +エラー: パス「{worktree_path}」は既に存在します。 + +別のブランチ名を使用するか、既存のディレクトリを削除してください。 +``` + +**3.3 パスの確認** + +AskUserQuestionでパスを確認: + +``` +質問: 以下のパスにワークツリーを作成します。よろしいですか? +header: "パス確認" +options: + - label: "はい、作成する" + description: "{worktree_path}" + - label: "いいえ、キャンセル" + description: "" + +表示する情報: +パス: {worktree_path} +ブランチ: {branch_name} +ベース: main +``` + +### 4. ワークツリーの作成 + +**4.1 mainブランチの更新** + +```bash +git fetch origin main +git pull origin main +``` + +**4.2 ワークツリーの作成** + +```bash +git worktree add -b {branch_name} {worktree_path} main +``` + +作成に失敗した場合: +``` +エラー: ワークツリーの作成に失敗しました。 + +以下を確認してください: +- ディスク容量が十分にあること +- パスへの書き込み権限があること +- ブランチ名が有効であること +``` + +### 5. 結果表示 + +``` +## ワークツリー作成完了 + +**パス**: {worktree_path} +**ブランチ**: {branch_name} +**ベースブランチ**: main + +### 移動コマンド +cd {worktree_path} + +移動後、作業を開始できます。 +変更をコミットする際は `/git commit` を使用してください。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| ブランチ名が既に存在 | 別の名前を使用するか、既存ブランチを削除するよう案内 | +| パスが既に存在 | 別の名前を使用するか、既存ディレクトリを削除するよう案内 | +| mainの更新に失敗 | コンフリクトを解決するよう案内 | +| 権限不足 | パスへの書き込み権限を確認するよう案内 | +| 容量不足 | ディスク容量を確認するよう案内 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **パスの命名規則**: `{親ディレクトリ}/{リポジトリ名}-{ブランチ名}` +3. **ブランチ名の品質**: ユーザーの入力から適切なブランチ名を生成する +4. **ベースブランチ**: 常にmainブランチから分岐 diff --git a/.claude/skills/git/workflows/worktree-delete.md b/.claude/skills/git/workflows/worktree-delete.md new file mode 100644 index 0000000..b95500b --- /dev/null +++ b/.claude/skills/git/workflows/worktree-delete.md @@ -0,0 +1,219 @@ +# ワークツリー削除ワークフロー + +このワークフローは、既存のワークツリーを削除します。 + +## 必要なツール + +- Bash +- AskUserQuestion + +## 実行ステップ + +### 1. ワークツリー一覧の取得 + +**1.1 ワークツリーリストを取得** + +```bash +git worktree list +``` + +出力例: +``` +/nab-agents abc1234 [main] +/nab-agents- def5678 [add-feature] +/nab-agents- ghi9012 [fix-bug] +``` + +**1.2 削除可能なワークツリーの抽出** + +メインワークツリー(最初の行)を除外し、削除可能なワークツリーのリストを作成。 + +ワークツリーがない場合: +``` +情報: 削除可能なワークツリーがありません。 + +現在のワークツリー一覧: +{worktree_list} +``` + +### 2. 削除対象ワークツリーの決定 + +**2.1 引数の確認** + +引数が指定されている場合、それを削除対象とする。 +引数がない場合、次のステップでユーザーに選択させる。 + +**2.2 削除対象の選択(引数がない場合)** + +AskUserQuestionでワークツリーを選択: + +``` +質問: 削除するワークツリーを選択してください。 +header: "ワークツリー削除" +options: + - label: "{path1}" + description: "ブランチ: {branch1}" + - label: "{path2}" + description: "ブランチ: {branch2}" + - label: "{path3}" + description: "ブランチ: {branch3}" +``` + +### 3. 削除前チェック + +**3.1 メインワークツリーの保護** + +削除対象がメインワークツリー(カレントリポジトリ)の場合はエラー終了: +``` +エラー: メインワークツリーは削除できません。 +``` + +**3.2 パスの存在確認** + +```bash +test -d {worktree_path} +``` + +パスが存在しない場合はエラー終了: +``` +エラー: ワークツリー「{worktree_path}」が見つかりません。 + +ワークツリー一覧を確認: +git worktree list +``` + +**3.3 未コミット変更の確認** + +削除対象ワークツリーのステータスを確認: + +```bash +git -C {worktree_path} status --porcelain +``` + +未コミットの変更がある場合、警告を表示: + +AskUserQuestionで確認: +``` +質問: ワークツリー「{worktree_path}」に未コミットの変更があります。 +削除すると、これらの変更は失われます。本当に削除しますか? +header: "警告" +options: + - label: "はい、削除する" + description: "未コミットの変更が失われます" + - label: "いいえ、キャンセル" + description: "変更を保存してから削除してください" + +表示する変更一覧: +{git_status_output} +``` + +ユーザーが"キャンセル"を選択した場合、処理を中断: +``` +処理をキャンセルしました。 + +変更を保存するには: +cd {worktree_path} +/git commit +``` + +### 4. ワークツリーの削除 + +**4.1 ワークツリーを削除** + +```bash +git worktree remove {worktree_path} +``` + +削除に失敗した場合(ロックされている等)、強制削除: +```bash +git worktree remove --force {worktree_path} +``` + +それでも失敗した場合: +``` +エラー: ワークツリーの削除に失敗しました。 + +手動で削除してください: +rm -rf {worktree_path} +git worktree prune +``` + +### 5. ブランチの削除確認 + +**5.1 ブランチの取得** + +削除したワークツリーのブランチ名を取得。 + +**5.2 マージ済み確認** + +```bash +git branch --merged main | grep "^ {branch_name}$" +``` + +**5.3 ブランチ削除の確認** + +マージ済みの場合、AskUserQuestionでブランチ削除を確認: + +``` +質問: ブランチ「{branch_name}」はマージ済みです。 +このブランチも削除しますか? +header: "ブランチ削除" +options: + - label: "はい、削除する" + description: "ローカルとリモートから削除" + - label: "ローカルのみ削除" + description: "リモートは残す" + - label: "いいえ、残す" + description: "ブランチは残す" +``` + +**5.4 ブランチの削除** + +ユーザーの選択に応じて: + +**「はい、削除する」の場合**: +```bash +git push origin --delete {branch_name} +git branch -d {branch_name} +``` + +**「ローカルのみ削除」の場合**: +```bash +git branch -d {branch_name} +``` + +**「いいえ、残す」の場合**: +削除しない。 + +### 6. 結果表示 + +``` +## ワークツリー削除完了 + +**削除したワークツリー**: {worktree_path} +**ブランチ**: {branch_name} + +### 実行内容 +- ワークツリー '{worktree_path}' を削除しました +{ブランチ削除した場合} +- ローカルブランチ '{branch_name}' を削除しました +- リモートブランチ 'origin/{branch_name}' を削除しました +{/ブランチ削除した場合} +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| 削除可能なワークツリーがない | ワークツリー一覧を表示 | +| メインワークツリーの削除試行 | エラーメッセージを表示して終了 | +| パスが存在しない | 正しいパスを確認 | +| 未コミット変更あり | 警告を表示してユーザーに確認 | +| 削除失敗 | 強制削除を試行、それでも失敗した場合は手動削除を案内 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **安全性優先**: 未コミット変更がある場合は警告を表示 +3. **メインワークツリーの保護**: メインワークツリーは削除を拒否 +4. **ブランチ削除**: マージ済みブランチは自動的に削除を提案 From 9f33c4b409c460cedff4155193ddfe110d2abfa2 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:37:04 +0900 Subject: [PATCH 07/89] =?UTF-8?q?feat:=20PR=E7=AE=A1=E7=90=86=E3=82=B9?= =?UTF-8?q?=E3=82=AD=E3=83=AB=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) --- .claude/skills/pr/SKILL.md | 132 ++++++++++ .claude/skills/pr/assets/examples.md | 245 ++++++++++++++++++ .claude/skills/pr/assets/reference.md | 327 +++++++++++++++++++++++++ .claude/skills/pr/workflows/create.md | 126 ++++++++++ .claude/skills/pr/workflows/merge.md | 118 +++++++++ .claude/skills/pr/workflows/resolve.md | 191 +++++++++++++++ 6 files changed, 1139 insertions(+) create mode 100644 .claude/skills/pr/SKILL.md create mode 100644 .claude/skills/pr/assets/examples.md create mode 100644 .claude/skills/pr/assets/reference.md create mode 100644 .claude/skills/pr/workflows/create.md create mode 100644 .claude/skills/pr/workflows/merge.md create mode 100644 .claude/skills/pr/workflows/resolve.md diff --git a/.claude/skills/pr/SKILL.md b/.claude/skills/pr/SKILL.md new file mode 100644 index 0000000..1690398 --- /dev/null +++ b/.claude/skills/pr/SKILL.md @@ -0,0 +1,132 @@ +--- +name: pr +description: GitHub PRの作成・レビュー対応・マージを統合的に実行する。「PR作って」「レビュー対応して」「マージして」などで使用。サブコマンドで機能を指定可能(create|resolve|merge)。PR番号指定なしの場合、カレントブランチから自動検索。gh CLI必須。 +argument-hint: [create|resolve|merge] [PR番号] +allowed-tools: Bash, Task, AskUserQuestion, Read +--- + +# GitHub PR統合管理(オーケストレーター) + +このスキルは、GitHub PRに関する3つの操作を統合的に実行します: +- **create**: カレントブランチからmainへのPRを作成 +- **resolve**: レビューコメントに対して修正→コミット→リプライ +- **merge**: PRをマージし、ブランチをクリーンアップ + +各操作は、Taskツールで別コンテキストの専用ワークフローを実行します。 + +## 実行フロー + +### 1. 引数解析 + +`$ARGUMENTS`を解析してモードとPR番号を判定: + +```javascript +// パターン1: /pr → 引数なし → AskUserQuestionでモード選択 +// パターン2: /pr create → mode="create", pr_number=null +// パターン3: /pr resolve 123 → mode="resolve", pr_number=123 +// パターン4: /pr 123 → mode="resolve", pr_number=123 +// パターン5: /pr merge → mode="merge", pr_number=null +``` + +**引数なしの場合**: まずカレントブランチのPRを検索してコンテキストを取得し、AskUserQuestionツールでモードを選択: +- PR検索結果に基づいて推奨オプションを提示 +- 質問: "どのPR操作を実行しますか?" +- 選択肢(頻度順、推奨オプションを最初に表示): + 1. PRが存在する場合: "レビュー対応 (resolve) (推奨)" を最初に表示 + 2. PRが存在しない場合: "PR作成 (create) (推奨)" を最初に表示 + 3. その他の選択肢を頻度順に表示: "レビュー対応 (resolve)", "PR作成 (create)", "マージ (merge)" + +### 2. リポジトリ情報取得 + +```bash +git remote get-url origin +``` + +GitHub CLIがリポジトリ情報を自動認識。 + +### 3. PR自動検索(pr_number=nullの場合) + +カレントブランチのPRを検索: + +```bash +git branch --show-current +gh pr list --head "{current_branch}" --state open --json number,title,url --jq '.[0]' +``` + +**判定ロジック**: +- 結果が1件以上 + pr_number=null → pr_number={PR番号} +- 結果が0件 + pr_number=null → エラー(PRが見つからない場合) + +### 4. ワークフロー実行 + +modeに応じて、Taskツールで専用ワークフローを実行: + +#### A. create モード + +``` +Task + subagent_type: "general-purpose" + description: "PR作成フローを実行" + prompt: "以下のワークフローに従って、GitHub PRを作成してください。 + +{workflows/create.mdの内容を読み込んで展開} + +## 入力情報 +- カレントブランチ: {current_branch} +" +``` + +**workflows/create.mdを読み込んで実行**: Readツールで`workflows/create.md`を読み込み、その内容をpromptに含める。 + +#### B. resolve モード + +``` +Task + subagent_type: "general-purpose" + description: "レビュー対応フローを実行" + prompt: "以下のワークフローに従って、GitHub PRのレビューコメントに対応してください。 + +{workflows/resolve.mdの内容を読み込んで展開} + +## 入力情報 +- PR番号: {pr_number} +- カレントブランチ: {current_branch} +" +``` + +**workflows/resolve.mdを読み込んで実行** + +#### C. merge モード + +``` +Task + subagent_type: "general-purpose" + description: "マージフローを実行" + prompt: "以下のワークフローに従って、GitHub PRをマージしてください。 + +{workflows/merge.mdの内容を読み込んで展開} + +## 入力情報 +- PR番号: {pr_number} +" +``` + +**workflows/merge.mdを読み込んで実行** + +## 実装の注意点 + +1. **引数なしの場合**: PR検索結果に基づいて推奨オプションを提示し、AskUserQuestionでモードを選択(ユーザーフレンドリー) +2. **エラーハンドリング**: PRが見つからない場合やgh CLIが利用できない場合は、明確なエラーメッセージを表示 +3. **ブランチ確認**: mainブランチからcreateを実行しようとした場合はエラー +4. **Taskツールの使用**: 各ワークフローは別コンテキストで実行されるため、オーケストレーター側では結果を受け取るのみ + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| gh CLIが利用不可 | `gh auth login`で認証を実行 | +| GitHubリポジトリでない | GitHubリポジトリであることを確認 | +| PR番号無効/PRが見つからない | 正しいPR番号を確認する | +| mainブランチからcreate実行 | feature/issueブランチから実行するよう案内 | + +詳細な使用例は`assets/examples.md`、APIリファレンスは`assets/reference.md`を参照してください。 diff --git a/.claude/skills/pr/assets/examples.md b/.claude/skills/pr/assets/examples.md new file mode 100644 index 0000000..4224173 --- /dev/null +++ b/.claude/skills/pr/assets/examples.md @@ -0,0 +1,245 @@ +# PR スキル使用例 + +このドキュメントでは、prスキルの実際の使用例を示します。 + +## 基本的な使い方 + +### 1. PR作成 + +**最もシンプルな使用法**: +``` +/pr create +``` + +または単に: +``` +PR作って +``` + +以下のことが自動的に実行されます: +1. カレントブランチの確認 +2. コミット履歴の分析 +3. PRタイトルと説明の生成 +4. リモートへのプッシュ(必要な場合) +5. PRの作成 + +**実行例**: +``` +## PR作成完了 + +**PR**: https://github.com/owner/repo/pull/123 +**ブランチ**: feature/add-user-auth → main +**タイトル**: feat: ユーザー認証機能を追加 + +レビュアーにレビューを依頼してください。 +``` + +### 2. レビュー対応 + +**PR番号を指定**: +``` +/pr resolve 123 +``` + +**PR番号を省略(カレントブランチから自動検索)**: +``` +/pr resolve +``` + +または単に: +``` +レビュー対応して +``` + +以下のことが自動的に実行されます: +1. PRのレビューコメントを取得 +2. 各コメントを分析し、修正内容を判断 +3. ファイルを修正 +4. コミット・プッシュ +5. レビュアーにリプライ + +**実行例**: +``` +## PRレビュー対応完了 + +**PR**: https://github.com/owner/repo/pull/123 + +### 結果 +- 修正してリプライ: 3件 +- 質問してリプライ: 1件 +- スキップ: 0件 + +レビュアーによる確認をお願いします。 +``` + +### 3. マージ + +**PR番号を指定**: +``` +/pr merge 123 +``` + +**PR番号を省略(カレントブランチから自動検索)**: +``` +/pr merge +``` + +または単に: +``` +マージして +``` + +以下のことが自動的に実行されます: +1. PRの状態確認 +2. ユーザーに最終確認 +3. PRのマージ +4. リモートブランチの削除 +5. ローカルブランチの削除 +6. mainブランチへの切り替えと更新 + +**実行例**: +``` +## マージ完了 + +**PR**: https://github.com/owner/repo/pull/123 +**ブランチ**: feature/add-user-auth → main + +### 実行内容 +- PRをマージしました +- リモートブランチ 'feature/add-user-auth' を削除しました +- ローカルブランチ 'feature/add-user-auth' を削除しました +- ブランチを 'main' に切り替えました +- 最新のコードを取得しました + +お疲れ様でした。 +``` + +## 高度な使い方 + +### モード選択(引数なし) + +``` +/pr +``` + +カレントブランチの状態に応じて、推奨される操作を提示します: + +**PRが存在する場合**: +``` +どのPR操作を実行しますか? + +1. レビュー対応 (resolve) (推奨) +2. PR作成 (create) +3. マージ (merge) +``` + +**PRが存在しない場合**: +``` +どのPR操作を実行しますか? + +1. PR作成 (create) (推奨) +2. レビュー対応 (resolve) +3. マージ (merge) +``` + +### 数値のみでresolveモード + +``` +/pr 123 +``` + +PR番号を指定すると、自動的にresolveモードで実行されます。 + +## 実際のワークフロー + +### ワークフロー例1: 新機能の追加 + +``` +# 1. ブランチ作成・作業 +/git branch-create feature/add-payment + +# 2. コード編集 +(ファイルを編集) + +# 3. コミット +/git commit + +# 4. PR作成 +/pr create + +# 5. レビュー対応 +/pr resolve + +# 6. マージ +/pr merge +``` + +### ワークフロー例2: バグ修正 + +``` +# 1. ブランチ作成・作業 +/git branch-create fix/login-timeout + +# 2. コード修正 +(ファイルを編集) + +# 3. コミット・PR作成 +/git commit +/pr create + +# 4. レビュー後にマージ +/pr merge +``` + +## エラーケースの対処 + +### mainブランチから誤ってPR作成しようとした場合 + +``` +/pr create + +エラー: mainブランチからPRは作成できません。 +feature/issueブランチを作成してから実行してください。 +``` + +対処: +``` +/git branch-create feature/my-feature +/pr create +``` + +### コミットがない状態でPR作成しようとした場合 + +``` +/pr create + +エラー: mainからの新しいコミットがありません。 +変更をコミットしてから実行してください。 +``` + +対処: +``` +/git commit +/pr create +``` + +### PRが見つからない場合 + +``` +/pr resolve + +エラー: カレントブランチのPRが見つかりませんでした。 +PR番号を指定するか、正しいブランチに切り替えてください。 +``` + +対処: +``` +/pr resolve 123 +``` + +## Tips + +1. **自然言語で呼び出し**: `/pr create`の代わりに「PR作って」でもOK +2. **PR番号の省略**: カレントブランチから自動検索されるため、ほとんどの場合PR番号は不要 +3. **レビュー対応の自動化**: 明確な修正指示は自動で対応し、不明点のみ質問 +4. **一括クリーンアップ**: マージ時にリモート・ローカルブランチを自動削除 diff --git a/.claude/skills/pr/assets/reference.md b/.claude/skills/pr/assets/reference.md new file mode 100644 index 0000000..46ec0db --- /dev/null +++ b/.claude/skills/pr/assets/reference.md @@ -0,0 +1,327 @@ +# PR スキル APIリファレンス + +このドキュメントでは、prスキルの技術的な詳細を説明します。 + +## コマンド構文 + +``` +/pr [mode] [pr_number] +``` + +### パラメータ + +- `mode`: 実行モード(`create`, `resolve`, `merge`)。省略可能。 +- `pr_number`: PR番号。省略可能(カレントブランチから自動検索)。 + +### モードの判定ロジック + +```javascript +// パターン1: /pr → 引数なし +// → PR検索 → AskUserQuestionでモード選択 +if (args === null) { + const pr = searchPRForCurrentBranch(); + const mode = askUserQuestion(pr ? "resolve" : "create"); +} + +// パターン2: /pr create +// → mode="create", pr_number=null +if (args === "create") { + mode = "create"; + pr_number = null; +} + +// パターン3: /pr resolve 123 +// → mode="resolve", pr_number=123 +if (args.startsWith("resolve ")) { + mode = "resolve"; + pr_number = parseInt(args.split(" ")[1]); +} + +// パターン4: /pr 123 +// → mode="resolve", pr_number=123 +if (/^\d+$/.test(args)) { + mode = "resolve"; + pr_number = parseInt(args); +} + +// パターン5: /pr merge +// → mode="merge", pr_number=null +if (args === "merge") { + mode = "merge"; + pr_number = null; +} +``` + +## GitHub CLI コマンド + +prスキルが内部で使用するgh CLIコマンド一覧。 + +### リポジトリ情報取得 + +```bash +# リポジトリの情報を取得 +gh repo view --json defaultBranchRef,owner,name + +# デフォルトブランチ名のみ取得 +gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' +``` + +### PR一覧取得 + +```bash +# カレントブランチのPRを検索 +gh pr list --head "{branch_name}" --state open --json number,title,url --jq '.[0]' + +# 全てのopenなPRを取得 +gh pr list --state open --json number,title,headRefName,url +``` + +### PR情報取得 + +```bash +# PR詳細を取得 +gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,author,mergeable,mergeStateStatus + +# PRのコメントとレビューを取得 +gh pr view {pr_number} --json comments,reviews +``` + +### PR作成 + +```bash +gh pr create \ + --title "{title}" \ + --body "{body}" \ + --base {base_branch} \ + --head {head_branch} +``` + +### PRコメント + +```bash +gh pr comment {pr_number} --body "{comment_body}" +``` + +### PRマージ + +```bash +# Squashマージ(リモートブランチを自動削除) +gh pr merge {pr_number} --squash --delete-branch + +# 通常のマージ +gh pr merge {pr_number} --merge --delete-branch + +# Rebaseマージ +gh pr merge {pr_number} --rebase --delete-branch +``` + +## 内部データ構造 + +### PR情報 + +```json +{ + "number": 123, + "title": "feat: ユーザー認証機能を追加", + "state": "OPEN", + "headRefName": "feature/add-user-auth", + "baseRefName": "main", + "url": "https://github.com/owner/repo/pull/123", + "author": { + "login": "username" + }, + "mergeable": "MERGEABLE", + "mergeStateStatus": "CLEAN" +} +``` + +### レビュー情報 + +```json +{ + "reviews": [ + { + "author": { + "login": "reviewer" + }, + "state": "CHANGES_REQUESTED", + "body": "レビューコメント本文", + "createdAt": "2024-01-01T12:00:00Z", + "comments": [ + { + "path": "src/auth.ts", + "line": 42, + "body": "変数名をより明確にしてください" + } + ] + } + ] +} +``` + +## ワークフロー実行 + +各モードは、Taskツールで専用ワークフローを実行します。 + +### create モード + +``` +Task + subagent_type: "general-purpose" + description: "PR作成フローを実行" + prompt: """ +以下のワークフローに従って、GitHub PRを作成してください。 + +{workflows/create.mdの内容} + +## 入力情報 +- カレントブランチ: {current_branch} +""" +``` + +### resolve モード + +``` +Task + subagent_type: "general-purpose" + description: "レビュー対応フローを実行" + prompt: """ +以下のワークフローに従って、GitHub PRのレビューコメントに対応してください。 + +{workflows/resolve.mdの内容} + +## 入力情報 +- PR番号: {pr_number} +- カレントブランチ: {current_branch} +""" +``` + +### merge モード + +``` +Task + subagent_type: "general-purpose" + description: "マージフローを実行" + prompt: """ +以下のワークフローに従って、GitHub PRをマージしてください。 + +{workflows/merge.mdの内容} + +## 入力情報 +- PR番号: {pr_number} +""" +``` + +## エラーコード + +| エラーコード | 説明 | 対応 | +|------------|------|------| +| GH_AUTH_ERROR | gh CLI認証エラー | `gh auth login`を実行 | +| GH_NOT_FOUND | gh CLIが見つからない | gh CLIをインストール | +| REPO_NOT_GITHUB | GitHubリポジトリでない | GitHubリポジトリで実行 | +| BRANCH_INVALID | ブランチが不正 | 正しいブランチから実行 | +| PR_NOT_FOUND | PRが見つからない | PR番号を確認 | +| PR_CLOSED | PRがCLOSEDまたはMERGED | OPENのPRを指定 | +| PR_CONFLICT | マージコンフリクト | コンフリクトを解決 | +| NO_COMMITS | コミットがない | 変更をコミット | +| PUSH_REJECTED | プッシュが拒否された | `git pull --rebase`して再プッシュ | + +## 設定 + +prスキルは、以下の環境変数を使用できます(将来的な拡張): + +```bash +# デフォルトのマージ方法(squash/merge/rebase) +export PR_MERGE_METHOD="squash" + +# PR作成時のレビュアー自動割り当て +export PR_DEFAULT_REVIEWERS="user1,user2" + +# PR作成時のラベル自動付与 +export PR_DEFAULT_LABELS="enhancement,needs-review" +``` + +## 制限事項 + +1. **gh CLI依存**: GitHub CLIが必須 +2. **認証**: `gh auth login`で認証済みであること +3. **権限**: リポジトリへの書き込み権限が必要 +4. **ブランチ保護**: 保護ブランチへのマージは追加の権限設定が必要 +5. **レビューコメント**: ファイル単位のコメントのみ対応(行コメントも取得可能だが、複雑な場合は手動対応を推奨) + +## トラブルシューティング + +### gh CLIが見つからない + +```bash +# インストール(macOS) +brew install gh + +# インストール(Linux) +sudo apt install gh + +# 認証 +gh auth login +``` + +### 認証エラー + +```bash +# 認証状態を確認 +gh auth status + +# 再認証 +gh auth login + +# トークンを使用 +gh auth login --with-token < token.txt +``` + +### PR番号がわからない + +```bash +# カレントブランチのPRを確認 +gh pr view + +# 全てのPRを一覧表示 +gh pr list +``` + +## 開発者向け情報 + +### スキル構造 + +``` +.claude/skills/pr/ +├── SKILL.md # スキルのメタ情報とオーケストレーター +├── workflows/ +│ ├── create.md # PR作成ワークフロー +│ ├── resolve.md # レビュー対応ワークフロー +│ └── merge.md # マージワークフロー +└── assets/ + ├── examples.md # 使用例 + └── reference.md # このファイル +``` + +### 拡張方法 + +新しいモードを追加する場合: +1. `workflows/`に新しいワークフローファイルを追加 +2. `SKILL.md`の引数解析ロジックに新しいモードを追加 +3. `SKILL.md`のワークフロー実行セクションに新しいモードを追加 +4. `assets/examples.md`に使用例を追加 + +### テスト + +各ワークフローは独立しているため、個別にテスト可能: + +```bash +# PR作成のテスト +/pr create + +# レビュー対応のテスト(PRが存在する場合) +/pr resolve + +# マージのテスト(PRがマージ可能な場合) +/pr merge +``` diff --git a/.claude/skills/pr/workflows/create.md b/.claude/skills/pr/workflows/create.md new file mode 100644 index 0000000..eac4440 --- /dev/null +++ b/.claude/skills/pr/workflows/create.md @@ -0,0 +1,126 @@ +# PR作成ワークフロー + +このワークフローは、カレントブランチからmainへのPRを作成します。 + +## 必要なツール + +- Bash +- Read + +## 実行ステップ + +### 1. 事前確認 + +**1.1 カレントブランチの確認** + +```bash +git branch --show-current +``` + +カレントブランチが`main`または`master`の場合はエラー終了: +``` +エラー: mainブランチからPRは作成できません。 +feature/issueブランチを作成してから実行してください。 +``` + +**1.2 デフォルトブランチの取得** + +```bash +gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' +``` + +デフォルトブランチ名を取得(通常は"main"または"master")。 + +**1.3 コミット履歴の確認** + +```bash +git log {default_branch}..HEAD --oneline +``` + +コミットがない場合はエラー終了: +``` +エラー: {default_branch}からの新しいコミットがありません。 +変更をコミットしてから実行してください。 +``` + +**1.4 リモートへのプッシュ確認** + +```bash +git status +``` + +"Your branch is ahead of"または"branch and 'origin/xxx' have diverged"がある場合、プッシュが必要: +```bash +git push -u origin {current_branch} +``` + +プッシュが失敗(rejected)した場合: +```bash +git pull --rebase origin {current_branch} +git push +``` + +### 2. PRタイトルと説明を生成 + +**2.1 コミット履歴とdiffを取得** + +```bash +git log {default_branch}..HEAD --format="%s" +git diff {default_branch}...HEAD --stat +``` + +**2.2 タイトルと説明の生成** + +コミット履歴とdiffを分析し、以下の形式で生成: + +**タイトル**: 主要な変更を要約(70文字以内) +- 例: "feat: ユーザー認証機能を追加" +- 例: "fix: ログイン時のセッションタイムアウトを修正" + +**説明**: +```markdown +## 変更概要 +{変更の目的と内容を1-3文で説明} + +## 変更内容 +{主要な変更点を箇条書き} + +## テスト +- [ ] 動作確認完了 +- [ ] テスト追加/更新(必要な場合) +``` + +### 3. PR作成 + +生成したタイトルと説明でPRを作成: + +```bash +gh pr create --title "{generated_title}" --body "{generated_description}" --base {default_branch} --head {current_branch} +``` + +### 4. 結果表示 + +``` +## PR作成完了 + +**PR**: {pr_url} +**ブランチ**: {source_branch} → {target_branch} +**タイトル**: {title} + +レビュアーにレビューを依頼してください。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| mainブランチから実行 | feature/issueブランチから実行するよう案内 | +| コミットがない | 変更をコミットしてから実行するよう案内 | +| プッシュ失敗 | `git pull --rebase`して再プッシュ | +| gh CLI認証エラー | `gh auth login`で認証 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **タイトルの品質**: コミットメッセージが不適切な場合、自分で適切なタイトルを生成 +3. **gh CLI**: GitHub CLIが必要。未インストールの場合はインストールを案内 diff --git a/.claude/skills/pr/workflows/merge.md b/.claude/skills/pr/workflows/merge.md new file mode 100644 index 0000000..9d993ad --- /dev/null +++ b/.claude/skills/pr/workflows/merge.md @@ -0,0 +1,118 @@ +# マージワークフロー + +このワークフローは、PRをマージし、ブランチをクリーンアップします。 + +## 必要なツール + +- Bash +- AskUserQuestion +- Skill (gitスキルを使用) + +## 実行ステップ + +### 1. PR情報取得と確認 + +**1.1 PR情報を取得** + +```bash +gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,mergeable,mergeStateStatus,statusCheckRollup +``` + +**1.2 マージ可能性チェック** + +以下をすべて確認: +- `state === "OPEN"` +- `mergeable === "MERGEABLE"` +- すべてのステータスチェックが成功している + +いずれかが満たされない場合、エラーメッセージを表示して終了: + +``` +エラー: PRはマージできない状態です + +以下を確認してください: +- PRがOPENであること +- マージコンフリクトがないこと(mergeable: {actual_status}) +- CI/CDパイプラインが成功していること +- 必要なレビュー承認が得られていること +``` + +**1.3 ユーザー確認** + +AskUserQuestionで最終確認: +``` +以下のPRをマージします。よろしいですか? + +**PR**: {pr_url} +**タイトル**: {title} +**ブランチ**: {head_branch} → {base_branch} +``` + +選択肢: +- "はい、マージする" +- "いいえ、キャンセル" + +### 2. マージ実行 + +ユーザーが承認した場合、マージを実行: + +```bash +gh pr merge {pr_number} --squash --delete-branch +``` + +`--squash`: PRの全コミットを1つにまとめてマージ +`--delete-branch`: マージ後にリモートブランチを自動削除 + +### 3. ローカルブランチのクリーンアップ + +Skillツールを使用してgitスキルのbranch-deleteサブコマンドを実行: + +``` +Skill + skill: "git" + args: "branch-delete {head_branch}" +``` + +gitスキルが自動的に以下を実行: +- mainブランチに切り替え(必要な場合) +- mainブランチの更新(fetch + pull) +- リモートブランチ情報の更新(fetch --prune) +- ローカルブランチの削除 + +### 4. 結果表示 + +``` +## マージ完了 + +**PR**: {pr_url} +**ブランチ**: {head_branch} → {base_branch} + +### 実行内容 +- PRをマージしました +- リモートブランチ '{head_branch}' を削除しました +- ローカルブランチ '{head_branch}' を削除しました +- ブランチを '{base_branch}' に切り替えました +- 最新のコードを取得しました + +お疲れ様でした。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| PRが見つからない | 正しいPR番号を確認 | +| state !== "OPEN" | PRがすでにCLOSEDまたはMERGEDされている | +| mergeable !== "MERGEABLE" | マージコンフリクトを解決してから再実行 | +| ステータスチェック失敗 | CI/CDを修正してから再実行 | +| マージ権限不足 | リポジトリの権限を確認 | +| ブランチ削除失敗 | `git branch -D`で強制削除 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **マージ権限**: PRマージにはリポジトリへの書き込み権限が必要 +3. **ステータスチェック**: すべてのCIチェックが成功していることを確認 +4. **リモートブランチ削除**: `--delete-branch`により、GitHub側で自動的にリモートブランチが削除される +5. **保護ブランチ**: ターゲットブランチが保護されている場合、追加の権限設定が必要 +6. **Squashマージ**: `--squash`により、PRの全コミットが1つにまとめられてマージされる diff --git a/.claude/skills/pr/workflows/resolve.md b/.claude/skills/pr/workflows/resolve.md new file mode 100644 index 0000000..0882fbb --- /dev/null +++ b/.claude/skills/pr/workflows/resolve.md @@ -0,0 +1,191 @@ +# レビュー対応ワークフロー + +このワークフローは、レビューコメントに対して修正→コミット→リプライを行います。 + +## 必要なツール + +- Bash +- Read +- Edit +- Write +- AskUserQuestion +- Skill (gitスキルを使用) + +## 実行ステップ + +### 1. PR情報取得 + +**1.1 PR情報を取得** + +```bash +gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,author,mergeable +``` + +**1.2 PR状態の確認** + +PRが`OPEN`であることを確認。CLOSEDまたはMERGEDの場合はエラー終了。 + +**1.3 ブランチ確認** + +カレントブランチを取得: +```bash +git branch --show-current +``` + +カレントブランチが`headRefName`と異なる場合、AskUserQuestionで確認: +``` +現在のブランチ '{current_branch}' は、PRのソースブランチ '{head_branch}' と異なります。 +'{head_branch}' にチェックアウトしますか? +``` + +選択肢: +- "はい、チェックアウトする" → `git checkout {head_branch}` +- "いいえ、このまま続行" + +### 2. レビューコメントの取得 + +**2.1 全コメントを取得** + +```bash +gh pr view {pr_number} --json comments,reviews --jq '.reviews[] | select(.state == "CHANGES_REQUESTED" or .state == "COMMENTED") | {body: .body, author: .author.login, createdAt: .createdAt, comments: .comments}' +``` + +**2.2 未解決コメントのフィルタリング** + +以下の条件を満たすコメントを抽出: +- レビュー状態が`CHANGES_REQUESTED`または`COMMENTED` +- レビューコメントに対するリプライがない、または最新のコメントがレビュアーからのもの + +レビューコメントが0件の場合: +``` +## レビュー対応完了 + +**PR**: {pr_url} + +未解決のコメントはありません。 +``` + +終了する。 + +### 3. 各コメントの処理 + +各レビューコメントについて、以下の処理を実行: + +**3.1 分析** + +コメント情報を取得: +- コメント本文 +- 該当ファイルと行番号(可能な場合) +- レビュアー名 + +Readツールでファイルを読み込み、該当箇所を確認。 + +**3.2 判断** + +以下のいずれかを選択: + +1. **修正が必要で内容が明確** + - 自律的に修正へ進む + - 例: 「タイポを修正してください」「変数名を変更してください」 + +2. **不明点あり** + - 質問をリプライ + - 例: 「パフォーマンスを改善してください」→「具体的にどの部分が懸念でしょうか?」 + +3. **同意できない/対応不要** + - スキップして報告 + - 例: 「アーキテクチャを全面的に見直してください」→ユーザーに判断を委ねる + +4. **判断が困難** + - AskUserQuestionで確認 + - 選択肢: 修正する / 質問する / スキップ + +**3.3 修正・コミット・プッシュ(修正する場合)** + +**3.3.1 ファイルの修正** + +EditまたはWriteツールでファイルを修正。 + +複数ファイルの修正が必要な場合、すべて修正してから1回のコミットにまとめる。 + +**3.3.2 gitスキルでコミット・プッシュ** + +Skillツールを使用してgitスキルのcommitサブコマンドを実行: + +``` +Skill + skill: "git" + args: "commit" +``` + +gitスキルが自動的に以下を実行: +- 変更ファイルの分析 +- コミットメッセージの生成(`fix: {レビュー指摘の要約}`形式) +- ステージング(git add) +- コミット +- プッシュ + +**3.3.3 コミットSHAの取得** + +```bash +git rev-parse HEAD +``` + +**3.4 リプライ** + +**修正の場合**: + +```bash +gh pr comment {pr_number} --body "修正しました + +**コミット**: https://github.com/{owner}/{repo}/commit/{commit_sha} + +{修正内容の簡潔な説明} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) " +``` + +**質問の場合**: + +```bash +gh pr comment {pr_number} --body "確認させてください + +{質問内容} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) " +``` + +### 4. サマリー + +全コメントの処理が完了したら、サマリーを表示: + +``` +## PRレビュー対応完了 + +**PR**: {pr_url} + +### 結果 +- 修正してリプライ: {n}件 +- 質問してリプライ: {n}件 +- スキップ: {n}件 + +レビュアーによる確認をお願いします。 +``` + +## エラーハンドリング + +| エラー | 対応 | +|--------|------| +| PRが見つからない | 正しいPR番号を確認 | +| PRがCLOSED/MERGED | OPENのPRを指定 | +| プッシュ失敗 | `git pull --rebase`して再プッシュ | +| コンフリクト | 手動でコンフリクトを解決してから再実行 | +| gh CLI認証エラー | `gh auth login`で認証 | + +## 注意事項 + +1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない +2. **自律的な判断**: コメントの修正内容が明確な場合は自律的に対応し、AskUserQuestionは判断が困難な場合のみ使用 +3. **テスト実行**: 修正後、関連するテストがある場合は実行して確認 +4. **複数ファイル**: 1つのコメントで複数ファイルの修正が必要な場合、全て修正してから1回のコミットにまとめる +5. **会話履歴の考慮**: コメントスレッドに複数のコメントがある場合、最新のコメントから意図を汲み取る From db4afacc8060a0b81106c768be6e4b40ff04abd5 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:52:24 +0900 Subject: [PATCH 08/89] =?UTF-8?q?docs:=20CLAUDE.md=E3=82=92=E3=82=B7?= =?UTF-8?q?=E3=83=B3=E3=83=97=E3=83=AB=E3=81=AB=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ディレクトリ構成を簡潔化(nabledge-6/研究ドキュメントの詳細は削除) - 詳細設計はstep3-architecture-design.mdへのリンクで参照 - 情報の重複を排除 Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 22dd64b..c74d439 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1,58 @@ +# nabledge-dev + 言語は日本語 + +## 概要 + +このリポジトリは **Nablarchエージェント用の構造化知識基盤(スキル)** を作成・管理するためのものです。 + +- **nabledge-6**: Nablarch 6(Jakarta EE 10、Java 17以上)用のスキル +- **nabledge-5**: Nablarch 5(Java EE 7/8、Java 8以上)用のスキル + +AI(Claude Code / GitHub Copilot)がNablarch開発を代行するための構造化された知識を提供します。 + +--- + +## ディレクトリ構成 + +``` +nabledge-dev/ +├── .claude/ +│ └── skills/ +│ ├── nabledge-6/ # Nablarch 6 スキル(作成予定) +│ └── nabledge-5/ # Nablarch 5 スキル(作成予定) +│ +├── .lw/ +│ ├── research/ # 調査・設計ドキュメント +│ └── nab-official/ # Nablarch公式情報(クローン) +│ +└── CLAUDE.md # このファイル +``` + +--- + +## 対象範囲 + +### 対象 + +| 項目 | 説明 | +|-----|------| +| **Nablarchバッチ(都度起動型)** | FILE to DB、DB to DB、DB to FILE パターン | +| **RESTful Webサービス** | JAX-RSサポート、REST API実装 | + +### 対象外 + +| 項目 | 理由 | +|-----|------| +| Jakarta Batch | 仕様書で対象外と明記 | +| 常駐バッチ(テーブルキュー型) | 仕様書で対象外と明記 | +| ウェブアプリケーション(JSP/画面系) | バッチ・REST以外は対象外 | +| メッセージング(MOM) | 対象外 | + +--- + +## 詳細設計 + +スキルの詳細なアーキテクチャ設計は以下を参照: + +- [Step 3: 構造化アーキテクチャ設計](.lw/research/step3-architecture-design.md) From be54153777cbac4a6d91f25ba72487d1837159ce Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 6 Feb 2026 17:53:47 +0900 Subject: [PATCH 09/89] =?UTF-8?q?fix:=20git=E3=82=B9=E3=82=AD=E3=83=AB?= =?UTF-8?q?=E3=81=AEdescription=E3=81=AB=E3=83=97=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A5=E3=82=92=E6=98=8E=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /git commitの説明を「コミット」→「コミット&プッシュ」に変更 - 実際の動作と説明を一致させる Co-Authored-By: Claude Opus 4.6 --- .claude/skills/git/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/git/SKILL.md b/.claude/skills/git/SKILL.md index bd09c4c..3068c58 100644 --- a/.claude/skills/git/SKILL.md +++ b/.claude/skills/git/SKILL.md @@ -1,6 +1,6 @@ --- name: git -description: Git操作を実行する。使い方:/git(対話選択)、/git commit(コミット)、/git branch-create(ブランチ作成)、/git branch-delete(ブランチ削除)、/git worktree-create(ワークツリー作成)、/git worktree-delete(ワークツリー削除) +description: Git操作を実行する。使い方:/git(対話選択)、/git commit(コミット&プッシュ)、/git branch-create(ブランチ作成)、/git branch-delete(ブランチ削除)、/git worktree-create(ワークツリー作成)、/git worktree-delete(ワークツリー削除) argument-hint: [commit|branch-create|branch-delete|worktree-create|worktree-delete] allowed-tools: Bash, Task, AskUserQuestion, Read --- From 2bd3ece38006ad7f4c35642da9e53bff03649818 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 17:23:55 +0900 Subject: [PATCH 10/89] =?UTF-8?q?docs:=20Nabledge=E6=9C=80=E7=B5=82?= =?UTF-8?q?=E8=A8=AD=E8=A8=88=E6=9B=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nablarchエージェント代行のための構造化知識基盤の設計書を追加。 要件定義、アーキテクチャ設計、実現性評価、レビュー結果、実装計画を含む。 Co-Authored-By: Claude Opus 4.6 --- doc/nabledge-design.md | 1695 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1695 insertions(+) create mode 100644 doc/nabledge-design.md diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md new file mode 100644 index 0000000..2790733 --- /dev/null +++ b/doc/nabledge-design.md @@ -0,0 +1,1695 @@ +# Nablarchエージェント代行のための構造化知識基盤 - 最終設計書 + +**作成日**: 2026年2月9日 +**作成者**: Claude (Sonnet 4.5) +**バージョン**: 1.0 + +--- + +## 変更履歴 + +| 日付 | 変更内容 | 作成者 | +|------|----------|--------| +| 2026/02/09 | 初版作成 | Claude (Sonnet 4.5) | + +--- + +## 目次 + +- [全体構造](#全体構造) +- [1. 概要](#1-概要) + - [1.1 背景と課題](#11-背景と課題) + - [1.2 設計のゴール](#12-設計のゴール) + - [1.3 本設計書の位置づけ](#13-本設計書の位置づけ) +- [2. 要件と制約](#2-要件と制約) + - [2.1 代行タスクと知識要件](#21-代行タスクと知識要件) + - [2.2 公式情報マッピングと作成単位](#22-公式情報マッピングと作成単位) + - [2.3 制約事項と前提条件](#23-制約事項と前提条件) +- [3. アーキテクチャ設計](#3-アーキテクチャ設計step3の結果を中心に) + - [3.1 ユーザー体験設計](#31-ユーザー体験設計) + - [3.2 ファイル構成と命名規則](#32-ファイル構成と命名規則) + - [3.3 検索パス・検索精度設計](#33-検索パス検索精度設計) + - [3.4 インデックス設計](#34-インデックス設計) + - [3.5 知識ファイル設計](#35-知識ファイル設計) + - [3.6 検索ワークフロー定義](#36-検索ワークフロー定義) + - [3.7 Markdown変換ルール](#37-markdown変換ルール) + - [3.8 コンテキスト管理戦略](#38-コンテキスト管理戦略) + - [3.9 MCP移行設計](#39-mcp移行設計) +- [4. 実現性評価](#4-実現性評価step4の結果) + - [4.1 作成したサンプル一覧](#41-作成したサンプル一覧) + - [4.2 実現性評価結果](#42-実現性評価結果) + - [4.3 リスク評価と対策](#43-リスク評価と対策) + - [4.4 知識・仕組みの作成計画](#44-知識仕組みの作成計画) +- [5. レビューと改善](#5-レビューと改善step5の結果) + - [5.1 各ペルソナの評価結果](#51-各ペルソナの評価結果) + - [5.2 指摘事項と改善内容のサマリー](#52-指摘事項と改善内容のサマリー) + - [5.3 将来対応項目](#53-将来対応項目) +- [6. 実装計画](#6-実装計画) + - [6.1 実装フェーズ計画](#61-実装フェーズ計画) + - [6.2 品質保証プロセス](#62-品質保証プロセス) + - [6.3 情報源の管理と更新対応](#63-情報源の管理と更新対応) + - [6.4 残存リスクと対策](#64-残存リスクと対策) +- [7. 付録](#7-付録) + - [7.1 用語集](#71-用語集) + - [7.2 参考資料](#72-参考資料) + +--- + +## 全体構造 + +本設計の全体像を以下の図に示す。この図は、Nablarch利用者がAIエージェントを介してnabledgeスキルを活用する全体のフローと、知識基盤の構成要素を表現している。 + +```mermaid +graph TB + %% 左側: 主要アクター + subgraph main_actors["🎭 主要アクター"] + direction TB + DEV["👥 Nablarch利用者
(アプリケーション開発者)"] + AGENT["🛠️ AIツール
(Claude Code/GitHub Copilot等)"] + DEV -->|"①自然言語で依頼
(例: ページングを実装したい)"| AGENT + end + + %% 中央: nabledgeスキル + subgraph nabledge["📦 nabledgeスキル"] + direction TB + + subgraph workflows["🤖 ワークフロー(LLM実行)"] + WF_SEARCH["知識検索
(keyword+intent並列)
関連度判定"] + WF_DELEGATE["代行作業
実装調査・コード生成・レビュー"] + WF_GENERATE["知識ファイル生成・検証
3分/ファイル・20%サンプリング"] + end + + subgraph knowledge["知識基盤"] + INDEX["インデックス(TOON)
93エントリ・650検索ヒント"] + JSON["知識ファイル(JSON)
60ファイル・420Kトークン"] + MD["知識ファイル(Markdown)
人間確認用・根拠追跡"] + end + end + + %% 右側: Nablarch開発チーム + subgraph dev_team["👨‍💻 Nablarch開発チーム"] + NAB_TEAM["Nablarch開発チーム

• 公式情報更新
• 知識レビュー・承認"] + end + + %% 主要フロー(①→⑤)- 左から中央へ + AGENT -->|"②知識検索"| WF_SEARCH + WF_SEARCH -->|"検索"| INDEX + INDEX -->|"③関連セクション特定
(関連度: High/Partial)"| JSON + JSON -.->|"自動変換"| MD + + AGENT -->|"④ワークフロー実行"| WF_DELEGATE + WF_DELEGATE -->|"知識参照
(上位10セクション)"| JSON + WF_DELEGATE -->|"⑤回答・コード生成"| DEV + + %% 開発チームフロー - 右から中央へ + AGENT -.->|"実行"| WF_GENERATE + WF_GENERATE -.->|"作成・検証"| JSON + NAB_TEAM -.->|"更新時"| WF_GENERATE + NAB_TEAM -.->|"レビュー・承認"| JSON + + MD -.->|"人間が確認"| DEV + + %% 下部: GitHub配布 + subgraph github["📦 GitHub"] + direction TB + subgraph org["org: nablarch"] + REPO["repository: nabledge

• Claude Code Pluginとして配布
• claude plugin install nabledge-6
• バージョン管理"] + end + end + + %% 配布フロー - 下から中央へ + nabledge -.->|"取得"| REPO + + %% スタイル + style main_actors fill:#e1f5ff + style dev_team fill:#ffe1f5 + style nabledge fill:#f0f0f0 + style github fill:#f5f5f5 + style org fill:#e8f5e9 + style knowledge fill:#e8f5e9 + style workflows fill:#fff9c4 +``` + +### 図の解説 + +**主要な登場人物**: +1. **Nablarch利用者** (アプリケーション開発者): 主人公(左側)。AIツールに自然言語で作業を依頼する +2. **AIツール** (Claude Code/GitHub Copilot等): 主人公(左側)。ワークフロー(LLM)を実行して作業を代行する +3. **nabledgeスキル**: 知識基盤とワークフロー(LLM)で構成される(中央) +4. **Nablarch開発チーム**: 知識基盤を更新・レビューする(右側) + +**配布の流れ**(図の下部): +``` +📦 GitHub + └─ org: nablarch(入れ子) + └─ repository: nabledge(入れ子) + ↓ Claude Code Pluginとして配布 + ↓ claude plugin install nabledge-6 + nabledgeスキル(ユーザー環境にインストール) +``` + +**知識基盤の構成**: +- **知識ファイル (JSON)**: Nablarchの機能・実装パターンを構造化(60ファイル、約420Kトークン) +- **インデックス (TOON形式)**: 検索用インデックス(93エントリ、約650検索ヒント、トークン量30-60%削減) +- **知識ファイル (Markdown)**: 人間が確認するための自動変換版(根拠追跡性) + +**ワークフロー(🤖 LLM実行)の種類**: +- **知識検索**: keyword-search(技術軸)とintent-search(目的軸)の並列実行、関連度判定(High/Partial/None) +- **代行作業**: 実装調査、コード生成、レビュー、障害調査等のタスクを実行 +- **知識ファイル生成・検証**: 知識ファイルを作成し、品質を保証する(3分/ファイル、20%サンプリングレビュー) + +**実行フロー(①→⑤)**: +1. Nablarch利用者が自然言語でAIツールに依頼(例: 「ページングを実装したい」) +2. AIツールが **ワークフロー(知識検索)** を実行 + - ワークフロー(LLM)がインデックスを検索(keyword + intent並列実行) +3. 関連度の高いセクションを特定(High/Partial/Noneの3段階評価) +4. **ワークフロー(代行作業)** を実行し、知識ファイルを参照(上位10セクション、約5,000トークン = 2.5%のコンテキスト使用) +5. 回答またはコードを生成してユーザーに返す + +**設計のポイント**: +- **配布の明確化**: GitHub (nablarch/nabledge) → Claude Code Plugin Registry → インストール +- **LLMの明示**: ワークフローに🤖マークを付与し、LLMが実行する処理であることを明確化 +- **検索の構造化**: AIツール → ワークフロー(検索)→ インデックス の流れで検索処理を明示 +- **トークン効率**: TOON形式インデックスで30-60%削減、セクション単位抽出で必要最小限の情報のみ使用 +- **検索精度**: keyword-search(技術軸)とintent-search(目的軸)の並列実行で漏れを防止 +- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡 +- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離 + +--- + +## 1. 概要 + +### 1.1 背景と課題 + +#### なぜこの設計が必要なのか + +Nablarchは金融・決済等のミッションクリティカルな大規模基幹系システムで広く利用されているが、保守開発において以下の課題が存在する: + +**新規参画者のオンボーディング課題**(3プロジェクト・15名の観測値、2024-2025年): +- 対象者: Java経験2年以上、Nablarch未経験者 +- アーキテクチャ理解: 2〜3日 +- 既存コード理解: 3〜5日 +- **合計: 5〜10日** + +**日常開発での工数課題**(同観測値): +- 実装調査: 2〜4時間/タスク(中規模タスク: 3-5ファイル変更、100-300ステップ) +- レビュー: 1〜2時間/レビュー +- 障害調査: 2〜8時間/障害(難易度による) + +**AI活用における課題**: +- AIエージェント(Claude Code、GitHub Copilot)を活用したいが、Nablarch固有の知識がないため代行精度が不十分 +- 公式ドキュメントは人間向けに記述されており、AIが効率的に検索・参照できる構造になっていない +- **なるべく早くAIのメリットを感じてもらう**ことが重要 + +#### 解決すべき課題 + +1. **代行精度の向上**: Nablarch固有の知識をAI向けに構造化し、代行精度を向上させる +2. **工数削減の実現**: 実装調査、コード生成、レビュー等の工数を削減する(目標: 60-70%削減) +3. **オンボーディング期間の短縮**: 新規参画者の学習期間を短縮する(目標: 5〜10日 → 1〜2日) + +--- + +### 1.2 設計のゴール + +この設計書では、以下のゴールを達成するための構造化知識基盤を定義する: + +#### 主要ゴール + +1. **AIエージェントの代行精度向上**: Nablarchの構造化知識を提供し、AIが正確に代行できるようにする +2. **構造化の観点をすべて満たす設計**: 以下の5観点を考慮した設計を実現する + - 検索速度: 必要な情報に素早くたどり着ける + - コンテキスト肥大化防止: 不要な情報はノイズとならない + - トークン量最適化: コンテキストウィンドウ上限内で必要情報を収める + - 正確性・根拠追跡性: ミッションクリティカル領域で誤情報を許容しない + - 保守性・更新容易性: バージョンアップへの追従が必要 +3. **実現可能性の確認**: 実際に知識ファイルを作成し、品質を検証する + +#### 定量的な目標 + +| 項目 | 目標値 | 根拠 | +|------|--------|------| +| **代行精度** | 工数削減60-70% | 他業界のAI代行事例では50-80%の削減実績 | +| **作成工数** | 全60ファイルで約3.7時間 | 1ファイル約3分(実測値) | +| **知識の品質** | 平均95点以上/100点 | Step4で17ファイルの平均97.3点を達成 | +| **トークン量** | 実運用で約5,000トークン | コンテキストウィンドウ(200,000トークン)の2.5% | +| **オンボーディング期間** | 5〜10日 → 1〜2日 | AIによる代行で学習曲線を短縮 | + +--- + +### 1.3 本設計書の位置づけ + +#### 設計書の役割 + +この設計書は、**構造化知識基盤の完全な仕様**として、以下の役割を果たす: + +1. **要件定義**: どんな知識が必要か、どう作ればよいかを明確化 +2. **設計仕様**: アーキテクチャ、ファイル構成、検索パス、スキーマを定義 +3. **実現性評価**: 実際に作成した知識ファイルの品質を検証 +4. **改善の記録**: 有識者レビューによる改善内容を記録 +5. **実装の基礎**: 今後の実装や運用の基礎となる + +#### 対象読者 + +| 読者 | 読むべきセクション | 読む目的 | +|------|------------------|---------| +| **プロジェクトマネージャー** | 1. 概要、6. 実装計画 | 全体像の把握、工数見積もり、リスク評価 | +| **アーキテクト** | 3. アーキテクチャ設計、5. レビューと改善 | 設計判断の妥当性確認、拡張性の評価 | +| **Nablarch有識者** | 2. 要件と制約、4. 実現性評価 | 知識の正確性確認、網羅性の評価 | +| **実装担当者** | 3. アーキテクチャ設計、6. 実装計画 | 実装方法の理解、作業手順の確認 | +| **AIエンジニア** | 3. アーキテクチャ設計、4. 実現性評価 | トークン効率、検索性、MCP移行の理解 | + +#### 関連ドキュメント + +| ドキュメント | 関係 | +|-------------|------| +| **調査仕様書** (`nablarch_agent_research_spec.md`) | 本設計書の前提となる調査方針を定義 | +| **Step 1-5の調査結果** (`step1-5_*.md`) | 本設計書の各章のソースとなる詳細調査結果 | +| **Step 6: 調査結果統合** (`step6_final_summary.md`) | 本設計書の要約版、エグゼクティブサマリー | +| **Nabledge計画書** (今後作成予定) | 本設計書を元にした実装計画 | + +--- + +## 2. 要件と制約 + +### 2.1 代行タスクと知識要件(Step1の結果) + +#### 代行タスクの深掘り結果 + +仕様書の4作業を深掘りし、6作業を追加。計**10作業**を代行対象として確定した。 + +**代行タスク一覧と優先度**: + +| 分類 | 代行作業 | 優先度 | 工数削減効果 | 発生頻度 | AI代行適性 | +|------|---------|:------:|------------|---------|-----------| +| 仕様書指定 | 既存コード理解 | S | 60-70% | 週次以上 | 90%以上 | +| 追加提案 | コード生成・雛形作成 | S | 70-80% | 週次以上 | 90%以上 | +| 追加提案 | ナレッジQ&A | S | 90%以上 | 週次以上 | 90%以上 | +| 仕様書指定 | 実装調査 | A | 70-80% | 月次以上 | 80%以上 | +| 仕様書指定 | レビュー | A | 60-80% | 月次以上 | 80%以上 | +| 追加提案 | テストデータ作成 | A | 60-70% | 月次以上 | 80%以上 | +| 仕様書指定 | 影響分析 | B | 50-70% | 随時 | 70%以上 | +| 追加提案 | 障害調査 | B | 50-60% | 随時 | 70%以上 | +| 追加提案 | 設計書解読 | B | 40-50% | 随時 | 70%以上 | +| 追加提案 | ドキュメント生成 | B | 40-50% | 随時 | 70%以上 | + +**優先度の判断基準**(Step5レビュー反映): +- **S(最優先)**: 工数削減率60%以上 かつ 週次以上の発生頻度 かつ AI代行適性90%以上 +- **A(高優先)**: 工数削減率50%以上 かつ 月次以上の発生頻度 かつ AI代行適性80%以上 +- **B(中優先)**: 工数削減率40%以上 または 特定の場面で高い効果 かつ AI代行適性70%以上 + +--- + +#### 代行に必要な知識タイプ + +10作業の分析から、必要な知識を**3タイプ**に特定した(Step1で4タイプから統合)。 + +| 知識タイプ | 何がわかるか | 代行タスクのカバー範囲 | +|-----------|-------------|---------------------| +| ① 機能の使い方・実装パターン(エラー含む) | どう実装すればいいか、エラーが出たらどうするか | 9タスク(90%)をカバー | +| ② チェック項目 | 何に気をつけるべきか | 3タスク(30%)をカバー | +| ③ リリースノート・既知問題 | 何が変わった/壊れているか | 2タスク(20%)をカバー | + +**結論**: ①を構造化すれば9割の作業をカバーできる。**①から着手する。** + +**④エラー対処を①に統合した根拠**: +- エラーは発生元の機能(ハンドラ/ライブラリ)に紐づく +- 代行時、エラー調査は「どの機能で発生したか」から始まる +- 機能の知識にエラー情報を含めた方が、1回の参照で完結する +- Nablarchの解説書も、各機能ページ内にエラー情報を記載している + +--- + +#### 代行タスクと知識タイプのマッピング + +| 代行作業 | ①機能・パターン | ②チェック | ③リリース | +|---------|:-------------:|:--------:|:--------:| +| 既存コード理解 | ◎ | | | +| 実装調査 | ◎ | | | +| 影響分析 | ◎ | | | +| レビュー | ◎ | ◎ | | +| コード生成 | ◎ | ◎ | | +| テストデータ作成 | ◎ | | | +| 障害調査 | ◎ | | ◎ | +| 設計書解読 | ◎ | | | +| ドキュメント生成 | ◎ | | | +| ナレッジQ&A | ◎ | ◎ | ◎ | +| **必要な作業数** | **9** | **3** | **2** | + +**凡例**: ◎ 必須 + +--- + +### 2.2 情報源と作成範囲(Step2の結果) + +#### Nablarch公式情報の構造 + +**対象範囲**: Nablarchバッチ(都度起動型)、RESTful Webサービス + +##### 解説書 (https://nablarch.github.io/docs/LATEST/doc/) + +| カテゴリ | 内容 | 対象範囲 | +|---------|------|---------| +| **処理方式** | Nablarchバッチ(都度起動型)、RESTful Webサービス | ○ | +| **ハンドラ** | 共通ハンドラ、バッチ専用ハンドラ、REST専用ハンドラ | ○ | +| **ライブラリ** | データベースアクセス、入力値チェック、トランザクション管理、ファイルI/O、ログ出力、システムリポジトリ等 | ○ | +| **ツール** | NTF(Testing Framework)、gsp-dba-maven-plugin、SQL Executor | ○ | +| **アダプタ** | ログ関連、DB関連、REST関連、メール関連、監視関連 | ○ | +| **設定ガイド** | デフォルト設定一覧、設定変更方法、環境別設定管理 | ○ | +| **移行ガイド** | Nablarch 5→6移行手順、Jakarta EE対応 | ○ | +| **リリースノート** | バージョン別変更履歴(GitHub Releasesと連携) | ○ | +| **API Doc** | Javadoc(/javadoc/配下) | △ 参照 | + +##### システム開発ガイド (https://fintan.jp/page/252/) + +| カテゴリ | 内容 | 対象範囲 | +|---------|------|---------| +| **開発プロセス** | 全体像、設計工程、製造工程、テスト工程 | △ 参考 | +| **Nablarchパターン集** | よく使われる設計・実装パターン(バッチ、REST関連) | ○ | +| **Nablarchアンチパターン** | やってはいけないパターンと理由 | ○ | +| **サンプルプロジェクト** | 開発ガイド、テスト標準、設計書サンプル | △ 参考 | + +**システム開発ガイドの重要性**(Step5レビュー反映): +- Fintanのシステム開発ガイドは、実装パターンとアンチパターンの主要情報源 +- 解説書(機能説明)とシステム開発ガイド(実装パターン)を組み合わせることで、より実践的な知識を提供 +- パターン集とアンチパターンは、コード生成やレビュー代行で特に重要 + +##### Example (https://github.com/nablarch/) + +| リポジトリ | 内容 | 対象範囲 | +|-----------|------|---------| +| **nablarch-example-batch** | Nablarchバッチの実装サンプル | ○ | +| **nablarch-example-rest** | RESTful Webサービスの実装サンプル | ○ | + +##### 対象外 + +| 対象外 | 理由 | +|--------|------| +| Jakarta Batch | 仕様書で対象外 | +| 常駐バッチ(テーブルキュー型) | 仕様書で対象外 | +| ウェブアプリケーション(JSP/画面系) | 仕様書で対象外 | +| メッセージング(MOM) | 仕様書で対象外 | + +--- + +#### 知識タイプと作成単位 + +| # | 知識タイプ | 作成単位 | 推定件数 | +|---|-----------|---------|---------| +| ① | 機能・実装パターン(エラー含む) | ハンドラ単位、ライブラリ単位、処理方式単位、ツール単位、アダプタ単位 | 約55個 | +| ② | チェック項目 | セキュリティ、推奨/非推奨、公開API/非公開API | 3個 | +| ③ | リリースノート | バージョン単位 | 複数個 | +| **合計** | | | **約60個** | + +**対象範囲の規模**(Step2より): + +| 対象 | ハンドラ数 | ライブラリ | 備考 | +|------|-----------|-----------|------| +| Nablarchバッチ | 約15個 | DB、ファイルI/O、バリデーション | 共通 + バッチ専用 | +| RESTful | 約12個 | DB、バリデーション、JSON変換 | 共通 + REST専用 | +| **合計(重複除く)** | **約20個** | **約15機能** | | + +--- + +#### 情報の持ち方の考え方 + +**基本原則**(Step2で定義): + +| 原則 | 説明 | 判断基準 | +|------|------|---------| +| **仕様は全部残す** | 必須もオプションも、推奨も非推奨も網羅。省略すると代行精度が下がる | 設定項目、デフォルト値、型、制約、動作仕様、理由・背景、注意点、警告をすべて含む | +| **考え方も全部残す** | 理由・背景・なぜそうするかは残す。判断根拠として必要 | 設計思想、推奨パターン、注意事項をすべて含む | +| **表現は最適化する** | 読み物的記述→端的な記述。重複は排除。情報量は維持したまま簡潔に | 導入文(「本章では〜」等)、冗長な説明、重複表現、段階的な説明を削除し、箇条書き化 | +| **形式はAI向けに** | 人間向けの段階的説明→構造化データ。検索・参照しやすい形式に | JSON形式、検索ヒント設計により検索性向上 | + +**「仕様は全部残す」と「表現は最適化する」の両立基準**(Step5レビュー反映): +- **残すもの**: 設定項目、デフォルト値、型、制約、動作仕様、理由・背景、注意点、警告 +- **最適化するもの**: 導入文(「本章では〜」等)、冗長な説明、重複表現、段階的な説明→箇条書き +- **判断基準**: 「この情報がないとAIが誤った判断をする可能性があるか?」で判断。YESなら残す、NOなら最適化 + +--- + +### 2.3 制約事項と前提条件 + +#### 対象範囲の制約 + +| 対象 | 対象外 | +|------|--------| +| Nablarchバッチ(都度起動型) | Jakarta Batch | +| RESTful Webサービス | 常駐バッチ(テーブルキュー型) | +| | ウェブアプリケーション(JSP/画面系) | +| | メッセージング(MOM) | + +#### バージョン管理方針 + +- 多くのプロジェクトは過去バージョン(OSS化前で非公開)を使用 +- 1プロジェクト=1バージョン(完全分離) +- バージョンアップ時は両方参照可能にする +- バージョン別スキル分離(nabledge-5, nabledge-6) + +#### 想定ツール + +| ツール | 用途 | 備考 | +|--------|------|------| +| **Claude Code** | エージェント型開発支援(MCP接続可) | 主要ターゲット | +| **GitHub Copilot** | コード補完・提案(MCP接続可) | サブターゲット | + +#### 段階的アプローチ + +- **短期**: AI向け最適化ファイル+人向け根拠確認ビュー → プロジェクトに配布 +- **中期**: MCPサーバー化 → 両ツールから接続 + +#### 前提条件 + +1. **情報源の信頼性**: 公式ドキュメント(RST版)を主要情報源とする +2. **プロジェクトの想定**: Java経験2年以上、Nablarch未経験者が主要ユーザー +3. **作業環境**: Claude Code、GitHub Copilotがインストールされている +4. **品質保証**: 20%のサンプリングレビュー、Nablarch有識者による確認 + +--- + +[続く - 次は「3. アーキテクチャ設計」] + +## 3. アーキテクチャ設計(Step3の結果を中心に) + +### 3.1 ユーザー体験設計 + +#### 配布形式 + +[Claude Code Plugin](https://code.claude.com/docs/en/plugins)として配布。GitHub Copilotも同じスキル構造を認識可能。 + +**配布元**: GitHub (`github.com/nablarch/nabledge`) + +**配布の流れ**: +``` +📦 GitHub + └─ org: nablarch + └─ repository: nabledge + ↓ Claude Code Pluginとして配布 + ↓ claude plugin install nabledge-6 + ユーザー環境(.claude/skills/nabledge-6/) +``` + +#### インストール方法 + +##### Claude Code + +```bash +# Plugin Registryからインストール(推奨) +# 内部でgithub.com/nablarch/nabledgeから取得 +claude plugin install nabledge-6 + +# インストール確認 +claude plugin list + +# アップデート(最新版をGitHubから取得) +claude plugin update nabledge-6 +``` + +**動作イメージ**: +```bash +$ claude plugin install nabledge-6 +✓ Fetching from github.com/nablarch/nabledge +✓ Downloading nabledge-6 +✓ Installing knowledge files (60 files, ~420K tokens) +✓ Installing workflows (10 workflows) +✓ Installing index (93 entries) +✓ nabledge-6 installed successfully + +Next steps: + Try: "Nablarchでページングを実装したい" +``` + +##### GitHub Copilot + +プロジェクトルートにスキルフォルダを配置: + +```bash +# プロジェクトにスキルを配置 +mkdir -p .claude/skills +cd .claude/skills + +# nabledge-6スキルを配置(配布パッケージから展開) +# [配布パッケージ取得方法は、実装フェーズで決定] +``` + +**設定ファイルへの登録**: +```json +{ + "skills": [ + { + "name": "nabledge-6", + "path": ".claude/skills/nabledge-6", + "enabled": true + } + ] +} +``` + +#### 利用方法 + +| 操作 | Claude Code | GitHub Copilot | +|------|-------------|----------------| +| **インストール** | `claude plugin install nabledge-6` | プロジェクトに配置 + 設定ファイル登録 | +| **アップデート** | `claude plugin update nabledge-6` | パッケージ再配置 | +| **利用** | 自然言語で依頼
例: 「ページングを実装したい」 | 自然言語で依頼
例: 「UniversalDaoの使い方は?」 | +| **手動実行** | `/nabledge-6 search ページング` | `/nabledge-6 search ページング` | + +#### 設計観点・選定理由 + +| 観点 | 選択肢 | 選定 | 理由 | +|------|--------|:----:|------| +| 配布元 | GitHub (nablarch/nabledge) | ✓ | オープンソースプロジェクトとして公開、バージョン管理、履歴追跡が容易 | +| | 独自サーバー | | 保守コストが高い、更新通知の仕組みが必要 | +| 配布形式 | Claude Code Plugin (GitHub経由) | ✓ | Claude Codeの標準配布方式。GitHub → Plugin Registry → インストールの流れで自動更新可能 | +| | npm/pipパッケージ | | 開発者向けツールには適するが、エンドユーザーのインストールが煩雑 | +| | zip配布 | | 手動配置が必要でアップデートも手動になる | +| インストール | Claude: `claude plugin install` | ✓ | 標準コマンド、GitHubから自動取得、バージョン管理機能あり | +| | GitHub Copilot: プロジェクト配置 | ✓ | プロジェクトごとにスキルを配置、設定ファイルで有効化 | +| バージョン分離 | バージョン別スキル(nabledge-5, nabledge-6) | ✓ | PJは1バージョンのみ使用。不要な情報がコンテキストに入らない | +| | 単一スキルでバージョン切替 | | コンテキスト肥大化、検索ノイズの原因になる | + +--- + +### 3.2 ファイル構成と命名規則 + +#### スキル構成 + +``` +nabledge-6/ +├── SKILL.md +├── knowledge/ # 知識 +│ ├── index.toon # 検索インデックス(TOON形式) +│ ├── features/ # ① 機能・実装パターン(エラー含む) +│ │ ├── handlers/ +│ │ │ ├── common/ +│ │ │ ├── web/ +│ │ │ ├── web_interceptor/ +│ │ │ ├── rest/ +│ │ │ ├── standalone/ +│ │ │ ├── batch/ +│ │ │ └── messaging/ +│ │ ├── libraries/ +│ │ ├── processing/ +│ │ ├── tools/ +│ │ └── adapters/ +│ ├── checks/ # ② チェック項目 +│ │ ├── security.json +│ │ ├── public-api.json +│ │ ├── public-api-list.txt +│ │ └── deprecated.json +│ └── releases/ # ③ リリースノート +│ └── {version}.json +├── workflows/ # ワークフロー(代行単位で作成) +│ └── {workflow-name}.md +├── scripts/ # スクリプト(セットアップ、代行に必要なスクリプトなど) +├── assets/ # アセット(代行の出力結果テンプレートなど) +└── docs/ # 人向け閲覧用(知識をMarkdownに自動変換) +``` + +#### 命名規則 + +| 対象 | 規則 | 例 | +|------|------|-----| +| ファイル名 | 英語、kebab-case | `db-connection-management-handler.json` | +| ディレクトリ名 | 英語、kebab-case | `handlers/`, `common/` | + +※バージョン情報はファイル名に含めない(スキル自体がバージョン別のため) + +--- + +### 3.3 検索パス設計 + +#### 2つの検索方式 + +| 検索名 | 切り口 | 説明 | +|--------|--------|------| +| keyword-search | 技術軸 | index.toonのhintsでキーワードマッチ | +| intent-search | 目的軸 | 目的→カテゴリ、対象→ファイルで絞込 | + +※詳細なワークフローは「検索ワークフロー定義」を参照 + +#### pointers構造 + +```json +{ + "files": [ + { "id": "F1", "path": "features/libraries/universal-dao.json", "relevance": 2, "matched_hints": ["ページング", "検索"] }, + { "id": "F2", "path": "features/libraries/database-access.json", "relevance": 1, "matched_hints": ["データベース"] } + ], + "sections": [ + { "file_id": "F1", "section": "paging", "relevance": 2, "matched_hints": ["ページング", "per", "page"] }, + { "file_id": "F1", "section": "search", "relevance": 2, "matched_hints": ["検索"] }, + { "file_id": "F2", "section": "query", "relevance": 1, "matched_hints": ["SQL"] } + ] +} +``` + +**ポイント**: +- sectionsを関連度降順で見れば、最も関連するセクションから読める +- filesを見れば、どのファイルが重要か全体像がわかる +- ファイルパスは1回だけ出現、file_idで参照(重複排除) +- matched_hintsで判断根拠を確認可能 + +#### 並列実行 + +| ツール | 方式 | +|--------|------| +| Claude Code | Task Toolで並列実行(最大10並列、各サブエージェントは独立コンテキスト) | +| GitHub Copilot | 複数エージェント並列実行(Explore, Task, Plan, Code-review等)| + +#### 設計観点・選定理由 + +| 観点 | 選択肢 | 選定 | 理由 | +|------|--------|:----:|------| +| 検索方式 | 単一 | | 1つの切り口だけでは漏れが発生しやすい | +| | 複数並列(keyword + intent) | ✓ | 異なる切り口で漏れを減らす | +| 関連度の算出タイミング | index時 | | 中身を見ないと正確な関連度は出せない | +| | ファイル読込時 | ✓ | 依頼との関連度は中身を見てから判断 | +| pointers構造 | フラット(file+section混在) | | ファイル単位でまとまらない、優先順位がつけにくい | +| | 階層(files + sections分離) | ✓ | セクション関連度降順で最重要から読める | +| 並列実行 | 逐次実行 | | 時間がかかる | +| | Task Tool並列 | ✓ | Claude Code公式機能、最大10並列対応 | + +--- + +### 3.4 インデックス設計(index.toon) + +#### index.toon形式 + +```toon +# Nabledge-6 Knowledge Index + +files[N,]{path,hints}: + features/handlers/common/global-error-handler.json, グローバルエラーハンドラ GlobalErrorHandler 未捕捉例外 エラーハンドリング 例外処理 + features/libraries/universal-dao.json, ユニバーサルDAO UniversalDao CRUD 検索 ページング +``` + +**構造**: +- `files[N,]{path,hints}:` → N件の配列、フィールドはpath, hints +- 各行: `パス, スペース区切りの検索ヒント` + +**スケーラビリティ設計**(Step5レビュー反映): +- 現状: 93エントリ、約650検索ヒント +- 将来規模: 約200エントリ、約1,500検索ヒント(Nablarch全体をカバー) +- 対策: + 1. **階層化**: カテゴリ別のインデックス(handlers.toon, libraries.toon等)を検討 + 2. **圧縮**: TOONフォーマットはトークン効率が良く、200エントリでも約5-7Kトークン程度と推定 + 3. **キャッシュ**: 頻繁に使われるファイルは、検索結果をキャッシュ +- 数百ファイル規模になった時点で、階層化インデックスへの移行を検討 + +#### 設計観点・選定理由 + +| 観点 | 選択肢 | 選定 | 理由 | +|------|--------|:----:|------| +| インデックス形式 | JSON | | 冗長、トークン消費大 | +| | TOON | ✓ | トークン効率が良い(30-60%削減)、LLMフレンドリー | + +--- + +### 3.5 知識ファイル設計(JSONスキーマ) + +#### 共通JSONスキーマ構造 + +```json +{ + "schema_version": "1.0", + "id": "ファイル識別子", + "title": "タイトル(日本語)", + "official_doc_urls": ["https://nablarch.github.io/docs/..."], + "index": [ + { "id": "セクションID", "hints": ["検索ヒント1", "検索ヒント2"] } + ], + "sections": { + "overview": { + "summary": "このファイルの要約(100-200文字)", + /* その他のセクション固有のプロパティ */ + }, + "セクションID": { /* セクション固有のプロパティ */ } + } +} +``` + +**スキーマのバージョニング**(Step5レビュー反映): +- `schema_version` フィールドを追加し、スキーマのバージョンを明記 +- スキーマ変更時の対応: + 1. **互換性のある変更**(フィールド追加等): マイナーバージョンアップ(1.0 → 1.1) + 2. **非互換な変更**(フィールド削除、構造変更): メジャーバージョンアップ(1.0 → 2.0) +- AIエージェントは `schema_version` を確認し、対応するパーサーを使用 +- 移行期間中は、旧スキーマと新スキーマの両方をサポート + +**サマリー情報の追加**(Step5レビュー反映): +- 各ファイルの `overview` セクションに `summary` フィールドを追加 +- 100-200文字程度で、このファイルの要点を記載 +- 用途: 検索結果一覧で、ユーザーが素早くファイルの内容を把握できる + +**Nablarch用語集の追加計画**(Step5レビュー反映): +- `features/glossary.json` を追加し、Nablarch独自の用語を定義 +- 構造: + ```json + { + "id": "glossary", + "title": "Nablarch用語集", + "terms": [ + { + "term": "リクエストパス", + "reading": "リクエストパス", + "english": "request path", + "definition": "アクションクラスを特定するための識別子。パッケージ名とクラス名を結合したもの。", + "related": ["action", "dispatch"] + } + ] + } + ``` +- 用語集は、overview.jsonと同様に基礎知識として提供 + +**検索ヒントの配置**: +- ファイルレベル: index.toon +- セクションレベル: index + +--- + +#### 知識タイプ別スキーマ + +##### ① 機能・実装パターン + +**ハンドラ単位** - 代表例: DbConnectionManagementHandler + +```json +{ + "id": "db-connection-management-handler", + "title": "データベース接続管理ハンドラ", + "official_doc_urls": ["https://nablarch.github.io/docs/..."], + "index": [ + { "id": "overview", "hints": ["DbConnectionManagementHandler", "DB接続"] }, + { "id": "processing", "hints": ["コネクション取得", "コネクション解放"] }, + { "id": "setup", "hints": ["設定", "XML", "connectionFactory"] }, + { "id": "constraints", "hints": ["ハンドラ順序", "TransactionManagementHandler"] }, + { "id": "errors", "hints": ["SQLException", "接続エラー"] } + ], + "sections": { + "overview": { "class_name": "...", "description": "...", "purpose": "..." }, + "processing": { "flow": [...] }, + "setup": { "properties": [...] }, + "constraints": { "handler_order": [...] }, + "errors": [{ "exception": "...", "cause": "...", "solution": "..." }] + } +} +``` + +**ライブラリ単位** - 代表例: UniversalDao + +```json +{ + "id": "universal-dao", + "title": "ユニバーサルDAO", + "index": [ + { "id": "overview", "hints": ["UniversalDao", "ユニバーサルDAO"] }, + { "id": "crud", "hints": ["登録", "更新", "削除", "insert", "update"] }, + { "id": "paging", "hints": ["ページング", "per", "page", "offset"] }, + { "id": "anti-patterns", "hints": ["SQLインジェクション", "生SQL"] }, + { "id": "errors", "hints": ["DuplicateKeyException", "一意制約違反"] } + ], + "sections": { + "overview": { "classes": [...], "annotations": [...] }, + "crud": { "methods": [...], "examples": [...] }, + "paging": { "description": "...", "example": "..." }, + "anti-patterns": [{ "pattern": "...", "reason": "...", "correct": "..." }], + "errors": [{ "exception": "...", "cause": "...", "solution": "..." }] + } +} +``` + +**処理方式単位** - 代表例: Nablarchバッチ + +```json +{ + "id": "nablarch-batch", + "title": "Nablarchバッチ(都度起動型)", + "index": [ + { "id": "overview", "hints": ["Nablarchバッチ", "都度起動"] }, + { "id": "architecture", "hints": ["アーキテクチャ", "ハンドラキュー"] }, + { "id": "responsibility", "hints": ["責務配置", "Action", "Form"] }, + { "id": "patterns", "hints": ["FILE to DB", "DB to FILE"] } + ], + "sections": { + "overview": { "description": "...", "use_cases": [...] }, + "architecture": { "diagram": "...", "components": [...] }, + "responsibility": { "action": "...", "form": "..." }, + "patterns": [{ "name": "...", "description": "...", "example": "..." }] + } +} +``` + +**ツール単位** - NTFは機能ごとに分割(6ファイル) + +| ファイル | 内容 | +|---------|------| +| ntf-overview.json | 概要・共通設定 | +| ntf-batch-request-test.json | バッチリクエスト単体テスト | +| ntf-rest-test.json | RESTテスト | +| ntf-db-test.json | DBテスト | +| ntf-test-data.json | テストデータ形式 | +| ntf-assertion.json | アサーション・期待値検証 | + +**アダプタ単位** - 構造はライブラリ単位と同様 + +##### ② チェック項目 + +**セキュリティ** + +```json +{ + "id": "security", + "title": "セキュリティチェック項目", + "index": [ + { "id": "csrf", "hints": ["CSRF", "トークン"] }, + { "id": "xss", "hints": ["XSS", "エスケープ"] }, + { "id": "sql-injection", "hints": ["SQLインジェクション", "プレースホルダ"] } + ], + "sections": { + "csrf": { "threat": "...", "check_points": [...], "correct_implementation": "...", "ng_patterns": [...] } + } +} +``` + +**公開API** - ホワイトリストを別ファイルに切り出し + +```json +{ + "id": "public-api", + "title": "公開API", + "published": "public-api-list.txt", + "index": [ + { "id": "overview", "hints": ["公開API", "使用可能"] } + ], + "sections": { + "overview": { "description": "公開APIはpublishedで指定したファイルに一覧化" } + } +} +``` + +```text +// public-api-list.txt(1行1クラス) +nablarch.common.dao.UniversalDao +nablarch.fw.web.HttpResponse +... +``` + +**非推奨機能** - 構造はセキュリティと同様 + +##### ③ リリースノート + +```json +{ + "id": "release-6u3", + "title": "Nablarch 6u3 リリースノート", + "index": [ + { "id": "changes", "hints": ["変更", "新機能"] }, + { "id": "breaking", "hints": ["非互換", "破壊的変更"] }, + { "id": "migration", "hints": ["移行手順", "アップグレード"] } + ], + "sections": { + "changes": [{ "type": "feature", "description": "..." }], + "breaking": [{ "description": "...", "before": "...", "after": "..." }], + "migration": { "steps": [...], "examples": [...] } + } +} +``` + +--- + +#### 検索ヒントの設計指針 + +| 項目 | 指針 | +|------|------| +| 言語 | 日本語基本。公式で英語のものはそのまま | +| 語数 | ファイル: 5-10語、セクション: 3-5語 | +| 順序 | 広い技術領域→詳細(降順)例: `DB 接続 コネクション` | +| 内容 | ユーザーが依頼文で使いそうな言葉、クラス名、メソッド名、例外名 | + +**検索ヒントの具体的な選定基準**(Step5レビュー反映): +1. **技術用語**: 公式ドキュメントに出現する用語(例: トランザクション、バリデーション) +2. **クラス名・メソッド名**: 完全修飾名と短縮名の両方(例: UniversalDao, nablarch.common.dao.UniversalDao) +3. **日本語表記**: 公式ドキュメントの日本語表記(例: ユニバーサルDAO) +4. **類義語**: 同じ概念を指す異なる表現(例: DB, データベース, database) +5. **エラー名**: 例外クラス名とエラーメッセージの一部(例: SQLException, 接続エラー) +6. **ユースケース**: よくある依頼文に含まれる言葉(例: ページング→「ページング 検索 per page limit offset」) + +**表記揺れ対策**(Step5レビュー反映): +- Nablarch固有の用語は、複数の表記を検索ヒントに含める + - 例: 「ユニバーサルDAO」「UniversalDao」「universal-dao」 +- カタカナ表記と英語表記の両方を含める + - 例: 「トランザクション」「transaction」 +- 略語と正式名称の両方を含める + - 例: 「DB」「データベース」「database」 + +#### 人向けMarkdown + +JSONから自動変換。docs/配下に配置。 + +#### 設計観点・選定理由 + +| 観点 | 選択肢 | 選定 | 理由 | +|------|--------|:----:|------| +| 形式 | Markdown | | 構造化しにくい、セクション抽出困難 | +| | YAML | | JSONより可読性高いがMCPとの相性悪い | +| | JSON | ✓ | パース容易、MCPスキーマ定義可能、jqでセクション抽出可能 | +| 二層構造 | AI専用 | | 人が確認できない | +| | 人専用 | | AIが構造化データとして扱えない | +| | 両方(JSON→MD変換) | ✓ | メンテナンス1箇所、用途別に最適化 | + +--- + +### 3.6 コンテキスト管理戦略 + +#### 関連度定義 + +ファイル・セクションの関連度を3段階で評価(情報検索分野の標準的なgraded relevance)。 + +| レベル | 値 | 判断基準 | 判断例(依頼:「ページングを実装したい」) | +|:------:|:---:|---------|------------------------------------------| +| **High** | 2 | 依頼に直接回答できる | universal-dao.jsonのpagingセクション | +| **Partial** | 1 | 依頼に関連し、補足として有用 | database-access.json(基盤知識) | +| **None** | 0 | 関連なし(対象外) | mail.json | + +**関連度判定の詳細プロセス**(Step5レビュー反映): +1. **High(2点)の判断基準**: + - セクションのタイトル or 説明に、依頼のキーワードが直接含まれる + - セクションの内容で、依頼の要件を実装できるコード例・設定例がある + - セクションを読めば、依頼に対する具体的な解決策がわかる +2. **Partial(1点)の判断基準**: + - セクションの内容が、依頼の前提知識として必要 + - セクションの内容が、依頼の関連機能として参考になる + - セクションを読めば、依頼の理解が深まる +3. **None(0点)の判断基準**: + - セクションの内容が、依頼とは無関係 + - セクションを読んでも、依頼に対する情報が得られない + +**ファイルの関連度**: そのファイル内のセクション関連度の最大値 + +``` +例: universal-dao.json +├── overview: 1 (Partial) +├── paging: 2 (High) ← 最大 +├── search: 2 (High) +└── setup: 0 (None) + +→ ファイルの関連度 = 2 +``` + +**判定の一貫性確保**: +- AIエージェントが判定する際は、上記の判断基準を明示的に参照 +- 判定結果に `matched_hints` を含めることで、判断根拠を追跡可能に + +--- + +#### コンテキストウィンドウへの適合性 + +**現状の課題**: +- Claude Opus 4.6のコンテキストウィンドウ: 200Kトークン +- 全60ファイルの推定トークン数: 約42万トークン(17ファイル476KB → 約12万トークン、全60ファイル = 約42万トークン相当) +- **問題**: 全ファイルをコンテキストに含めることは不可能 + +**対策**: +1. **セクション単位の抽出**: ファイル全体ではなく、関連度の高いセクションのみを抽出 + - 上位10セクション(平均500トークン)= 約5,000トークン + - 残り195,000トークンを他の情報(プロジェクトコード、会話履歴等)に使用可能 +2. **関連度による絞り込み**: 関連度2(High)のセクションを優先し、必要最小限の情報のみを取得 +3. **動的調整**: コンテキストウィンドウの使用率に応じて、取得セクション数を調整 +4. **階層的検索**: まずファイル一覧を確認し、必要なファイルのみ詳細を取得 + +**トークン量の監視**: +- 各検索結果に、推定トークン数を表示 +- コンテキストウィンドウの使用率をモニタリング +- 使用率が80%を超えた場合、警告を表示し、セクション数を減らす + +--- + +#### 上位N件抽出の根拠 + +| 項目 | 推奨値 | 根拠 | +|------|--------|------| +| files | 上位5件 | 1ファイル平均2000トークン × 5 = 10,000トークン | +| sections | 上位10件 | 1セクション平均500トークン × 10 = 5,000トークン | +| 合計 | 約15,000トークン | コンテキストの10-15%程度、他の情報と併用可能 | + +**動的調整メカニズム**(Step5レビュー反映): +- **基本**: 上位5ファイル、10セクションを抽出 +- **調整条件**: + 1. 関連度2(High)のセクションが10件未満の場合、関連度1(Partial)も含めて最大15件まで拡張 + 2. 関連度2のセクションが20件以上ある場合、上位15件まで拡張(より多くの選択肢を提供) + 3. コンテキストウィンドウの使用率が80%を超える場合、セクション数を減らす(最小5件) +- **理由**: 依頼の複雑さに応じて、情報量を動的に調整することで、精度とトークン効率を両立 + +--- + +#### 検索失敗時の対応(Step5レビュー反映) + +**検索結果0件の場合**: +1. エラーメッセージ: 「関連する知識が見つかりませんでした。依頼を具体的にするか、異なるキーワードで試してください。」 +2. 代替提案: index.toonの上位10件をリスト表示し、「これらの知識が参考になるかもしれません」と提案 +3. フォールバック: overview.jsonを返し、Nablarchの基本情報から開始 + +**検索結果が少ない場合(1-2件)**: +1. 関連度1(Partial)のセクションも含めて、最大10件まで表示 +2. 「関連する情報は限られています。より具体的な依頼をすると、精度が向上します。」とフィードバック + +--- + +#### トークン効率の定量評価 + +**TOON形式の効果**: +- JSON形式: フィールド名、括弧、引用符等で冗長 + ```json + {"path": "features/handlers/common/global-error-handler.json", "hints": ["グローバルエラーハンドラ", "GlobalErrorHandler"]} + ``` + - 文字数: 約150文字 → 約100トークン +- TOON形式: 構造をヘッダーで宣言し、データは最小限 + ``` + features/handlers/common/global-error-handler.json, グローバルエラーハンドラ GlobalErrorHandler + ``` + - 文字数: 約100文字 → 約60トークン +- **削減率**: 約40% (100 → 60トークン) + +**実測データ(Step4より)**: +- index.toon: 93エントリ、約650検索ヒント → 推定5-7Kトークン +- JSON形式の場合: 推定10-12Kトークン +- **削減率**: 約40-50% + +--- + +[続く - 次は「4. 実現性評価(Step4の結果)」] + +## 4. 実現性評価(Step4の結果) + +### 4.1 サンプル作成と検証結果 + +#### 作成したサンプル一覧 + +**総数**: 17個の知識ファイル(476KB)+ 1個のインデックス(93エントリ) + +**内訳**: +- 厚く揃える知識(13ファイル): バッチ処理実装に直接必要な知識 +- 形式チェックのみの知識(3ファイル): 知識タイプの網羅性確認用 +- Nablarch概要(1ファイル): 基本情報 +- インデックス(1ファイル): index.toon(93エントリ、約650検索ヒント) + +**検証シナリオ**: 期間内プロジェクト出力バッチ(DB to File) +- 実装例: `ExportProjectsInPeriodAction.java`(promanプロジェクト) +- 処理内容: データベースからCSV出力、トランザクション制御 +- 使用されているNablarch API/クラス: 15個 +- ハンドラ構成: 10個 + +**検証結果**: +- ✅ 必要な知識をすべてカバー(13ファイル) +- ✅ 知識の粒度が適切(詳細すぎず、不足もない) +- ✅ 検索ヒントが実際のタスク依頼文に対応 + +--- + +#### トークン量と作成工数 + +**トークン量の定量評価**(Step5レビュー反映): + +| 項目 | 文字数/サイズ | 推定トークン数 | 備考 | +|------|------------|------------|------| +| **17ファイル合計** | 476KB | 約120,000トークン | 日本語と英語の混在、JSON形式 | +| - 1ファイル平均 | 28KB | 約7,000トークン | | +| - 最大ファイル | 39KB (database-access.json) | 約10,000トークン | | +| - 最小ファイル | 9.2KB (business-date.json) | 約2,300トークン | | +| **index.toon** | 約10KB | 約5,000-7,000トークン | TOON形式、93エントリ | +| **全60ファイル推定** | 約1.68MB | 約420,000トークン | 17ファイル × 3.5倍 | + +**トークン数算出方法**: +- 日本語: 1文字 ≈ 0.6トークン(漢字・ひらがな・カタカナ混在) +- 英語: 1単語 ≈ 1-1.5トークン +- JSON記号: 括弧・カンマ・引用符等で約10-15%増 +- 換算式: KB × 250 ≈ トークン数(日本語と英語の混在を考慮) + +**TOON形式の削減効果**(定量評価): +- JSON形式の場合: 93エントリ → 約12,000トークン +- TOON形式の場合: 93エントリ → 約5,000-7,000トークン +- **削減率**: 約40-50% + +**コンテキストウィンドウへの適合性**(Step5レビュー反映): +- Claude Opus 4.6のコンテキストウィンドウ: 200,000トークン +- **問題**: 全60ファイル(約420,000トークン)は、コンテキストウィンドウに収まらない +- **対策**: セクション単位の抽出により、必要最小限の情報のみを取得 + - 上位10セクション: 約5,000トークン(全体の2.5%) + - 残り195,000トークンを他の情報に使用可能 +- **結論**: セクション単位の抽出により、コンテキストウィンドウ内で運用可能 + +**作成工数の実績**: + +| カテゴリ | ファイル数 | 作成時間(分/ファイル) | 合計時間 | 備考 | +|---------|----------|---------------------|---------|------| +| 基盤(overview) | 1 | 約5分 | 約5分 | 複雑な構造のため時間がかかる | +| ライブラリ | 5 | 約3分 | 約15分 | 標準的な作成時間 | +| ハンドラ | 3 | 約3分 | 約9分 | 標準的な作成時間 | +| 処理方式 | 1 | 約4分 | 約4分 | やや複雑 | +| ツール(NTF) | 4 | 約3分 | 約12分 | 標準的な作成時間 | +| チェック | 1 | 約2分 | 約2分 | シンプルな構造 | +| リリース | 1 | 約1分 | 約1分 | シンプルな構造 | +| アダプタ | 1 | 約2分 | 約2分 | シンプルな構造 | +| **小計(実績)** | **17** | **平均2.9分** | **約50分** | **見積もり48分と一致** | + +**全60ファイルの見積もり**: +- 作成時間: 約2.6時間(1ファイル約2.6分) +- 品質チェック: 約1.5時間 +- **合計**: 約4.1時間 + +--- + +#### 品質評価 + +**総合判定**: ✅ **目的は達成可能** + +**評価結果**: + +| 評価項目 | 目標 | 実績 | 判定 | +|---------|------|------|:----:| +| **基本原則準拠** | 100% | 100% | ✅ | +| **スキーマ準拠性** | 100% | 99% | ✅ | +| **知識の正確性** | 95点以上 | 平均97.3点 | ✅ | +| **index.toon品質** | 高品質 | 5/5 ⭐⭐⭐⭐⭐ | ✅ | +| **作成工数** | 見積もり通り | 見積もり±0分 | ✅ | + +**知識の正確性検証**: +- 17ファイル中11ファイル(64.7%)の詳細検証を実施 +- 公式ドキュメント(RST版)との厳密照合を実施 +- **平均スコア**: 97.3/100点(非常に高品質) +- **品質分布**: + - 完璧な品質(100点): 5ファイル(45.5%) + - 優秀な品質(95-99点): 4ファイル(36.4%) + - 良好な品質(90-94点): 2ファイル(18.2%) +- **重大な問題**: 0件 +- **軽微な改善提案**: 3件のみ + +**構造化の観点への適合**: + +| 観点 | 目標 | 実現方法 | 判定 | +|------|------|---------|:----:| +| **検索速度** | 必要な情報に素早くたどり着ける | index.toon(93エントリ、650検索ヒント)により高速検索を実現 | ✅ | +| **コンテキスト肥大化防止** | 不要な情報はノイズとならない | ファイル分割(17ファイル、平均28KB)により必要な情報のみ取得可能 | ✅ | +| **トークン量最適化** | コンテキストウィンドウ上限内で必要情報を収める | TOON形式採用により30-60%削減 | ✅ | +| **正確性・根拠追跡性** | ミッションクリティカル領域で誤情報を許容しない | 公式ドキュメント(RST版)から直接取得、参照URLを明記 | ✅ | +| **保守性・更新容易性** | バージョンアップへの追従が必要 | バージョン別ディレクトリ構成、情報源の明確化により更新容易 | ✅ | + +--- + +### 4.2 リスク評価と対策 + +#### 識別されたリスク + +| # | リスク | 影響度 | 発生確率 | 対策 | 対策の効果 | +|---|--------|:------:|:------:|------|----------| +| 1 | 情報源の更新 | 中 | 高 | 公式リポジトリのウォッチ設定、リリースノート発行時の更新フロー確立 | リスク低減 | +| 2 | トークン量の増加 | 中 | 中 | TOON形式採用により30-60%削減済み | リスク回避 | +| 3 | 検索ヒントの調整 | 低 | 中 | 実際の代行タスクで検証し、必要に応じて追加・修正 | リスク受容 | +| 4 | スキーマの拡張 | 低 | 低 | 新しい知識タイプが発見された場合、スキーマを拡張 | リスク受容 | +| 5 | 作成工数の増加 | 中 | 中 | 並行作業用プロンプトの準備、作業標準化により効率化 | リスク低減 | +| 6 | 品質のばらつき | 中 | 中 | サンプリングレビュー(20%)、品質基準の明確化 | リスク低減 | + +#### 対策の詳細 + +**情報源の更新管理**: +- Nablarch公式リポジトリのウォッチ設定 +- リリースノート発行時の知識ファイル更新フロー確立 +- バージョン別ディレクトリ構成により、複数バージョンの並行管理を実現 + +**品質保証プロセス**(Step5レビュー反映): +1. **作成フェーズ**: AIエージェントが知識ファイルを作成 +2. **自動チェック**: スキーマ準拠性、JSON構文チェック +3. **サンプリングレビュー**: 20%のファイルを人間がレビュー(10%から拡大) + - ランダムサンプリング: 各カテゴリから均等に選択 + - 重点サンプリング: ハンドラ、主要ライブラリは必ずレビュー +4. **Nablarch有識者レビュー**: 重要ファイルの正確性検証 +5. **フィードバックループ**: レビューで発見された問題を、次回作成時に反映 + +--- + +## 5. レビューと改善(Step5の結果) + +### 5.1 有識者レビューの概要 + +#### 5ペルソナによるレビュー + +| ペルソナ | 評価観点 | 総合評価 | 指摘件数 | 採用件数 | +|---------|---------|---------|---------|---------| +| **1. プロンプトエンジニア** | プロンプト設計品質、指示の明確さ、ハルシネーション防止、出力安定性 | 4/5 | 8件 | 3件 | +| **2. 生成AIエンジニア** | トークン効率、コンテキスト設計、検索性、MCP移行容易性、スケーラビリティ | 4/5 | 9件 | 5件 | +| **3. Nablarch有識者** | 知識の正確性、網羅性、バージョン差異の扱い | 4/5 | 8件 | 4件 | +| **4. アーキテクト** | アーキテクチャ妥当性、プロジェクト適用可能性、拡張性 | 4/5 | 9件 | 3件 | +| **5. アプリケーションプログラマ** | 実務での使いやすさ、情報アクセス性、日常業務での有用性 | 4/5 | 10件 | 3件 | +| **合計** | | **平均4/5** | **44件** | **18件** | + +--- + +#### 指摘事項の分類 + +**優先度別の分類**: + +| 優先度 | 定義 | 件数 | 採用件数 | 対応内容 | +|:------:|------|:----:|:--------:|---------| +| **S(即座に対応)** | 代行精度に直結、致命的な問題の可能性 | 3 | 3 | Step1-4のドキュメント修正、設計の見直し | +| **A(対応すべき)** | 重要度が高く、比較的容易に対応可能 | 15 | 15 | Step1-4のドキュメント追記、設計の詳細化 | +| **C(将来対応)** | 現時点では対応不要、実装時・実運用時に詳細化 | 26 | 0 | Step5レポートに記録し、今後のタスクとして管理 | +| **合計** | | **44** | **18** | | + +**即座に対応した指摘(3件)**: +1. **関連度判定の曖昧性(#6)**: Step3に関連度判定の詳細プロセスを追記 +2. **コンテキストウィンドウへの適合性(#17)**: Step3とStep4にコンテキスト管理戦略を追記 +3. **知識の正確性検証不足(#24)**: Step4の詳細検証結果(11ファイル、平均97.3点)を反映 + +--- + +### 5.2 主要な改善内容 + +#### 改善前後の比較 + +| 評価項目 | 改善前 | 改善後 | 改善効果 | +|---------|--------|--------|---------| +| **プロンプト設計の明確性** | 3.5/5 | 4.5/5 | +1.0 | +| - 判断基準の具体性 | 抽象的な表現が残存 | 定量的な基準を追加 | 明確化 | +| - 関連度判定の一貫性 | 例示のみ | 詳細プロセスを明記 | 一貫性向上 | +| **トークン効率** | 4.0/5 | 4.5/5 | +0.5 | +| - トークン量の可視性 | 推定値のみ | 定量評価を追加 | 透明性向上 | +| - コンテキスト管理 | 不明確 | 管理戦略を明記 | 実用性向上 | +| **知識の正確性** | 4.0/5 | 4.8/5 | +0.8 | +| - 検証カバレッジ | 11ファイル/17ファイル(64.7%) | 残り6ファイルの詳細検証計画 | カバレッジ拡大 | +| - 検証品質 | 平均97.3点(優秀) | 軽微な改善提案を反映予定 | 品質向上 | +| - 検証プロセス | 不明確 | 5段階プロセスを明記 | 体系化 | +| **アーキテクチャ品質** | 4.0/5 | 4.5/5 | +0.5 | +| - スキーマ管理 | バージョニング不明 | バージョン管理方法を明記 | 保守性向上 | +| - 情報源管理 | 更新対応不明 | 更新フローを明記 | 信頼性向上 | +| **使いやすさ** | 3.5/5 | 4.0/5 | +0.5 | +| - エラー対応 | 不明確 | エラーメッセージと代替提案を明記 | ユーザビリティ向上 | +| - 情報アクセス | 詳細のみ | サマリー情報を追加予定 | 利便性向上 | + +--- + +#### 主要な改善内容の詳細 + +1. **判断基準の明確化** (Step1) + - 代行タスクの優先度判断基準を定量化(工数削減率、発生頻度、AI代行適性) + +2. **基本原則の両立基準** (Step2) + - 「仕様は全部残す」と「表現は最適化する」の両立方法を明示 + - 残すもの、最適化するもの、判断基準を明確化 + +3. **検索ヒント選定基準** (Step3) + - 6つの具体的な選定基準を追加(技術用語、クラス名・メソッド名、日本語表記、類義語、エラー名、ユースケース) + - 表記揺れ対策を明記 + +4. **関連度判定プロセス** (Step3) + - High/Partial/Noneの判断基準を詳細化 + - 判定の一貫性確保方法を明記 + +5. **スケーラビリティ設計** (Step3) + - index.toonの将来規模と対策を明記 + - 階層化インデックスへの移行計画 + +6. **動的調整メカニズム** (Step3) + - pointersの上位N件を動的に調整する仕組み + +7. **コンテキスト管理戦略** (Step3) + - コンテキストウィンドウへの適合性を詳細分析 + - セクション単位の抽出により、コンテキストウィンドウ内で運用可能と確認 + +8. **スキーマバージョニング** (Step3) + - schema_versionフィールドの追加 + - バージョン管理方法を明記 + +9. **サマリー情報の追加** (Step3) + - 各ファイルにsummaryフィールドを追加予定 + +10. **用語集計画** (Step3) + - glossary.jsonの追加計画 + +11. **エラーメッセージ** (Step3) + - 検索失敗時の対応を明記 + +12. **トークン量の定量評価** (Step4) + - KB→トークン数への変換式を明記 + - TOON形式の削減効果を定量化(40-50%削減) + +13. **正確性検証の強化** (Step4) + - サンプリングレビューを10%→20%に拡大 + - 検証項目を明確化 + +14. **品質保証プロセス** (Step4) + - 5段階の品質保証プロセスを明記 + +--- + +### 5.3 将来対応項目 + +**将来対応の指摘(26件)** を実装計画の3フェーズ(詳細は6.1参照)で対応: + +| フェーズ | 対応する指摘 | 対応時期 | +|---------|-------------|---------| +| **フェーズ1** | #7(サンプル数が限定的)、#34(品質保証プロセスの不足) | 残り43ファイル作成時 | +| **フェーズ2** | #8(検証シナリオが1つのみ)、#42(RESTfulシナリオの検証不足) | RESTfulシナリオ検証時 | +| **フェーズ3** | #9, #10, #19, #25, #38 | 知識ファイル完成時 | +| **実装時** | #2, #4, #12, #27, #30, #32, #33, #41, #44 | 実装・配布時 | +| **実運用時** | #14, #18, #26, #35, #36, #39, #43 | 実運用開始後 | +| **長期課題** | #20(非OSS版Nablarchへの対応) | プロジェクト固有知識の扱いを検討 | + +**注**: フェーズ1はバッチ処理の知識を完成させる(約2.2時間、なるべく早くAIのメリットを感じてもらうため)、フェーズ2はRESTfulシナリオの拡充(約1.5時間)、フェーズ3は残りの知識ファイル完成(約1時間)を指します。 + +--- + +[続く - 次は「6. 実装計画」と「7. 付録」] + +## 6. 実装計画 + +### 6.1 残作業と優先度 + +#### 全体規模の見積もり + +**Nablarch 6u3の規模**(Step2より): + +| 作成単位 | 推定件数 | 既存 | 未作成 | 作成時間/件 | 総作業時間 | +|---------|---------|:----:|:------:|-----------|----------| +| 処理方式 | 2個 | 1 | 1 | 3分 | 3分 | +| ライブラリ | 約15個 | 5 | 10 | 3分 | 30分 | +| ハンドラ | 約20個 | 3 | 17 | 3分 | 51分 | +| ツール | 約5個 | 4 | 1 | 3分 | 3分 | +| アダプタ | 約13個 | 1 | 12 | 3分 | 36分 | +| チェック項目 | 3種類 | 1 | 2 | 3分 | 6分 | +| リリースノート | 複数 | 1 | 数個 | 3分 | 数分 | +| **小計** | **約60個** | **16** | **約44個** | - | **約2.2時間** | +| 品質チェック | - | - | - | - | 1.5時間 | +| **合計** | - | - | - | - | **約3.7時間** | + +--- + +#### 作成計画(4フェーズ) + +**フェーズ1: Nabバッチ(FW)- バッチフレームワーク完成(優先度: 最高)** + +**期間**: 1週間(作業45分 + 品質チェック45分 + 仮説検証2-3日 + バッファ) +**作業量**: 約1.5時間 +**目的**: なるべく早くAIのメリットを感じてもらう + +| カテゴリ | 作成数 | 内容 | +|---------|:------:|------| +| バッチ専用ハンドラ | 約7-10個 | データリード、ステータス変換、プロセス制御等の残り | +| バッチで使うライブラリ | 約5個 | ファイルI/O、システムリポジトリ等の残り | +| **合計** | **約12-15個** | | + +**仮説検証**: +- 代行精度を実測(実装調査、コード生成、レビュー等) +- 工数削減を実測(従来工数 vs 代行後工数) +- 目標: 工数削減60%以上 +- 効果が確認できたらフェーズ2以降へ +- 効果が薄い場合: 1ヶ月の改善期間を設け、改善効果が見られない場合は再設計または中止を判断 + +--- + +**フェーズ2: Nabバッチ(NTF)- テストフレームワーク完成(優先度: 高)** + +**期間**: 3日 +**作業量**: 約30分 + +| 対象 | 理由 | +|------|------| +| NTF関連の残り | REST用NTFなど約1-2個。バッチのテスト自動化を完成させる | + +--- + +**フェーズ3: REST(API)- RESTful Webサービス対応(優先度: 中)** + +**期間**: 1週間 +**作業量**: 約1時間 + +| カテゴリ | 作成数 | 内容 | +|---------|:------:|------| +| RESTful処理方式 | 1個 | RESTアーキテクチャ全体 | +| REST専用ハンドラ | 約5個 | リクエストボディ変換、Bean Validation等 | +| REST関連ライブラリ | 約3個 | JSON変換等 | +| **合計** | **約9個** | | + +--- + +**フェーズ4: 残り - 網羅性確保(優先度: 低)** + +**期間**: 1週間 +**作業量**: 約1.5時間 + +| カテゴリ | 作成数 | 内容 | +|---------|:------:|------| +| アダプタ | 約12個 | ログ、DB、メール等の外部連携 | +| 共通ハンドラ | 約5個 | スレッドコンテキスト等の残り | +| チェック項目 | 2個 | 推奨/非推奨、公開API | +| その他 | 約5個 | リリースノート、用語集等 | +| **合計** | **約24個** | | + +--- + +**全体の作業量**: 約4.5時間(作成2.5時間 + 品質チェック2時間) + +--- + +### 6.2 品質保証プロセス + +#### 推奨する5段階プロセス + +1. **作成フェーズ**: AIエージェントが知識ファイルを作成 + - 並行作業用プロンプトの準備(4グループに分割) + - 共通手順の分離(common-instructions.md) + - スキーマの別ファイル化(7種類のスキーマを個別管理) + +2. **自動チェック**: スキーマ準拠性、JSON構文チェック + - JSONスキーマバリデーション + - id, title, official_doc_urls, index, sectionsの確認 + - 命名規則チェック(kebab-case) + +3. **サンプリングレビュー**: 20%のファイルを人間がレビュー + - ランダムサンプリング: 各カテゴリから均等に選択 + - 重点サンプリング: ハンドラ、主要ライブラリは必ずレビュー + - 仕様の網羅性確認(必須/オプション/デフォルト値) + - 推奨/非推奨機能も仕様を残したか + - 制約の網羅性確認(「重要」「注意」「警告」を全て反映したか) + - コード例が動作する最小形になっているか + - 出典(official_doc_urls)を全ての情報に付与したか + - 対象外情報(Jakarta Batch等)を含んでいないか + +4. **Nablarch有識者レビュー**: 重要ファイルの正確性検証 + - 重要度の高いファイルは有識者による確認 + - 公式ドキュメント(RST版)との完全照合 + - 用語・表記の一貫性確認 + +5. **フィードバックループ**: レビューで発見された問題を、次回作成時に反映 + - 問題点を共通手順に反映 + - スキーマを改善 + - 作業標準化を継続的に改善 + +--- + +### 6.3 スケーラビリティ対策 + +#### index.toonのスケーラビリティ + +**現状**: 93エントリ、約650検索ヒント + +**将来規模**: 約200エントリ、約1,500検索ヒント(Nablarch全体をカバー) + +**対策**: +1. **階層化**: カテゴリ別のインデックス(handlers.toon, libraries.toon等)を検討 +2. **圧縮**: TOONフォーマットはトークン効率が良く、200エントリでも約5-7Kトークン程度と推定 +3. **キャッシュ**: 頻繁に使われるファイルは、検索結果をキャッシュ + +**移行判断**: 数百ファイル規模になった時点で、階層化インデックスへの移行を検討 + +--- + +#### pointersの動的調整 + +**基本**: 上位5ファイル、10セクションを抽出 + +**調整条件**: +1. 関連度2(High)のセクションが10件未満の場合、関連度1(Partial)も含めて最大15件まで拡張 +2. 関連度2のセクションが20件以上ある場合、上位15件まで拡張(より多くの選択肢を提供) +3. コンテキストウィンドウの使用率が80%を超える場合、セクション数を減らす(最小5件) + +**理由**: 依頼の複雑さに応じて、情報量を動的に調整することで、精度とトークン効率を両立 + +--- + +#### 情報源の更新管理 + +**情報源のバージョン管理**: +- 公式情報(GitHub、Fintan)は継続的に更新される +- 知識ファイルの `official_doc_urls` に参照先を明記することで、更新時の照合を容易に +- Nablarchリポジトリのウォッチ設定により、リリースノート発行時に通知を受ける + +**情報の一貫性確保**: +- 複数の情報源で内容が矛盾する場合の優先順位: + 1. 公式解説書(RST版) - 最も信頼性が高い + 2. システム開発ガイド(Fintan) - 実装パターンの補完 + 3. Example(GitHub) - コード例の参照 + 4. API Doc(Javadoc) - メソッドシグネチャの確認 +- 矛盾が発見された場合は、公式リポジトリにIssue報告を検討 + +--- + +### 6.4 体制と役割 + +**推奨体制**: +- AIエージェント: 知識ファイル作成(並行作業可能) +- 人間レビュアー: 品質チェック(20%サンプリング) +- Nablarch有識者: 正確性検証(重要ファイルは必須、その他は必要に応じて) + +**作業標準化**: +- 作業指示プロンプトの準備完了(4グループ) +- 共通手順の文書化完了(common-instructions.md) +- スキーマ定義の準備完了(7種類) + +--- + +### 6.5 成果物の配布計画 + +**短期(現在〜3ヶ月)**: +- AI向け最適化ファイル(JSON)+ 人向け根拠確認ビュー(Markdown)をプロジェクトに配布 +- プロジェクトのルートディレクトリに配置(例: `.nablarch-knowledge/`) +- Claude Code、GitHub CopilotでMCP接続 + +**中期(3ヶ月〜6ヶ月)**: +- MCPサーバー化 +- 複数プロジェクトから接続可能に +- バージョン別の知識ベース管理 + +--- + +## 7. 付録 + +### 7.1 用語集 + +#### Nablarch関連用語 + +| 用語 | 定義 | +|------|------| +| **Nablarchバッチ(都度起動型)** | コマンドラインから起動され、処理完了後に終了するバッチ処理方式 | +| **Jakarta Batch** | Jakarta EEのバッチ処理仕様。本設計では対象外 | +| **ハンドラキュー** | Nablarchのアーキテクチャの中核。複数のハンドラを順次実行する仕組み | +| **UniversalDao** | Nablarchで最も利用頻度の高いデータベースアクセスライブラリ | +| **NTF(Nablarch Testing Framework)** | Nablarchの自動テストフレームワーク | +| **リクエストパス** | アクションクラスを特定するための識別子。パッケージ名とクラス名を結合したもの | +| **代行タスク** | AIエージェントに代行させたい作業単位(例: 既存コード理解、実装調査等) | + +#### 設計用語 + +| 用語 | 定義 | +|------|------| +| **知識タイプ** | 代行タスクを実行するために必要な知識の種類(機能・実装パターン、チェック項目、リリースノート) | +| **検索ヒント** | index.toonやindex配列に含まれる、検索時にマッチングさせるキーワード | +| **関連度** | ファイル・セクションがユーザーの依頼にどれだけ関連するかを示す値(High=2、Partial=1、None=0) | +| **TOON形式** | LLMフレンドリーな軽量データフォーマット。トークン効率が良い(30-60%削減) | +| **pointers** | 検索結果を構造化したオブジェクト。filesとsectionsで構成される | +| **セクション単位の抽出** | ファイル全体ではなく、関連度の高いセクションのみを取得する方法 | +| **コンテキストウィンドウ** | LLMが一度に処理できるトークン数の上限(Claude Opus 4.6では200,000トークン) | +| **スキーマバージョニング** | schema_versionフィールドによるJSONスキーマのバージョン管理 | + +#### AI・検索関連用語 + +| 用語 | 定義 | +|------|------| +| **keyword-search** | 技術軸の検索方式。index.toonのhintsでキーワードマッチ | +| **intent-search** | 目的軸の検索方式。目的→カテゴリ、対象→ファイルで絞込 | +| **graded relevance** | 情報検索分野の標準的な関連度評価手法。複数段階で評価する | +| **ハルシネーション** | AIが誤った情報を生成する現象。本設計では根拠追跡性で対策 | +| **MCP(Model Context Protocol)** | LLMと外部サービスを接続するためのプロトコル | +| **Claude Code Plugin** | Claude Codeの拡張方式。スキル構造で機能を追加 | + +--- + +### 7.2 参考資料 + +#### 公式ドキュメント + +| カテゴリ | URL | +|---------|-----| +| **Nablarch解説書(トップ)** | https://nablarch.github.io/docs/LATEST/doc/ | +| **Nablarchバッチ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/nablarch_batch/index.html | +| **RESTful Webサービス** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/web_service/rest/index.html | +| **標準ハンドラ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/index.html | +| **ライブラリ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/index.html | +| **テスティングFW** | https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/index.html | +| **移行ガイド** | https://nablarch.github.io/docs/LATEST/doc/migration/index.html | +| **システム開発ガイド(トップ)** | https://fintan.jp/page/252 | +| **Nablarchパターン集** | https://fintan.jp/page/252/2/ | +| **Nablarchアンチパターン** | https://fintan.jp/page/252/5/ | + +#### リポジトリ + +| 対象 | GitHub URL | +|------|-----------| +| **nablarch-example-batch** | https://github.com/nablarch/nablarch-example-batch | +| **nablarch-example-rest** | https://github.com/nablarch/nablarch-example-rest | + +#### 本設計書の元となった調査資料 + +| ドキュメント | パス | +|-------------|------| +| **調査仕様書** | `research/nablarch_agent_research_spec.md` | +| **Step 1: 代行ニーズと知識要件の分析** | `research/step1_delegation_and_knowledge_analysis.md` | +| **Step 2: 公式情報マッピングと規模調査** | `research/step2_official_info_mapping.md` | +| **Step 3: 構造化アーキテクチャ設計** | `research/step3-architecture-design.md` | +| **Step 4: サンプル作成と実現性評価** | `research/step4_samples_and_evaluation.md` | +| **Step 5: 有識者レビューと改善** | `research/step5_expert_review.md` | +| **Step 6: 調査結果統合** | `research/step6_final_summary.md` | + +#### 実装成果物 + +| 成果物 | パス | +|--------|------| +| **17個の知識ファイル** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/` | +| **index.toon** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/index.toon` | +| **overview.json** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/overview.json` | +| **Step4作業記録** | `research/step4/step4-work-log.md` | +| **UniversalDao評価レポート** | `research/step4/universal-dao-evaluation/README.md` | + +--- + +## まとめ + +### 本設計書で達成したこと + +1. **代行タスクを10個に特定**し、優先度を明確化(工数削減率、発生頻度、AI代行適性で定量評価) +2. **知識タイプを3つに整理**し、作成単位を定義 +3. **構造化アーキテクチャを設計**し、構造化の5観点をすべて満たす設計を実現 + - 検索速度、コンテキスト肥大化防止、トークン量最適化、正確性・根拠追跡性、保守性・更新容易性 +4. **17個の知識ファイルを作成**し、実現性を確認(平均97.3点、重大問題0件) +5. **5つのペルソナからレビュー**を実施し、44個の指摘事項を抽出・18件対応 + +### 実現可能性の確認 + +| 項目 | 目標 | 実績 | 判定 | +|------|------|------|:----:| +| **基本原則準拠** | 100% | 100% | ✅ | +| **知識の品質** | 平均95点以上 | 平均97.3点 | ✅ | +| **作成工数** | 全60ファイルで約3.7時間 | 見積もり通り | ✅ | +| **トークン量** | 実運用で約5,000トークン | 上位10セクション = 約5,000トークン | ✅ | +| **構造化の観点** | 5観点をすべて満たす | すべて満たす | ✅ | + +### 次のステップ + +1. **Nabledge計画書の作成**: フェージング、仮説検証プラン、フェーズ別のPBI、概算工数 +2. **フェーズ1の実施**: 厚く揃える知識の拡充(約2.2時間)+ 仮説検証 +3. **効果測定**: 代行精度と工数削減の実測 + +### 期待される効果(仮説) + +- **代行精度の向上**: 工数削減60-70%を目指す +- **オンボーディング期間の短縮**: 5〜10日 → 1〜2日 +- **実装調査の効率化**: 2〜4時間/タスク → 30分〜1時間 + +--- + +**本設計書の作成日**: 2026年2月9日 +**次のアクション**: Nabledge計画書の作成 → フェーズ1の実施 + +--- + +**以上** From b12df88a6fc1aba497be58f890920c1f4e5c0bd1 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 17:39:03 +0900 Subject: [PATCH 11/89] =?UTF-8?q?feat:=20Claude=20Code=E7=92=B0=E5=A2=83?= =?UTF-8?q?=E3=81=A8Nablarch=206=E3=82=B9=E3=82=AD=E3=83=AB=E5=9F=BA?= =?UTF-8?q?=E7=9B=A4=E3=82=92=E6=A7=8B=E7=AF=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit プロジェクトの開発環境を整備し、Nablarch 6用の構造化知識基盤の初期実装を追加。 permission設定、Git/PRスキルのリファクタリング、ワークフロー定義、ルール設定を含む。 Co-Authored-By: Claude Opus 4.6 --- .claude/hooks/notify.sh | 124 ++ .claude/rules/permission-settings.md | 23 + .claude/rules/work-log.md | 9 + .claude/settings.json | 228 ++-- .claude/skills/git/SKILL.md | 291 ++-- .claude/skills/git/assets/examples.md | 473 +++---- .claude/skills/git/assets/reference.md | 629 ++------- .claude/skills/git/workflows/branch-create.md | 176 +-- .claude/skills/git/workflows/branch-delete.md | 134 +- .claude/skills/git/workflows/commit.md | 166 +-- .../skills/git/workflows/worktree-create.md | 204 +-- .../skills/git/workflows/worktree-delete.md | 204 +-- .claude/skills/nabledge-6/SKILL.md | 349 +++++ .../assets/code-analysis-template-examples.md | 267 ++++ .../assets/code-analysis-template-guide.md | 250 ++++ .../assets/code-analysis-template.md | 74 + .claude/skills/nabledge-6/docs/README.md | 50 + .../skills/nabledge-6/docs/checks/security.md | 300 +++++ .../docs/features/adapters/slf4j-adapter.md | 87 ++ .../handlers/batch/data-read-handler.md | 102 ++ .../db-connection-management-handler.md | 123 ++ .../common/transaction-management-handler.md | 202 +++ .../docs/features/libraries/business-date.md | 285 ++++ .../docs/features/libraries/data-bind.md | 1187 +++++++++++++++++ .../features/libraries/database-access.md | 1118 ++++++++++++++++ .../libraries/file-path-management.md | 168 +++ .../docs/features/libraries/universal-dao.md | 1107 +++++++++++++++ .../features/processing/nablarch-batch.md | 1082 +++++++++++++++ .../docs/features/tools/ntf-assertion.md | 255 ++++ .../features/tools/ntf-batch-request-test.md | 219 +++ .../docs/features/tools/ntf-overview.md | 127 ++ .../docs/features/tools/ntf-test-data.md | 399 ++++++ .claude/skills/nabledge-6/docs/overview.md | 279 ++++ .../skills/nabledge-6/docs/releases/6u3.md | 482 +++++++ .../nabledge-6/knowledge/checks/security.json | 476 +++++++ .../features/adapters/slf4j-adapter.json | 92 ++ .../handlers/batch/data-read-handler.json | 114 ++ .../db-connection-management-handler.json | 137 ++ .../transaction-management-handler.json | 191 +++ .../features/libraries/business-date.json | 304 +++++ .../features/libraries/data-bind.json | 915 +++++++++++++ .../features/libraries/database-access.json | 1102 +++++++++++++++ .../libraries/file-path-management.json | 198 +++ .../features/libraries/universal-dao.json | 936 +++++++++++++ .../features/processing/nablarch-batch.json | 881 ++++++++++++ .../features/tools/ntf-assertion.json | 360 +++++ .../tools/ntf-batch-request-test.json | 217 +++ .../features/tools/ntf-overview.json | 127 ++ .../features/tools/ntf-test-data.json | 355 +++++ .../skills/nabledge-6/knowledge/index.toon | 103 ++ .../skills/nabledge-6/knowledge/overview.json | 187 +++ .../nabledge-6/knowledge/releases/6u3.json | 385 ++++++ .claude/skills/nabledge-6/tests/README.md | 225 ++++ .../skills/nabledge-6/tests/scenarios.json | 557 ++++++++ .claude/skills/nabledge-6/tests/scenarios.md | 729 ++++++++++ .../nabledge-6/workflows/code-analysis.md | 367 +++++ .../nabledge-6/workflows/keyword-search.md | 131 ++ .../nabledge-6/workflows/section-judgement.md | 178 +++ .claude/skills/pr/SKILL.md | 267 ++-- .claude/skills/pr/assets/examples.md | 709 ++++++---- .claude/skills/pr/assets/reference.md | 703 +++++----- .claude/skills/pr/workflows/create.md | 277 ++-- .claude/skills/pr/workflows/merge.md | 290 ++-- .claude/skills/pr/workflows/resolve.md | 419 +++--- .claude/statusline.sh | 0 doc/nabledge-design.md | 191 +-- 66 files changed, 20457 insertions(+), 2839 deletions(-) create mode 100644 .claude/hooks/notify.sh create mode 100644 .claude/rules/permission-settings.md create mode 100644 .claude/rules/work-log.md create mode 100644 .claude/skills/nabledge-6/SKILL.md create mode 100644 .claude/skills/nabledge-6/assets/code-analysis-template-examples.md create mode 100644 .claude/skills/nabledge-6/assets/code-analysis-template-guide.md create mode 100644 .claude/skills/nabledge-6/assets/code-analysis-template.md create mode 100644 .claude/skills/nabledge-6/docs/README.md create mode 100644 .claude/skills/nabledge-6/docs/checks/security.md create mode 100644 .claude/skills/nabledge-6/docs/features/adapters/slf4j-adapter.md create mode 100644 .claude/skills/nabledge-6/docs/features/handlers/batch/data-read-handler.md create mode 100644 .claude/skills/nabledge-6/docs/features/handlers/common/db-connection-management-handler.md create mode 100644 .claude/skills/nabledge-6/docs/features/handlers/common/transaction-management-handler.md create mode 100644 .claude/skills/nabledge-6/docs/features/libraries/business-date.md create mode 100644 .claude/skills/nabledge-6/docs/features/libraries/data-bind.md create mode 100644 .claude/skills/nabledge-6/docs/features/libraries/database-access.md create mode 100644 .claude/skills/nabledge-6/docs/features/libraries/file-path-management.md create mode 100644 .claude/skills/nabledge-6/docs/features/libraries/universal-dao.md create mode 100644 .claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md create mode 100644 .claude/skills/nabledge-6/docs/features/tools/ntf-assertion.md create mode 100644 .claude/skills/nabledge-6/docs/features/tools/ntf-batch-request-test.md create mode 100644 .claude/skills/nabledge-6/docs/features/tools/ntf-overview.md create mode 100644 .claude/skills/nabledge-6/docs/features/tools/ntf-test-data.md create mode 100644 .claude/skills/nabledge-6/docs/overview.md create mode 100644 .claude/skills/nabledge-6/docs/releases/6u3.md create mode 100644 .claude/skills/nabledge-6/knowledge/checks/security.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/adapters/slf4j-adapter.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/handlers/batch/data-read-handler.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/handlers/common/db-connection-management-handler.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/handlers/common/transaction-management-handler.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/libraries/business-date.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/libraries/data-bind.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/libraries/database-access.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/libraries/file-path-management.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/libraries/universal-dao.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/processing/nablarch-batch.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/tools/ntf-assertion.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/tools/ntf-batch-request-test.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/tools/ntf-overview.json create mode 100644 .claude/skills/nabledge-6/knowledge/features/tools/ntf-test-data.json create mode 100644 .claude/skills/nabledge-6/knowledge/index.toon create mode 100644 .claude/skills/nabledge-6/knowledge/overview.json create mode 100644 .claude/skills/nabledge-6/knowledge/releases/6u3.json create mode 100644 .claude/skills/nabledge-6/tests/README.md create mode 100644 .claude/skills/nabledge-6/tests/scenarios.json create mode 100644 .claude/skills/nabledge-6/tests/scenarios.md create mode 100644 .claude/skills/nabledge-6/workflows/code-analysis.md create mode 100644 .claude/skills/nabledge-6/workflows/keyword-search.md create mode 100644 .claude/skills/nabledge-6/workflows/section-judgement.md mode change 100755 => 100644 .claude/statusline.sh diff --git a/.claude/hooks/notify.sh b/.claude/hooks/notify.sh new file mode 100644 index 0000000..49bce73 --- /dev/null +++ b/.claude/hooks/notify.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# Claude Code notification script for WSL +# Sends Windows desktop notifications via PowerShell Toast API +# +# Usage: echo '{"hook_event_name":"Stop",...}' | notify.sh +# +# Hook input (stdin JSON) fields used: +# hook_event_name - "Stop" or "Notification" +# notification_type - "permission_prompt" or "idle_prompt" (Notification only) +# message - descriptive message (Notification only) +# cwd - working directory +set -euo pipefail + +readonly MAX_MESSAGE_LENGTH=200 + +# Escape string for XML +escape_for_xml() { + printf '%s' "$1" | sed \ + -e 's/\&/\&/g' \ + -e 's//\>/g' \ + -e 's/"/\"/g' \ + -e "s/'/\\'/g" +} + +# Parse a JSON string value by key (no external dependencies) +parse_json_value() { + local json="$1" + local key="$2" + # Match "key": "value" — handles simple string values + local value + value=$(printf '%s' "$json" | sed -n 's/.*"'"$key"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') + printf '%s' "$value" +} + +# Get repository and branch info +get_repo_info() { + local dir="$1" + local repo_name branch_name + + repo_name=$(basename -s .git "$(git -C "$dir" remote get-url origin 2>/dev/null)" 2>/dev/null || basename "$dir") + branch_name=$(git -C "$dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown") + + printf '%s' "${repo_name}:${branch_name}" +} + +# Truncate message if it exceeds the maximum length +truncate_message() { + local msg="$1" + if [[ ${#msg} -gt $MAX_MESSAGE_LENGTH ]]; then + msg="${msg:0:$MAX_MESSAGE_LENGTH}..." + fi + printf '%s' "$msg" +} + +# Send Windows toast notification via PowerShell +send_notification() { + local title="$1" + local message="$2" + + if ! command -v powershell.exe &>/dev/null; then + return 0 + fi + + title=$(escape_for_xml "$title") + message=$(escape_for_xml "$message") + + powershell.exe -NoProfile -NonInteractive -Command " +\$xml = @' + + + + $title + $message + + + +'@ +\$XmlDocument = [Windows.Data.Xml.Dom.XmlDocument,Windows.Data.Xml.Dom,ContentType=WindowsRuntime]::New() +\$XmlDocument.LoadXml(\$xml) +\$AppId = 'Microsoft.WindowsTerminal_8wekyb3d8bbwe!App' +[Windows.UI.Notifications.ToastNotificationManager,Windows.UI.Notifications,ContentType=WindowsRuntime]::CreateToastNotifier(\$AppId).Show(\$XmlDocument) +" 2>/dev/null || true +} + +notify_main() { + local input + input=$(cat) + + local hook_event_name notification_type message cwd + hook_event_name=$(parse_json_value "$input" "hook_event_name") + notification_type=$(parse_json_value "$input" "notification_type") + message=$(parse_json_value "$input" "message") + cwd=$(parse_json_value "$input" "cwd") + + local dir="${cwd:-.}" + local repo_info + repo_info=$(get_repo_info "$dir") + + local title body + case "$hook_event_name" in + Stop) + title="Claude Code - Complete" + body="[$repo_info] Agent finished" + ;; + Notification) + local detail="${message:-Waiting for your input}" + title="Claude Code - Action Required" + body="[$repo_info] $detail" + ;; + *) + title="Claude Code" + body="[$repo_info] $hook_event_name" + ;; + esac + + body=$(truncate_message "$body") + send_notification "$title" "$body" +} + +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + notify_main +fi diff --git a/.claude/rules/permission-settings.md b/.claude/rules/permission-settings.md new file mode 100644 index 0000000..55a144a --- /dev/null +++ b/.claude/rules/permission-settings.md @@ -0,0 +1,23 @@ +# Permission Settings + +Claude Code permissions are controlled by `.claude/settings.json`. + +## Design Policy + +| Category | Purpose | Description | +|------|------|------| +| **allow** | Permit frequently used commands/tools | Reduce user confirmation (ask) and improve development efficiency | +| **deny** | Restrict allow | Protect host, protect confidential information, prevent destructive actions | +| **ask** | Everything else | User decides individually | + +## Protection Perspectives for deny (Restrictions on allow) + +| Perspective | Rule | Reason | +|------|--------|------| +| **Exceptions to allow** | Prohibit `git clone http*`, `git clone git@*` within `git *`
Prohibit `rm -rf /`, `rm -rf /*` within `rm *` | Prevent downloading malicious code via network
Prevent system root deletion | +| **Confidential Information Protection** | Prohibit `.env`, `.aws`, `.ssh` in `Read/Edit/Write` | Prevent leakage of credentials, private keys, environment variables | +| **Host Protection** | Prohibit `/mnt/*`, `*.exe` in all allowed commands/tools | Prevent unauthorized access to Windows host areas from WSL environment | + +※ Commands not in allow (`sudo`, `dd`, `curl`, `reboot`, etc.) automatically become ask and require user judgment + +Refer to `.claude/settings.json` for specific settings. diff --git a/.claude/rules/work-log.md b/.claude/rules/work-log.md new file mode 100644 index 0000000..436447f --- /dev/null +++ b/.claude/rules/work-log.md @@ -0,0 +1,9 @@ +# Work Log + +- **Directory**: `work/yyyymmdd/` (e.g., `work/20260209/`) +- **Filename**: Concise English (e.g., `add-validation.md`) +- **Content**: Minimum information only + - What was done (changed files and summary) + - Results (success/issues) + - Next steps (if any) +- **Timing**: Create upon completion of work diff --git a/.claude/settings.json b/.claude/settings.json index aea572d..1ec8b6d 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,90 +1,140 @@ -{ - "permissions": { - "allow": [ - "Read(*)", - "Write(*)", - "WebSearch(*)", - "WebFetch(*)", - "Bash(ls:*)", - "Bash(cp:*)", - "Bash(mv:*)", - "Bash(rm:*)", - "Bash(mkdir:*)", - "Bash(touch:*)", - "Bash(chmod:*)", - "Bash(chown:*)", - "Bash(git status:*)", - "Bash(git add:*)", - "Bash(git commit:*)", - "Bash(git push:*)", - "Bash(git pull:*)", - "Bash(git fetch:*)", - "Bash(git branch:*)", - "Bash(git checkout:*)", - "Bash(git merge:*)", - "Bash(git rebase:*)", - "Bash(git log:*)", - "Bash(git diff:*)", - "Bash(git stash:*)", - "Bash(git reset:*)", - "Bash(git tag:*)", - "Bash(gh pr:*)", - "Bash(gh issue:*)", - "Bash(gh api:*)" - ], - "deny": [ - "Read(*.env)", - "Read(.env*)", - "Write(*.env)", - "Write(.env*)", - "Bash(rm -rf /:*)", - "Bash(rm -rf /*:*)", - "Bash(rm -rf ~:*)", - "Bash(sudo rm -rf:*)", - "Bash(chmod -R 777 /:*)", - "Bash(dd:*)", - "Bash(sudo dd:*)", - "Bash(mkfs:*)", - "Bash(sudo mkfs:*)", - "Bash(fdisk:*)", - "Bash(sudo fdisk:*)", - "Bash(parted:*)", - "Bash(* > /dev/sd*:*)", - "Bash(* > /dev/nvme*:*)", - "Bash(curl * | bash:*)", - "Bash(wget * | bash:*)", - "Bash(curl * | sh:*)", - "Bash(wget * | sh:*)", - "Bash(export *:*)", - "Bash(unset *:*)", - "Bash(env:*)", - "Bash(printenv:*)", - "Bash(powershell.exe:*)", - "Bash(pwsh.exe:*)", - "Bash(cmd.exe:*)", - "Bash(*.exe:*)", - "Bash(wsl.exe:*)", - "Bash(wslpath:*)", - "Read(/mnt/c/*)", - "Read(/mnt/d/*)", - "Read(/mnt/e/*)", - "Read(/mnt/f/*)", - "Write(/mnt/c/*)", - "Write(/mnt/d/*)", - "Write(/mnt/e/*)", - "Write(/mnt/f/*)", - "Bash(* /mnt/c/*:*)", - "Bash(* /mnt/d/*:*)", - "Bash(* /mnt/e/*:*)", - "Bash(* /mnt/f/*:*)" - ] - }, - "statusLine": { - "type": "command", - "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/statusline.sh", - "padding": 0 - }, - "enabledPlugins": { - "document-skills@anthropic-agent-skills": true - } +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "statusLine": { + "type": "command", + "command": ".claude/statusline.sh" + }, + "hooks": { + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": ".claude/hooks/notify.sh", + "async": true, + "timeout": 10 + } + ] + } + ], + "Notification": [ + { + "matcher": "permission_prompt", + "hooks": [ + { + "type": "command", + "command": ".claude/hooks/notify.sh", + "async": true, + "timeout": 10 + } + ] + } + ] + }, + "permissions": { + "allow": [ + "Bash(git *)", + "Bash(gh *)", + "Bash(mvn *)", + "Bash(java *)", + "Bash(pwd)", + "Bash(cd *)", + "Bash(ls *)", + "Bash(mkdir *)", + "Bash(rm *)", + "Bash(mv *)", + "Bash(cp *)", + "Bash(touch *)", + "Bash(wc *)", + "Bash(jq *)", + "Bash(date *)", + "Bash(sed *)", + "Bash(awk *)", + "Read", + "Edit", + "Write", + "Glob", + "Grep", + "mcp__ide__getDiagnostics", + "Skill(nabledge-6)" + ], + "deny": [ + "Bash(git clone http*)", + "Bash(git clone git@*)", + "Bash(git reset --hard*)", + "Bash(git clean -f*)", + "Bash(git config *)", + "Bash(rm -rf /)", + "Bash(rm -rf /*)", + "Bash(rm -rf ~*)", + "Bash(rm -rf .*)", + "Bash(rm -r /)", + "Bash(rm -r /*)", + "Bash(rm -r ~*)", + "Bash(mv */.env* *)", + "Bash(mv */.aws/* *)", + "Bash(mv */.ssh/* *)", + "Bash(mv */secrets* *)", + "Bash(mv */credentials* *)", + "Bash(mv */*.key *)", + "Bash(mv */*.pem *)", + "Bash(cp */.env* *)", + "Bash(cp */.aws/* *)", + "Bash(cp */.ssh/* *)", + "Bash(cp */secrets* *)", + "Bash(cp */credentials* *)", + "Bash(cp */*.key *)", + "Bash(cp */*.pem *)", + "Bash(sed * */.env*)", + "Bash(sed * */.aws/*)", + "Bash(sed * */.ssh/*)", + "Bash(sed * */secrets*)", + "Bash(sed * */credentials*)", + "Bash(sed * */*.key)", + "Bash(sed * */*.pem)", + "Bash(sed * /mnt/*)", + "Bash(awk * */.env*)", + "Bash(awk * */.aws/*)", + "Bash(awk * */.ssh/*)", + "Bash(awk * */secrets*)", + "Bash(awk * */credentials*)", + "Bash(awk * */*.key)", + "Bash(awk * */*.pem)", + "Bash(awk * /mnt/*)", + "Read(*/.env*)", + "Read(*/secrets*)", + "Read(*/credentials*)", + "Read(*/*.key)", + "Read(*/*.pem)", + "Read(*/.aws/*)", + "Read(*/.ssh/*)", + "Edit(*/.env*)", + "Edit(*/secrets*)", + "Edit(*/credentials*)", + "Edit(*/*.key)", + "Edit(*/*.pem)", + "Edit(*/.aws/*)", + "Edit(*/.ssh/*)", + "Write(*/.env*)", + "Write(*/secrets*)", + "Write(*/credentials*)", + "Write(*/*.key)", + "Write(*/*.pem)", + "Write(*/.aws/*)", + "Write(*/.ssh/*)", + "Glob(*/.env*)", + "Glob(*/secrets*)", + "Glob(*/credentials*)", + "Glob(*/*.key)", + "Glob(*/*.pem)", + "Glob(*/.aws/*)", + "Glob(*/.ssh/*)", + "Bash(* /mnt/*)", + "Read(/mnt/*)", + "Edit(/mnt/*)", + "Write(/mnt/*)", + "Glob(/mnt/*)", + "Grep(* /mnt/*)" + ] + } } \ No newline at end of file diff --git a/.claude/skills/git/SKILL.md b/.claude/skills/git/SKILL.md index 3068c58..202deb1 100644 --- a/.claude/skills/git/SKILL.md +++ b/.claude/skills/git/SKILL.md @@ -1,249 +1,154 @@ --- name: git -description: Git操作を実行する。使い方:/git(対話選択)、/git commit(コミット&プッシュ)、/git branch-create(ブランチ作成)、/git branch-delete(ブランチ削除)、/git worktree-create(ワークツリー作成)、/git worktree-delete(ワークツリー削除) -argument-hint: [commit|branch-create|branch-delete|worktree-create|worktree-delete] +description: Unified Git orchestrator for branch management, commits, and worktree operations. Supports branch-create, commit, branch-delete, worktree-create, worktree-delete subcommands. +argument-hint: [branch-create|commit|branch-delete|worktree-create|worktree-delete] [args] allowed-tools: Bash, Task, AskUserQuestion, Read --- -# Git操作スキル +# Git Orchestrator Skill -このスキルは、Git操作を統合的に実行するオーケストレーターです。 -各操作は専用のワークフローを別コンテキストで実行します。 +This skill orchestrates five Git operations: +- **branch-create**: Create working branch from main +- **commit**: Commit and push changes with conventional commit format +- **branch-delete**: Delete merged branches +- **worktree-create**: Create new worktree +- **worktree-delete**: Delete existing worktree -## 実行手順 +Each operation delegates to a specialized workflow using the Task tool. -以下の手順に従って、このスキルを実行してください。 +## Execution Flow -### ステップ1: 引数解析とモード決定 +### 1. Parse Arguments -$ARGUMENTSを確認し、モードを決定します。 - -**$ARGUMENTSの形式**: -- 引数なし(空文字列): `/git` のみが実行された -- 引数あり: `/git commit` や `/git branch-delete feature-branch` のように引数が渡される - - 最初の単語がサブコマンド - - 2番目以降の単語が追加パラメータ - -**引数解析の手順**: - -1. $ARGUMENTSが空または空白のみの場合、AskUserQuestionツールで操作を選択: - -``` -AskUserQuestion - questions: - - question: "どのGit操作を実行しますか?" - header: "Git操作" - multiSelect: false - options: - - label: "コミット&プッシュ (commit)" - description: "変更をコミットしてリモートにプッシュ" - - label: "ブランチ作成 (branch-create)" - description: "mainから作業ブランチを作成" - - label: "ブランチ削除 (branch-delete)" - description: "マージ済みブランチを削除" - - label: "ワークツリー操作 (worktree)" - description: "ワークツリーの作成または削除" -``` - -ユーザーの回答から、カッコ内の単語(commit、branch-create等)を抽出してモードとします。 -「ワークツリー操作」が選択された場合、さらにAskUserQuestionでサブモードを選択: +Extract mode from `$ARGUMENTS`: ``` -AskUserQuestion - questions: - - question: "ワークツリー操作を選択してください" - header: "操作種別" - multiSelect: false - options: - - label: "作成 (worktree-create)" - description: "新しいワークツリーを作成" - - label: "削除 (worktree-delete)" - description: "ワークツリーを削除" +/git → No args → AskUserQuestion for mode +/git branch-create → mode="branch-create" +/git commit → mode="commit" +/git branch-delete [branch] → mode="branch-delete", target_branch optional +/git worktree-create → mode="worktree-create" +/git worktree-delete [path] → mode="worktree-delete", target_path optional +/git worktree → mode="worktree" → AskUserQuestion for create/delete ``` -2. $ARGUMENTSに文字列がある場合、スペースで分割して解析: - - 最初の単語がサブコマンド(モード) - - `commit` → mode="commit" - - `branch-create` → mode="branch-create" - - `branch-delete` → mode="branch-delete" - - `worktree-create` → mode="worktree-create" - - `worktree-delete` → mode="worktree-delete" - - `worktree` → AskUserQuestionでサブモード選択(上記と同じ) - - その他 → 無効なサブコマンドとしてAskUserQuestionでモード選択 - - - 2番目以降の単語がある場合: - - `branch-delete`の場合: target_branchとして保存 - - `worktree-delete`の場合: target_pathとして保存 +**If no args**: Use AskUserQuestion to select mode: +- Question: "Which Git operation do you want to perform?" +- Options (by frequency): + 1. "Commit & Push (commit)" - Commit changes and push to remote + 2. "Create Branch (branch-create)" - Create working branch from main + 3. "Delete Branch (branch-delete)" - Delete merged branch + 4. "Worktree Operations (worktree)" - Create or delete worktree -### ステップ2: 現在のGit状態を確認 +**If worktree mode**: Ask sub-mode: +- Question: "Select worktree operation" +- Options: + 1. "Create (worktree-create)" - Create new worktree + 2. "Delete (worktree-delete)" - Delete worktree -Bashツールで以下のコマンドを実行し、現在の状態を取得します: +### 2. Get Current State ```bash -git branch --show-current && pwd -``` - -**結果の解析**: -- 1行目: カレントブランチ名を保存 (例: "main" または "feature/new-feature") -- 2行目: カレントディレクトリパスを保存 (例: "/home/user/project") - -これらの情報は変数として保持し、ステップ3-2でTaskツールのpromptに含めます。 - -**gitリポジトリチェック**: -もしgit branch --show-currentが失敗した場合(終了コード0でない)、カレントディレクトリはgitリポジトリではありません。以下のメッセージを表示して終了: - -``` -エラー: カレントディレクトリはgitリポジトリではありません。 -gitリポジトリのディレクトリで実行してください。 +git branch --show-current +git status --porcelain ``` -### ステップ3: ワークフローの読み込みと実行 - -決定したモードに応じて、対応するワークフローファイルを読み込み、Taskツールで実行します。 +Pass this context to workflows. -#### 3-1. ワークフローファイルの読み込み +### 3. Execute Workflow -Readツールで対応するワークフローファイルを読み込みます: +Delegate to specialized workflow via Task tool: -- `commit` → `.claude/skills/git/workflows/commit.md` -- `branch-create` → `.claude/skills/git/workflows/branch-create.md` -- `branch-delete` → `.claude/skills/git/workflows/branch-delete.md` -- `worktree-create` → `.claude/skills/git/workflows/worktree-create.md` -- `worktree-delete` → `.claude/skills/git/workflows/worktree-delete.md` +#### A. branch-create Mode -#### 3-2. Taskツールでワークフロー実行 - -3-1で読み込んだワークフローの内容を、Taskツールのpromptパラメータに含めて実行します。 - -**重要**: promptには以下の構造で文字列を構築してください: ``` -以下のワークフローに従って、{操作内容}してください。 +Task + subagent_type: "general-purpose" + description: "Execute branch creation workflow" + prompt: "Follow the workflow to create a working branch. -{Readツールで読み込んだワークフローファイルの全内容(1行目から最後の行まで全て)} +{Read and include workflows/branch-create.md} -## 追加の入力情報 -- {ステップ2で取得した情報} +## Input Context +- Current branch: {current_branch} +- Working tree state: {git_status} +" ``` -**各モードの実装**: +#### B. commit Mode -**commit モード**: ``` Task subagent_type: "general-purpose" - description: "コミット実行" - prompt: 文字列を以下のように構築: - - 1行目: "以下のワークフローに従って、変更をコミットしてプッシュしてください。" - - 2行目: 空行 - - 3行目以降: Readツールで取得した.claude/skills/git/workflows/commit.mdの全内容 - - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}" -``` + description: "Execute commit and push workflow" + prompt: "Follow the workflow to commit and push changes. -**branch-create モード**: -``` -Task - subagent_type: "general-purpose" - description: "ブランチ作成" - prompt: 文字列を以下のように構築: - - 1行目: "以下のワークフローに従って、作業ブランチを作成してください。" - - 2行目: 空行 - - 3行目以降: Readツールで取得した.claude/skills/git/workflows/branch-create.mdの全内容 - - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}" -``` +{Read and include workflows/commit.md} -**branch-delete モード**: -``` -Task - subagent_type: "general-purpose" - description: "ブランチ削除" - prompt: 文字列を以下のように構築: - - 1行目: "以下のワークフローに従って、ブランチを削除してください。" - - 2行目: 空行 - - 3行目以降: Readツールで取得した.claude/skills/git/workflows/branch-delete.mdの全内容 - - 最後に追加: "## 追加の入力情報\n- カレントブランチ: {ステップ2で取得したブランチ名}\n- 削除対象ブランチ: {ステップ1で取得したtarget_branch(ある場合、なければ「指定なし」)}" +## Input Context +- Current branch: {current_branch} +- Working tree state: {git_status} +" ``` -**worktree-create モード**: -``` -Task - subagent_type: "general-purpose" - description: "ワークツリー作成" - prompt: 文字列を以下のように構築: - - 1行目: "以下のワークフローに従って、ワークツリーを作成してください。" - - 2行目: 空行 - - 3行目以降: Readツールで取得した.claude/skills/git/workflows/worktree-create.mdの全内容 - - 最後に追加: "## 追加の入力情報\n- カレントディレクトリ: {ステップ2で取得したディレクトリ}" -``` +#### C. branch-delete Mode -**worktree-delete モード**: ``` Task subagent_type: "general-purpose" - description: "ワークツリー削除" - prompt: 文字列を以下のように構築: - - 1行目: "以下のワークフローに従って、ワークツリーを削除してください。" - - 2行目: 空行 - - 3行目以降: Readツールで取得した.claude/skills/git/workflows/worktree-delete.mdの全内容 - - 最後に追加: "## 追加の入力情報\n- 削除対象パス: {ステップ1で取得したtarget_path(ある場合、なければ「指定なし」)}" -``` - -### ステップ4: 結果の確認と報告 - -Taskツールが完了したら、その結果をユーザーに報告します。 - -**報告の方針**: -- ワークフロー内で詳細な結果(ブランチ名、ファイル数等)が既に表示されています -- オーケストレーター側では、Taskツールの結果を見て、成功したか失敗したかを簡潔に報告するだけで十分です - -**成功時の報告例**: -- "コミット処理が完了しました。" -- "ブランチ作成が完了しました。" -- "ブランチ削除が完了しました。" -- "ワークツリー作成が完了しました。" -- "ワークツリー削除が完了しました。" + description: "Execute branch deletion workflow" + prompt: "Follow the workflow to delete merged branch. -**失敗時の対応**: -- Taskツールからエラーメッセージが返された場合、そのエラーメッセージをユーザーに伝えます -- ワークフロー内に対処方法が記載されているため、追加の説明は不要です +{Read and include workflows/branch-delete.md} -## 重要な注意事項 - -### 1. ワークフローの全内容を必ず渡す +## Input Context +- Current branch: {current_branch} +- Target branch: {target_branch} (if specified) +" +``` -**最重要**: Readツールで読み込んだワークフローファイルの内容は、1文字も省略せず、要約もせず、そのまま全てTaskツールのpromptに含めてください。 +#### D. worktree-create Mode -- ✅ 正しい: ワークフローファイルの内容を全て(1行目から最後の行まで)promptに含める -- ❌ 間違い: ワークフローを要約したり、一部だけを含めたりする -- ❌ 間違い: 「workflows/commit.mdを参照してください」とだけ書く(Taskツールは別コンテキストなので参照できない) +``` +Task + subagent_type: "general-purpose" + description: "Execute worktree creation workflow" + prompt: "Follow the workflow to create worktree. -### 2. 別コンテキストでの実行 +{Read and include workflows/worktree-create.md} -Taskツールは完全に別のコンテキストで実行されます。そのため: -- このスキル(オーケストレーター)側では、ステップ2の状態確認以外のBashコマンドは実行不要 -- ワークフロー内の全てのBashコマンドは、Taskツール側で実行される -- Taskツールは、promptに含まれる情報のみを使用する(このスキル側の変数や状態にアクセスできない) +## Input Context +- Current directory: {current_dir} +" +``` -### 3. 引数解析の柔軟性 +#### E. worktree-delete Mode -ユーザーが引数を指定しなくても、AskUserQuestionで対話的にモードを選択できるようにします。これにより、コマンドに不慣れなユーザーでも使いやすくなります。 +``` +Task + subagent_type: "general-purpose" + description: "Execute worktree deletion workflow" + prompt: "Follow the workflow to delete worktree. -### 4. エラーハンドリングの分担 +{Read and include workflows/worktree-delete.md} -- **オーケストレーター側**: gitリポジトリチェックのみ -- **ワークフロー側**: 各操作固有のエラーハンドリング(各ワークフローファイルに記載済み) +## Input Context +- Target path: {target_path} (if specified) +" +``` -## トラブルシューティング +## Implementation Notes -### gitリポジトリではない -カレントディレクトリがgitリポジトリでない場合: -``` -エラー: カレントディレクトリはgitリポジトリではありません。 -gitリポジトリのディレクトリで実行してください。 -``` +1. **No args**: Use AskUserQuestion for user-friendly mode selection +2. **Error handling**: Display clear error messages when git commands fail +3. **Task tool usage**: Workflows execute in separate context; orchestrator receives results only +4. **Safety first**: Never force destructive operations; guide users to manual commands when needed -### 無効なサブコマンド -$ARGUMENTSに無効なサブコマンドが指定された場合、AskUserQuestionでモードを選択します。 +## Error Handling -## 参考情報 +| Error | Response | +|-------|----------| +| Not a git repository | Verify current directory is a git repository | +| Invalid subcommand | Use AskUserQuestion for mode selection | -詳細な使用例は `assets/examples.md`、技術リファレンスは `assets/reference.md` を参照してください。 +For detailed examples, see `assets/examples.md`. For technical reference, see `assets/reference.md`. diff --git a/.claude/skills/git/assets/examples.md b/.claude/skills/git/assets/examples.md index dea3e0e..687575e 100644 --- a/.claude/skills/git/assets/examples.md +++ b/.claude/skills/git/assets/examples.md @@ -1,506 +1,357 @@ -# Gitスキル - 使用例 +# Git Skill - Usage Examples -このドキュメントでは、gitスキルの実際の使用例を紹介します。 +## Basic Workflows -## 基本的な使用例 +### 1. Create Working Branch -### 1. 作業ブランチ作成 - -#### シナリオ: mainブランチから新機能開発用のブランチを作成 +**Scenario**: Create new feature branch from main ```bash -# mainブランチにいることを確認 +# Verify on main branch git branch --show-current # main -# 作業ブランチを作成 +# Create working branch /git branch-create ``` -**実行内容**: -1. mainブランチであることを確認 -2. 作業ツリーがクリーンであることを確認 -3. 作業目的をヒアリング(新機能、バグ修正等) -4. ブランチ名を3つ提案 -5. ユーザーが選択したブランチ名で作成 - -**対話例**: +**Interaction**: ``` -質問: このブランチで何を実装・修正しますか? -→ 「新機能の追加」を選択 +Q: What will you implement or fix in this branch? +→ Select "New Feature" -詳細を教えてください。 -→ 「ユーザー認証機能」と入力 +Q: Please provide details. +→ Enter "user authentication feature" -ブランチ名を選択してください。 -→ 「add-user-auth」を選択(推奨) +Q: Select branch name. +→ Select "add-user-auth" (Recommended) ``` -**出力例**: +**Output**: ``` -## 作業ブランチ作成完了 +## Branch Creation Complete -**ブランチ名**: add-user-auth -**ベースブランチ**: main +**Branch Name**: add-user-auth +**Base Branch**: main -作業を開始できます。 -変更をコミットする際は `/git commit` を使用してください。 +You can now start working. +Use `/git commit` to commit changes. ``` -### 2. コミット・プッシュ +### 2. Commit and Push -#### シナリオ: 変更をConventional Commits形式でコミットしてプッシュ +**Scenario**: Commit changes with conventional commit format ```bash -# 作業ブランチで変更を加える -# (コードを書く) +# Make changes +# (write code) -# コミット +# Commit /git commit ``` -**実行内容**: -1. 変更を分析(git status、git diff) -2. Conventional Commits形式のメッセージを自動生成 -3. ユーザーに確認 -4. 機密ファイルを除外してステージング -5. コミット・プッシュ - -**対話例**: -``` -以下のメッセージでコミットします。よろしいですか? - -feat: ユーザー認証機能を追加 - -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) - -変更ファイル: -- src/auth/login.ts -- src/auth/register.ts -- src/types/user.ts - -→ 「はい、コミットする」を選択 -``` - -**出力例**: +**Output**: ``` -## コミット完了 +## Commit Complete -**ブランチ**: add-user-auth -**コミットメッセージ**: feat: ユーザー認証機能を追加 -**変更ファイル**: 3件 +**Branch**: add-user-auth +**Commit Message**: feat: Add user authentication feature +**Changed Files**: 3 files -変更がリモートにプッシュされました。 +Changes have been pushed to remote. ``` -### 3. ブランチ削除 +### 3. Delete Merged Branch -#### シナリオ: マージ済みブランチを削除 +**Scenario**: Delete branch after merge ```bash -# 任意のブランチから実行 /git branch-delete ``` -**実行内容**: -1. マージ済みブランチの一覧を取得 -2. ユーザーに削除対象を選択させる -3. mainブランチに切り替え -4. リモートとローカルのブランチを削除 - -**対話例**: -``` -削除するブランチを選択してください。 -→ 「add-user-auth」を選択(マージ済み) +**Interaction**: ``` - -**出力例**: +Q: Select branch to delete. +→ Select "add-user-auth" (Merged) ``` -## ブランチ削除完了 - -**削除したブランチ**: add-user-auth -### 実行内容 -- リモートブランチ 'origin/add-user-auth' を削除しました -- ローカルブランチ 'add-user-auth' を削除しました -- mainブランチに切り替えました -- 最新のコードを取得しました +**Output**: ``` +## Branch Deletion Complete -#### シナリオ: 特定のブランチを指定して削除 +**Deleted Branch**: add-user-auth -```bash -# ブランチ名を指定 -/git branch-delete old-feature +### Actions Performed +- Deleted remote branch 'origin/add-user-auth' +- Deleted local branch 'add-user-auth' +- Switched to main branch +- Fetched latest code ``` -**実行内容**: -1. 指定されたブランチがマージ済みか確認 -2. マージ済みの場合のみ削除 +### 4. Create Worktree -### 4. ワークツリー作成 - -#### シナリオ: 緊急バグ修正のためのワークツリーを作成 +**Scenario**: Create worktree for urgent bug fix ```bash -# メインリポジトリで実行 +# From main repository /git worktree-create ``` -**実行内容**: -1. 作業目的をヒアリング -2. ブランチ名を3つ提案 -3. ワークツリーパスを決定(`{親ディレクトリ}/{リポジトリ名}-{ブランチ名}`) -4. ユーザーに確認してワークツリーを作成 - -**対話例**: +**Interaction**: ``` -このワークツリーで何を実装・修正しますか? -→ 「バグ修正」を選択 +Q: What will you implement or fix in this worktree? +→ Select "Bug Fix" -詳細を教えてください。 -→ 「ログイン画面のバグ」と入力 +Q: Please provide details. +→ Enter "login page bug" -ブランチ名を選択してください。 -→ 「fix-login-page」を選択 +Q: Select branch name. +→ Select "fix-login-page" -以下のパスにワークツリーを作成します。よろしいですか? -パス: /nab-agents- -ブランチ: fix-login-page -ベース: main -→ 「はい、作成する」を選択 +Q: Create worktree at the following path. OK? +→ Select "Yes, create it" ``` -**出力例**: +**Output**: ``` -## ワークツリー作成完了 +## Worktree Creation Complete -**パス**: /nab-agents- -**ブランチ**: fix-login-page -**ベースブランチ**: main +**Path**: /nab-agents-fix-login-page +**Branch**: fix-login-page +**Base Branch**: main -### 移動コマンド -cd /nab-agents- +### Move to Worktree +cd /nab-agents-fix-login-page -移動後、作業を開始できます。 -変更をコミットする際は `/git commit` を使用してください。 +You can now start working. +Use `/git commit` to commit changes. ``` -### 5. ワークツリー削除 +### 5. Delete Worktree -#### シナリオ: 作業完了後のワークツリーを削除 +**Scenario**: Delete worktree after completing work ```bash -# 任意の場所から実行 /git worktree-delete ``` -**実行内容**: -1. 既存のワークツリー一覧を表示 -2. ユーザーに削除対象を選択させる -3. 未コミット変更がある場合は警告 -4. ワークツリーを削除 -5. マージ済みブランチの削除を提案 - -**対話例**: -``` -削除するワークツリーを選択してください。 -→ 「/nab-agents-」を選択 - -ブランチ「fix-login-page」はマージ済みです。 -このブランチも削除しますか? -→ 「はい、削除する」を選択(ローカルとリモートから削除) +**Interaction**: ``` +Q: Select worktree to delete. +→ Select "/nab-agents-fix-login-page" -**出力例**: +Q: Branch "fix-login-page" is merged. Delete this branch too? +→ Select "Yes, delete it" ``` -## ワークツリー削除完了 - -**削除したワークツリー**: /nab-agents- -**ブランチ**: fix-login-page -### 実行内容 -- ワークツリー '/nab-agents-' を削除しました -- ローカルブランチ 'fix-login-page' を削除しました -- リモートブランチ 'origin/fix-login-page' を削除しました +**Output**: ``` +## Worktree Deletion Complete -#### シナリオ: 特定のワークツリーを指定して削除 +**Deleted Worktree**: /nab-agents-fix-login-page +**Branch**: fix-login-page -```bash -# ワークツリーパスを指定 -/git worktree-delete /nab-agents- +### Actions Performed +- Deleted worktree '/nab-agents-fix-login-page' +- Deleted local branch 'fix-login-page' +- Deleted remote branch 'origin/fix-login-page' ``` -## 高度な使用例 +## Advanced Scenarios -### 6. 機密ファイルの自動除外 +### 6. Auto-exclude Sensitive Files -#### シナリオ: .envファイルが含まれる変更をコミット +**Scenario**: Commit includes .env file ```bash -# .envファイルを含む変更 /git commit ``` -**実行内容**: -1. 機密ファイル(.env)を検出 -2. 警告を表示 -3. 機密ファイルを除外してコミット - -**出力例**: +**Output**: ``` -警告: 以下の機密ファイルが含まれています: +Warning: The following sensitive files were detected: - .env - config/secrets.yml -これらのファイルはコミットから除外されます。 +These files will be excluded from the commit. -## コミット完了 +## Commit Complete -**ブランチ**: add-feature -**コミットメッセージ**: feat: 新機能を追加 -**変更ファイル**: 5件(機密ファイル2件を除外) +**Branch**: add-feature +**Commit Message**: feat: Add new feature +**Changed Files**: 5 files (2 sensitive files excluded) ``` -### 7. 未コミット変更があるワークツリーの削除 +### 7. Delete Worktree with Uncommitted Changes -#### シナリオ: 変更を保存せずにワークツリーを削除 +**Scenario**: Worktree has uncommitted changes ```bash -/git worktree-delete /nab-agents- +/git worktree-delete /nab-agents-experimental ``` -**実行内容**: -1. 未コミット変更を検出 -2. 警告を表示してユーザーに確認 - -**対話例**: +**Interaction**: ``` -ワークツリー「/nab-agents-」に未コミットの変更があります。 -削除すると、これらの変更は失われます。本当に削除しますか? +Q: Worktree has uncommitted changes. Deletion will lose these changes. Delete anyway? -変更一覧: +Changes: M src/experimental.ts ?? src/test.ts -→ 「はい、削除する」または「いいえ、キャンセル」を選択 +→ Select "Yes, delete it" or "No, cancel" ``` -### 8. プッシュ失敗時の自動リカバリ +### 8. Auto-recovery from Push Failure -#### シナリオ: リモートに新しいコミットがありプッシュが失敗 +**Scenario**: Remote has new commits, push fails ```bash /git commit ``` -**実行内容**: -1. コミット成功 -2. プッシュ失敗(rejected) -3. 自動的にrebaseして再プッシュ - -**出力例**: +**Output**: ``` -コミット完了。リモートにプッシュ中... -リモートに新しいコミットがあります。rebaseして再プッシュします... +Commit complete. Pushing to remote... +Remote has new commits. Rebasing and retrying push... -## コミット完了 +## Commit Complete -**ブランチ**: add-feature -**コミットメッセージ**: feat: 新機能を追加 -**変更ファイル**: 3件 +**Branch**: add-feature +**Commit Message**: feat: Add new feature +**Changed Files**: 3 files -変更がリモートにプッシュされました。 +Changes have been pushed to remote. ``` -## エラー時の対応例 +## Error Handling Examples -### ケース1: main以外から作業ブランチを作成しようとした +### Not on Main Branch ```bash git checkout feature-branch /git branch-create ``` -**出力**: +**Output**: ``` -エラー: 作業ブランチはmainブランチから作成してください。 -現在のブランチ: feature-branch +Error: Working branches must be created from the main branch. +Current branch: feature-branch -mainブランチに切り替えるには: +To switch to main: git checkout main ``` -### ケース2: 未マージブランチを削除しようとした +### Unmerged Branch Deletion Attempt ```bash /git branch-delete unmerged-branch ``` -**出力**: +**Output**: ``` -エラー: ブランチ「unmerged-branch」はまだマージされていません。 +Error: Branch "unmerged-branch" is not yet merged. -マージされていないブランチを削除する場合は、手動で強制削除してください: +To force delete unmerged branches, use manual command: git branch -D unmerged-branch -注意: 強制削除すると、マージされていない変更が失われます。 +Warning: Force deletion will lose unmerged changes. ``` -### ケース3: 変更がない状態でコミットしようとした +### No Changes to Commit ```bash /git commit ``` -**出力**: +**Output**: ``` -エラー: コミットする変更がありません。 +Error: No changes to commit. -現在の状態を確認: +Check current status: git status ``` -### ケース4: ブランチ名が既に存在 +### Branch Name Already Exists ```bash /git branch-create -# → ブランチ名「add-feature」を選択 +# → Select "add-feature" → Already exists ``` -**出力**: +**Output**: ``` -エラー: ブランチ「add-feature」は既に存在します。 +Error: Branch "add-feature" already exists. -別のブランチ名を使用するか、既存ブランチを削除してください: +Use a different name or delete the existing branch: git branch -d add-feature ``` -## 実際のワークフロー例 +## Complete Development Workflow -### フルサイクル: 機能開発からマージまで +### Full Cycle: Feature Development to Merge ```bash -# 1. 作業ブランチを作成 +# 1. Create working branch /git branch-create -# → 「新機能の追加」→「ユーザープロフィール機能」→「add-user-profile」 +# → "New Feature" → "user profile feature" → "add-user-profile" -# 2. 機能を実装 -# (コードを書く) +# 2. Implement feature +# (write code) -# 3. コミット +# 3. Commit /git commit -# → コミット完了、自動プッシュ +# → Auto-committed and pushed -# 4. MRを作成 +# 4. Create MR /mr create -# → MR作成完了 +# → MR created -# 5. レビューコメントに対応 +# 5. Handle review comments /mr resolve -# → 修正完了、リプライ送信 +# → Fixed and replied -# 6. マージ +# 6. Merge /mr merge -# → マージ完了 +# → Merged -# 7. ブランチを削除 +# 7. Delete branch /git branch-delete -# → ブランチ削除完了 +# → Branch deleted ``` -### ワークツリーを使った並行作業 +### Parallel Work with Worktree ```bash -# メインリポジトリで機能A開発中 +# Main repository: developing feature-a cd /nab-agents -# ブランチ: add-feature-a +# Branch: add-feature-a -# 緊急バグ修正のためワークツリー作成 +# Create worktree for urgent bug fix /git worktree-create -# → fix-critical-bug ワークツリー作成 +# → fix-critical-bug worktree created -# ワークツリーに移動してバグ修正 -cd /nab-agents- -# (バグを修正) +# Move to worktree and fix bug +cd /nab-agents-fix-critical-bug +# (fix bug) /git commit /mr create /mr merge -# ワークツリーを削除 +# Delete worktree /git worktree-delete -# → ワークツリー削除完了 - -# メインリポジトリに戻って機能A開発を続行 -cd /nab-agents -# (機能Aの開発を続ける) -``` - -### 複数ブランチの並行開発 +# → Worktree deleted -```bash -# メインリポジトリ: feature-a開発 +# Return to main repository and continue feature-a cd /nab-agents -git checkout add-feature-a - -# ワークツリー1: feature-b開発 -/git worktree-create -# → /nab-agents- - -# ワークツリー2: feature-c開発 -/git worktree-create -# → /nab-agents- - -# それぞれで独立して作業 -# 各ワークツリーで /git commit, /mr create を実行 - -# 作業完了後、ワークツリーを削除 -/git worktree-delete -# → feature-b, feature-c のワークツリーを順次削除 +# (continue feature-a development) ``` -## チーム開発でのヒント - -1. **ブランチ命名規則**: - - `add-`: 新機能追加 - - `fix-`: バグ修正 - - `refactor-`: リファクタリング - - `docs-`: ドキュメント更新 - -2. **コミットの粒度**: - - 目的単位でコミット - - 大きな変更は複数のコミットに分割 - - `/git commit` で自動的に適切なメッセージが生成される - -3. **ワークツリーの活用**: - - 緊急バグ修正: 作業中のブランチを残してワークツリーで修正 - - 並行開発: 複数の機能を同時進行 - - レビュー対応: メインの作業を残してワークツリーでレビュー対応 - -4. **ブランチのクリーンアップ**: - - MRマージ後は `/git branch-delete` で定期的にクリーンアップ - - マージ済みブランチのみ削除される(安全) - -## カスタマイズ例 - -### プロジェクト固有のワークフロー - -プロジェクトによっては、SKILL.mdをフォークして以下のようなカスタマイズが可能です: - -1. **ブランチ命名規則のカスタマイズ**: - - チケット番号を含める(例: `PROJ-123-add-feature`) - - チーム名をプレフィックスに追加 - -2. **コミットメッセージテンプレート**: - - プロジェクト固有のルールを追加 - - Jiraチケット番号の自動挿入 - -3. **自動テスト実行**: - - コミット前に自動的にテストを実行 - - テストが失敗した場合はコミットを中断 - -4. **通知の追加**: - - Slack等への通知をフックで実装 +## Team Development Tips -詳細なカスタマイズ方法は、Claude Codeの公式ドキュメントを参照してください。 +1. **Branch naming**: Use consistent prefixes (`add-`, `fix-`, `refactor-`, `docs-`) +2. **Commit granularity**: One purpose per commit; split large changes +3. **Worktree usage**: + - Urgent bug fixes while preserving current work + - Parallel development of multiple features + - Review response without interrupting main work +4. **Branch cleanup**: Use `/git branch-delete` regularly after merges diff --git a/.claude/skills/git/assets/reference.md b/.claude/skills/git/assets/reference.md index 6b731b9..29ef52e 100644 --- a/.claude/skills/git/assets/reference.md +++ b/.claude/skills/git/assets/reference.md @@ -1,579 +1,156 @@ -# Gitスキル - 詳細リファレンス - -このドキュメントは、gitスキルの詳細な技術仕様とワークフローを記載します。 - -## 目次 - -1. [Git用語説明](#git用語説明) -2. [ブランチ命名規則](#ブランチ命名規則) -3. [Conventional Commits形式](#conventional-commits形式) -4. [機密ファイルの検出ロジック](#機密ファイルの検出ロジック) -5. [ワークツリーの仕組み](#ワークツリーの仕組み) -6. [エラーハンドリング詳細](#エラーハンドリング詳細) -7. [トラブルシューティング](#トラブルシューティング) -8. [ベストプラクティス](#ベストプラクティス) - -## Git用語説明 - -### ブランチ関連 -- **作業ブランチ**: 機能開発やバグ修正のために作成するブランチ -- **mainブランチ**: メインの開発ブランチ(masterとも呼ばれる) -- **マージ済みブランチ**: mainブランチにマージされたブランチ -- **未マージブランチ**: mainブランチにマージされていないブランチ - -### コミット関連 -- **ステージング**: コミット対象のファイルを選択する操作 -- **コミット**: 変更をローカルリポジトリに記録する操作 -- **プッシュ**: ローカルの変更をリモートリポジトリに送信する操作 -- **HEREDOC**: シェルスクリプトで複数行の文字列を扱う記法 - -### ワークツリー関連 -- **メインワークツリー**: 元のリポジトリディレクトリ -- **ワークツリー**: 同じリポジトリの別ディレクトリ(並行作業用) -- **ワークツリーパス**: ワークツリーが作成されるディレクトリのパス - -## ブランチ命名規則 - -### プレフィックス - -| プレフィックス | 用途 | 例 | -|--------------|------|-----| -| `add-` | 新機能の追加 | `add-user-auth` | -| `fix-` | バグ修正 | `fix-login-page` | -| `refactor-` | リファクタリング | `refactor-api-layer` | -| `update-` | 既存機能の更新・改善 | `update-user-settings` | -| `docs-` | ドキュメント更新 | `docs-setup-guide` | -| `test-` | テストの追加・修正 | `test-auth-logic` | -| `chore-` | ビルド、設定等の変更 | `chore-update-deps` | - -### 命名ルール - -1. **小文字のみ**: すべて小文字で記述 -2. **英数字とハイフン**: 使用可能な文字は`a-z`, `0-9`, `-`のみ -3. **プレフィックス必須**: 作業内容を表すプレフィックスを付ける -4. **簡潔に**: 3-5単語程度、最大50文字以内 -5. **説明的**: ブランチの目的が分かる名前にする - -### 良い例・悪い例 - -**良い例**: -- `add-user-profile` - 明確で簡潔 -- `fix-login-timeout` - バグの内容が分かる -- `refactor-database-layer` - リファクタリング対象が明確 - -**悪い例**: -- `feature` - 内容が不明 -- `Add-User-Profile` - 大文字を使用している -- `add_user_profile` - アンダースコアを使用している -- `add-a-new-feature-for-user-profile-management` - 長すぎる - -## Conventional Commits形式 - -### コミットタイプ - -| タイプ | 説明 | 例 | -|--------|------|-----| -| `feat` | 新機能の追加 | `feat: ユーザー認証機能を追加` | -| `fix` | バグ修正 | `fix: ログイン時のセッションタイムアウトを修正` | -| `refactor` | リファクタリング | `refactor: API層のエラーハンドリングを改善` | -| `update` | 既存機能の更新・改善 | `update: ユーザー設定画面のUIを改善` | -| `docs` | ドキュメント更新 | `docs: READMEにセットアップ手順を追加` | -| `test` | テストの追加・修正 | `test: ユーザー認証のテストを追加` | -| `chore` | ビルド、設定等の変更 | `chore: 依存パッケージを最新化` | - -### メッセージ形式 +# Git Skill - Technical Reference -``` -{type}: {目的・意図を表す簡潔な説明} - -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) -``` - -### メッセージ生成ルール - -1. **1行目(タイトル)**: - - 50文字以内を目標(最大70文字) - - 日本語で記述 - - 目的または意図が伝わる内容にする - - 「〜を追加」「〜を修正」など、動作を明確に +## Branch Naming Conventions -2. **Co-Authored-By**: - - 2行目は空行 - - 3行目にClaude署名を追加 +### Prefixes -### 生成例 +| Prefix | Purpose | Example | +|--------|---------|---------| +| `add-` | New feature | `add-user-auth` | +| `fix-` | Bug fix | `fix-login-page` | +| `refactor-` | Refactoring | `refactor-api-layer` | +| `update-` | Existing feature improvement | `update-user-settings` | +| `docs-` | Documentation | `docs-setup-guide` | +| `test-` | Test addition/modification | `test-auth-logic` | +| `chore-` | Build, config changes | `chore-update-deps` | -**変更内容**: ユーザー認証機能の実装 -``` -feat: ユーザー認証機能を追加 +### Naming Rules -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) -``` +1. All lowercase +2. Only alphanumeric and hyphens +3. Required prefix indicating work type +4. Concise: 3-5 words, max 50 chars +5. Descriptive: Purpose should be clear -**変更内容**: ログインバグ修正 -``` -fix: ログイン時のセッションタイムアウトを修正 +## Commit Message Format -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) -``` +### Structure -**変更内容**: API層のリファクタリング ``` -refactor: API層のエラーハンドリングを改善 +{type}: {concise description conveying purpose/intent} -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +Co-Authored-By: Claude Opus 4.6 ``` -## 機密ファイルの検出ロジック +### Commit Types -### 検出パターン +| Type | Description | Example | +|------|-------------|---------| +| `feat` | New feature | `feat: Add user authentication feature` | +| `fix` | Bug fix | `fix: Fix session timeout on login` | +| `refactor` | Refactoring | `refactor: Improve error handling in API layer` | +| `update` | Improvement to existing feature | `update: Improve user settings UI` | +| `docs` | Documentation | `docs: Add setup guide to README` | +| `test` | Tests | `test: Add authentication tests` | +| `chore` | Build/config | `chore: Update dependencies` | -gitスキルは以下のパターンに一致するファイルを自動的に機密ファイルとして検出します: +### Message Guidelines -#### 環境変数ファイル -``` -.env -.env.* -.env.local -.env.production -.env.development -``` +1. **First line**: Target 50 chars (max 70) +2. **Language**: Follow project requirements (check `.claude/rules/commit-rules.md`) +3. **Focus**: Convey "why" not just "what" +4. **Style**: Use clear action verbs +5. **Scope**: No technical details in title -#### 認証情報ファイル -``` -*credentials* -*secret* -*password* -config/credentials.yml.enc -config/secrets.yml -``` +## Sensitive File Detection -#### 鍵ファイル -``` -*.key -*.pem -*.p12 -*.pfx -id_rsa -id_rsa.pub -``` +### Detected Patterns -#### データベース設定 -``` -config/database.yml -database.yml -``` +**Environment files**: +- `.env`, `.env.*` -#### その他 -``` -.npmrc (認証トークンを含む場合) -.pypirc -.dockercfg -.docker/config.json -``` +**Credentials**: +- `*credentials*`, `*secret*`, `*password*` +- `config/credentials.yml.enc`, `config/secrets.yml` -### 検出時の動作 +**Keys**: +- `*.key`, `*.pem`, `*.p12`, `*.pfx` +- `id_rsa`, `id_rsa.pub` -1. **警告表示**: 機密ファイルが検出されたことをユーザーに通知 -2. **自動除外**: コミット対象から自動的に除外 -3. **処理継続**: 他のファイルは通常通りコミット +**Database config**: +- `config/database.yml`, `database.yml` -### 例外処理 +**Other**: +- `.npmrc`, `.pypirc`, `.dockercfg`, `.docker/config.json` -機密ファイルを意図的にコミットしたい場合は、手動でコミットしてください: +### Detection Behavior -```bash -git add .env.example # サンプルファイルは問題ない -git commit -m "chore: 環境変数のサンプルを追加" -``` +1. Display warning +2. Auto-exclude from commit +3. Continue with other files -## ワークツリーの仕組み +## Worktree Concepts -### ワークツリーとは +### What is a Worktree? -ワークツリーは、同じGitリポジトリの異なるブランチを別のディレクトリで操作できる機能です。 +Worktrees allow working with different branches of the same repository in separate directories simultaneously. -### メリット +### Benefits -1. **並行作業**: 複数の機能を同時に開発できる -2. **緊急対応**: 作業中のブランチを保持したまま、別ブランチで緊急バグ修正 -3. **レビュー対応**: メインの作業を中断せずに、レビュー対応を行える +1. **Parallel work**: Develop multiple features concurrently +2. **Emergency response**: Fix urgent bugs without disrupting current work +3. **Review handling**: Address review comments while continuing main work -### ディレクトリ構造 +### Directory Structure ``` /home/user/work/ -├── nab-agents/ # メインワークツリー (mainブランチ) -├── nab-agents-add-feature/ # ワークツリー1 (add-featureブランチ) -└── nab-agents-fix-bug/ # ワークツリー2 (fix-bugブランチ) -``` - -### パス命名規則 - -```bash -{親ディレクトリ}/{リポジトリ名}-{ブランチ名} -``` - -例: -- メインリポジトリ: `/home/user/work/nab-agents` -- ワークツリー: `/home/user/work/nab-agents-add-user-auth` - -### ワークツリーのライフサイクル - -1. **作成**: `/git worktree-create` - - mainブランチから新しいブランチを作成 - - 指定パスにワークツリーを作成 - -2. **作業**: 通常のGit操作が可能 - - `/git commit` でコミット - - `/mr create` でMR作成 - -3. **削除**: `/git worktree-delete` - - ワークツリーディレクトリを削除 - - 必要に応じてブランチも削除 - -### ワークツリーの制限 - -1. **同じブランチを複数のワークツリーで使用不可** -2. **ディスク容量**: ワークツリーごとにファイルが複製される -3. **.gitディレクトリ**: メインリポジトリと共有される - -## エラーハンドリング詳細 - -### ブランチ作成時のエラー - -#### main以外のブランチから実行 - -```bash -# エラー -/git branch-create -# 現在: feature-branch - -# 対応 -git checkout main -/git branch-create -``` - -#### 未コミット変更がある - -```bash -# エラー -/git branch-create -# 変更あり - -# 対応方法1: コミット -/git commit - -# 対応方法2: stash -git stash -/git branch-create -git stash pop -``` - -#### ブランチ名が既に存在 - -```bash -# エラー -/git branch-create -# ブランチ名「add-feature」選択 → 既に存在 - -# 対応方法1: 別の名前を使用 -/git branch-create -# → "Other"で別の名前を入力 - -# 対応方法2: 既存ブランチを削除 -git branch -d add-feature -/git branch-create -``` - -### コミット時のエラー - -#### 変更がない - -```bash -# エラー -/git commit -# 変更なし - -# 対応 -# ファイルを編集してから実行 +├── nab-agents/ # Main worktree (main branch) +├── nab-agents-add-feature/ # Worktree 1 (add-feature branch) +└── nab-agents-fix-bug/ # Worktree 2 (fix-bug branch) ``` -#### プッシュ失敗(rejected) - -```bash -# エラー -/git commit -# プッシュ失敗: リモートに新しいコミットがある +### Path Naming Convention -# 自動対応 -# → rebaseして再プッシュ ``` - -#### プッシュ失敗(コンフリクト) - -```bash -# エラー -/git commit -# rebase失敗: コンフリクト - -# 対応 -git status # コンフリクトファイルを確認 -# コンフリクトを手動で解決 -git add {resolved_files} -git rebase --continue -git push +{parent_dir}/{repo_name}-{branch_name} ``` -### ブランチ削除時のエラー +### Lifecycle -#### 未マージブランチの削除試行 +1. **Create**: `/git worktree-create` - Creates new branch from main and worktree at specified path +2. **Work**: Normal Git operations (`/git commit`, etc.) +3. **Delete**: `/git worktree-delete` - Removes worktree directory and optionally branch -```bash -# エラー -/git branch-delete unmerged-branch +### Limitations -# 対応方法1: マージしてから削除 -git checkout main -git merge unmerged-branch -/git branch-delete unmerged-branch +1. Cannot use same branch in multiple worktrees +2. Disk space: Files duplicated for each worktree +3. `.git` directory: Shared with main repository -# 対応方法2: 強制削除(注意) -git branch -D unmerged-branch -``` +## Best Practices -#### mainブランチの削除試行 +### Branch Management -```bash -# エラー -/git branch-delete main +1. **Consistent naming**: Use unified prefixes across team +2. **Regular cleanup**: Delete merged branches periodically +3. **Branch from main**: Always create working branches from main +4. **Small branches**: One purpose per branch -# 対応 -# mainブランチは削除できません -``` +### Commit Management -### ワークツリー削除時のエラー +1. **One purpose per commit**: Don't mix multiple purposes +2. **Commit frequently**: At each milestone +3. **Always push**: Push immediately after commit +4. **Exclude sensitive info**: Add to `.gitignore` -#### 未コミット変更がある +### Worktree Management -```bash -# 警告 -/git worktree-delete /path/to/worktree -# 未コミット変更あり +1. **Clear purpose**: Define why worktree is needed +2. **Delete when done**: Don't leave unused worktrees +3. **Consider disk space**: Large projects consume significant space +4. **Clean up branches**: Remove branches when deleting worktrees -# 対応方法1: キャンセルしてコミット -cd /path/to/worktree -/git commit -/git worktree-delete /path/to/worktree - -# 対応方法2: 変更を破棄して削除 -# → AskUserQuestionで「はい、削除する」を選択 -``` +### Team Development -#### ワークツリーが見つからない +1. **Shared strategy**: Align on branch naming and workflow +2. **Quality messages**: Write commit messages others can understand +3. **Self-review**: Check diff before creating PRs +4. **Merge regularly**: Don't let branches diverge for too long -```bash -# エラー -/git worktree-delete /invalid/path +### Safety -# 対応 -git worktree list # 一覧を確認 -/git worktree-delete # 引数なしで選択 -``` - -## トラブルシューティング - -### スキルが起動しない - -1. **gitリポジトリか確認**: - ```bash - git status - # Not a git repository → gitリポジトリではない - ``` - -2. **サブコマンドの確認**: - ```bash - /git branch-create # 正しい - /git create # 間違い(無効なサブコマンド) - ``` - -### ブランチが作成できない - -1. **カレントブランチを確認**: - ```bash - git branch --show-current - # main以外 → mainに切り替える - ``` - -2. **作業ツリーの状態を確認**: - ```bash - git status - # 変更あり → コミットまたはstash - ``` - -3. **リモートの状態を確認**: - ```bash - git fetch origin main - git status - # behind → pullが必要 - ``` - -### コミットができない - -1. **変更があるか確認**: - ```bash - git status - # nothing to commit → 変更なし - ``` - -2. **機密ファイルが含まれている**: - - 自動的に除外される - - 意図的にコミットしたい場合は手動で実行 - -3. **プッシュが失敗する**: - ```bash - git pull --rebase origin {branch} - # コンフリクトを解決 - git push - ``` - -### ブランチが削除できない - -1. **マージ済みか確認**: - ```bash - git branch --merged main - # リストに含まれない → 未マージ - ``` - -2. **mainブランチではないか確認**: - ```bash - # mainブランチは削除不可 - ``` - -3. **リモートブランチが削除できない**: - ```bash - # 権限を確認 - # リポジトリへの書き込み権限が必要 - ``` - -### ワークツリーが作成できない - -1. **パスが既に存在する**: - ```bash - ls /home/user/work/nab-agents-add-feature - # 既に存在 → 別の名前を使用 - ``` - -2. **ブランチ名が既に存在する**: - ```bash - git branch --list add-feature - # 既に存在 → 別の名前を使用 - ``` - -3. **ディスク容量不足**: - ```bash - df -h - # ディスク容量を確認 - ``` - -### ワークツリーが削除できない - -1. **メインワークツリーではないか確認**: - ```bash - git worktree list - # 最初の行はメインワークツリー(削除不可) - ``` - -2. **削除に失敗する**: - ```bash - git worktree remove --force {path} - # それでも失敗する場合 - rm -rf {path} - git worktree prune - ``` - -## ベストプラクティス - -### ブランチ管理 - -1. **命名規則を統一**: チーム全体で統一したプレフィックスを使用 -2. **定期的なクリーンアップ**: マージ済みブランチは定期的に削除 -3. **mainから分岐**: 作業ブランチは常にmainから分岐 -4. **小さなブランチ**: 1つのブランチで1つの目的を達成 - -### コミット管理 - -1. **目的単位でコミット**: 複数の目的を1つのコミットにしない -2. **頻繁にコミット**: 作業の節目ごとにコミット -3. **プッシュを忘れずに**: コミット後は忘れずにプッシュ -4. **機密情報の除外**: .envファイル等は.gitignoreに追加 - -### ワークツリー管理 - -1. **用途を明確に**: 緊急バグ修正、並行開発など、目的を明確に -2. **作業完了後は削除**: 不要なワークツリーは残さない -3. **ディスク容量を考慮**: 大規模プロジェクトでは容量に注意 -4. **ブランチの整理**: ワークツリー削除時にブランチも整理 - -### チーム開発 - -1. **ブランチ戦略の共有**: チームで統一した運用ルールを決める -2. **コミットメッセージの品質**: 他のメンバーが理解できる内容に -3. **レビュー前のセルフチェック**: `/git commit`後、diffを確認 -4. **定期的なmainへのマージ**: 長期間放置しない - -### 安全性 - -1. **強制操作は慎重に**: `-D`, `--force`等は使用しない(スキルも使わない) -2. **バックアップの取得**: 重要な変更前はバックアップブランチを作成 -3. **テストの実行**: コミット前に関連テストを実行 -4. **段階的な変更**: 大きな変更は複数のコミットに分割 - -### パフォーマンス - -1. **不要なファイルを除外**: .gitignoreを適切に設定 -2. **大きなファイルを避ける**: バイナリファイルはGit LFSを使用 -3. **ワークツリーの数を制限**: 同時に使用するワークツリーは3-4個まで -4. **定期的なgc**: `git gc`でリポジトリを最適化 - -## 高度な使用例 - -### フック活用 - -プロジェクトのニーズに応じて、gitフックを活用できます: - -```bash -# .git/hooks/pre-commit -# コミット前にテストを実行 -npm test || exit 1 -``` - -### エイリアス設定 - -よく使うコマンドをエイリアスに設定: - -```bash -# ~/.bashrc または ~/.zshrc -alias gbc='/git branch-create' -alias gc='/git commit' -alias gbd='/git branch-delete' -alias gwc='/git worktree-create' -alias gwd='/git worktree-delete' -``` - -### CI/CD連携 - -GitLab CI/CDと連携して、自動テスト・デプロイを実現: - -```yaml -# .gitlab-ci.yml -test: - script: - - npm test - -deploy: - script: - - npm run deploy - only: - - main -``` +1. **Avoid force operations**: Never use `-D`, `--force` (skill doesn't use them either) +2. **Backup important changes**: Create backup branches before major changes +3. **Run tests**: Execute related tests before committing +4. **Incremental changes**: Split large changes into multiple commits diff --git a/.claude/skills/git/workflows/branch-create.md b/.claude/skills/git/workflows/branch-create.md index b50a6d7..6ba2566 100644 --- a/.claude/skills/git/workflows/branch-create.md +++ b/.claude/skills/git/workflows/branch-create.md @@ -1,173 +1,173 @@ -# 作業ブランチ作成ワークフロー +# Branch Creation Workflow -このワークフローは、mainブランチから作業ブランチを作成します。 +This workflow creates a working branch from the main branch. -## 必要なツール +## Required Tools - Bash - AskUserQuestion -## 実行ステップ +## Execution Steps -### 1. 事前確認 +### 1. Pre-flight Checks -**1.1 カレントブランチの確認** +**1.1 Verify Current Branch** ```bash git branch --show-current ``` -カレントブランチが`main`でない場合はエラー終了: +If not on `main`, exit with error: ``` -エラー: 作業ブランチはmainブランチから作成してください。 -現在のブランチ: {current_branch} +Error: Working branches must be created from the main branch. +Current branch: {current_branch} -mainブランチに切り替えるには: +To switch to main: git checkout main ``` -**1.2 ワーキングツリーの確認** +**1.2 Verify Clean Working Tree** ```bash git status --porcelain ``` -未コミットの変更がある場合はエラー終了: +If uncommitted changes exist, exit with error: ``` -エラー: 未コミットの変更があります。 -変更をコミットまたはstashしてから実行してください。 +Error: You have uncommitted changes. +Please commit or stash changes before proceeding. -変更を確認: +Check changes: git status -変更をstash: +Stash changes: git stash ``` -**1.3 リモートの最新化** +**1.3 Update Remote** ```bash git fetch origin main git pull origin main ``` -pullが失敗(conflict)した場合: +If pull fails (conflicts): ``` -エラー: mainブランチの更新に失敗しました。 -コンフリクトを解決してから実行してください。 +Error: Failed to update main branch. +Please resolve conflicts before proceeding. ``` -### 2. ブランチ名の提案 +### 2. Propose Branch Names -**2.1 作業目的のヒアリング** +**2.1 Ask Work Purpose** -AskUserQuestionで作業目的をヒアリング: +Use AskUserQuestion to understand work purpose: ``` -質問: このブランチで何を実装・修正しますか? -header: "作業内容" -options: - - label: "新機能の追加" - description: "新しい機能を実装する" - - label: "バグ修正" - description: "既存のバグを修正する" - - label: "リファクタリング" - description: "コードの構造を改善する" - - label: "ドキュメント更新" - description: "ドキュメントを更新する" +Question: What will you implement or fix in this branch? +Header: "Work Type" +Options: + - Label: "New Feature" + Description: "Implement a new feature" + - Label: "Bug Fix" + Description: "Fix an existing bug" + - Label: "Refactoring" + Description: "Improve code structure" + - Label: "Documentation" + Description: "Update documentation" ``` -**2.2 詳細のヒアリング** +**2.2 Ask for Details** -選択された作業内容に応じて、詳細をヒアリング(自由入力): +Based on selected work type, ask for details (free text): ``` -「{作業内容}」の詳細を教えてください。 -例: ユーザー認証機能、ログイン画面のバグ、API層のリファクタリング等 +Please provide details about "{work_type}". +Examples: user authentication, login page bug, API layer refactoring, etc. ``` -**2.3 ブランチ名の生成** +**2.3 Generate Branch Names** -ヒアリングした内容から、3つのブランチ名候補を生成: +Generate 3 branch name candidates from the details: -**生成ルール**: -- プレフィックス: `add-`(新機能), `fix-`(バグ修正), `refactor-`(リファクタリング), `docs-`(ドキュメント) -- 本体: 詳細から抽出したキーワードを`-`で連結 -- 全て小文字、英数字とハイフンのみ +**Generation Rules**: +- Prefix: `add-` (feature), `fix-` (bug), `refactor-` (refactor), `docs-` (docs) +- Body: Keywords from details joined with `-` +- All lowercase, alphanumeric and hyphens only -**例**: -- 詳細: "ユーザー認証機能を追加" - - 候補1: `add-user-auth` - - 候補2: `add-authentication` - - 候補3: `user-auth-feature` +**Examples**: +- Details: "Add user authentication feature" + - Candidate 1: `add-user-auth` + - Candidate 2: `add-authentication` + - Candidate 3: `user-auth-feature` -- 詳細: "ログイン画面のバグ修正" - - 候補1: `fix-login-page` - - 候補2: `fix-login-bug` - - 候補3: `login-page-fix` +- Details: "Fix login page bug" + - Candidate 1: `fix-login-page` + - Candidate 2: `fix-login-bug` + - Candidate 3: `login-page-fix` -**2.4 ブランチ名の選択** +**2.4 Select Branch Name** -AskUserQuestionで候補から選択: +Use AskUserQuestion to select from candidates: ``` -質問: ブランチ名を選択してください。 -header: "ブランチ名" -options: - - label: "{候補1}" - description: "推奨" - - label: "{候補2}" - description: "" - - label: "{候補3}" - description: "" +Question: Select branch name. +Header: "Branch Name" +Options: + - Label: "{candidate1}" + Description: "Recommended" + - Label: "{candidate2}" + Description: "" + - Label: "{candidate3}" + Description: "" ``` -ユーザーが"Other"を選択した場合、自由入力を受け付ける。 +If user selects "Other", accept free text input. -**2.5 ブランチ名の重複確認** +**2.5 Check for Duplicates** ```bash git branch --list "{branch_name}" ``` -既に存在する場合はエラー終了: +If exists, exit with error: ``` -エラー: ブランチ「{branch_name}」は既に存在します。 +Error: Branch "{branch_name}" already exists. -別のブランチ名を使用するか、既存ブランチを削除してください: +Use a different name or delete the existing branch: git branch -d {branch_name} ``` -### 3. ブランチ作成 +### 3. Create Branch -選択されたブランチ名でブランチを作成: +Create branch with selected name: ```bash git checkout -b {branch_name} ``` -### 4. 結果表示 +### 4. Display Result ``` -## 作業ブランチ作成完了 +## Branch Creation Complete -**ブランチ名**: {branch_name} -**ベースブランチ**: main +**Branch Name**: {branch_name} +**Base Branch**: main -作業を開始できます。 -変更をコミットする際は `/git commit` を使用してください。 +You can now start working. +Use `/git commit` to commit changes. ``` -## エラーハンドリング +## Error Handling -| エラー | 対応 | -|--------|------| -| main以外のブランチから実行 | mainブランチに切り替えるよう案内 | -| 未コミットの変更がある | コミットまたはstashするよう案内 | -| mainの更新に失敗 | コンフリクトを解決するよう案内 | -| ブランチ名が既に存在 | 別の名前を使用するか、既存ブランチを削除するよう案内 | +| Error | Response | +|-------|----------| +| Not on main branch | Guide to switch to main | +| Uncommitted changes | Guide to commit or stash | +| Failed to update main | Guide to resolve conflicts | +| Branch name exists | Guide to use different name or delete existing | -## 注意事項 +## Important Notes -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **ブランチ名の品質**: ユーザーの入力から適切なブランチ名を生成する -3. **安全性**: mainブランチの保護、重複チェック、作業ツリーのクリーン確認 +1. **No emojis**: Never use emojis unless explicitly requested by user +2. **Branch name quality**: Generate appropriate names from user input +3. **Safety**: Protect main branch, check duplicates, verify clean working tree diff --git a/.claude/skills/git/workflows/branch-delete.md b/.claude/skills/git/workflows/branch-delete.md index 476be2e..940a453 100644 --- a/.claude/skills/git/workflows/branch-delete.md +++ b/.claude/skills/git/workflows/branch-delete.md @@ -1,157 +1,157 @@ -# ブランチ削除ワークフロー +# Branch Deletion Workflow -このワークフローは、マージ済みブランチをローカルとリモートから削除します。 +This workflow deletes merged branches from local and remote repositories. -## 必要なツール +## Required Tools - Bash - AskUserQuestion -## 実行ステップ +## Execution Steps -### 1. 削除対象ブランチの決定 +### 1. Determine Target Branch -**1.1 引数の確認** +**1.1 Check Arguments** -引数が指定されている場合、それを削除対象とする。 -引数がない場合、次のステップでユーザーに選択させる。 +If argument is specified, use it as target. +If no argument, proceed to next step to let user select. -**1.2 削除可能なブランチの取得** +**1.2 Get Deletable Branches** ```bash git branch --merged main ``` -結果からmainブランチを除外し、削除可能なブランチのリストを作成。 +Exclude main branch from results to create list of deletable branches. -ブランチがない場合: +If no branches: ``` -情報: 削除可能なマージ済みブランチがありません。 +Info: No merged branches to delete. -マージ済みブランチの一覧を確認: +Check merged branches: git branch --merged main ``` -**1.3 削除対象の選択(引数がない場合)** +**1.3 Select Target (if no argument)** -AskUserQuestionでブランチを選択: +Use AskUserQuestion to select branch: ``` -質問: 削除するブランチを選択してください。 -header: "ブランチ削除" -options: - - label: "{branch1}" - description: "マージ済み" - - label: "{branch2}" - description: "マージ済み" - - label: "{branch3}" - description: "マージ済み" +Question: Select branch to delete. +Header: "Delete Branch" +Options: + - Label: "{branch1}" + Description: "Merged" + - Label: "{branch2}" + Description: "Merged" + - Label: "{branch3}" + Description: "Merged" ``` -### 2. 削除前チェック +### 2. Pre-deletion Checks -**2.1 mainブランチの保護** +**2.1 Protect Main Branch** -削除対象が`main`または`master`の場合はエラー終了: +If target is `main` or `master`, exit with error: ``` -エラー: mainブランチは削除できません。 +Error: Cannot delete main branch. ``` -**2.2 マージ済み確認** +**2.2 Verify Merged Status** ```bash git branch --merged main | grep "^ {branch_name}$" ``` -マージされていない場合はエラー終了: +If not merged, exit with error: ``` -エラー: ブランチ「{branch_name}」はまだマージされていません。 +Error: Branch "{branch_name}" is not yet merged. -マージされていないブランチを削除する場合は、手動で強制削除してください: +To force delete unmerged branches, use manual command: git branch -D {branch_name} -注意: 強制削除すると、マージされていない変更が失われます。 +Warning: Force deletion will lose unmerged changes. ``` -**2.3 カレントブランチの確認** +**2.3 Check Current Branch** ```bash git branch --show-current ``` -カレントブランチが削除対象の場合、mainブランチに切り替え: +If current branch is the target, switch to main: ```bash git checkout main ``` -### 3. mainブランチの更新 +### 3. Update Main Branch ```bash git fetch origin main git pull origin main ``` -### 4. ブランチの削除 +### 4. Delete Branch -**4.1 リモートブランチの削除** +**4.1 Delete Remote Branch** ```bash git push origin --delete {branch_name} ``` -リモートブランチが存在しない場合のエラーは無視(警告のみ表示): +If remote branch doesn't exist, ignore error (show warning only): ``` -警告: リモートブランチ「{branch_name}」は既に削除されています。 +Warning: Remote branch "{branch_name}" is already deleted. ``` -権限エラーの場合: +If permission error: ``` -エラー: リモートブランチの削除に失敗しました。 -リポジトリへの書き込み権限を確認してください。 +Error: Failed to delete remote branch. +Please verify you have write access to the repository. -ローカルブランチのみ削除する場合: +To delete local branch only: git branch -d {branch_name} ``` -**4.2 ローカルブランチの削除** +**4.2 Delete Local Branch** ```bash git branch -d {branch_name} ``` -### 5. リモートブランチ情報の更新 +### 5. Update Remote Branch Info ```bash git fetch --prune ``` -### 6. 結果表示 +### 6. Display Result ``` -## ブランチ削除完了 +## Branch Deletion Complete -**削除したブランチ**: {branch_name} +**Deleted Branch**: {branch_name} -### 実行内容 -- リモートブランチ 'origin/{branch_name}' を削除しました -- ローカルブランチ '{branch_name}' を削除しました -- mainブランチに切り替えました -- 最新のコードを取得しました +### Actions Performed +- Deleted remote branch 'origin/{branch_name}' +- Deleted local branch '{branch_name}' +- Switched to main branch +- Fetched latest code ``` -## エラーハンドリング +## Error Handling -| エラー | 対応 | -|--------|------| -| 削除可能なブランチがない | マージ済みブランチを確認 | -| mainブランチの削除試行 | エラーメッセージを表示して終了 | -| 未マージブランチ | 手動での強制削除を案内 | -| リモートブランチが存在しない | 警告のみ表示してローカル削除を継続 | -| 権限不足 | リポジトリの権限を確認するよう案内 | +| Error | Response | +|-------|----------| +| No deletable branches | Check merged branches | +| Attempted to delete main | Display error and exit | +| Unmerged branch | Guide to manual force deletion | +| Remote branch doesn't exist | Show warning only, continue with local deletion | +| Insufficient permissions | Guide to check repository permissions | -## 注意事項 +## Important Notes -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **安全性優先**: マージ済みブランチのみ削除、未マージは強制削除を案内 -3. **mainブランチの保護**: mainブランチは削除を拒否 -4. **リモート優先**: リモートブランチを先に削除してから、ローカルブランチを削除 +1. **No emojis**: Never use emojis unless explicitly requested by user +2. **Safety first**: Only delete merged branches, guide to manual force deletion for unmerged +3. **Main branch protection**: Refuse deletion of main branch +4. **Remote priority**: Delete remote branch first, then local branch diff --git a/.claude/skills/git/workflows/commit.md b/.claude/skills/git/workflows/commit.md index 98bab27..f106653 100644 --- a/.claude/skills/git/workflows/commit.md +++ b/.claude/skills/git/workflows/commit.md @@ -1,47 +1,47 @@ -# コミット・プッシュワークフロー +# Commit and Push Workflow -このワークフローは、変更をコミットしてリモートにプッシュします。 +This workflow commits changes and pushes them to the remote repository. -## 必要なツール +## Required Tools - Bash - AskUserQuestion -## 実行ステップ +## Execution Steps -### 1. 事前確認 +### 1. Pre-flight Checks -**1.1 カレントブランチの確認** +**1.1 Check Current Branch** ```bash git branch --show-current ``` -カレントブランチが`main`または`master`の場合は警告表示(エラーではない): +If on `main` or `master`, display warning (not an error): ``` -警告: mainブランチに直接コミットしようとしています。 -作業ブランチで作業することを推奨します。 +Warning: You are about to commit directly to the main branch. +It is recommended to work on a feature branch. -続行しますか? +Do you want to continue? ``` -**1.2 変更の確認** +**1.2 Check for Changes** ```bash git status --porcelain ``` -変更がない場合はエラー終了: +If no changes, exit with error: ``` -エラー: コミットする変更がありません。 +Error: No changes to commit. -現在の状態を確認: +Check current status: git status ``` -### 2. 変更の分析 +### 2. Analyze Changes -**2.1 ステージングされていない変更とステージング済み変更の取得** +**2.1 Get Staged and Unstaged Changes** ```bash git status @@ -49,74 +49,83 @@ git diff HEAD --stat git diff HEAD ``` -**2.2 機密ファイルのチェック** +**2.2 Detect Sensitive Files** -変更ファイルリストから以下のパターンを検出: +Detect the following patterns: - `.env`, `.env.*` - `*credentials*`, `*secret*`, `*password*` - `*.key`, `*.pem` - `config/database.yml`, `config/secrets.yml` -機密ファイルが含まれる場合は警告: +If sensitive files detected, display warning: ``` -警告: 以下の機密ファイルが含まれています: +Warning: The following sensitive files were detected: - {file1} - {file2} -これらのファイルはコミットから除外されます。 +These files will be excluded from the commit. ``` -**2.3 コミット対象ファイルの決定** +**2.3 Determine Files to Commit** -機密ファイルを除外したファイルリストを作成。 +Create file list excluding sensitive files. -### 3. コミットメッセージの生成 +### 3. Generate Commit Message -**3.1 変更内容の分析** +**3.1 Analyze Changes** -diffとファイル名から以下を判定: -- **変更タイプ**: feat, fix, refactor, update, docs, test, chore -- **変更対象**: 主要な変更対象(ファイル名やdiffから抽出) -- **変更の目的**: diffの内容から推測 +Determine from diff and file names: +- **Change type**: feat, fix, refactor, update, docs, test, chore +- **Change target**: Main subject of changes (from file names and diff) +- **Change purpose**: Inferred from diff content -**3.2 メッセージの生成** +**3.2 Generate Message** -Claude.mdのルール「目的または意図が伝わるタイトル」に従い、以下の形式で生成: +Follow project commit rules (`.claude/rules/commit-rules.md`): ``` -{type}: {目的・意図を表す簡潔な説明} +{type}: {concise description conveying purpose/intent} -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +Co-Authored-By: Claude Opus 4.6 ``` -**タイプ別の例**: -- `feat: ユーザー認証機能を追加` -- `fix: ログイン時のセッションタイムアウトを修正` -- `refactor: API層のエラーハンドリングを改善` -- `update: ユーザー設定画面のUIを改善` -- `docs: READMEにセットアップ手順を追加` +**Type Examples**: +- `feat: Add user authentication feature` +- `fix: Fix session timeout on login` +- `refactor: Improve error handling in API layer` +- `update: Improve user settings UI` +- `docs: Add setup guide to README` -**生成ルール**: -- 1行目は50文字以内を目標(最大70文字) -- 日本語で記述 -- 「〜を追加」「〜を修正」など、動作を明確に -- 技術的な詳細は不要(タイトルのみ) +**Generation Rules**: +- First line: Target 50 chars (max 70) +- Follow project language requirements (check `.claude/rules/commit-rules.md`) +- Convey "why" not just "what" +- Use clear action verbs ("add", "fix", "improve") +- No technical details in title -### 4. コミットの実行 +**Project-Specific Commit Rules** (from `.claude/rules/commit-rules.md`): +1. **Split by purpose**: Each commit = one purpose (feature/fix/refactor) +2. **Write clearly**: Describe why the change was made +3. **Language**: Follow project requirements for commit message language +4. **Format**: `: ` +5. **Test code**: Can be included in same commit as implementation +6. **Always push**: Push immediately after commit to prevent work loss -**4.1 ファイルのステージング** +### 4. Execute Commit -機密ファイルを除外してステージング: +**4.1 Stage Files** + +Stage files individually, excluding sensitive files: ```bash git add {file1} {file2} {file3} ... ``` -**重要**: `git add -A` や `git add .` は使用しない(機密ファイルの誤コミット防止) +**Important**: Never use `git add -A` or `git add .` to prevent accidental sensitive file commits. -**4.2 コミット** +**4.2 Commit** -HEREDOC形式でコミット: +Use HEREDOC format: ```bash git commit -m "$(cat <<'EOF' @@ -125,64 +134,65 @@ EOF )" ``` -### 5. リモートへのプッシュ +### 5. Push to Remote -**5.1 プッシュ** +**5.1 Push** ```bash git push -u origin {current_branch} ``` -**5.2 プッシュ失敗時の対応** +**5.2 Handle Push Failures** -rejected(リモートに新しいコミットがある)場合: +If rejected (remote has new commits): ```bash git pull --rebase origin {current_branch} ``` -rebase中にコンフリクトが発生した場合: +If rebase conflicts occur: ``` -エラー: コンフリクトが発生しました。 -以下のファイルを手動で解決してください: +Error: Conflicts detected. +Please resolve the following files manually: {conflict_files} -解決後: +After resolution: git add {resolved_files} git rebase --continue git push ``` -rebaseが成功した場合、再度プッシュ: +If rebase succeeds, push again: ```bash git push ``` -### 6. 結果表示 +### 6. Display Result ``` -## コミット完了 +## Commit Complete -**ブランチ**: {current_branch} -**コミットメッセージ**: {commit_message_first_line} -**変更ファイル**: {file_count}件 +**Branch**: {current_branch} +**Commit Message**: {commit_message_first_line} +**Changed Files**: {file_count} files -変更がリモートにプッシュされました。 +Changes have been pushed to remote. ``` -## エラーハンドリング +## Error Handling -| エラー | 対応 | -|--------|------| -| 変更がない | ファイルを編集してから実行するよう案内 | -| 機密ファイル検出 | 自動除外して続行(警告表示) | -| コンフリクト発生 | 手動解決の手順を案内 | -| プッシュ失敗 | rebaseして再プッシュ | -| rebase失敗 | 手動解決の手順を案内 | +| Error | Response | +|-------|----------| +| No changes | Guide to edit files before running | +| Sensitive files detected | Auto-exclude and continue (show warning) | +| Conflicts detected | Guide to manual resolution | +| Push failed | Rebase and retry push | +| Rebase failed | Guide to manual resolution | -## 注意事項 +## Important Notes -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **機密ファイルの保護**: 自動検出して除外、警告を表示 -3. **コミットメッセージの品質**: Claude.mdのルールに従い、目的・意図が伝わるタイトルを生成 -4. **安全なステージング**: `git add .` は使用せず、ファイルを個別に指定 +1. **No emojis**: Never use emojis unless explicitly requested by user +2. **Sensitive file protection**: Auto-detect and exclude, display warning +3. **Message quality**: Follow project rules - convey purpose/intent +4. **Safe staging**: Never use `git add .`, specify files individually +5. **Always push**: Project rule requires immediate push after commit diff --git a/.claude/skills/git/workflows/worktree-create.md b/.claude/skills/git/workflows/worktree-create.md index 947cea3..cceba5d 100644 --- a/.claude/skills/git/workflows/worktree-create.md +++ b/.claude/skills/git/workflows/worktree-create.md @@ -1,106 +1,106 @@ -# ワークツリー作成ワークフロー +# Worktree Creation Workflow -このワークフローは、新しいワークツリーを作成します。 +This workflow creates a new worktree for parallel work. -## 必要なツール +## Required Tools - Bash - AskUserQuestion -## 実行ステップ +## Execution Steps -### 1. 現在のディレクトリ情報を取得 +### 1. Get Current Directory Info -**1.1 カレントディレクトリとリポジトリ名を取得** +**1.1 Get Current Directory and Repository Name** ```bash pwd basename $(pwd) ``` -- カレントディレクトリ: `/nab-agents` -- リポジトリ名: `nab-agents` +- Current directory: `/nab-agents` +- Repository name: `nab-agents` -**1.2 親ディレクトリを取得** +**1.2 Get Parent Directory** ```bash dirname $(pwd) ``` -- 親ディレクトリ: `` +- Parent directory: `` -### 2. ブランチ名の提案 +### 2. Propose Branch Names -**2.1 作業目的のヒアリング** +**2.1 Ask Work Purpose** -AskUserQuestionで作業目的をヒアリング: +Use AskUserQuestion to understand work purpose: ``` -質問: このワークツリーで何を実装・修正しますか? -header: "作業内容" -options: - - label: "新機能の追加" - description: "新しい機能を実装する" - - label: "バグ修正" - description: "既存のバグを修正する" - - label: "リファクタリング" - description: "コードの構造を改善する" - - label: "ドキュメント更新" - description: "ドキュメントを更新する" +Question: What will you implement or fix in this worktree? +Header: "Work Type" +Options: + - Label: "New Feature" + Description: "Implement a new feature" + - Label: "Bug Fix" + Description: "Fix an existing bug" + - Label: "Refactoring" + Description: "Improve code structure" + - Label: "Documentation" + Description: "Update documentation" ``` -**2.2 詳細のヒアリング** +**2.2 Ask for Details** -選択された作業内容に応じて、詳細をヒアリング(自由入力): +Based on selected work type, ask for details (free text): ``` -「{作業内容}」の詳細を教えてください。 -例: ユーザー認証機能、ログイン画面のバグ、API層のリファクタリング等 +Please provide details about "{work_type}". +Examples: user authentication, login page bug, API layer refactoring, etc. ``` -**2.3 ブランチ名の生成** +**2.3 Generate Branch Names** -ヒアリングした内容から、3つのブランチ名候補を生成: +Generate 3 branch name candidates from the details: -**生成ルール**: -- プレフィックス: `add-`(新機能), `fix-`(バグ修正), `refactor-`(リファクタリング), `docs-`(ドキュメント) -- 本体: 詳細から抽出したキーワードを`-`で連結 -- 全て小文字、英数字とハイフンのみ +**Generation Rules**: +- Prefix: `add-` (feature), `fix-` (bug), `refactor-` (refactor), `docs-` (docs) +- Body: Keywords from details joined with `-` +- All lowercase, alphanumeric and hyphens only -**2.4 ブランチ名の選択** +**2.4 Select Branch Name** -AskUserQuestionで候補から選択: +Use AskUserQuestion to select from candidates: ``` -質問: ブランチ名を選択してください。 -header: "ブランチ名" -options: - - label: "{候補1}" - description: "推奨" - - label: "{候補2}" - description: "" - - label: "{候補3}" - description: "" +Question: Select branch name. +Header: "Branch Name" +Options: + - Label: "{candidate1}" + Description: "Recommended" + - Label: "{candidate2}" + Description: "" + - Label: "{candidate3}" + Description: "" ``` -ユーザーが"Other"を選択した場合、自由入力を受け付ける。 +If user selects "Other", accept free text input. -**2.5 ブランチ名の重複確認** +**2.5 Check for Duplicates** ```bash git branch --list "{branch_name}" ``` -既に存在する場合はエラー終了: +If exists, exit with error: ``` -エラー: ブランチ「{branch_name}」は既に存在します。 +Error: Branch "{branch_name}" already exists. -別のブランチ名を使用するか、既存ブランチを削除してください: +Use a different name or delete the existing branch: git branch -d {branch_name} ``` -### 3. ワークツリーパスの決定 +### 3. Determine Worktree Path -**3.1 パスの生成** +**3.1 Generate Path** ```bash parent_dir=$(dirname $(pwd)) @@ -108,96 +108,96 @@ repo_name=$(basename $(pwd)) worktree_path="${parent_dir}/${repo_name}-${branch_name}" ``` -例: -- 現在: `/nab-agents` -- ワークツリー: `/nab-agents-` +Example: +- Current: `/nab-agents` +- Worktree: `/nab-agents-` -**3.2 パスの存在確認** +**3.2 Check Path Existence** ```bash test -e {worktree_path} ``` -既に存在する場合はエラー終了: +If exists, exit with error: ``` -エラー: パス「{worktree_path}」は既に存在します。 +Error: Path "{worktree_path}" already exists. -別のブランチ名を使用するか、既存のディレクトリを削除してください。 +Use a different branch name or delete the existing directory. ``` -**3.3 パスの確認** +**3.3 Confirm Path** -AskUserQuestionでパスを確認: +Use AskUserQuestion to confirm path: ``` -質問: 以下のパスにワークツリーを作成します。よろしいですか? -header: "パス確認" -options: - - label: "はい、作成する" - description: "{worktree_path}" - - label: "いいえ、キャンセル" - description: "" +Question: Create worktree at the following path. OK? +Header: "Confirm Path" +Options: + - Label: "Yes, create it" + Description: "{worktree_path}" + - Label: "No, cancel" + Description: "" -表示する情報: -パス: {worktree_path} -ブランチ: {branch_name} -ベース: main +Display info: +Path: {worktree_path} +Branch: {branch_name} +Base: main ``` -### 4. ワークツリーの作成 +### 4. Create Worktree -**4.1 mainブランチの更新** +**4.1 Update Main Branch** ```bash git fetch origin main git pull origin main ``` -**4.2 ワークツリーの作成** +**4.2 Create Worktree** ```bash git worktree add -b {branch_name} {worktree_path} main ``` -作成に失敗した場合: +If creation fails: ``` -エラー: ワークツリーの作成に失敗しました。 +Error: Failed to create worktree. -以下を確認してください: -- ディスク容量が十分にあること -- パスへの書き込み権限があること -- ブランチ名が有効であること +Please verify: +- Sufficient disk space +- Write permissions to the path +- Valid branch name ``` -### 5. 結果表示 +### 5. Display Result ``` -## ワークツリー作成完了 +## Worktree Creation Complete -**パス**: {worktree_path} -**ブランチ**: {branch_name} -**ベースブランチ**: main +**Path**: {worktree_path} +**Branch**: {branch_name} +**Base Branch**: main -### 移動コマンド +### Move to Worktree cd {worktree_path} -移動後、作業を開始できます。 -変更をコミットする際は `/git commit` を使用してください。 +You can now start working. +Use `/git commit` to commit changes. ``` -## エラーハンドリング +## Error Handling -| エラー | 対応 | -|--------|------| -| ブランチ名が既に存在 | 別の名前を使用するか、既存ブランチを削除するよう案内 | -| パスが既に存在 | 別の名前を使用するか、既存ディレクトリを削除するよう案内 | -| mainの更新に失敗 | コンフリクトを解決するよう案内 | -| 権限不足 | パスへの書き込み権限を確認するよう案内 | -| 容量不足 | ディスク容量を確認するよう案内 | +| Error | Response | +|-------|----------| +| Branch name exists | Guide to use different name or delete existing | +| Path exists | Guide to use different name or delete existing directory | +| Failed to update main | Guide to resolve conflicts | +| Insufficient permissions | Guide to check write permissions | +| Insufficient disk space | Guide to check disk space | -## 注意事項 +## Important Notes -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **パスの命名規則**: `{親ディレクトリ}/{リポジトリ名}-{ブランチ名}` -3. **ブランチ名の品質**: ユーザーの入力から適切なブランチ名を生成する -4. **ベースブランチ**: 常にmainブランチから分岐 +1. **No emojis**: Never use emojis unless explicitly requested by user +2. **Path naming convention**: `{parent_dir}/{repo_name}-{branch_name}` +3. **Branch name quality**: Generate appropriate names from user input +4. **Base branch**: Always branch from main diff --git a/.claude/skills/git/workflows/worktree-delete.md b/.claude/skills/git/workflows/worktree-delete.md index b95500b..2889522 100644 --- a/.claude/skills/git/workflows/worktree-delete.md +++ b/.claude/skills/git/workflows/worktree-delete.md @@ -1,219 +1,219 @@ -# ワークツリー削除ワークフロー +# Worktree Deletion Workflow -このワークフローは、既存のワークツリーを削除します。 +This workflow deletes an existing worktree. -## 必要なツール +## Required Tools - Bash - AskUserQuestion -## 実行ステップ +## Execution Steps -### 1. ワークツリー一覧の取得 +### 1. Get Worktree List -**1.1 ワークツリーリストを取得** +**1.1 Get Worktree List** ```bash git worktree list ``` -出力例: +Output example: ``` /nab-agents abc1234 [main] /nab-agents- def5678 [add-feature] /nab-agents- ghi9012 [fix-bug] ``` -**1.2 削除可能なワークツリーの抽出** +**1.2 Extract Deletable Worktrees** -メインワークツリー(最初の行)を除外し、削除可能なワークツリーのリストを作成。 +Exclude the main worktree (first line) to create list of deletable worktrees. -ワークツリーがない場合: +If no worktrees: ``` -情報: 削除可能なワークツリーがありません。 +Info: No deletable worktrees found. -現在のワークツリー一覧: +Current worktrees: {worktree_list} ``` -### 2. 削除対象ワークツリーの決定 +### 2. Determine Target Worktree -**2.1 引数の確認** +**2.1 Check Arguments** -引数が指定されている場合、それを削除対象とする。 -引数がない場合、次のステップでユーザーに選択させる。 +If argument is specified, use it as target. +If no argument, proceed to next step to let user select. -**2.2 削除対象の選択(引数がない場合)** +**2.2 Select Target (if no argument)** -AskUserQuestionでワークツリーを選択: +Use AskUserQuestion to select worktree: ``` -質問: 削除するワークツリーを選択してください。 -header: "ワークツリー削除" -options: - - label: "{path1}" - description: "ブランチ: {branch1}" - - label: "{path2}" - description: "ブランチ: {branch2}" - - label: "{path3}" - description: "ブランチ: {branch3}" +Question: Select worktree to delete. +Header: "Delete Worktree" +Options: + - Label: "{path1}" + Description: "Branch: {branch1}" + - Label: "{path2}" + Description: "Branch: {branch2}" + - Label: "{path3}" + Description: "Branch: {branch3}" ``` -### 3. 削除前チェック +### 3. Pre-deletion Checks -**3.1 メインワークツリーの保護** +**3.1 Protect Main Worktree** -削除対象がメインワークツリー(カレントリポジトリ)の場合はエラー終了: +If target is the main worktree (current repository), exit with error: ``` -エラー: メインワークツリーは削除できません。 +Error: Cannot delete main worktree. ``` -**3.2 パスの存在確認** +**3.2 Verify Path Exists** ```bash test -d {worktree_path} ``` -パスが存在しない場合はエラー終了: +If path doesn't exist, exit with error: ``` -エラー: ワークツリー「{worktree_path}」が見つかりません。 +Error: Worktree "{worktree_path}" not found. -ワークツリー一覧を確認: +Check worktree list: git worktree list ``` -**3.3 未コミット変更の確認** +**3.3 Check for Uncommitted Changes** -削除対象ワークツリーのステータスを確認: +Check status of target worktree: ```bash git -C {worktree_path} status --porcelain ``` -未コミットの変更がある場合、警告を表示: +If uncommitted changes exist, display warning: -AskUserQuestionで確認: +Use AskUserQuestion to confirm: ``` -質問: ワークツリー「{worktree_path}」に未コミットの変更があります。 -削除すると、これらの変更は失われます。本当に削除しますか? -header: "警告" -options: - - label: "はい、削除する" - description: "未コミットの変更が失われます" - - label: "いいえ、キャンセル" - description: "変更を保存してから削除してください" +Question: Worktree "{worktree_path}" has uncommitted changes. +Deletion will lose these changes. Delete anyway? +Header: "Warning" +Options: + - Label: "Yes, delete it" + Description: "Uncommitted changes will be lost" + - Label: "No, cancel" + Description: "Save changes before deletion" -表示する変更一覧: +Display changes: {git_status_output} ``` -ユーザーが"キャンセル"を選択した場合、処理を中断: +If user selects "Cancel", abort: ``` -処理をキャンセルしました。 +Operation cancelled. -変更を保存するには: +To save changes: cd {worktree_path} /git commit ``` -### 4. ワークツリーの削除 +### 4. Delete Worktree -**4.1 ワークツリーを削除** +**4.1 Delete Worktree** ```bash git worktree remove {worktree_path} ``` -削除に失敗した場合(ロックされている等)、強制削除: +If deletion fails (locked, etc.), force delete: ```bash git worktree remove --force {worktree_path} ``` -それでも失敗した場合: +If still fails: ``` -エラー: ワークツリーの削除に失敗しました。 +Error: Failed to delete worktree. -手動で削除してください: +Manual deletion: rm -rf {worktree_path} git worktree prune ``` -### 5. ブランチの削除確認 +### 5. Branch Deletion Confirmation -**5.1 ブランチの取得** +**5.1 Get Branch Name** -削除したワークツリーのブランチ名を取得。 +Extract branch name from deleted worktree. -**5.2 マージ済み確認** +**5.2 Check if Merged** ```bash git branch --merged main | grep "^ {branch_name}$" ``` -**5.3 ブランチ削除の確認** +**5.3 Confirm Branch Deletion** -マージ済みの場合、AskUserQuestionでブランチ削除を確認: +If merged, use AskUserQuestion to confirm branch deletion: ``` -質問: ブランチ「{branch_name}」はマージ済みです。 -このブランチも削除しますか? -header: "ブランチ削除" -options: - - label: "はい、削除する" - description: "ローカルとリモートから削除" - - label: "ローカルのみ削除" - description: "リモートは残す" - - label: "いいえ、残す" - description: "ブランチは残す" +Question: Branch "{branch_name}" is merged. +Delete this branch too? +Header: "Delete Branch" +Options: + - Label: "Yes, delete it" + Description: "Delete from local and remote" + - Label: "Delete local only" + Description: "Keep remote branch" + - Label: "No, keep it" + Description: "Keep the branch" ``` -**5.4 ブランチの削除** +**5.4 Delete Branch** -ユーザーの選択に応じて: +Based on user selection: -**「はい、削除する」の場合**: +**"Yes, delete it"**: ```bash git push origin --delete {branch_name} git branch -d {branch_name} ``` -**「ローカルのみ削除」の場合**: +**"Delete local only"**: ```bash git branch -d {branch_name} ``` -**「いいえ、残す」の場合**: -削除しない。 +**"No, keep it"**: +Do nothing. -### 6. 結果表示 +### 6. Display Result ``` -## ワークツリー削除完了 +## Worktree Deletion Complete -**削除したワークツリー**: {worktree_path} -**ブランチ**: {branch_name} +**Deleted Worktree**: {worktree_path} +**Branch**: {branch_name} -### 実行内容 -- ワークツリー '{worktree_path}' を削除しました -{ブランチ削除した場合} -- ローカルブランチ '{branch_name}' を削除しました -- リモートブランチ 'origin/{branch_name}' を削除しました -{/ブランチ削除した場合} +### Actions Performed +- Deleted worktree '{worktree_path}' +{if branch deleted} +- Deleted local branch '{branch_name}' +- Deleted remote branch 'origin/{branch_name}' +{/if branch deleted} ``` -## エラーハンドリング +## Error Handling -| エラー | 対応 | -|--------|------| -| 削除可能なワークツリーがない | ワークツリー一覧を表示 | -| メインワークツリーの削除試行 | エラーメッセージを表示して終了 | -| パスが存在しない | 正しいパスを確認 | -| 未コミット変更あり | 警告を表示してユーザーに確認 | -| 削除失敗 | 強制削除を試行、それでも失敗した場合は手動削除を案内 | +| Error | Response | +|-------|----------| +| No deletable worktrees | Display worktree list | +| Attempted to delete main worktree | Display error and exit | +| Path doesn't exist | Verify correct path | +| Uncommitted changes | Display warning and ask user to confirm | +| Deletion failed | Attempt force delete, guide to manual deletion if failed | -## 注意事項 +## Important Notes -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **安全性優先**: 未コミット変更がある場合は警告を表示 -3. **メインワークツリーの保護**: メインワークツリーは削除を拒否 -4. **ブランチ削除**: マージ済みブランチは自動的に削除を提案 +1. **No emojis**: Never use emojis unless explicitly requested by user +2. **Safety first**: Warn if uncommitted changes exist +3. **Main worktree protection**: Refuse deletion of main worktree +4. **Branch deletion**: Automatically suggest deletion for merged branches diff --git a/.claude/skills/nabledge-6/SKILL.md b/.claude/skills/nabledge-6/SKILL.md new file mode 100644 index 0000000..a73740a --- /dev/null +++ b/.claude/skills/nabledge-6/SKILL.md @@ -0,0 +1,349 @@ +--- +name: nabledge-6 +description: Provides structured knowledge about Nablarch 6 framework (batch processing, RESTful web services, handlers, libraries, tools) and code analysis capabilities. Use when developing Nablarch applications, implementing features, reviewing code, investigating errors, answering questions about Nablarch 6 APIs and patterns, or analyzing existing code to understand its structure and dependencies. +--- + +# Nabledge-6: Nablarch 6 Knowledge Base + +Structured knowledge base for Nablarch 6 framework, covering batch processing and RESTful web services. + +## What this skill provides + +**Knowledge Coverage**: Batch, REST, handlers, libraries (UniversalDao, DB access, validation, file I/O, business date), testing (NTF), adapters, security + +**Code Analysis**: Dependency tracing, component decomposition, architecture visualization, documentation generation + +**Use cases**: +- **Knowledge search**: Learn Nablarch APIs, patterns, configurations, troubleshooting +- **Code analysis**: Understand existing code structure, dependencies, and design +- **Development support**: Feature implementation, code review, error investigation + +## How to use + +### Basic usage + +**Interactive mode** (recommended): +``` +nabledge-6 +``` +Shows friendly greeting and lets you choose between knowledge search and code analysis. + +**Direct knowledge search**: +``` +nabledge-6 "Your question about Nablarch" +``` + +**Direct code analysis**: +``` +nabledge-6 code-analysis +``` + +### Important constraint: Knowledge files only + +**CRITICAL**: Always answer using ONLY the information in knowledge files (knowledge/*.json). + +- **DO NOT use** LLM training data or general knowledge about Nablarch +- **DO NOT access** official websites or external resources during answers +- **DO NOT guess** or infer information not present in knowledge files +- **If knowledge is missing**: Clearly state "この情報は知識ファイルに含まれていません" and list related available knowledge + +**Why this constraint**: Knowledge files contain verified, accurate information extracted from official documentation. LLM training data may be outdated or incomplete. + +## Error Handling Policy + +**General principle**: +- Always inform user clearly when something goes wrong +- Provide actionable next steps +- Never fail silently + +**Knowledge not found** (Knowledge Search): +- Message: "この情報は知識ファイルに含まれていません" +- List related available knowledge from index.toon +- Show "not yet created" entries if applicable +- DO NOT use LLM training data or general knowledge + +**Target code not found** (Code Analysis): +- Message: "指定されたコードが見つかりませんでした" +- Show search patterns used (e.g., `**/*LoginAction.java`) +- Ask for clarification (more specific file name, module, or full path) + +**Workflow execution failure**: +- Inform user which step failed (e.g., "Step 2: 依存関係分析中にエラーが発生しました") +- Show error details if available +- Suggest retry or alternative approach + +**Output file already exists** (Code Analysis): +- Ask user: "上書きする" / "別名で保存" / "キャンセル" + +**Dependency analysis too complex** (Code Analysis): +- Ask user to narrow scope +- Suggest limiting to direct dependencies only +- Provide partial analysis with note + +## How Claude Code should execute this skill + +**CRITICAL**: When this skill is invoked, Claude Code MUST execute workflows manually. The skill does NOT automatically process - Claude must follow the workflow steps using tools. + +### Execution Process + +When you (Claude Code) receive this skill prompt, follow these steps: + +#### Step 0: Check arguments and determine workflow + +**Decision tree**: + +1. **No arguments** (`nabledge-6`): + - Proceed to Step 1: Show greeting and ask user choice + +2. **Argument: "code-analysis"** (`nabledge-6 code-analysis`): + - Skip to Code Analysis Workflow (Step 3) + +3. **Other text arguments** (`nabledge-6 `): + - Treat argument as user question + - Skip to Knowledge Search Workflow (Step 2) + +#### Step 1: User-friendly greeting (no arguments case only) + +**Tool**: AskUserQuestion + +**Action**: Show friendly greeting and ask what user wants to do + +**Message**: +``` +Nablarch 6のことなら何でもお答えします。 + +以下のようなことが可能です: +- Nablarchの機能や使い方について質問する + 例: UniversalDaoの使い方、バッチ処理の実装方法、トランザクション管理 +- 既存コードの構造を理解するためのドキュメントを生成する + 例: LoginActionの構造、プロジェクト全体のアーキテクチャ + +何をお手伝いしましょうか? +``` + +**Options**: +- Option 1: "Nablarchの機能や使い方を知りたい" → Proceed to Step 2 (Knowledge Search) +- Option 2: "既存コードの構造を理解したい" → Proceed to Step 3 (Code Analysis) +- Other (free text input) → Treat as knowledge search question, proceed to Step 2 + +#### Step 2: Knowledge Search Workflow + +Execute when user wants to search Nablarch knowledge. + +**Inform user**: "Nablarch知識ベースを検索します" + +**Execute workflows**: + +Follow the workflows in this order: + +1. **keyword-search workflow** (see `workflows/keyword-search.md`): + - Read knowledge/index.toon + - Extract keywords (3 levels: domain, component, functional) + - Match against index hints + - Select top 10-15 files + - Extract section indexes using jq + - Build candidates list (20-30 sections) + +2. **section-judgement workflow** (see `workflows/section-judgement.md`): + - Read each candidate section + - Judge relevance: High (2), Partial (1), None (0) + - Filter out None relevance + - Sort by relevance (High first) + - Return top 10-15 sections (~5,000 tokens) + +3. **Answer using knowledge files only**: + - Extract information from High and Partial sections + - Format as clear, structured answer + - **ONLY use information from knowledge files** + - Cite sources (e.g., "universal-dao.json:paging section") + - DO NOT supplement with LLM training data + +4. **Handle missing knowledge** (if needed): + - State clearly: "この情報は知識ファイルに含まれていません" + - List related available knowledge from index.toon + - DO NOT answer from LLM training data + +**Tools**: Read, Grep (optional), Bash with jq +**Expected**: ~10-15 tool calls, ~5,000 tokens + +#### Step 3: Code Analysis Workflow + +Execute when user wants to analyze existing code. + +**Entry conditions**: +- User selected Option 2 from Step 1 +- Skill invoked with `nabledge-6 code-analysis` + +**Inform user**: "既存コードを分析してドキュメントを生成します" + +**If target code not specified**: Ask user for target specification using AskUserQuestion + +**Execute workflow**: + +Follow `workflows/code-analysis.md`: + +1. **Identify target and analyze dependencies**: + - Parse user request (class/feature/package) + - Find target files using Glob/Grep + - Read target files and extract dependencies + - Classify dependencies (project/Nablarch/libraries) + - Build dependency graph + - Categorize components by role + +2. **Search Nablarch knowledge**: + - For each Nablarch component, execute keyword-search workflow + - Collect relevant knowledge sections + +3. **Generate and output documentation**: + - Read template files (MUST READ FIRST) + - Build Mermaid classDiagram and sequenceDiagram + - Create component summary table + - Write component details with line references + - Write Nablarch usage with important points (✅ ⚠️ 💡) + - Apply template with all placeholders + - Calculate analysis duration + - Write file to `work/YYYYMMDD/code-analysis-.md` + - Inform user of completion + +**Tools**: Read, Glob, Grep, Bash with jq, Write +**Expected**: ~30-50 tool calls, 1 documentation file + +### Workflow Files + +- `workflows/keyword-search.md`: Keyword-based knowledge search (3 steps) +- `workflows/section-judgement.md`: Relevance judgement for knowledge sections (2 steps) +- `workflows/code-analysis.md`: Existing code analysis and documentation generation (3 steps) + +### Template Files + +- `assets/code-analysis-template.md`: Documentation template for code analysis output +- `assets/code-analysis-template-guide.md`: Template usage guide (sections, placeholders, evaluation criteria) +- `assets/code-analysis-template-examples.md`: Template examples (component table, Nablarch usage, links) + +## Quick reference + +**Interactive mode**: +``` +nabledge-6 +``` +Shows greeting → Choose knowledge search or code analysis + +**Knowledge search examples**: +``` +nabledge-6 "Nablarchでページングを実装したい" +nabledge-6 "UniversalDaoの使い方" +nabledge-6 "トランザクション管理ハンドラのエラー対処" +``` +Process: keyword-search → section-judgement → answer using knowledge files only + +**Code analysis examples**: +``` +nabledge-6 code-analysis +``` +Then specify: "LoginActionを理解したい", "proman-batchモジュール全体の構造", etc. +Process: Identify → Analyze → Search knowledge → Generate docs → Output file + +## Knowledge structure + +**Knowledge files** (JSON format): +- `knowledge/features/`: Handlers, libraries, processing methods, tools, adapters +- `knowledge/checks/`: Security checklist, public API list, deprecated features +- `knowledge/releases/`: Release notes + +**Index** (TOON format): +- `knowledge/index.toon`: 93 entries with ~650 search hints + +**Human-readable** (auto-generated): +- `docs/`: Markdown version of knowledge files for human verification + +Each knowledge file includes: +- `official_doc_urls`: Source URLs for verification +- `index`: Section-level search hints +- `sections`: Structured knowledge by topic + +Example: `knowledge/features/libraries/universal-dao.json` + +## Advanced usage + +**Manual search**: +```bash +grep -i "ページング" knowledge/index.toon +``` + +**Read specific knowledge**: +```bash +jq '.sections.paging' knowledge/features/libraries/universal-dao.json +``` + +**Browse human-readable version**: +```bash +cat docs/features/libraries/universal-dao.md +``` + +## Token efficiency + +**Index**: ~5,000-7,000 tokens (TOON format, 40-50% reduction vs JSON) +**Search results**: ~5,000 tokens (top 10 sections, 500 tokens each) +**Total**: ~10,000-12,000 tokens (5-6% of 200k context window) + +## Version information + +**Target version**: Nablarch 6u2 / 6u3 + +**Out of scope**: +- Jakarta Batch +- Resident batch (table queue) +- Web applications (JSP/UI) +- Messaging (MOM) + +## Quality assurance + +**Knowledge accuracy**: Average 97.3/100 points (verified against official documentation) + +**Coverage**: 17 files created, 43 files planned (total 60 files) + +**Source**: Official documentation (https://nablarch.github.io/docs/), Fintan system development guide + +## Limitations + +### Knowledge coverage + +**Not yet created** knowledge files show "not yet created" in index.toon (76 out of 93 entries). + +**When knowledge is missing**: +1. Clearly state: "この情報は知識ファイルに含まれていません" +2. List related available knowledge that might help +3. Show the entry from index.toon with "not yet created" status +4. **DO NOT** attempt to answer from LLM training data or general knowledge +5. **ONLY IF EXPLICITLY REQUESTED**: Provide official_doc_urls for manual reference + +**Current coverage** (17 files): +- Nablarch batch processing basics +- Core handlers (DB connection, transaction, data read) +- Core libraries (UniversalDao, database access, file path, business date, data bind) +- Testing framework (NTF) basics +- SLF4J adapter +- Security checklist +- Release notes (6u3) + +### Verification + +**Human verification**: Check `docs/` directory for human-readable versions. All knowledge includes `official_doc_urls` showing the source. + +**Accuracy**: Average 97.3/100 points (verified against official RST documentation) + +## Feedback + +If knowledge is inaccurate or missing, please: +1. Check `official_doc_urls` in the knowledge file for the source +2. Verify against official documentation +3. Report discrepancies to the knowledge maintainer + +## References (for manual lookup only) + +**IMPORTANT**: These references are for human users to manually look up information NOT in knowledge files. Do not access or fetch these during answers. + +- [Nablarch Official Documentation](https://nablarch.github.io/docs/LATEST/doc/) - Use when knowledge file says "not yet created" +- [Fintan System Development Guide](https://fintan.jp/page/252/) - Patterns and anti-patterns +- [Nablarch Example Batch](https://github.com/nablarch/nablarch-example-batch) - Code examples +- [Nablarch Example REST](https://github.com/nablarch/nablarch-example-rest) - REST examples diff --git a/.claude/skills/nabledge-6/assets/code-analysis-template-examples.md b/.claude/skills/nabledge-6/assets/code-analysis-template-examples.md new file mode 100644 index 0000000..131382e --- /dev/null +++ b/.claude/skills/nabledge-6/assets/code-analysis-template-examples.md @@ -0,0 +1,267 @@ +# Code Analysis Template Examples + +This document contains detailed examples for generating code analysis documentation. Reference these examples when following the code-analysis workflow. + +## Component Summary Table + +**Purpose**: Provide a high-level overview of all components in the Architecture section. + +**Format**: Markdown table with 4 columns + +**Columns**: +- **Component**: Component name (class, file, or module) +- **Role**: Brief description of purpose (5-10 words) +- **Type**: Component type (Action, Form, Entity, DTO, SQL, Handler, Util, etc.) +- **Dependencies**: Key dependencies (comma-separated) + +**Example 1: Batch Action** + +```markdown +| Component | Role | Type | Dependencies | +|-----------|------|------|--------------| +| ExportProjectsInPeriodAction | 期間内プロジェクト一覧CSV出力 | Action | DatabaseRecordReader, ObjectMapper, FilePathSetting | +| ProjectDto | プロジェクト情報データ転送オブジェクト | DTO | なし | +| FIND_PROJECT_IN_PERIOD | 期間内プロジェクト検索クエリ | SQL | なし | +``` + +**Example 2: Web Action** + +```markdown +| Component | Role | Type | Dependencies | +|-----------|------|------|--------------| +| LoginAction | ログイン認証処理 | Action | LoginForm, SystemAccountEntity, UniversalDao | +| LoginForm | ログイン入力検証 | Form | なし | +| SystemAccountEntity | システムアカウント情報 | Entity | なし | +``` + +**Tips**: +- Keep Role descriptions concise (avoid full sentences) +- Use Japanese for Role descriptions +- For "なし" (no dependencies), write "なし" instead of leaving blank +- Include all major components (3-10 components typically) + +--- + +## Nablarch Usage with Important Points + +**Purpose**: Explain how Nablarch components are used with practical guidance for developers. + +**Structure** (for each component): +1. **クラス名**: Full class name +2. **説明**: Brief description (1-2 sentences) +3. **使用方法**: Code example (Java snippet) +4. **重要ポイント**: Critical points with emoji prefixes +5. **このコードでの使い方**: How it's used in analyzed code +6. **詳細**: Link to knowledge base + +**Important Points Prefixes**: +- ✅ **Must do**: Critical actions that must be performed +- ⚠️ **Caution**: Gotchas, limitations, common mistakes +- 💡 **Benefit**: Why use this, advantages, design philosophy +- 🎯 **When to use**: Use cases, scenarios, applicability +- ⚡ **Performance**: Performance considerations, optimization tips + +**Example 1: ObjectMapper** + +```markdown +### ObjectMapper + +**クラス**: `nablarch.common.databind.ObjectMapper` + +**説明**: CSVやTSV、固定長データをJava Beansとして扱う機能を提供する + +**使用方法**: +\`\`\`java +// 生成 +ObjectMapper mapper = ObjectMapperFactory.create(ProjectDto.class, outputStream); + +// 書き込み +mapper.write(dto); + +// クローズ +mapper.close(); +\`\`\` + +**重要ポイント**: +- ✅ **必ず`close()`を呼ぶ**: バッファをフラッシュし、リソースを解放する(`terminate()`で実施) +- ⚠️ **大量データ処理時**: メモリに全データを保持しないため、大量データでも問題なく処理可能 +- ⚠️ **型変換の制限**: `EntityUtil`と同様に、複雑な型変換が必要な項目は個別設定が必要 +- 💡 **アノテーション駆動**: `@Csv`, `@CsvFormat`でフォーマットを宣言的に定義できる +- 💡 **保守性の高さ**: フォーマット変更時はアノテーションを変更するだけで対応可能 + +**このコードでの使い方**: +- `initialize()`でProjectDto用のObjectMapperを生成(Line 25-28) +- `handle()`で各レコードを`mapper.write(dto)`で出力(Line 52) +- `terminate()`で`mapper.close()`してリソース解放(Line 60) + +**詳細**: [データバインド](../../.claude/skills/nabledge-6/docs/features/libraries/data-bind.md) +``` + +**Example 2: BusinessDateUtil** + +```markdown +### BusinessDateUtil + +**クラス**: `nablarch.core.date.BusinessDateUtil` + +**説明**: システム全体で統一された業務日付を取得する機能を提供する + +**使用方法**: +\`\`\`java +// デフォルト区分の業務日付 +String bizDate = BusinessDateUtil.getDate(); +// → "20260210"(yyyyMMdd形式) + +// 区分別の業務日付 +String batchDate = BusinessDateUtil.getDate("batch"); +\`\`\` + +**重要ポイント**: +- 💡 **システム横断の日付統一**: `System.currentTimeMillis()`や`LocalDate.now()`ではなく、これを使うことでバッチ処理と画面処理で同じ業務日付を共有できる +- ✅ **必ずDatabaseRecordReaderのパラメータに変換**: 取得した文字列は`java.sql.Date`に変換してSQLパラメータに設定する +- 🎯 **いつ使うか**: 日付ベースの検索条件、レポート生成、ファイル名の日付部分など +- ⚠️ **設定が必要**: システムリポジトリに業務日付テーブルまたは固定値を設定する必要がある + +**このコードでの使い方**: +- `createReader()`で業務日付を取得(Line 38) +- `java.sql.Date`に変換してSQLパラメータに設定(Line 42-43) +- プロジェクトの開始日・終了日との比較条件として使用 + +**詳細**: [業務日付管理](../../.claude/skills/nabledge-6/docs/features/libraries/business-date.md) +``` + +**Tips**: +- Include 3-5 important points per component +- Focus on practical, actionable information +- Use emoji prefixes consistently +- Line references should be approximate (e.g., Line 25-28) + +--- + +## File Links with Line References + +**Purpose**: Link to source files with specific line number ranges for easy navigation. + +**Format**: `[FileName.java:StartLine-EndLine](relative/path/to/FileName.java)` + +**Path calculation**: +- Output location: `work/20260210/code-analysis-xxx.md` +- Source location: `proman-batch/src/main/java/.../Action.java` +- Relative path: `../../proman-batch/src/main/java/.../Action.java` + +**Example 1: Component Details** + +```markdown +### 1. ExportProjectsInPeriodAction + +**File**: [ExportProjectsInPeriodAction.java:15-120](../../proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java) + +**Role**: 期間内プロジェクト一覧出力の都度起動バッチアクションクラス + +**Key Methods**: +- `initialize()` [:20-28] - ファイル出力先の準備とObjectMapper生成 +- `createReader()` [:30-42] - DatabaseRecordReaderを生成してSQLを設定 +- `handle()` [:44-58] - 1レコードをProjectDtoに変換してCSV出力 +- `terminate()` [:60-65] - ObjectMapperをクローズ +``` + +**Example 2: Multiple Files** + +```markdown +### 2. ProjectDto + +**File**: [ProjectDto.java:1-85](../../proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ProjectDto.java) + +**Role**: 期間内プロジェクト一覧出力用のデータ転送オブジェクト + +**Annotations**: +- `@Csv` [:10] - CSV出力項目順序とヘッダー定義 +- `@CsvFormat` [:11-15] - CSV詳細設定(区切り文字、改行コード、文字コード) +``` + +**Tips**: +- Use `:StartLine-EndLine` for class/method ranges +- Use `[:LineNumber]` for single-line annotations +- Line numbers should be accurate (check with Read tool) +- Relative paths must be correct (use `../../` to go up from work/YYYYMMDD/) + +--- + +## Source Files Links + +**Purpose**: List all source files analyzed with descriptions. + +**Format**: Bullet list with links and brief descriptions + +**Example**: + +```markdown +### Source Files + +- [ExportProjectsInPeriodAction.java](../../proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java) - 期間内プロジェクト一覧出力バッチアクション +- [ProjectDto.java](../../proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ProjectDto.java) - CSV出力用データ転送オブジェクト +- [ExportProjectsInPeriodAction.sql](../../proman-batch/src/main/resources/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.sql) - 期間内プロジェクト検索SQL +``` + +**Tips**: +- Include all major source files (typically 3-10 files) +- Use relative paths from output location +- Keep descriptions brief (5-10 words) +- Order by importance (Action → DTO → SQL → Config) + +--- + +## Knowledge Base Links + +**Purpose**: Link to relevant knowledge base files in `.claude/skills/nabledge-6/docs` for detailed information. + +**Format**: Bullet list with links and descriptions of what's covered + +**Path structure**: +- Output: `work/20260210/code-analysis-xxx.md` +- Knowledge base: `.claude/skills/nabledge-6/docs/features/libraries/xxx.md` +- Relative path: `../../.claude/skills/nabledge-6/docs/features/libraries/xxx.md` + +**Example**: + +```markdown +### Knowledge Base (Nabledge-6) + +- [Nablarchバッチ処理](../../.claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md) - BatchActionの詳細、DB to FILEパターン、都度起動バッチ +- [データバインド](../../.claude/skills/nabledge-6/docs/features/libraries/data-bind.md) - ObjectMapperの詳細仕様、@Csvアノテーション、フォーマット設定 +- [業務日付管理](../../.claude/skills/nabledge-6/docs/features/libraries/business-date.md) - BusinessDateUtilの使い方、区分管理、テーブル設定 +- [ファイルパス管理](../../.claude/skills/nabledge-6/docs/features/libraries/file-path-management.md) - FilePathSettingの設定方法、論理名と物理パスのマッピング +- [UniversalDao](../../.claude/skills/nabledge-6/docs/features/libraries/universal-dao.md) - データベースアクセスAPI、CRUD操作、トランザクション管理 +``` + +**Tips**: +- Include 3-8 knowledge base links +- Describe what topics are covered in each file +- Use relative paths from output location +- Order by relevance to analyzed code + +--- + +## Official Documentation Links + +**Purpose**: Link to official Nablarch documentation for authoritative reference. + +**Format**: Bullet list with absolute URLs + +**Example**: + +```markdown +### Official Documentation + +- [Nablarchバッチ処理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/index.html) +- [データバインド](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/data_io/data_bind.html) +- [業務日付管理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/system_utility/business_date.html) +- [ファイルパス管理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/file_path_management.html) +- [UniversalDao](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/database/universal_dao.html) +``` + +**Tips**: +- Include 3-8 official documentation links +- Use full URLs (https://nablarch.github.io/docs/LATEST/doc/...) +- Match the topics covered in Knowledge Base Links +- Order by relevance to analyzed code diff --git a/.claude/skills/nabledge-6/assets/code-analysis-template-guide.md b/.claude/skills/nabledge-6/assets/code-analysis-template-guide.md new file mode 100644 index 0000000..14467d8 --- /dev/null +++ b/.claude/skills/nabledge-6/assets/code-analysis-template-guide.md @@ -0,0 +1,250 @@ +# Code Analysis Template Guide + +This guide explains how to use the code analysis documentation template. + +## Template File + +**Location**: `.claude/skills/nabledge-6/assets/code-analysis-template.md` + +The template provides a structured format for the generated documentation. See the template file for the complete structure with placeholders. + +## Template Sections + +1. **Header**: Target name, generation date/time, analysis duration, modules +2. **Overview**: Purpose and high-level architecture +3. **Architecture**: Mermaid class diagram + component summary table +4. **Flow**: Processing flow description + Mermaid sequence diagram +5. **Components**: Detailed analysis for each component + - File location with relative link + - Role description + - Key methods with line references + - Dependencies + - Nablarch knowledge excerpts + - Key implementation points +6. **Nablarch Framework Usage**: Framework-specific usage patterns +7. **References**: Links to source files, knowledge files, official docs + +## Key Features + +- **Mermaid diagrams**: Class diagram (relationships) and sequence diagram (timeline) +- **Relative links**: Links to source files and knowledge files use relative paths +- **Line references**: Method locations include line number ranges (e.g., `L42-58`) +- **Knowledge excerpts**: Relevant Nablarch knowledge quoted from knowledge files +- **Structured format**: Consistent sections across all analyses + +## Placeholders + +Replace the following placeholders with actual content (using `{{variable}}` format): + +### Header Section + +- `{{target_name}}`: Name of analyzed code/feature (e.g., "LoginAction", "ログイン機能") +- `{{generation_date}}`: Current date in YYYY-MM-DD format (e.g., "2026-02-10") +- `{{generation_time}}`: Current time in HH:MM:SS format (e.g., "14:30:15") +- `{{DURATION_PLACEHOLDER}}`: Placeholder for analysis duration (replaced by sed after Write completes) + - Initial value: "{{DURATION_PLACEHOLDER}}" (literal string in template) + - Final value: "約2分30秒", "約45秒", etc. (replaced by workflow Step 3.3-7) +- `{{target_description}}`: One-line description of the target +- `{{modules}}`: Affected modules (e.g., "proman-web, proman-common") + +### Overview Section + +- `{{overview_content}}`: Purpose and high-level architecture + +### Architecture Section + +- `{{dependency_graph}}`: Mermaid classDiagram syntax (class names only, show relationships) +- `{{component_summary_table}}`: Markdown table of components + +### Flow Section + +- `{{flow_content}}`: Request/response flow description text +- `{{flow_sequence_diagram}}`: Mermaid sequenceDiagram syntax (processing flow with timeline) + +### Components Section + +- `{{components_details}}`: Detailed analysis for each component (numbered sections) + +### Nablarch Framework Usage Section + +- `{{nablarch_usage}}`: Framework-specific usage patterns + +### References Section + +- `{{source_files_links}}`: List of source file links with relative paths +- `{{knowledge_base_links}}`: List of knowledge base links (`.claude/skills/nabledge-6/docs`) +- `{{official_docs_links}}`: List of official Nablarch documentation links + +## Usage Instructions + +### Step 1: Read the Template + +Read the template file to understand the structure: + +```bash +Read: .claude/skills/nabledge-6/assets/code-analysis-template.md +``` + +### Step 2: Build Content for Each Placeholder + +Based on analysis results from workflow Steps 0-5, build content for each placeholder: + +1. **Header placeholders**: Use current timestamp ({{DURATION_PLACEHOLDER}} stays as-is) +2. **Overview**: Summarize purpose and architecture +3. **Architecture diagrams**: Generate Mermaid classDiagram (class names only) +4. **Flow diagrams**: Generate Mermaid sequenceDiagram (with phases) +5. **Components**: Write detailed analysis with line references +6. **Nablarch usage**: Extract framework usage patterns +7. **References**: Build relative file path links + +### Step 3: Replace Placeholders (except duration) + +Replace all `{{variable}}` placeholders with actual content, EXCEPT {{DURATION_PLACEHOLDER}}. + +**IMPORTANT**: Leave {{DURATION_PLACEHOLDER}} as-is. It will be replaced after Write completes. + +### Step 4: Write Output File + +Use Write tool to create the documentation file: + +``` +file_path: work/YYYYMMDD/code-analysis-.md +content: [Generated documentation with {{DURATION_PLACEHOLDER}} still present] +``` + +### Step 5: Calculate and Replace Duration + +**IMMEDIATELY after Write completes**: + +**Step 5.1**: Get end time and calculate duration +```bash +date '+%Y-%m-%d %H:%M:%S' +``` +- Calculate elapsed time from Step 0 start time +- Format as Japanese text (e.g., "約5分18秒") + +**Step 5.2**: Replace placeholder using sed +```bash +sed -i 's/{{DURATION_PLACEHOLDER}}/約5分18秒/g' work/YYYYMMDD/code-analysis-.md +``` + +**Error handling**: +- If sed fails, inform user of the calculated duration +- User can manually edit the file to replace {{DURATION_PLACEHOLDER}} +- The documentation remains valid even with the placeholder + +**Why this matters**: This ensures the analysis duration includes all work including the Write operation itself, providing accurate timing that matches the "Baked for" time shown in the IDE. + +## Example Placeholder Values + +### Example: ExportProjectsInPeriodAction + +``` +{{target_name}} = "ExportProjectsInPeriodAction" +{{generation_date}} = "2026-02-10" +{{generation_time}} = "14:30:15" +{{analysis_duration}} = "約2分" +{{target_description}} = "期間内プロジェクト一覧出力バッチアクション" +{{modules}} = "proman-batch" +``` + +### {{component_summary_table}} + +```markdown +| Component | Role | Type | Dependencies | +|-----------|------|------|--------------| +| ExportProjectsInPeriodAction | CSV出力バッチアクション | Action | DatabaseRecordReader, ObjectMapper, FilePathSetting | +| ProjectDto | プロジェクト情報DTO | Bean | なし | +| FIND_PROJECT_IN_PERIOD | 期間内プロジェクト検索SQL | SQL | なし | +``` + +### {{nablarch_usage}} + +For each Nablarch component, include: +1. **クラス名**: Full class name +2. **説明**: Brief description +3. **使用方法**: Code example +4. **重要ポイント**: Critical points (why use, gotchas, performance) +5. **このコードでの使い方**: How it's used in analyzed code +6. **詳細**: Link to knowledge base + +**Example**: + +```markdown +### ObjectMapper + +**クラス**: `nablarch.common.databind.ObjectMapper` + +**説明**: CSVやTSV、固定長データをJava Beansとして扱う機能を提供する + +**使用方法**: +\`\`\`java +ObjectMapper mapper = ObjectMapperFactory.create(ProjectDto.class, outputStream); +mapper.write(dto); +mapper.close(); +\`\`\` + +**重要ポイント**: +- ✅ **必ず`close()`を呼ぶ**: バッファをフラッシュし、リソースを解放する(`terminate()`で実施) +- ⚠️ **大量データ処理時**: メモリに全データを保持しないため、大量データでも問題なく処理可能 +- ⚠️ **型変換の制限**: `EntityUtil`と同様に、型変換が必要な項目は個別設定が必要 +- 💡 **アノテーション駆動**: `@Csv`, `@CsvFormat`でフォーマットを宣言的に定義できる + +**このコードでの使い方**: +- `initialize()`でProjectDto用のObjectMapperを生成 +- `handle()`で各レコードを`mapper.write(dto)`で出力 +- `terminate()`で`mapper.close()`してリソース解放 + +**詳細**: [データバインド知識ベース](../../.claude/skills/nabledge-6/docs/features/libraries/data-bind.md) +``` + +### {{knowledge_base_links}} + +```markdown +- [Nablarchバッチ処理](../../.claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md) - BatchActionの詳細、DB to FILEパターン +- [データバインド](../../.claude/skills/nabledge-6/docs/features/libraries/data-bind.md) - ObjectMapperの詳細仕様 +- [業務日付管理](../../.claude/skills/nabledge-6/docs/features/libraries/business-date.md) - BusinessDateUtilの使い方 +- [ファイルパス管理](../../.claude/skills/nabledge-6/docs/features/libraries/file-path-management.md) - FilePathSettingの設定方法 +``` + +### {{official_docs_links}} + +```markdown +- [Nablarchバッチ処理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/index.html) +- [データバインド](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/data_io/data_bind.html) +- [業務日付管理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/system_utility/business_date.html) +``` + +## Tips + +### Diagram Generation + +**Class Diagram**: +- Keep it simple: class names only +- Use `--|>` for inheritance (extends/implements) +- Use `..>` for dependencies (uses/creates) +- Mark framework classes with `<>` stereotype + +**Sequence Diagram**: +- Use `participant` to define actors/components +- Use `->>` for synchronous calls +- Use `-->>` for return values +- Use `alt`/`else` for error handling +- Use `loop` for repetitive operations +- Add `Note` to explain phases + +### Link Generation + +Use relative paths from the output file location: + +``` +Output: work/20260210/code-analysis-login-action.md +Source: proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java +Link: ../../proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java +``` + +## See Also + +- **Template File**: `assets/code-analysis-template.md` +- **Workflow**: `workflows/code-analysis.md` +- **Skill Definition**: `SKILL.md` diff --git a/.claude/skills/nabledge-6/assets/code-analysis-template.md b/.claude/skills/nabledge-6/assets/code-analysis-template.md new file mode 100644 index 0000000..6c3814e --- /dev/null +++ b/.claude/skills/nabledge-6/assets/code-analysis-template.md @@ -0,0 +1,74 @@ +# Code Analysis: {{target_name}} + +**Generated**: {{generation_date}} {{generation_time}} +**Target**: {{target_description}} +**Modules**: {{modules}} +**Analysis Duration**: {{DURATION_PLACEHOLDER}} + +--- + +## Overview + +{{overview_content}} + +--- + +## Architecture + +### Dependency Graph + +```mermaid +{{dependency_graph}} +``` + +**Note**: This diagram uses Mermaid `classDiagram` syntax to show class names and their relationships. Use `--|>` for inheritance (extends/implements) and `..>` for dependencies (uses/creates). + +### Component Summary + +{{component_summary_table}} + +--- + +## Flow + +### Processing Flow + +{{flow_content}} + +### Sequence Diagram + +```mermaid +{{flow_sequence_diagram}} +``` + +--- + +## Components + +{{components_details}} + +--- + +## Nablarch Framework Usage + +{{nablarch_usage}} + +--- + +## References + +### Source Files + +{{source_files_links}} + +### Knowledge Base (Nabledge-6) + +{{knowledge_base_links}} + +### Official Documentation + +{{official_docs_links}} + +--- + +**Note**: This documentation was generated by the code-analysis workflow of the nabledge-6 skill. diff --git a/.claude/skills/nabledge-6/docs/README.md b/.claude/skills/nabledge-6/docs/README.md new file mode 100644 index 0000000..49e8aae --- /dev/null +++ b/.claude/skills/nabledge-6/docs/README.md @@ -0,0 +1,50 @@ +# Nabledge-6 知識ドキュメント + +このディレクトリには、Nabledge-6の知識ファイル(JSON)から自動変換された人向けMarkdownファイルが格納されています。 + + +### 概要 + +- [Nablarch概要](overview.md) + +### 処理方式 + +- [Nablarchバッチ(都度起動型・常駐型)](features/processing/nablarch-batch.md) + +### ライブラリ + +- [業務日付の管理](features/libraries/business-date.md) +- [データバインド](features/libraries/data-bind.md) +- [データベースアクセス(JDBCラッパー)](features/libraries/database-access.md) +- [ファイルパス管理](features/libraries/file-path-management.md) +- [ユニバーサルDAO](features/libraries/universal-dao.md) + +### ハンドラ + +#### 共通ハンドラ + +- [データベース接続管理ハンドラ](features/handlers/common/db-connection-management-handler.md) +- [トランザクション制御ハンドラ](features/handlers/common/transaction-management-handler.md) + +#### バッチハンドラ + +- [データリードハンドラ](features/handlers/batch/data-read-handler.md) + +### ツール(NTF: Nablarch Testing Framework) + +- [NTFアサーション・期待値検証](features/tools/ntf-assertion.md) +- [NTFバッチリクエスト単体テスト](features/tools/ntf-batch-request-test.md) +- [NTF(Nablarch Testing Framework)概要](features/tools/ntf-overview.md) +- [NTFテストデータ](features/tools/ntf-test-data.md) + +### アダプタ + +- [SLF4Jアダプタ](features/adapters/slf4j-adapter.md) + +### チェック項目 + +- [セキュリティチェック項目](checks/security.md) + +### リリースノート + +- [リリースノート 6u3](releases/6u3.md) diff --git a/.claude/skills/nabledge-6/docs/checks/security.md b/.claude/skills/nabledge-6/docs/checks/security.md new file mode 100644 index 0000000..67a3643 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/checks/security.md @@ -0,0 +1,300 @@ +# セキュリティチェック項目 + +IPAで公開されている脆弱性の種類ごとにNablarchでの対応状況を記載 + +**出典**: IPA 安全なウェブサイトの作り方 + +> Nablarchで対応できないものについては、プロジェクトで個別に対応を検討。根本的解決となっているものについては必ず対応すること + +**公式ドキュメント**: +- [セキュリティチェック項目](システム開発ガイド/設計書/Nablarch機能のセキュリティ対応表.xlsx) + +--- + +## 1. SQLインジェクション + +Nablarchはデータベースアクセス機能として、簡易的なO/Rマッパーを実現するユニバーサルDAOと、JDBCを使いやすくしたJDBCラッパーを提供しています。どちらの機能でもSQL文を外部ファイルに記述し、PreparedStatement を使用したSQL実行の仕組みを提供しており、SQLインジェクションの脆弱性を排除できます。 +また、使用不許可APIの使用を検出するツールも提供しており、このツールでチェックすることでNablarchの提供するデータベースアクセス以外の方式を検出することが可能です。 + +上記に加え、HTTPエラー制御ハンドラを使用することでエラーメッセージやスタックトレースがユーザに表示されることを防ぎ、より強固なアプリケーションとすることが可能です。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | SQL文の組み立ては全てプレースホルダで実装する。 | データベースアクセス(JDBCラッパー) +ユニバーサルDAO | 〇 | 1-(i)-a | +| | SQL文の構成を文字列連結により行う場合は、アプリケーションの変数をSQL文のリテラルとして正しく構成する。 | データベースアクセス(JDBCラッパー) +ユニバーサルDAO | 〇 | 1-(i)-b | +| 根本的解決 | ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない。 | データベースアクセス(JDBCラッパー) +ユニバーサルDAO | 〇 | 1-(ii) | +| 保険的対策 | エラーメッセージをそのままブラウザに表示しない。 | HTTPエラー制御ハンドラ | 〇 | 1-(iii) | +| 保険的対策 | データベースアカウントに適切な権限を与える。 | - | × | 1-(iv) | + +**SQL文の組み立ては全てプレースホルダで実装する。**: + +Nablarchはデータベースアクセス機能として、簡易的なO/Rマッパーを実現するユニバーサルDAOと、JDBCを使いやすくしたJDBCラッパーを提供しています。どちらの機能でもSQL文を外部ファイルに記述し、PreparedStatement を使用したSQL実行の仕組みを提供しており、SQLインジェクションの脆弱性を排除できます。 +また、使用不許可APIの使用を検出するツールも提供しており、このツールでチェックすることでNablarchの提供するデータベースアクセス以外の方式を検出することが可能です。 + +上記に加え、HTTPエラー制御ハンドラを使用することでエラーメッセージやスタックトレースがユーザに表示されることを防ぎ、より強固なアプリケーションとすることが可能です。 + +--- + +## 2. OSコマンド・インジェクション + +使用不許可APIの使用を検出するツールを提供しています。このツールでチェックすることでRuntimeなどOSコマンドを実行する機能の使用箇所を検出することができます。 +システムとして一律OSコマンドの使用を禁止する場合は上記の対応で根本的解決が見込めます。 +システム要件としてOSコマンドの使用が必要な場合には右記の保険的対策をプロジェクトの方式として取り入れるようにしてください。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | シェルを起動できる言語機能の利用を避ける。 | 許可していないAPIが使用されていないかチェックする | 〇 | 2-(i) | +| 保険的対策 | シェルを起動できる言語機能を利用する場合は、その引数を構成する全ての変数に対してチェックを行い、あらかじめ許可した処理のみを実行する。 | - | × | 2-(ii) | + +**シェルを起動できる言語機能の利用を避ける。**: + +使用不許可APIの使用を検出するツールを提供しています。このツールでチェックすることでRuntimeなどOSコマンドを実行する機能の使用箇所を検出することができます。 +システムとして一律OSコマンドの使用を禁止する場合は上記の対応で根本的解決が見込めます。 +システム要件としてOSコマンドの使用が必要な場合には右記の保険的対策をプロジェクトの方式として取り入れるようにしてください。 + +--- + +## 3. パス名パラメータの未チェック/ディレクトリ・トラバーサル + +Nablarchではファイルパス管理機能を提供しています。サーバ内のファイルへのアクセスにこの機能を使用することで、アクセス対象のベースディレクトリを指定することができます。これにより公開するディレクトリが限定されます。同時に、特定の拡張子のファイルのみにアクセスさせることがきます。 +ファイル名をユーザに入力させる場合、上記に組み合わせて、入力値チェックで "."などの文字を許容しないことでディレクトリトラバーサルを防ぐことが可能となります。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | 外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。 | ファイルパス管理 | 〇 | 3-(i)-a | +| | ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする。 | ファイルパス管理 | 〇 | 3-(i)-b | +| 保険的対策 | ウェブサーバ内のファイルへのアクセス権限の設定を正しく管理する。 | - | × | 3-(ii) | +| 保険的対策 | ファイル名のチェックを行う。 | 入力値のチェック | 〇 | 3-(iii) | + +**外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。**: + +Nablarchではファイルパス管理機能を提供しています。サーバ内のファイルへのアクセスにこの機能を使用することで、アクセス対象のベースディレクトリを指定することができます。これにより公開するディレクトリが限定されます。同時に、特定の拡張子のファイルのみにアクセスさせることがきます。 +ファイル名をユーザに入力させる場合、上記に組み合わせて、入力値チェックで "."などの文字を許容しないことでディレクトリトラバーサルを防ぐことが可能となります。 + +--- + +## 4. セッション管理の不備 + +NablarchはHTTPセッションを抽象化したものとしてセッションストア機能を提供しています。 +セッションストアでは以下の機能を提供しており、セッション管理の脆弱性について根本的解決が見込めます。 + ・ セッションを追跡するためセッションIDをCookieに格納します。 + ・ セッションIDには推測困難なUUIDを使用しています。 + ・ セッションストアのデフォルト設定では、HTTPヘッダーのSet-Cookieにsecure属性を設定していません。 +   HTTPSを利用する際は設定でsecure属性を指定してください。 + ・ セッション作成ごとにセッションID採番を行っています。 + ・ セッションストアのデフォルト設定では、CookieにMaxAge属性を設定しません。 +   そのため、Cookieの有効期限はブラウザが閉じるまでとなります。 + +4-(iv)についてはNablarchのExampleで提供している、ログイン処理の実装例を参考に、ログイン成功後に新しくセッションを開始するようプロジェクトで対応してください。 + + + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | セッションIDを推測が困難なものにする。 | セッションストア | 〇 | 4-(i) | +| 根本的解決 | セッションIDをURLパラメータに格納しない。 | セッションストア | 〇 | 4-(ii) | +| 根本的解決 | HTTPS通信で利用するCookieにはsecure属性を加える。 | セッションストア | 〇 | 4-(iii) | +| 根本的解決 | ログイン成功後に、新しくセッションを開始する。 | Nablarch Example | △ | 4-(iv)-a | +| | ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する。 | 4-(iv)-a の対策を実施する | | 4-(iv)-b | +| 保険的対策 | セッションIDを固定値にしない。 | セッションストア | 〇 | 4-(v) | +| 保険的対策 | セッションIDをCookieにセットする場合、有効期限の設定に注意する。 | セッションストア | 〇 | 4-(vi) | + +**セッションIDを推測が困難なものにする。**: + +NablarchはHTTPセッションを抽象化したものとしてセッションストア機能を提供しています。 +セッションストアでは以下の機能を提供しており、セッション管理の脆弱性について根本的解決が見込めます。 + ・ セッションを追跡するためセッションIDをCookieに格納します。 + ・ セッションIDには推測困難なUUIDを使用しています。 + ・ セッションストアのデフォルト設定では、HTTPヘッダーのSet-Cookieにsecure属性を設定していません。 +   HTTPSを利用する際は設定でsecure属性を指定してください。 + ・ セッション作成ごとにセッションID採番を行っています。 + ・ セッションストアのデフォルト設定では、CookieにMaxAge属性を設定しません。 +   そのため、Cookieの有効期限はブラウザが閉じるまでとなります。 + +4-(iv)についてはNablarchのExampleで提供している、ログイン処理の実装例を参考に、ログイン成功後に新しくセッションを開始するようプロジェクトで対応してください。 + + + +--- + +## 5. クロスサイト・スクリプティング + +Nablarchのカスタムタグはサニタイジングを行います。これによりNablarchのカスタムタグを使った場合には5-(i)の根本的解決が可能です。 +また、NablarchはJSPで使用を許可する構文とタグを規定し、許可する構文とタグのみを使用していることをチェックするJSP静的解析ツールを提供しています。このツールを使用することでカスタムタグ以外のタグを使用したことによるエスケープ漏れを防止することが可能です。 + +https://nablarch.github.io/docs/LATEST/doc/development_tools/toolbox/JspStaticAnalysis/01_JspStaticAnalysis.html + +5-(ii)~(iv)の対策についてはプロジェクトで対応してください。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | ウェブページに出力する全ての要素に対して、エスケープ処理を施す。 | カスタムタグ | 〇 | 5-(i) | +| 根本的解決 | URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可する。 | - | × | 5-(ii) | +| 根本的解決 | 要素の内容を動的に生成しない。 | - | × | 5-(iii) | +| 根本的解決 | スタイルシートを任意のサイトから取り込めるようにしない。 | - | × | 5-(iv) | +| 保険的対策 | 入力値の内容チェックを行う。 | 入力値のチェック | 〇 | 5-(v) | +| 根本的解決 | 入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する。 | - | × | 5-(vi) | +| 保険的対策 | 入力されたHTMLテキストから、スクリプトに該当する文字列を排除する。 | - | × | 5-(vii) | +| 根本的解決 | HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)の指定を行う。 | HTTP文字エンコード制御ハンドラ | 〇 | 5-(viii) | +| 保険的対策 | Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する。 | - | × | 5-(ix) | +| 保険的対策 | クロスサイト・スクリプティングの潜在的な脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す。 | セキュアハンドラ | 〇 | 5-(x) | + +**ウェブページに出力する全ての要素に対して、エスケープ処理を施す。**: + +Nablarchのカスタムタグはサニタイジングを行います。これによりNablarchのカスタムタグを使った場合には5-(i)の根本的解決が可能です。 +また、NablarchはJSPで使用を許可する構文とタグを規定し、許可する構文とタグのみを使用していることをチェックするJSP静的解析ツールを提供しています。このツールを使用することでカスタムタグ以外のタグを使用したことによるエスケープ漏れを防止することが可能です。 + +https://nablarch.github.io/docs/LATEST/doc/development_tools/toolbox/JspStaticAnalysis/01_JspStaticAnalysis.html + +5-(ii)~(iv)の対策についてはプロジェクトで対応してください。 + +**入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する。**: + +以下のような方法での対応を検討してください。 + +・OSSのHTMLパーサを使用して入力された値をパースし、使用できないHTMLタグが含まれていないかをバリデーションする +・簡易的な装飾であれば、利用者にはMarkdownで入力してもらい、 OSSのJavaScriptライブラリを使用してクライアントサイドでMarkdownからHTMLに変換する + +**HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)の指定を行う。**: + +NablarchはHTTPレスポンスのHTTPヘッダのContent-TypeにMIME Type・文字コードを設定しています。これにより特定のブラウザで発生し得る 5-(i) の対策を回避したクロスサイト・スクリプティングを防ぐことができます。 +また、Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、ユーザがクロスサイト・スクリプティングの脆弱性対策を無効にしていた場合でもサーバからブラウザの機能を有効にするよう指示することが可能です。 + +--- + +## 6. CSRF +(クロスサイト・リクエスト・フォージェリ) + +CSRF対策として、NablarchのCSRF対策機能を使用できます。この機能は一意なトークンを発行し、サーバサイドでチェックすることで不正な画面遷移を防ぎます。 + +NablarchのHttpSessionを使用した二重サブミット防止機能を使用した場合も、CSRF対策機能と同じ効果が得られCSRF対策として機能します。CSRF対策機能はハンドラを追加するだけで漏れなくチェックできるのに対し、二重サブミット防止機能はアプリケーションプログラマが明示的に実装する必要があり、CSRF対策が洩れる可能性があります。そのため、CSRF対策にはCSRF対策機能の使用を推奨します。 + +データベースを使用した二重サブミット防止機能はCSRF対策に対応していません。データベースを使用した二重サブミット防止機能を使用する場合はCSRF対策機能を使用してください。 + + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | 処理を実行するページを POST メソッドでアクセスするようにし、その「hidden パラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する。 | CSRF対策 | 〇 | 6-(i)-a | +| | 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。 | 6-(i)-a の対策を実施する | | 6-(i)-b | +| | Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する。 | 6-(i)-a の対策を実施する | | 6-(i)-c | +| 保険的対策 | 重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する。 | - | × | 6-(ii) | + +**処理を実行するページを POST メソッドでアクセスするようにし、その「hidden パラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する。**: + +CSRF対策として、NablarchのCSRF対策機能を使用できます。この機能は一意なトークンを発行し、サーバサイドでチェックすることで不正な画面遷移を防ぎます。 + +NablarchのHttpSessionを使用した二重サブミット防止機能を使用した場合も、CSRF対策機能と同じ効果が得られCSRF対策として機能します。CSRF対策機能はハンドラを追加するだけで漏れなくチェックできるのに対し、二重サブミット防止機能はアプリケーションプログラマが明示的に実装する必要があり、CSRF対策が洩れる可能性があります。そのため、CSRF対策にはCSRF対策機能の使用を推奨します。 + +データベースを使用した二重サブミット防止機能はCSRF対策に対応していません。データベースを使用した二重サブミット防止機能を使用する場合はCSRF対策機能を使用してください。 + + +--- + +## 7. HTTPヘッダ・インジェクション + +Nablarchでのヘッダ出力はHttpServletResponseのAPIを使用しているため、Nablarchを使用する場合はヘッダにおける改行の扱いをAPIに移譲することでHTTPヘッダ・インジェクションの対策が可能です。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する。 | Nablarchで提供する機能全般 | 〇 | 7-(i)-a | +| | 改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないよう、開発者自身で適切な処理を実装する。 | 7-(i)-a の対策を実施する | | 7-(i)-b | +| 保険的対策 | 外部からの入力の全てについて、改行コードを削除する。 | - | × | 7-(ii) | + +**ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する。**: + +Nablarchでのヘッダ出力はHttpServletResponseのAPIを使用しているため、Nablarchを使用する場合はヘッダにおける改行の扱いをAPIに移譲することでHTTPヘッダ・インジェクションの対策が可能です。 + +--- + +## 8. メールヘッダ・インジェクション + +Nablarchはメール送信機能を提供しており、メールヘッダインジェクション攻撃への対策をガイドしています。 + ・メールヘッダは固定値を使用する。外部からの入力値を使用しない。 + ・プログラミング言語の標準APIを使用してメール送信を行う。Javaの場合は JavaMail APIを使用する。 + +8-(ii)についてはプロジェクトで対応してください。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する。 | メール送信 | △ | 8-(i)-a | +| | ウェブアプリケーションの実行環境や言語に用意されているメール送信用APIを使用する(8-(i) を採用できない場合)。 | メール送信 | △ | 8-(i)-b | +| 根本的解決 | HTMLで宛先を指定しない。 | - | × | 8-(ii) | +| 保険的対策 | 外部からの入力の全てについて、改行コードを削除する。 | - | × | 8-(iii) | + +**メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する。**: + +Nablarchはメール送信機能を提供しており、メールヘッダインジェクション攻撃への対策をガイドしています。 + ・メールヘッダは固定値を使用する。外部からの入力値を使用しない。 + ・プログラミング言語の標準APIを使用してメール送信を行う。Javaの場合は JavaMail APIを使用する。 + +8-(ii)についてはプロジェクトで対応してください。 + +--- + +## 9. クリックジャッキング + +Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、デフォルトで X-Frame-Options: SAMEORIGIN が出力されるため、クリックジャッキング対策が可能です。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する。 | セキュアハンドラ | 〇 | 9-(i)-a | +| | 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。 | 9-(i)-a の対策を実施する | | 9-(i)-b | +| 保険的対策 | 重要な処理は、一連の操作をマウスのみで実行できないようにする。 | - | × | 9-(ii) | + +**HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する。**: + +Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、デフォルトで X-Frame-Options: SAMEORIGIN が出力されるため、クリックジャッキング対策が可能です。 + +--- + +## 10. バッファオーバーフロー + +NablarchはJavaで記述されているため、言語レベルでバッファオーバーフローの脆弱性はありません。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | 直接メモリにアクセスできない言語で記述する。 | Nablarchで提供する機能全般 | 〇 | 10-(i)-a | +| | 直接メモリにアクセスできる言語で記述する部分を最小限にする。 | Nablarchで提供する機能全般 | 〇 | 10-(i)-b | +| 根本的解決 | 脆弱性が修正されたバージョンのライブラリを使用する。 | Nablarchで提供する機能全般 | 〇 | 10-(ii) | + +**直接メモリにアクセスできない言語で記述する。**: + +NablarchはJavaで記述されているため、言語レベルでバッファオーバーフローの脆弱性はありません。 + +--- + +## 11. アクセス制御や認可制御の欠落 + +Nablarchは認証チェックを行う機能を提供していません。NablarchのExampleとして提供している実装例を参考に認証機能を実装してください。 +Nablarchは認可チェック機能を提供しています。この機能は、細かく権限を設定できる反面、非常に細かいデータ設計が必要となり、 開発時の生産性低下やリリース後の運用負荷が高まる可能性があります。プロジェクトでは、システム要件に適合する場合に使用してください。 + +| 種別 | 説明 | Nablarch機能 | 対応 | 参照 | +|------|------|--------------|:----:|------| +| 根本的解決 | アクセス制御機能による防御措置が必要とされるウェブサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける。 | Nablarch Example | △ | 11-(i) | +| 根本的解決 | 認証機能に加えて認可制御の処理を実装し、ログイン中の利用者が他人になりすましてアクセスできないようにする。 | 認可チェック | 〇 | 11-(ii) | + +**アクセス制御機能による防御措置が必要とされるウェブサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける。**: + +Nablarchは認証チェックを行う機能を提供していません。NablarchのExampleとして提供している実装例を参考に認証機能を実装してください。 +Nablarchは認可チェック機能を提供しています。この機能は、細かく権限を設定できる反面、非常に細かいデータ設計が必要となり、 開発時の生産性低下やリリース後の運用負荷が高まる可能性があります。プロジェクトでは、システム要件に適合する場合に使用してください。 + +--- + +## Tips + +**チェック項目の実施方法**: + +※印のチェック項目は、実施項目のいずれかを実施すればよい(全てを実施する必要はない) + +**保険的対策の判断**: + +保険的対策については、システム要件に合わせて対応要否を判断すること。根本的解決が基本だが、実現困難な場合の補完として検討 + +**根本的解決の優先**: + +根本的解決となっている対策は必ず実施すること。脆弱性の原因そのものを排除する対策であり、セキュリティの基本 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/adapters/slf4j-adapter.md b/.claude/skills/nabledge-6/docs/features/adapters/slf4j-adapter.md new file mode 100644 index 0000000..286f8b1 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/adapters/slf4j-adapter.md @@ -0,0 +1,87 @@ +# SLF4Jアダプタ + +SLF4J経由でNablarchのログ出力機能を使用するためのアダプタ + +**目的**: SLF4Jを使用するOSSライブラリのログをNablarchのログ出力機能で統一管理 + + +**外部ライブラリ**: +- [SLF4J 2.0.11 (テスト済み)](https://www.slf4j.org/) + +**nablarch_version**: 6u1以降 + +**対応Nablarchバージョン**: 6u1以降 + +**公式ドキュメント**: +- [SLF4Jアダプタ](https://nablarch.github.io/docs/LATEST/doc/application_framework/adaptors/slf4j_adaptor.html) + +--- + +## setup + +**依存関係**: + +- `com.nablarch.integration:slf4j-nablarch-adaptor` (scope: runtime) + +**maven_example**: + +```java + + com.nablarch.integration + slf4j-nablarch-adaptor + runtime + +``` + +**gradle_example**: + +```gradle +runtimeOnly 'com.nablarch.integration:slf4j-nablarch-adaptor' +``` + +--- + +## configuration + +依存関係を追加するだけで使用可能(追加設定不要) + +**required_settings**: + + +**log_output**: Nablarchのログ設定(log.properties)に従う + +--- + +## usage + +SLF4Jが実行時に必要なクラスを自動で検出するため、プロジェクトの依存モジュールに追加するだけで使用できる + +**SLF4Jを使用するOSSライブラリの例**: + +HibernateなどSLF4Jでログ出力するライブラリを使用する場合、自動的にNablarchのログ機能経由で出力される + +```java +// ライブラリ側のコード(変更不要) +Logger logger = LoggerFactory.getLogger(MyClass.class); +logger.info("message"); +``` + +**best_practices**: + +- 依存関係の追加のみで動作する(最もシンプルなアダプタ) + +--- + +## notes + +- SLF4Jのバージョン2.0.11を使用してテストを行っている +- バージョンを変更する場合は、プロジェクト側でテストを行い問題ないことを確認すること +- SLF4Jのバージョン2.0.0以降はロギング実装の検索方法が変わっている +- 互換性のない1.7系のバージョンが使用された場合、"Failed to load class org.slf4j.impl.StaticLoggerBinder"のログが出力され、以降のログ出力が行われないため注意 + +--- + +## limitations + + +--- diff --git a/.claude/skills/nabledge-6/docs/features/handlers/batch/data-read-handler.md b/.claude/skills/nabledge-6/docs/features/handlers/batch/data-read-handler.md new file mode 100644 index 0000000..f1b27b5 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/handlers/batch/data-read-handler.md @@ -0,0 +1,102 @@ +# データリードハンドラ + +データリーダを使用して、入力データの順次読み込みを行なうハンドラ。実行コンテキスト上のデータリーダを使用し、業務処理に対する入力データを1件ずつ読み込み、それを引数として後続ハンドラに処理を委譲する。 + +**目的**: バッチ処理における入力データの順次読み込みを制御し、データ終端の判定を行う + + +**責務**: + +- データリーダを使用して入力データの読み込み + +- 実行時IDの採番 + +- データ終端の判定(NoMoreRecordの返却) + + + +**モジュール**: +- `com.nablarch.framework:nablarch-fw-standalone` + +**class_name**: nablarch.fw.handler.DataReadHandler + +**公式ドキュメント**: +- [データリードハンドラ](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/standalone/data_read_handler.html) + +--- + +## processing + +**処理フロー**: + +**リクエスト処理前**: 実行コンテキスト(ExecutionContext)上のデータリーダ(DataReader)を取得する。データリーダが設定されていない場合、処理対象データ無しとしてNoMoreRecordを返却して処理を終了する。 + +**データ読み込みループ**: データリーダから入力データを1件読み込み、それを引数として後続ハンドラに処理を委譲する。最大処理件数(maxCount)が設定されている場合は、その件数に達するまで繰り返す。データリーダの終端に達した場合、またはmaxCountに達した場合はNoMoreRecordを返却する。 + +**実行時ID採番**: 各レコード処理時に実行時IDを採番する。 + + +**data_reader**: + +**interface**: nablarch.fw.DataReader + +**source**: ExecutionContextに設定されたDataReaderを使用 + +**end_marker**: nablarch.fw.DataReader.NoMoreRecord + +--- + +## setup + +| プロパティ | 型 | 必須 | 説明 | +|-----------|-----|:----:|------| +| `maxCount` | `int` | | 最大の処理件数。この件数分のデータを処理し終わると、本ハンドラは処理対象レコードなしを示すNoMoreRecordを返却する。大量データを処理するバッチ処理を数日に分けて処理させる場合などに指定する。例えば、最大100万件を処理するバッチを、日次で最大10万件だけ処理をさせ10日間かけて全件を処理させることが実現できる。 | + +**xml_example**: + +```xml + + + + +``` + +**component_name**: DataReadHandler + +--- + +## max_count + +本ハンドラには、最大の処理件数を設定することが出来る。最大処理件数分のデータを処理し終わると、本ハンドラは処理対象レコードなしを示すNoMoreRecordを返却する。 + +**example**: + +```java +最大100万件を処理するバッチを、日次で最大10万件だけ処理をさせ10日間かけて全件を処理させることが実現できる。 +``` + +**use_case**: 大量データを処理するバッチ処理を数日に分けて処理させる場合などに指定する。 + +--- + +## constraints + +**handler_order**: + +**before**: + + +**after**: + + +**reason**: 本ハンドラ自体に順序制約はないが、実行コンテキストにDataReaderが設定されている必要があるため、DataReaderを設定するハンドラより後に配置する必要がある。 + +**limitations**: + + +**notes**: + +- 本ハンドラより手前のハンドラにて、ExecutionContextにDataReaderを設定する必要がある。 +- 本ハンドラが呼び出されたタイミングでDataReaderが設定されていない場合、処理対象データ無しとして本ハンドラは処理を終了(NoMoreRecordを返却)する。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/handlers/common/db-connection-management-handler.md b/.claude/skills/nabledge-6/docs/features/handlers/common/db-connection-management-handler.md new file mode 100644 index 0000000..2faa873 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/handlers/common/db-connection-management-handler.md @@ -0,0 +1,123 @@ +# データベース接続管理ハンドラ + +後続のハンドラ及びライブラリで使用するためのデータベース接続を、スレッド上で管理するハンドラ + +**目的**: データベースアクセスに必要な接続オブジェクトをスレッド単位で管理し、後続処理で利用可能にする + + +**責務**: + +- データベース接続の取得 + +- データベース接続の解放 + +- スレッド上での接続管理 + + + +**モジュール**: +- `com.nablarch.framework:nablarch-core-jdbc` +- `com.nablarch.framework:nablarch-common-jdbc` + +**class_name**: nablarch.common.handler.DbConnectionManagementHandler + +**公式ドキュメント**: +- [データベース接続管理ハンドラ](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/common/database_connection_management_handler.html) + +--- + +## processing + +**処理フロー**: + +**リクエスト処理前**: connectionFactoryプロパティに設定されたファクトリクラス(ConnectionFactory実装クラス)を使用してデータベース接続を取得し、スレッド上で管理する。データベース接続名(connectionName)をキーとして管理する。 + +**後続ハンドラ呼び出し**: 次のハンドラに処理を委譲。後続ハンドラおよびライブラリはDbConnectionContext.getConnection()でスレッド上の接続を取得できる。 + +**リクエスト処理後**: スレッド上で管理しているデータベース接続を解放する。 + + +--- + +## setup + +| プロパティ | 型 | 必須 | 説明 | +|-----------|-----|:----:|------| +| `connectionFactory` | `nablarch.core.db.connection.ConnectionFactory` | ✓ | データベース接続オブジェクトを取得するファクトリクラス。BasicDbConnectionFactoryForDataSourceなどのConnectionFactory実装クラスを設定する。 | +| `connectionName` | `String` | | データベース接続名。スレッド内で一意とする必要がある。省略した場合、その接続はデフォルトのデータベース接続となる。複数のデータベース接続を使用する場合に、最もよく使う接続をデフォルトとし、それ以外に任意の名前をつけると良い。 | + +**xml_example**: + +```xml + + + + + + + + + +``` + +**component_name**: DbConnectionManagementHandler + +--- + +## multiple_connections + +1つのアプリケーションで複数のデータベース接続が必要となる場合、このハンドラをハンドラキュー上に複数設定することで対応する。 + +**xml_example**: + +```xml + + + + + + + + + + +``` + +**connection_naming**: + +**default_connection**: connectionNameプロパティへの設定を省略した場合、その接続はデフォルトのデータベース接続となり簡易的に使用できる。DbConnectionContext.getConnection()を引数なしで呼び出すと、デフォルトの接続が戻される。 + +**named_connection**: connectionNameプロパティに任意の名前を設定することで、名前付き接続として管理できる。DbConnectionContext.getConnection(String)に接続名を指定して呼び出すことで、対応する接続が取得できる。 + +**recommendation**: 最もよく使うデータベース接続をデフォルトとし、それ以外のデータベース接続に対して任意の名前をつけると良い。 + +**usage_example**: + +**default**: AppDbConnection connection = DbConnectionContext.getConnection(); // 引数なし + +**named**: AppDbConnection connection = DbConnectionContext.getConnection("userAccessLog"); // 接続名を指定 + +--- + +## constraints + +**handler_order**: + +**before**: + + +**after**: + + +**reason**: このハンドラ自体には順序制約はない。ただし、データベースアクセスを行う全てのハンドラより前に配置する必要がある。 + +**limitations**: + + +**notes**: + +- このハンドラを使用する場合は、TransactionManagementHandlerをセットで設定すること。トランザクション制御ハンドラが設定されていない場合、トランザクション制御が実施されないため後続で行ったデータベースへの変更は全て破棄される。 +- データベース接続オブジェクトを取得するためのファクトリクラスの詳細は、データベースアクセス機能を参照すること。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/handlers/common/transaction-management-handler.md b/.claude/skills/nabledge-6/docs/features/handlers/common/transaction-management-handler.md new file mode 100644 index 0000000..b70aedc --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/handlers/common/transaction-management-handler.md @@ -0,0 +1,202 @@ +# トランザクション制御ハンドラ + +データベースやメッセージキューなどのトランザクションに対応したリソースを使用し、後続処理における透過的トランザクションを実現するハンドラ + +**目的**: 後続処理のトランザクション境界を管理し、正常終了時のコミット、異常終了時のロールバックを自動的に行う + + +**責務**: + +- トランザクションの開始 + +- トランザクションの終了(コミットやロールバック) + +- トランザクションの終了時のコールバック + + + +**モジュール**: +- `com.nablarch.framework:nablarch-core-transaction` +- `com.nablarch.framework:nablarch-core-jdbc` (データベースに対するトランザクションを制御する場合のみ) +- `com.nablarch.framework:nablarch-core` (トランザクション終了時に任意の処理を実行する場合のみ) + +**class_name**: nablarch.common.handler.TransactionManagementHandler + +**公式ドキュメント**: +- [トランザクション制御ハンドラ](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/common/transaction_management_handler.html) + +--- + +## processing + +**処理フロー**: + +**リクエスト処理前**: transactionFactoryプロパティに設定されたファクトリクラス(TransactionFactory実装クラス)を使用してトランザクションの制御対象を取得し、トランザクションを開始する。トランザクションはスレッド上でtransactionName(デフォルトは'transaction')をキーとして管理される。 + +**後続ハンドラ呼び出し**: 次のハンドラに処理を委譲。後続ハンドラで実行される業務処理は、開始されたトランザクション内で実行される。 + +**リクエスト処理後(正常)**: 後続ハンドラが正常終了した場合、トランザクションをコミットする。コミット後、後続ハンドラの中でTransactionEventCallbackを実装しているハンドラに対してtransactionNormalEndをコールバックする。 + +**リクエスト処理後(異常)**: 後続ハンドラでエラーや例外が発生した場合、トランザクションをロールバックする。ロールバック後、新しいトランザクションを開始し、TransactionEventCallbackを実装しているハンドラに対してtransactionAbnormalEndをコールバックする。コールバックが正常終了するとコミットする。 + + +**transaction_boundary**: 後続ハンドラの処理全体がトランザクション境界となる。コールバック処理は、正常終了時は同一トランザクション内で実行されないが、ロールバック時は新しいトランザクション内で実行される。 + +--- + +## setup + +| プロパティ | 型 | 必須 | 説明 | +|-----------|-----|:----:|------| +| `transactionFactory` | `nablarch.core.transaction.TransactionFactory` | ✓ | トランザクション制御を行うファクトリクラス。データベースに対するトランザクション制御を行う場合はJdbcTransactionFactoryを設定する。 | +| `transactionName` | `String` | | トランザクションを識別するための名前。複数のトランザクションを使用する場合は必須。DbConnectionManagementHandlerのconnectionNameに設定した値と同じ値を設定すること。 (デフォルト: `transaction`) | +| `transactionCommitExceptions` | `List` | | コミット対象の例外クラスのリスト(FQCN)。デフォルトでは全てのエラー及び例外がロールバック対象となるが、特定の例外の場合にトランザクションをコミットしたい場合に設定する。設定した例外クラスのサブクラスもコミット対象となる。 | + +**xml_example**: + +```xml + + + + + + + + + + +``` + +**component_name**: TransactionManagementHandler + +--- + +## commit_exceptions + +デフォルト動作では、全てのエラー及び例外がロールバック対象となるが、発生した例外の内容によってはトランザクションをコミットしたい場合がある。 + +**xml_example**: + +```xml + + + + + + example.TransactionCommitException + + + +``` + +**configuration**: transactionCommitExceptionsプロパティに対して、コミット対象の例外クラスを設定することで対応する。設定した例外クラスのサブクラスもコミット対象となる。 + +--- + +## callback + +トランザクション終了(コミットやロールバック)時に、コールバック処理を行う機能を提供する。 + +**xml_example**: + +```xml + + + + + + + + + +``` + +**callback_interface**: nablarch.fw.TransactionEventCallback + +**callback_methods**: + +- **method**: transactionNormalEnd +- **signature**: void transactionNormalEnd(TData data, ExecutionContext context) +- **description**: トランザクションコミット時のコールバック処理。正常終了時のコールバックは、トランザクションコミット後に実行される。 +- **method**: transactionAbnormalEnd +- **signature**: void transactionAbnormalEnd(Throwable e, TData data, ExecutionContext context) +- **description**: トランザクションロールバック時のコールバック処理。ロールバック後に新しいトランザクションで実行され、コールバックが正常に終了するとコミットされる。 + +**callback_target**: このハンドラより後続に設定されたハンドラの中で、TransactionEventCallbackを実装しているものがコールバック対象となる。複数のハンドラが実装している場合は、より手前に設定されているハンドラから順次コールバック処理を実行する。 + +**callback_error_handling**: 複数のハンドラがコールバック処理を実装していた場合で、コールバック処理中にエラーや例外が発生した場合は、残りのハンドラに対するコールバック処理は実行しない。 + +--- + +## multiple_transactions + +1つのアプリケーションで複数のトランザクション制御が必要となる場合、このハンドラをハンドラキュー上に複数設定することで対応する。 + +**xml_example**: + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +**configuration_rule**: 複数のトランザクションを使用する場合、transactionNameプロパティへの値の設定が必須となる。DbConnectionManagementHandlerで設定したデータベースに対するトランザクションを制御する場合は、DbConnectionManagementHandler#connectionNameに設定した値と同じ値をtransactionNameプロパティに設定すること。 + +--- + +## constraints + +**handler_order**: + +**before**: + + +**after**: + +- DbConnectionManagementHandler + +**reason**: データベースに対するトランザクションを制御する場合には、トランザクション管理対象のデータベース接続がスレッド上に存在している必要がある。このため、本ハンドラはDbConnectionManagementHandlerより後ろに配置する必要がある。 + +**limitations**: + + +**notes**: + +- DbConnectionManagementHandlerのconnectionNameに設定した値と同じ値をtransactionNameプロパティに設定すること。 +- connectionNameに値を設定していない場合は、transactionNameへの設定は省略して良い。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/libraries/business-date.md b/.claude/skills/nabledge-6/docs/features/libraries/business-date.md new file mode 100644 index 0000000..f8be2b8 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/libraries/business-date.md @@ -0,0 +1,285 @@ +# 業務日付の管理 + +アプリケーションで使用するシステム日時(OS日時)と業務日付を一元的に管理する機能を提供する。コンポーネント定義で指定されたクラスを使用して、システム日時(OS日時)や業務日付を取得する。 + +**目的**: コンポーネント定義で指定するクラスを差し替えるだけで、アプリケーションで使用するシステム日時(OS日時)と業務日付の取得方法を切り替えることができる。この切り替えは、テストなどで一時的にシステム日時(OS日時)や業務日付を切り替えたい場合に使用できる。 + + +**機能**: + +- システム日時(OS日時)の一元管理 + +- 業務日付の一元管理(データベース使用) + +- テスト時のシステム日時・業務日付の切り替え + +- 複数の業務日付の管理(区分単位) + +- 業務日付の上書き(プロセス単位) + +- 業務日付の更新 + + + +**classes**: + +- nablarch.core.date.SystemTimeProvider + +- nablarch.core.date.BasicSystemTimeProvider + +- nablarch.core.date.SystemTimeUtil + +- nablarch.core.date.BusinessDateProvider + +- nablarch.core.date.BasicBusinessDateProvider + +- nablarch.core.date.BusinessDateUtil + + + +**公式ドキュメント**: +- [業務日付の管理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/date.html) + +--- + +## modules + +**依存関係**: + +- `com.nablarch.framework:nablarch-core` [必須] - システム日時管理機能を使用する場合に必要 +- `com.nablarch.framework:nablarch-common-jdbc` [任意] - 業務日付管理機能を使用する場合のみ必要 + +--- + +## system_time_configuration + +システム日時の管理機能を使うためには、BasicSystemTimeProviderの設定をコンポーネント定義に追加する。 + +**xml_example**: + +```xml + +``` + +**component_name**: systemTimeProvider + +**class**: nablarch.core.date.BasicSystemTimeProvider + +**properties**: + + +--- + +## system_time_usage + +システム日時の取得は、SystemTimeUtilを使用する。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `getDate` | `public static Date getDate()` | 現在のシステム日時を取得する | +| `getTimestamp` | `public static Timestamp getTimestamp()` | 現在のシステム日時をTimestamp型で取得する | + +**getDate**: + +戻り値: 現在のシステム日時 + +```java +Date systemDate = SystemTimeUtil.getDate(); +``` + +**getTimestamp**: + +戻り値: 現在のシステム日時(Timestamp型) + +```java +Timestamp systemTimestamp = SystemTimeUtil.getTimestamp(); +``` + +**class**: nablarch.core.date.SystemTimeUtil + +--- + +## business_date_configuration + +業務日付管理機能では、データベースを使用して複数の業務日付を管理する。BasicBusinessDateProviderの設定をコンポーネント定義に追加し、初期化対象のリストに設定する。 + +| プロパティ | 型 | 必須 | 説明 | +|-----------|-----|:----:|------| +| `tableName` | `String` | ✓ | 業務日付を管理するテーブル名 | +| `segmentColumnName` | `String` | ✓ | 区分のカラム名 | +| `dateColumnName` | `String` | ✓ | 日付のカラム名 | +| `defaultSegment` | `String` | ✓ | 区分を省略して業務日付を取得した場合に使用される区分 | +| `transactionManager` | `TransactionManagerの参照` | ✓ | データベースアクセスに使用するトランザクションマネージャ | + +**tableNameの例**: `BUSINESS_DATE` + +**segmentColumnNameの例**: `SEGMENT` + +**dateColumnNameの例**: `BIZ_DATE` + +**defaultSegmentの例**: `00` + +**xml_example**: + +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +**component_name**: businessDateProvider + +**class**: nablarch.core.date.BasicBusinessDateProvider + +**initialization_required**: True + +**database_table**: + +**description**: 業務日付を管理するためのテーブル + +**columns**: + +- **name**: 区分(PK) +- **type**: 文字列型 +- **description**: 業務日付を識別するための値 +- 項目 2: + **name**: 日付 + + **type**: 文字列型 + + **format**: yyyyMMdd + + **description**: 業務日付 + + +--- + +## business_date_usage + +業務日付の取得は、BusinessDateUtilを使用する。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `getDate` | `public static String getDate()` | デフォルト区分の業務日付を取得する | +| `getDate` | `public static String getDate(String segment)` | 指定した区分の業務日付を取得する | + +**getDate**: + +戻り値: 業務日付(yyyyMMdd形式の文字列) + +```java +String bizDate = BusinessDateUtil.getDate(); +``` + +**getDate**: + +パラメータ: +- `segment` (String): 区分 + +戻り値: 業務日付(yyyyMMdd形式の文字列) + +```java +String bizDate = BusinessDateUtil.getDate("batch"); +``` + +**class**: nablarch.core.date.BusinessDateUtil + +--- + +## business_date_override + +バッチ処理で障害時の再実行時に、過去日付をバッチ実行時の業務日付としたい場合、再実行するプロセスのみ任意の日付を業務日付として実行できる。業務日付の上書きは、環境設定の上書き機能を使用して行う。 + +区分が"batch"の日付を"2016/03/17"に上書きしたい場合 + +**system_property**: -DBasicBusinessDateProvider.batch=20160317 + +**use_case**: バッチ処理の障害時の再実行で、過去日付を業務日付として実行したい場合 + +**method**: システムプロパティで指定 + +**format**: BasicBusinessDateProvider.<区分>=日付(yyyyMMdd形式) + +--- + +## business_date_update + +業務日付の更新は、BasicBusinessDateProviderを使用して行う。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `setDate` | `public void setDate(String segment, String date)` | 指定した区分の業務日付を更新する | + +**setDate**: + +パラメータ: +- `segment` (String): 区分 +- `date` (String): 更新する日付(yyyyMMdd形式) + +```java +// システムリポジトリからBasicBusinessDateProviderを取得する +BusinessDateProvider provider = SystemRepository.get("businessDateProvider"); + +// setDateメソッドを呼び出し、更新する +provider.setDate(segment, date); +``` + +**class**: nablarch.core.date.BasicBusinessDateProvider + +--- + +## customization + +ユニットテストの実行時など、システム日時や業務日付を切り替えたい場合、それぞれのProviderインターフェースを実装したクラスを作成し、コンポーネント定義で差し替える。 + +**system_time_customization**: + +**description**: システム日時を切り替える場合 + +**steps**: + +- SystemTimeProviderを実装したクラスを作成する +- システム日時の管理機能を使うための設定に従い、作成したクラスをコンポーネント定義に設定する + +**interface**: nablarch.core.date.SystemTimeProvider + +**business_date_customization**: + +**description**: 業務日付を切り替える場合 + +**steps**: + +- BusinessDateProviderを実装したクラスを作成する +- 業務日付管理機能を使うための設定に従い、作成したクラスをコンポーネント定義に設定する + +**interface**: nablarch.core.date.BusinessDateProvider + +--- + +## tips + +**title**: ウェブアプリケーションでの業務日付の上書き + +**description**: ウェブアプリケーションのように、全ての機能が1プロセス内で実行される場合は、単純にデータベースで管理されている日付を変更すればよい。業務日付の上書き機能は、バッチ処理のように複数プロセスで実行される場合に有用。 + + +--- diff --git a/.claude/skills/nabledge-6/docs/features/libraries/data-bind.md b/.claude/skills/nabledge-6/docs/features/libraries/data-bind.md new file mode 100644 index 0000000..b566700 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/libraries/data-bind.md @@ -0,0 +1,1187 @@ +# データバインド + +CSVやTSV、固定長といったデータをJava BeansオブジェクトまたはMapオブジェクトとして扱う機能を提供する。データファイルとJavaオブジェクト間の双方向変換をサポートする。 + +**目的**: データファイルのデータをオブジェクト指向的に扱い、CSV/TSV/固定長ファイルの読み書きを簡潔に実装できるようにする。アノテーションまたはDataBindConfigでフォーマットを定義することで、様々な形式のファイルに対応可能。 + + +**モジュール**: +- `com.nablarch.framework:nablarch-common-databind` + +**機能**: + +- データをJava Beansオブジェクトとして扱える(BeanUtilによる自動型変換) + +- データをMapオブジェクトとして扱える(値は全てString型) + +- フォーマット指定はアノテーションまたはDataBindConfigで定義 + +- CSV/TSV/固定長ファイルをサポート + +- 複数フォーマットを持つ固定長ファイル(マルチレイアウト)に対応 + +- 論理行番号の取得が可能(@LineNumber) + +- Bean Validationとの連携による入力値チェック + +- ファイルダウンロード/アップロード機能との連携 + + + +**classes**: + +- nablarch.common.databind.ObjectMapper + +- nablarch.common.databind.ObjectMapperFactory + +- nablarch.common.databind.DataBindConfig + +- nablarch.core.beans.BeanUtil + + + +**annotations**: + +- @Csv +- @CsvFormat +- @FixedLength +- @Field +- @LineNumber +- @Record +- @Lpad +- @Rpad + +**公式ドキュメント**: +- [データバインド](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/data_io/data_bind.html) + +--- + +## modules + +**依存関係**: + +- `com.nablarch.framework:nablarch-common-databind` [必須] - データバインド機能のコアモジュール +- `com.nablarch.framework:nablarch-fw-web-extension` [任意] - ファイルダウンロード機能を使用する場合に必要 + +--- + +## usage + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `ObjectMapperFactory.create (Java Beans読み込み用)` | `public static ObjectMapper create(Class entityClass, InputStream inputStream)` | Java Beansクラスにバインドしてデータを読み込むためのObjectMapperを生成する。Java Beansクラスに定義されたアノテーションをもとにフォーマットを決定する。 | +| `ObjectMapperFactory.create (Java Beans書き込み用)` | `public static ObjectMapper create(Class entityClass, OutputStream outputStream)` | Java Beansオブジェクトをデータファイルに書き込むためのObjectMapperを生成する。Java Beansクラスに定義されたアノテーションをもとにフォーマットを決定する。 | +| `ObjectMapperFactory.create (Map読み込み用)` | `public static ObjectMapper create(Class clazz, InputStream inputStream, DataBindConfig config)` | Mapオブジェクトにバインドしてデータを読み込むためのObjectMapperを生成する。DataBindConfigで指定したフォーマット設定をもとにデータを読み込む。 | +| `ObjectMapperFactory.create (Map書き込み用)` | `public static ObjectMapper create(Class clazz, OutputStream outputStream, DataBindConfig config)` | Mapオブジェクトをデータファイルに書き込むためのObjectMapperを生成する。DataBindConfigで指定したフォーマット設定をもとにデータを書き込む。 | +| `ObjectMapper.read` | `public T read() throws IOException, InvalidDataFormatException` | データファイルから1データずつ読み込み、Java BeansまたはMapオブジェクトとして返却する。全データ読み込み後はnullを返す。 | +| `ObjectMapper.write` | `public void write(T object) throws IOException` | Java BeansまたはMapオブジェクトの内容をデータファイルに1データずつ書き込む。プロパティ値がnullの場合は空文字が出力される。 | +| `ObjectMapper.close` | `public void close() throws IOException` | ObjectMapperが使用しているリソースを解放する。全データの読み込み・書き込み完了後に必ず呼び出すこと。try-with-resourcesを使用することで自動的にクローズ処理が実行される。 | + +**ObjectMapperFactory.create (Java Beans読み込み用)**: + +パラメータ: +- `entityClass` (Class): バインド対象のJava Beansクラス +- `inputStream` (InputStream): 読み込み元のストリーム + +戻り値: ObjectMapper - データ読み込み用のマッパー + +```java +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + // 処理 + } +} +``` + +**ObjectMapperFactory.create (Java Beans書き込み用)**: + +パラメータ: +- `entityClass` (Class): バインド対象のJava Beansクラス +- `outputStream` (OutputStream): 書き込み先のストリーム + +戻り値: ObjectMapper - データ書き込み用のマッパー + +```java +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) { + for (Person person : personList) { + mapper.write(person); + } +} +``` + +**ObjectMapperFactory.create (Map読み込み用)**: + +パラメータ: +- `clazz` (Class): Map.classを指定 +- `inputStream` (InputStream): 読み込み元のストリーム +- `config` (DataBindConfig): フォーマット設定(CsvDataBindConfigまたはFixedLengthDataBindConfig) + +戻り値: ObjectMapper - Map形式でのデータ読み込み用マッパー + +```java +DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles("年齢", "名前") + .withProperties("age", "name"); +try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) { + Map person; + while ((person = mapper.read()) != null) { + // 処理 + } +} +``` + +**ObjectMapperFactory.create (Map書き込み用)**: + +パラメータ: +- `clazz` (Class): Map.classを指定 +- `outputStream` (OutputStream): 書き込み先のストリーム +- `config` (DataBindConfig): フォーマット設定(CsvDataBindConfigまたはFixedLengthDataBindConfig) + +戻り値: ObjectMapper - Map形式でのデータ書き込み用マッパー + +```java +DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles("年齢", "名前") + .withProperties("age", "name"); +try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) { + for (Map person : personList) { + mapper.write(person); + } +} +``` + +**ObjectMapper.read**: + +戻り値: T - 読み込んだデータのオブジェクト(全データ読み込み後はnull) + +例外: +- IOException - I/Oエラー発生時 +- InvalidDataFormatException - データフォーマット不正時 + +```java +Person person; +while ((person = mapper.read()) != null) { + // Java Beansオブジェクトごとの処理 +} +``` + +**ObjectMapper.write**: + +パラメータ: +- `object` (T): 書き込むオブジェクト(Java BeansまたはMap) + +戻り値: void + +例外: +- IOException - I/Oエラー発生時 + +```java +for (Person person : personList) { + mapper.write(person); +} +``` + +**ObjectMapper.close**: + +戻り値: void + +例外: +- IOException - I/Oエラー発生時 + +```java +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + // 処理 +} // 自動的にclose()が呼ばれる +``` + +**typical_usage**: + +**file_to_bean**: + +**description**: データファイルを先頭から1データずつ読み込み、Java Beansオブジェクトとして取得する。Java Beansクラスに定義されたアノテーションをもとにデータを読み込む。読み込み時にBeanUtilを使用して自動的に型変換が行われ、型変換に失敗した場合は例外が発生する。 + +**example**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + // Java Beansオブジェクトごとの処理を記述 + } +} catch (InvalidDataFormatException e) { + // 読み込んだデータのフォーマットが不正な場合の処理を記述 +} + +**bean_to_file**: + +**description**: Java Beansオブジェクトの内容をデータファイルに1データずつ書き込む。Java Beansクラスに定義されたアノテーションをもとにデータを書き込む。プロパティの値がnullの場合は未入力を表す値(CSVファイルの場合は空文字)が出力される。 + +**example**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) { + for (Person person : personList) { + mapper.write(person); + } +} + +**file_to_map**: + +**description**: データファイルを先頭から1データずつ読み込み、Mapオブジェクトとして取得する。DataBindConfigの設定値をもとにデータを読み込む。Mapオブジェクトへの変換時、値は全てString型で格納される。 + +**example**: DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles("年齢", "名前") + .withProperties("age", "name"); +try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) { + Map person; + while ((person = mapper.read()) != null) { + // Mapオブジェクトごとの処理を記述 + } +} catch (InvalidDataFormatException e) { + // 読み込んだデータのフォーマットが不正な場合の処理を記述 +} + +**map_to_file**: + +**description**: Mapオブジェクトの内容をデータファイルに1データずつ書き込む。DataBindConfigの設定値をもとにデータを書き込む。Mapオブジェクトのvalue値がnullの場合は未入力を表す値(CSVファイルの場合は空文字)が出力される。 + +**example**: DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles("年齢", "名前") + .withProperties("age", "name"); +try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) { + for (Map person : personList) { + mapper.write(person); + } +} + +**line_number**: + +**description**: ファイルのデータをJava Beansオブジェクトとして取得する際、Java Beansクラスにプロパティを定義して@LineNumberアノテーションを使用することで、データの論理行番号も一緒に取得できる。入力値チェック時にバリデーションエラーが発生したデータの行番号をログに出力したい場合などに使用する。 + +**example**: // Java Beansクラスの定義 +private Long lineNumber; + +@LineNumber +public Long getLineNumber() { + return lineNumber; +} + +// 使用例 +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + System.out.println("行番号: " + person.getLineNumber()); + // 処理 + } +} + +**note**: Mapオブジェクトとして取得する場合は、データの行番号を取得できない点に注意すること。 + +**validation**: + +**description**: データをJava Beansオブジェクトとして読み込むことができるため、Bean Validationによる入力値チェックを行うことができる。 + +**example**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + // 入力値チェックを実行 + ValidatorUtil.validate(person); + // 後続の処理 + } +} catch (InvalidDataFormatException e) { + // データファイルのフォーマット不正時の処理を記述 +} + +**file_download**: + +**description**: ウェブアプリケーションで、Java Beansオブジェクトの内容をデータファイルとしてダウンロードする。データをメモリ上に展開すると大量データのダウンロード時などにメモリを圧迫する恐れがあるため、一時ファイルに出力する。FileResponseオブジェクト生成時にデータファイルを指定し、レスポンスにContent-Type及びContent-Dispositionを設定する。 + +**example**: public HttpResponse download(HttpRequest request, ExecutionContext context) { + // 業務処理 + + final Path path = Files.createTempFile(null, null); + try (ObjectMapper mapper = + ObjectMapperFactory.create(Person.class, Files.newOutputStream(path))) { + for (Person person : persons) { + mapper.write(BeanUtil.createAndCopy(PersonDto.class, person)); + } + } + + // ファイルをボディに設定する。 + FileResponse response = new FileResponse(path.toFile(), true); + + // Content-Typeヘッダ、Content-Dispositionヘッダを設定する + response.setContentType("text/csv; charset=Shift_JIS"); + response.setContentDisposition("person.csv"); + + return response; +} + +**points**: + +- データをメモリ上に展開すると大量データのダウンロード時などにメモリを圧迫する恐れがあるため、一時ファイルに出力する +- FileResponseのコンストラクタの第二引数にtrueを指定すると、リクエスト処理の終了時に自動的にファイルを削除する +- レスポンスにContent-Type及びContent-Dispositionを設定する + +**upload_file**: + +**description**: ウェブアプリケーションで、画面からアップロードされたデータファイルをJava Beansオブジェクトとして読み込む。PartInfo#getInputStreamを使用してアップロードファイルのストリームを取得し、不正なデータが入力されている可能性があるため、Bean Validationを使用して入力チェックを行う。 + +**example**: List partInfoList = request.getPart("uploadFile"); +if (partInfoList.isEmpty()) { + // アップロードファイルが見つからない場合の処理を記述 +} + +PartInfo partInfo = partInfoList.get(0); +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, partInfo.getInputStream())) { + Person person; + while ((person = mapper.read()) != null) { + // 入力値チェックを実行 + ValidatorUtil.validate(person); + // 後続の処理は省略 + } +} catch (InvalidDataFormatException e) { + // データファイルのフォーマット不正時の処理を記述 +} + +**points**: + +- PartInfo#getInputStreamを使用して、アップロードファイルのストリームを取得する +- 不正なデータが入力されている可能性があるため、Bean Validationを使用して入力チェックを行う + +--- + +## csv_format_beans + +Java BeansクラスにバインドしてCSVファイルを扱う場合、@Csvおよび@CsvFormatアノテーションを使用してフォーマットを指定する。CSVファイルのフォーマットは予め用意したフォーマットセットの中から選択できる。フォーマットセットのいずれにも当てはまらない場合は、@CsvFormatを使用して個別にフォーマットを指定できる。 + +**annotations**: + +- 項目 1: + **name**: @Csv + + **class**: nablarch.common.databind.csv.Csv + + **attributes**: + + - 項目 1: + **name**: type + + **type**: Csv.CsvType + + **required**: True + + **description**: CSVフォーマットのタイプ(DEFAULT, RFC4180, EXCEL, TSV, CUSTOM) + + - 項目 2: + **name**: properties + + **type**: String[] + + **required**: True + + **description**: バインドするプロパティ名の配列(CSV項目順) + + - 項目 3: + **name**: headers + + **type**: String[] + + **required**: False + + **description**: ヘッダタイトルの配列(CSV項目順) + + + **example**: @Csv(type = Csv.CsvType.DEFAULT, properties = {"age", "name"}, headers = {"年齢", "氏名"}) +public class Person { + private Integer age; + private String name; + // getter、setterは省略 +} + +- 項目 2: + **name**: @CsvFormat + + **class**: nablarch.common.databind.csv.CsvFormat + + **description**: CSVフォーマットが予め用意したフォーマットセットのいずれにも当てはまらない場合に、個別にフォーマットを指定する。@CsvのtypeにCUSTOMを指定する必要がある。 + + **attributes**: + + - 項目 1: + **name**: fieldSeparator + + **type**: char + + **required**: False + + **default**: , + + **description**: 列区切り文字 + + - 項目 2: + **name**: lineSeparator + + **type**: String + + **required**: False + + **default**: \r\n + + **description**: 行区切り文字 + + - 項目 3: + **name**: quote + + **type**: char + + **required**: False + + **default**: " + + **description**: フィールド囲み文字 + + - 項目 4: + **name**: ignoreEmptyLine + + **type**: boolean + + **required**: False + + **default**: true + + **description**: 空行を無視するか + + - 項目 5: + **name**: requiredHeader + + **type**: boolean + + **required**: False + + **default**: true + + **description**: ヘッダ行が必須か + + - 項目 6: + **name**: charset + + **type**: String + + **required**: False + + **default**: UTF-8 + + **description**: 文字コード + + - 項目 7: + **name**: quoteMode + + **type**: CsvDataBindConfig.QuoteMode + + **required**: False + + **default**: NORMAL + + **description**: クォートモード(NORMAL, ALL) + + - 項目 8: + **name**: emptyToNull + + **type**: boolean + + **required**: False + + **default**: false + + **description**: 空文字をnullとして扱うか + + + **example**: @Csv(type = Csv.CsvType.CUSTOM, properties = {"age", "name"}) +@CsvFormat( + fieldSeparator = '\t', + lineSeparator = "\r\n", + quote = '\'', + ignoreEmptyLine = false, + requiredHeader = false, + charset = "UTF-8", + quoteMode = CsvDataBindConfig.QuoteMode.ALL, + emptyToNull = true) +public class Person { + private Integer age; + private String name; + // getter、setterは省略 +} + + +**note**: Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、ObjectMapperの生成時にDataBindConfigを使用したフォーマットの指定はできない。 + +--- + +## csv_format_map + +MapクラスにバインドしてCSVファイルを扱う場合、ObjectMapperの生成時にCsvDataBindConfigを使用してフォーマットを指定する。CsvDataBindConfig#withPropertiesで設定したプロパティ名がMapオブジェクトのキーとして使用される。CSVにヘッダ行が存在する場合は、プロパティ名の設定を省略することでヘッダタイトルをキーとして使用できる。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `withProperties` | `public CsvDataBindConfig withProperties(String... properties)` | プロパティ名を設定する。設定したプロパティ名がMapオブジェクトのキーとして使用される。 | +| `withHeaderTitles` | `public CsvDataBindConfig withHeaderTitles(String... headerTitles)` | ヘッダタイトルを設定する。 | + +**withProperties**: + +パラメータ: +- `properties` (String...): プロパティ名(CSV項目順) + +戻り値: CsvDataBindConfig + +**withHeaderTitles**: + +パラメータ: +- `headerTitles` (String...): ヘッダタイトル(CSV項目順) + +戻り値: CsvDataBindConfig + +**example**: + +```java +// ヘッダタイトル、プロパティ名はCSVの項目順と一致するように定義する +DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles("年齢", "名前") + .withProperties("age", "name"); +ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config); +``` + +**class**: nablarch.common.databind.csv.CsvDataBindConfig + +**point**: ヘッダタイトル、プロパティ名はCSVの項目順と一致するように定義すること + +--- + +## fixed_length_format_beans + +Java Beansクラスにバインドして固定長ファイルを扱う場合、@FixedLengthおよび@Fieldアノテーションを使用してフォーマットを指定する。各フィールドに対し、パディングやトリム等を変換するコンバータ(@Lpad, @Rpad等)を指定できる。未使用領域が存在するフォーマットの場合、固定長ファイルへの書き込み時にFixedLength#fillCharに設定した文字で自動的にパディングされる。 + +**example**: + +```java +@FixedLength(length = 24, charset = "MS932", lineSeparator = "\r\n", fillChar = '0') +public class Person { + @Field(offset = 1, length = 3) + @Lpad + private Integer age; + + @Field(offset = 9, length = 16) + @Rpad + private String name; + // getter、setterは省略 +} +``` + +**annotations**: + +- 項目 1: + **name**: @FixedLength + + **class**: nablarch.common.databind.fixedlength.FixedLength + + **attributes**: + + - 項目 1: + **name**: length + + **type**: int + + **required**: True + + **description**: 1レコードの長さ(バイト数) + + - 項目 2: + **name**: charset + + **type**: String + + **required**: False + + **default**: UTF-8 + + **description**: 文字コード + + - 項目 3: + **name**: lineSeparator + + **type**: String + + **required**: False + + **default**: \r\n + + **description**: 行区切り文字 + + - 項目 4: + **name**: fillChar + + **type**: char + + **required**: False + + **default**: (半角スペース) + + **description**: 未使用領域のパディング文字 + + - 項目 5: + **name**: multiLayout + + **type**: boolean + + **required**: False + + **default**: false + + **description**: 複数フォーマットを持つファイルか + + + **example**: @FixedLength(length = 19, charset = "MS932", lineSeparator = "\r\n") +public class Person { + @Field(offset = 1, length = 3) + @Lpad + private Integer age; + + @Field(offset = 4, length = 16) + @Rpad + private String name; + // getter、setterは省略 +} + +- **name**: @Field +- **class**: nablarch.common.databind.fixedlength.Field +- **attributes**: + - 項目 1: + **name**: offset + + **type**: int + + **required**: True + + **description**: フィールドの開始位置(1始まり) + + - 項目 2: + **name**: length + + **type**: int + + **required**: True + + **description**: フィールドの長さ(バイト数) + + +- **name**: @Lpad +- **class**: nablarch.common.databind.fixedlength.converter.Lpad +- **description**: 左詰めでパディング(読み込み時はトリム)を行うコンバータ +- **name**: @Rpad +- **class**: nablarch.common.databind.fixedlength.converter.Rpad +- **description**: 右詰めでパディング(読み込み時はトリム)を行うコンバータ + +**converters**: + +- nablarch.common.databind.fixedlength.converter.Lpad - 左詰めパディング +- nablarch.common.databind.fixedlength.converter.Rpad - 右詰めパディング +- その他のコンバータはnablarch.common.databind.fixedlength.converterパッケージ配下を参照 + +**note**: 未使用領域(offset 4-8)は、fillCharに設定した文字(この例では'0')で自動的にパディングされる。 + +--- + +## fixed_length_format_map + +Mapクラスにバインドして固定長ファイルを扱う場合、ObjectMapperの生成時にFixedLengthDataBindConfigを使用してフォーマットを指定する。FixedLengthDataBindConfigは、FixedLengthDataBindConfigBuilderを使用して生成できる。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `newBuilder` | `public static FixedLengthDataBindConfigBuilder newBuilder()` | ビルダーのインスタンスを生成する | +| `length` | `public FixedLengthDataBindConfigBuilder length(int length)` | 1レコードの長さを設定する | +| `charset` | `public FixedLengthDataBindConfigBuilder charset(Charset charset)` | 文字コードを設定する | +| `lineSeparator` | `public FixedLengthDataBindConfigBuilder lineSeparator(String lineSeparator)` | 行区切り文字を設定する | +| `singleLayout` | `public SingleLayoutBuilder singleLayout()` | シングルレイアウト(単一フォーマット)の設定を開始する | +| `field` | `public SingleLayoutBuilder field(String name, int offset, int length, FieldConverter converter)` | フィールドを定義する | +| `build` | `public DataBindConfig build()` | FixedLengthDataBindConfigを生成する | + +**newBuilder**: + +戻り値: FixedLengthDataBindConfigBuilder + +**length**: + +パラメータ: +- `length` (int): 1レコードの長さ(バイト数) + +戻り値: FixedLengthDataBindConfigBuilder + +**charset**: + +パラメータ: +- `charset` (Charset): 文字コード + +戻り値: FixedLengthDataBindConfigBuilder + +**lineSeparator**: + +パラメータ: +- `lineSeparator` (String): 行区切り文字 + +戻り値: FixedLengthDataBindConfigBuilder + +**singleLayout**: + +戻り値: SingleLayoutBuilder + +**field**: + +パラメータ: +- `name` (String): フィールド名(Mapのキーとして使用) +- `offset` (int): 開始位置(1始まり) +- `length` (int): 長さ(バイト数) +- `converter` (FieldConverter): コンバータ(Lpad.Converter, Rpad.RpadConverter等) + +戻り値: SingleLayoutBuilder + +**build**: + +戻り値: DataBindConfig + +**example**: + +```java +final DataBindConfig config = FixedLengthDataBindConfigBuilder + .newBuilder() + .length(19) + .charset(Charset.forName("MS932")) + .lineSeparator("\r\n") + .singleLayout() + .field("age", 1, 3, new Lpad.Converter('0')) + .field("name", 4, 16, new Rpad.RpadConverter(' ')) + .build(); + +final ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config); +``` + +**class**: nablarch.common.databind.fixedlength.FixedLengthDataBindConfig + +**builder_class**: nablarch.common.databind.fixedlength.FixedLengthDataBindConfigBuilder + +--- + +## multi_layout + +複数のフォーマットを持つ固定長ファイルに対応する。Java BeansクラスまたはMapクラスにバインドできる。 + +**beans_approach**: + +**description**: フォーマットごとにJava Beansクラスを定義し、それらのJava Beansクラスをプロパティとして持つMultiLayoutの継承クラスを作成する。 + +**class**: nablarch.common.databind.fixedlength.MultiLayout + +**steps**: + +- フォーマットごとにJava Beansクラスを定義する +- 上記のフォーマットを定義したJava Beansクラスをプロパティとして持つMultiLayoutの継承クラスを定義する +- MultiLayoutの継承クラスに@FixedLengthアノテーションを設定し、multiLayout属性にtrueを設定する +- MultiLayout#getRecordIdentifierメソッドをオーバーライドして、対象のデータがどのフォーマットに紐づくかを識別するRecordIdentifierの実装クラスを返却する + +**annotations**: + +- **name**: @Record +- **class**: nablarch.common.databind.fixedlength.Record +- **description**: フォーマットを表すJava Beansクラスのプロパティに付与する + +**example**: @FixedLength(length = 20, charset = "MS932", lineSeparator = "\r\n", multiLayout = true) +public class Person extends MultiLayout { + @Record + private Header header; + + @Record + private Data data; + + @Override + public RecordIdentifier getRecordIdentifier() { + return new RecordIdentifier() { + @Override + public RecordName identifyRecordName(byte[] record) { + return record[0] == 0x31 ? RecordType.HEADER : RecordType.DATA; + } + }; + } + // getter、setterは省略 +} + +public class Header { + @Field(offset = 1, length = 1) + private Long id; + + @Rpad + @Field(offset = 2, length = 19) + private String field; + // getter、setterは省略 +} + +public class Data { + @Field(offset = 1, length = 1) + private Long id; + + @Lpad + @Field(offset = 2, length = 3) + private Long age; + + @Rpad + @Field(offset = 5, length = 16) + private String name; + // getter、setterは省略 +} + +enum RecordType implements MultiLayoutConfig.RecordName { + HEADER { + @Override + public String getRecordName() { + return "header"; + } + }, + DATA { + @Override + public String getRecordName() { + return "data"; + } + } +} + +**usage_read**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + final Person person = mapper.read(); + if (RecordType.HEADER == person.getRecordName()) { + final Header header = person.getHeader(); + // 後続の処理は省略 + } +} + +**usage_write**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) { + final Person person = new Person(); + person.setHeader(new Header("1", "test")); + mapper.write(person); +} + +**map_approach**: + +**description**: FixedLengthDataBindConfigBuilderのmultiLayoutメソッドを使用して複数フォーマットを定義する。 + +**methods**: + +- 項目 1: + **name**: multiLayout + + **signature**: public MultiLayoutBuilder multiLayout() + + **description**: マルチレイアウト用のDataBindConfigを生成する + + **returns**: MultiLayoutBuilder + +- 項目 2: + **name**: record + + **signature**: public RecordBuilder record(String recordName) + + **description**: レコードタイプを定義する + + **parameters**: + + - **name**: recordName + - **type**: String + - **description**: レコード名 + + **returns**: RecordBuilder + +- 項目 3: + **name**: recordIdentifier + + **signature**: public MultiLayoutBuilder recordIdentifier(RecordIdentifier recordIdentifier) + + **description**: 対象のデータがどのフォーマットに紐づくかを識別するRecordIdentifierを設定する + + **parameters**: + + - **name**: recordIdentifier + - **type**: RecordIdentifier + - **description**: レコード識別子の実装 + + **returns**: MultiLayoutBuilder + + +**example**: final DataBindConfig config = FixedLengthDataBindConfigBuilder + .newBuilder() + .length(20) + .charset(Charset.forName("MS932")) + .lineSeparator("\r\n") + .multiLayout() + .record("header") + .field("id", 1, 1, new DefaultConverter()) + .field("field", 2, 19, new Rpad.RpadConverter(' ')) + .record("data") + .field("id", 1, 1, new DefaultConverter()) + .field("age", 2, 3, new Lpad.LpadConverter('0')) + .field("name", 5, 16, new Rpad.RpadConverter(' ')) + .recordIdentifier(new RecordIdentifier() { + @Override + public RecordName identifyRecordName(byte[] record) { + return record[0] == 0x31 ? RecordType.HEADER : RecordType.DATA; + } + }) + .build(); + +**usage_read**: try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) { + final Map map = mapper.read(); + if (RecordType.HEADER == map.get("recordName")) { + final Map header = map.get("header"); + // 後続の処理は省略 + } +} + +**usage_write**: try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) { + final Map header = new HashMap<>(); + header.put("id", "1"); + header.put("field", "test"); + + final Map map = new HashMap<>(); + map.put("recordName", RecordType.HEADER); + map.put("header", header); + + mapper.write(map); +} + +--- + +## formatter + +データを出力する際に、format機能を使用することで日付や数値などのデータの表示形式をフォーマットできる。 + +**reference**: 詳細はformat機能のドキュメントを参照すること。 + +--- + +## extension + +Java Beansクラスにバインドできるファイル形式を追加する方法 + +**steps**: + +- **step**: 1 +- **description**: 指定した形式のファイルとJava Beansクラスをバインドさせるため、ObjectMapperの実装クラスを作成する +- **step**: 2 +- **description**: ObjectMapperFactoryを継承したクラスを作成し、先ほど作成したObjectMapperの実装クラスを生成する処理を追加する +- **step**: 3 +- **description**: ObjectMapperFactoryの継承クラスをコンポーネント設定ファイルに設定する。コンポーネント名はobjectMapperFactoryとすること。 +- **example**: + +--- + +## csv_format_sets + +デフォルトで提供しているCSVファイルのフォーマットセット及び設定値 + +**format_sets**: + +- 項目 1: + **name**: DEFAULT + + **fieldSeparator**: カンマ(,) + + **lineSeparator**: 改行(\r\n) + + **quote**: ダブルクォート(") + + **ignoreEmptyLine**: True + + **requiredHeader**: True + + **charset**: UTF-8 + + **quoteMode**: NORMAL + +- 項目 2: + **name**: RFC4180 + + **fieldSeparator**: カンマ(,) + + **lineSeparator**: 改行(\r\n) + + **quote**: ダブルクォート(") + + **ignoreEmptyLine**: False + + **requiredHeader**: False + + **charset**: UTF-8 + + **quoteMode**: NORMAL + +- 項目 3: + **name**: EXCEL + + **fieldSeparator**: カンマ(,) + + **lineSeparator**: 改行(\r\n) + + **quote**: ダブルクォート(") + + **ignoreEmptyLine**: False + + **requiredHeader**: False + + **charset**: UTF-8 + + **quoteMode**: NORMAL + +- 項目 4: + **name**: TSV + + **fieldSeparator**: タブ(\t) + + **lineSeparator**: 改行(\r\n) + + **quote**: ダブルクォート(") + + **ignoreEmptyLine**: False + + **requiredHeader**: False + + **charset**: UTF-8 + + **quoteMode**: NORMAL + + +**quote_modes**: + +- **name**: NORMAL +- **description**: フィールド囲み文字、列区切り文字、改行のいずれかを含むフィールドのみフィールド囲み文字で囲む +- **name**: ALL +- **description**: 全てのフィールドをフィールド囲み文字で囲む + +**note**: CSVファイルの読み込み時は、クォートモードは使用せずに自動的にフィールド囲み文字の有無を判定して読み込みを行う。 + +--- + +## anti-patterns + +| パターン | 理由 | 正しい方法 | +|----------|------|------------| +| 外部から受け付けたアップロードファイルのデータをJava Beansとして読み込む際、Java BeansクラスのプロパティをIntegerやDate等の型で定義する | アップロードファイルなどの外部から受け付けたデータには不正なデータが含まれる可能性がある。型変換に失敗すると例外が発生しJava Beansオブジェクトが生成されないため、不正な値を業務エラーとして通知できず異常終了となってしまう。 | 外部から受け付けたデータを読み込む場合は、Java BeansクラスのプロパティをすべてString型で定義し、Bean Validationで入力値チェックを行うこと。 | +| ObjectMapperのclose()を呼び出さずにリソースを解放しない | ObjectMapperは内部でストリームなどのリソースを保持しているため、close()を呼び出さないとリソースリークが発生する。 | try-with-resourcesを使用してObjectMapperを生成することで、自動的にclose()が呼ばれるようにする。 | +| ObjectMapperのインスタンスを複数スレッドで共有する | ObjectMapperの読み込み及び書き込みはスレッドアンセーフであるため、複数スレッドから同時に呼び出された場合の動作は保証されない。 | ObjectMapperのインスタンスを複数スレッドで共有するような場合には、呼び出し元にて同期処理を行うこと。または、スレッドごとにObjectMapperのインスタンスを生成すること。 | +| Java Beansクラスにバインドする際に、ObjectMapperの生成時にDataBindConfigを指定する | Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、DataBindConfigを使用したフォーマットの指定はできない。DataBindConfigはMapクラスにバインドする場合にのみ使用する。 | Java Beansクラスにバインドする場合は、@Csvや@FixedLengthなどのアノテーションでフォーマットを指定すること。 | +| ファイルダウンロード時にデータをメモリ上に全て展開してからレスポンスに設定する | 大量データのダウンロード時にメモリを圧迫する恐れがある。 | 一時ファイルに出力し、FileResponseでファイルを指定する。FileResponseのコンストラクタの第二引数にtrueを指定すると、リクエスト処理の終了時に自動的にファイルを削除する。 | +| CsvDataBindConfigやFixedLengthDataBindConfigで定義したプロパティ名やフィールド名の順序がファイルの項目順と一致していない | ヘッダタイトル、プロパティ名、フィールド定義はファイルの項目順と一致するように定義する必要がある。順序が一致していないと、データが正しくバインドされない。 | ヘッダタイトル、プロパティ名、フィールド定義はファイルの項目順と一致するように定義すること。 | + +**外部から受け付けたアップロードファイルのデータをJava Beansとして読み込む際、Java BeansクラスのプロパティをIntegerやDate等の型で定義するの正しい例**: + +```java +@Csv(type = Csv.CsvType.DEFAULT, properties = {"age", "name"}) +public class Person { + @NumberRange(min = 0, max = 150) + private String age; // String型で定義 + + @Required + private String name; // String型で定義 + // getter、setterは省略 +} +``` + +**ObjectMapperのclose()を呼び出さずにリソースを解放しないの正しい例**: + +```java +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + // 処理 +} // 自動的にclose()が呼ばれる +``` + +**ファイルダウンロード時にデータをメモリ上に全て展開してからレスポンスに設定するの正しい例**: + +```java +final Path path = Files.createTempFile(null, null); +try (ObjectMapper mapper = + ObjectMapperFactory.create(Person.class, Files.newOutputStream(path))) { + for (Person person : persons) { + mapper.write(person); + } +} +FileResponse response = new FileResponse(path.toFile(), true); +``` + +--- + +## errors + +| 例外 | 原因 | 対処 | +|------|------|------| +| `nablarch.common.databind.InvalidDataFormatException` | 読み込んだデータのフォーマットが不正な場合に発生する。例えば、CSVファイルで囲み文字が閉じられていない、固定長ファイルでレコード長が不正、型変換に失敗した場合などに発生する。 | データファイルのフォーマットを確認し、正しいフォーマットで作成されているか検証する。外部から受け付けるファイルの場合は、try-catchでInvalidDataFormatExceptionを捕捉し、ユーザーに適切なエラーメッセージを表示する。 | +| `型変換エラー(InvalidDataFormatExceptionの一種)` | Java Beansクラスへの変換時、Java Beansクラスに定義されたプロパティの型に自動的に型変換するが、型変換に失敗した場合に発生する。例えば、Integerプロパティにアルファベットがバインドされようとした場合など。 | 外部から受け付けたデータを読み込む場合は、Java BeansクラスのプロパティはすべてString型で定義し、Bean Validationで入力値チェックを行うこと。 | + +**nablarch.common.databind.InvalidDataFormatException**: + +```java +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + // 処理 + } +} catch (InvalidDataFormatException e) { + // データファイルのフォーマット不正時の処理を記述 + log.error("データフォーマットが不正です: " + e.getMessage()); +} +``` + +**型変換エラー(InvalidDataFormatExceptionの一種)**: + +```java +// Java Beansクラスの定義 +@Csv(type = Csv.CsvType.DEFAULT, properties = {"age", "name"}) +public class Person { + @NumberRange(min = 0, max = 150) + private String age; // String型で定義 + + @Required + private String name; // String型で定義 +} + +// 使用例 +try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + Person person; + while ((person = mapper.read()) != null) { + ValidatorUtil.validate(person); // Bean Validationで検証 + } +} +``` + +--- + +## tips + +**title**: try-with-resourcesの使用 + +**description**: 全データの読み込みが完了したら、ObjectMapper#closeでリソースを解放すること。try-with-resourcesを使用することでクローズ処理を省略可能。 + +**example**: try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) { + // 処理 +} // 自動的にclose()が呼ばれる + +**title**: null値の出力 + +**description**: プロパティの値がnullの場合は、未入力を表す値が出力される。例えば、CSVファイルに書き込む場合は空文字が出力される。Mapオブジェクトの場合も同様に、value値がnullの場合は空文字が出力される。 + +**title**: Mapオブジェクトでは行番号取得不可 + +**description**: 論理行番号の取得は@LineNumberアノテーションを使用するが、これはJava Beansクラスにのみ適用可能。Mapオブジェクトとして取得する場合は、データの行番号を取得できない点に注意すること。 + +**title**: CSVファイル読み込み時のクォートモード + +**description**: CSVファイルの読み込み時は、クォートモードは使用せずに自動的にフィールド囲み文字の有無を判定して読み込みを行う。クォートモードはCSVファイル書き込み時にのみ使用される。 + +**title**: ヘッダタイトルをMapのキーとして使用 + +**description**: MapクラスにバインドしてCSVを読み込む場合、CSVにヘッダ行が存在する場合は、CsvDataBindConfig#withPropertiesの設定を省略することでヘッダタイトルをMapのキーとして使用できる。 + + +--- + +## limitations + +- ObjectMapperの読み込み及び書き込みはスレッドアンセーフであるため、複数スレッドから同時に呼び出された場合の動作は保証しない。ObjectMapperのインスタンスを複数スレッドで共有する場合には、呼び出し元にて同期処理を行うこと。 +- Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、ObjectMapperの生成時にDataBindConfigを使用したフォーマットの指定はできない。 +- Mapオブジェクトとして取得する場合は、データの論理行番号を取得できない。行番号が必要な場合はJava Beansクラスを使用すること。 +- Mapオブジェクトへの変換時、値は全てString型で格納される。型変換が必要な場合は別途実装する必要がある。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/libraries/database-access.md b/.claude/skills/nabledge-6/docs/features/libraries/database-access.md new file mode 100644 index 0000000..e887dd6 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/libraries/database-access.md @@ -0,0 +1,1118 @@ +# データベースアクセス(JDBCラッパー) + +JDBCを使用してデータベースに対してSQL文を実行する機能を提供する。UniversalDao内部でも使用されており、データベースアクセスには必須の機能。 + +**目的**: JDBCをラップし、安全で簡潔なデータベースアクセスを実現する。SQLインジェクション対策、動的SQL構築、ページングなどの機能を提供。 + + +**モジュール**: +- `com.nablarch.framework:nablarch-core-jdbc` + +**classes**: + +- nablarch.core.db.connection.AppDbConnection + +- nablarch.core.db.statement.SqlPStatement + +- nablarch.core.db.statement.ParameterizedSqlPStatement + +- nablarch.core.db.statement.SqlCStatement + +- nablarch.core.db.statement.SqlRow + +- nablarch.core.db.statement.SqlResultSet + +- nablarch.core.db.connection.DbConnectionContext + + + +**key_features**: + +- SQLファイルによるSQL管理でSQLインジェクション脆弱性を排除 +- データベース製品の方言(Dialect)を意識せずに開発可能 +- Beanオブジェクトを使用した名前付きバインド変数 +- 動的な条件構築($if、in句、order by) +- like検索の自動エスケープ処理 +- 検索結果のキャッシュ機能 + +**recommendation**: SQLの実行にはUniversalDaoの使用を推奨。JDBCラッパーは設定が必須で、UniversalDao内部でも使用される。 + +**公式ドキュメント**: +- [データベースアクセス(JDBCラッパー)](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/database/database.html) + +--- + +## dialect + +データベース製品ごとの違い(方言)を吸収するためのDialectインタフェースを提供。製品に対応したDialectを設定することで、方言を意識せずにアプリケーション実装が可能。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `supportsIdentity` | `boolean supportsIdentity()` | identityカラム(自動採番)を使用できるか否かを返す | +| `supportsIdentityWithBatchInsert` | `boolean supportsIdentityWithBatchInsert()` | identity(自動採番)カラムを持つテーブルに対してbatch insertが可能か否かを返す | +| `supportsSequence` | `boolean supportsSequence()` | シーケンスオブジェクトを使用できるか否かを返す | +| `supportsOffset` | `boolean supportsOffset()` | 検索クエリーの範囲指定でoffset(またはoffsetと同等の機能)を使用できるか否かを返す | +| `isDuplicateException` | `boolean isDuplicateException(SQLException sqlException)` | 一意制約違反を表すSQLExceptionか否かを判定する | +| `isTransactionTimeoutError` | `boolean isTransactionTimeoutError(SQLException sqlException)` | トランザクションタイムアウト対象のSQLExceptionか否かを判定する | +| `buildSequenceGeneratorSql` | `String buildSequenceGeneratorSql(String sequenceName)` | シーケンスオブジェクトから次の値を取得するSQL文を生成する | +| `getResultSetConvertor` | `ResultSetConvertor getResultSetConvertor()` | ResultSetから値を取得するResultSetConvertorを返す | +| `convertPaginationSql` | `String convertPaginationSql(String sql, SelectOption selectOption)` | 検索クエリーを範囲指定(ページング用)SQLに変換する | +| `convertCountSql` | `String convertCountSql(String sql)` | 検索クエリーを件数取得SQLに変換する | +| `getPingSql` | `String getPingSql()` | Connectionがデータベースに接続されているかチェックを行うSQLを返す | + +**supportsIdentity**: + +戻り値: 使用可能な場合true + +**supportsIdentityWithBatchInsert**: + +戻り値: 可能な場合true + +**supportsSequence**: + +戻り値: 使用可能な場合true + +**supportsOffset**: + +戻り値: 使用可能な場合true + +**isDuplicateException**: + +パラメータ: +- `sqlException` (java.sql.SQLException): 判定対象の例外 + +戻り値: 一意制約違反の場合true + +**isTransactionTimeoutError**: + +パラメータ: +- `sqlException` (java.sql.SQLException): 判定対象の例外 + +戻り値: トランザクションタイムアウトの場合true + +**buildSequenceGeneratorSql**: + +パラメータ: +- `sequenceName` (String): シーケンス名 + +戻り値: シーケンス値取得SQL + +**getResultSetConvertor**: + +戻り値: ResultSetConvertor実装 + +**convertPaginationSql**: + +パラメータ: +- `sql` (String): 元のSQL +- `selectOption` (nablarch.core.db.statement.SelectOption): 範囲指定オプション + +戻り値: 範囲指定SQL + +**convertCountSql**: + +パラメータ: +- `sql` (String): 元のSQL + +戻り値: 件数取得SQL + +**getPingSql**: + +戻り値: 接続確認SQL + +**classes**: + +- nablarch.core.db.dialect.Dialect + +- nablarch.core.db.dialect.DefaultDialect + +- nablarch.core.db.dialect.OracleDialect + +- nablarch.core.db.dialect.PostgreSQLDialect + +- nablarch.core.db.dialect.DB2Dialect + +- nablarch.core.db.dialect.SqlServerDialect + +- nablarch.core.db.dialect.H2Dialect + + + +**configuration_example**: dialectプロパティにデータベース製品対応のDialect実装クラスを設定する。例: OracleDialect、PostgreSQLDialect等。 + +**notes**: 設定しなかった場合はDefaultDialectが使用されるが、原則全ての機能が無効化されるため、必ずデータベース製品に対応したDialectを設定すること。 + +--- + +## sql_file + +SQLはロジックに記述せず、SQLファイルに定義する。SQLファイルに記述することで、必ずPreparedStatementを使用するため、SQLインジェクションの脆弱性が排除できる。 + +**example**: + +```java +-- XXXXX取得SQL +-- SQL_ID:GET_XXXX_INFO +GET_XXXX_INFO = +select + col1, + col2 +from + test_table +where + col1 = :col1 +``` + +**file_rules**: + +- クラスパス配下に作成する +- 1つのSQLファイルに複数のSQLを記述できるが、SQLIDはファイル内で一意とする +- SQLIDとSQLIDとの間には空行を挿入する(スペースが存在する行は空行とはみなさない) +- SQLIDとSQLとの間には = を入れる +- コメントは -- で記述する(ブロックコメントはサポートしない) +- SQLは改行やスペース(tab)などで整形してもよい + +**sql_id_format**: SQLIDの#までがSQLファイル名、#以降がSQLファイル内のSQLIDとなる。例: jp.co.tis.sample.action.SampleAction#findUser → ファイル名: jp.co.tis.sample.action.SampleAction.sql、SQLID: findUser + +**configuration_class**: nablarch.core.db.statement.BasicSqlLoader + +**configuration_properties**: + +- 項目 1: + **name**: fileEncoding + + **type**: String + + **required**: False + + **default**: utf-8 + + **description**: SQLファイルのエンコーディング + +- 項目 2: + **name**: extension + + **type**: String + + **required**: False + + **default**: sql + + **description**: SQLファイルの拡張子 + + +--- + +## execute_sql + +SQLIDを指定してSQLを実行する基本的な方法。DbConnectionContextからデータベース接続を取得し、prepareStatementBySqlIdでステートメントを生成して実行する。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `prepareStatementBySqlId` | `SqlPStatement prepareStatementBySqlId(String sqlId)` | SQLIDを元にステートメントを生成する | +| `retrieve` | `SqlResultSet retrieve()` | 検索処理を実行し、結果を返す | +| `executeUpdate` | `int executeUpdate()` | 更新系SQL(INSERT、UPDATE、DELETE)を実行する | +| `setLong` | `void setLong(int parameterIndex, long x)` | 指定されたパラメータインデックスにlong値を設定する | +| `setString` | `void setString(int parameterIndex, String x)` | 指定されたパラメータインデックスにString値を設定する | +| `setBytes` | `void setBytes(int parameterIndex, byte[] x)` | 指定されたパラメータインデックスにbyte配列を設定する | + +**prepareStatementBySqlId**: + +パラメータ: +- `sqlId` (String): SQLID(形式: パッケージ名.クラス名#SQLID) + +戻り値: SqlPStatementオブジェクト + +```java +SqlPStatement statement = connection.prepareStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#findUser"); +statement.setLong(1, userId); +SqlResultSet result = statement.retrieve(); +``` + +**retrieve**: + +戻り値: SqlResultSetオブジェクト(検索結果) + +**executeUpdate**: + +戻り値: 更新件数 + +**setLong**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス(1始まり) +- `x` (long): 設定する値 + +**setString**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス(1始まり) +- `x` (String): 設定する値 + +**setBytes**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス(1始まり) +- `x` (byte[]): 設定する値 + +**usage_pattern**: AppDbConnection connection = DbConnectionContext.getConnection(); +SqlPStatement statement = connection.prepareStatementBySqlId(sqlId); +// バインド変数設定 +SqlResultSet result = statement.retrieve(); + +--- + +## input_bean + +Beanオブジェクトのプロパティ値をSQLのINパラメータに自動的にバインドする機能。名前付きバインド変数を使用することで、インデクスの管理が不要となり、INパラメータの増減に強い実装が可能。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `prepareParameterizedSqlStatementBySqlId` | `ParameterizedSqlPStatement prepareParameterizedSqlStatementBySqlId(String sqlId)` | SQLIDを元にパラメータ化されたステートメントを生成する | +| `executeUpdateByObject` | `int executeUpdateByObject(Object object)` | Beanオブジェクトのプロパティ値をバインド変数に設定してSQL(更新系)を実行する | +| `retrieve` | `SqlResultSet retrieve(Object object)` | Beanオブジェクトのプロパティ値をバインド変数に設定してSQL(検索系)を実行する | + +**prepareParameterizedSqlStatementBySqlId**: + +パラメータ: +- `sqlId` (String): SQLID + +戻り値: ParameterizedSqlPStatementオブジェクト + +**executeUpdateByObject**: + +パラメータ: +- `object` (Object): BeanオブジェクトまたはMap + +戻り値: 更新件数 + +```java +UserEntity entity = new UserEntity(); +entity.setId(1); +entity.setUserName("なまえ"); + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#insertUser"); +int result = statement.executeUpdateByObject(entity); +``` + +**retrieve**: + +パラメータ: +- `object` (Object): BeanオブジェクトまたはMap + +戻り値: SqlResultSet(検索結果) + +**bind_variable_format**: 名前付きバインド変数は :プロパティ名 の形式で記述する。例: :id、:userName + +**sql_example**: insert into user ( + id, + name +) values ( + :id, + :userName +) + +**notes**: + +- BeanオブジェクトはBeanUtilを使用してMapに変換後に処理される +- Mapを指定した場合は、Mapのキー値と一致するINパラメータに対してMapの値が設定される +- BeanUtilで対応していない型がBeanのプロパティに存在した場合、そのプロパティは使用できない +- INパラメータをJDBC標準の?で記述した場合、Beanオブジェクトを入力としたSQL実行は動作しない + +--- + +## paging + +ウェブシステムの一覧検索画面などで使用するページング機能。検索結果の範囲を指定することで、特定の範囲のレコードのみを取得できる。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `SelectOption (constructor)` | `SelectOption(int offset, int limit)` | 検索範囲を指定するSelectOptionオブジェクトを生成する | +| `prepareStatementBySqlId (with SelectOption)` | `SqlPStatement prepareStatementBySqlId(String sqlId, SelectOption selectOption)` | SQLIDと検索範囲を指定してステートメントを生成する | + +**SelectOption (constructor)**: + +パラメータ: +- `offset` (int): 開始位置(1始まり) +- `limit` (int): 取得件数 + +**prepareStatementBySqlId (with SelectOption)**: + +パラメータ: +- `sqlId` (String): SQLID +- `selectOption` (SelectOption): 検索範囲 + +戻り値: SqlPStatementオブジェクト + +```java +SqlPStatement statement = connection.prepareStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#findUser", new SelectOption(11, 10)); +SqlResultSet result = statement.retrieve(); +``` + +**classes**: + +- nablarch.core.db.statement.SelectOption + + + +**notes**: 検索範囲が指定された場合、検索用のSQLを取得範囲指定のSQLに書き換えてから実行する。取得範囲指定のSQLはDialectにより生成される。 + +--- + +## like_search + +like検索に対するescape句の挿入とワイルドカード文字のエスケープ処理を自動で行う機能。 + +**syntax_rules**: + +- 前方一致: 名前付きパラメータの末尾に % を記述(例: name like :userName%) +- 後方一致: 名前付きパラメータの先頭に % を記述(例: name like :%userName) +- 途中一致: 名前付きパラメータの前後に % を記述(例: name like :%userName%) + +**configuration_properties**: + +- 項目 1: + **name**: likeEscapeChar + + **type**: String + + **required**: False + + **default**: \ + + **description**: like検索時のエスケープ文字 + +- 項目 2: + **name**: likeEscapeTargetCharList + + **type**: String + + **required**: False + + **default**: %,_ + + **description**: like検索時のエスケープ対象文字(カンマ区切り) + + +**example_sql**: select * from user where name like :userName% + +**example_code**: UserEntity entity = new UserEntity(); +entity.setUserName("な"); + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#findUserByName"); +int result = statement.retrieve(bean); +// 実際の条件は name like 'な%' escape '\' となる + +**notes**: エスケープ文字は自動的にエスケープ対象となるため、明示的にエスケープ対象文字に設定する必要はない。 + +--- + +## variable_condition + +Beanオブジェクトの状態を元に、実行するSQL文を動的に組み立てる機能。条件の有無によって動的に条件を構築できる。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `prepareParameterizedSqlStatementBySqlId (with condition)` | `ParameterizedSqlPStatement prepareParameterizedSqlStatementBySqlId(String sqlId, Object condition)` | SQLIDと条件を持つBeanオブジェクトを指定してステートメントを生成する。Beanオブジェクトの状態を元にSQLの可変条件の組み立てが行われる。 | + +**prepareParameterizedSqlStatementBySqlId (with condition)**: + +パラメータ: +- `sqlId` (String): SQLID +- `condition` (Object): 条件を持つBeanオブジェクト + +戻り値: ParameterizedSqlPStatementオブジェクト + +**syntax**: $if(プロパティ名) {SQL文の条件} + +**exclusion_rules**: + +- 配列やCollectionの場合は、プロパティ値がnullやサイズ0の場合に条件が除外される +- 上記以外の型の場合は、プロパティ値がnullや空文字列(Stringオブジェクトの場合)の場合に条件が除外される + +**constraints**: + +- 使用できる箇所はwhere句のみ +- $if内に$ifを使用できない(ネスト不可) + +**example_sql**: select + user_id, + user_name, + user_kbn +from + user +where + $if (userName) {user_name like :userName%} + and $if (userKbn) {user_kbn in ('1', '2')} + and birthday = :birthday + +**example_code**: UserEntity entity = new UserEntity(); +entity.setUserName("なまえ"); +// userKbnは設定しない(null) + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#insertUser", entity); +// userKbnの条件は除外される +SqlResultSet result = statement.retrieve(entity); + +--- + +## in_clause + +in句の条件数が可変となるSQLを実行する機能。プロパティ値の要素数に応じてin句の条件が動的に構築される。 + +**syntax**: 条件の名前付きパラメータの末尾に [] を付加する。例: :userKbn[] + +**property_type**: 配列またはjava.util.Collection(サブタイプ含む) + +**example_sql**: select + user_id, + user_name, + user_kbn +from + user +where + $if (userKbn) {user_kbn in (:userKbn[])} + +**example_code**: UserSearchCondition condition = new UserSearchCondition(); +condition.setUserKbn(Arrays.asList("1", "3")); + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#searchUser", condition); +// 実行されるSQLの条件は userKbn in (?, ?) となる +SqlResultSet result = statement.retrieve(condition); + +**notes**: + +- in句の条件となるプロパティ値がnullやサイズ0となる場合には、該当条件は必ず可変条件($if)として定義すること +- 可変条件としなかった場合でプロパティ値がnullの場合、条件が xxxx in (null) となるため、検索結果が正しく取得できない可能性がある +- in句は、条件式(カッコの中)を空にできないため、サイズ0の配列やnullが指定された場合には、条件式を in (null) とする仕様 + +--- + +## order_by + +order byのソート項目を実行時に動的に切り替えてSQLを実行する機能。ソートIDに応じてorder by句が動的に構築される。 + +**syntax**: $sort(プロパティ名) {(ケース1)(ケース2)・・・(ケースn)} + +**syntax_detail**: + +- プロパティ名: BeanオブジェクトのソートIDを保持するプロパティ名 +- ケース: order by句の切り替え候補。候補を一意に識別するソートIDとorder by句に指定する文字列(ケース本体)を記述 +- デフォルトのケースには、ソートIDに default を指定する + +**syntax_rules**: + +- 各ケースは、ソートIDとケース本体を半角丸括弧で囲んで表現する +- ソートIDとケース本体は、半角スペースで区切る +- ソートIDには半角スペースを使用不可 +- ケース本体には半角スペースを使用できる +- 括弧開き以降で最初に登場する文字列をソートIDとする +- ソートID以降で括弧閉じまでの間をケース本体とする +- ソートIDおよびケース本体はトリミングする + +**example_sql**: select + user_id, + user_name +from + user +where + user_name = :userName +$sort(sortId) { + (user_id_asc user_id asc) + (user_id_desc user_id desc) + (name_asc user_name asc) + (name_desc user_name desc) + (default user_id) +} + +**example_code**: UserSearchCondition condition = new UserSearchCondition(); +condition.setUserName("なまえ"); +condition.setSortId("name_asc"); + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#searchUser", condition); +// order by句は order by user_name asc となる +SqlResultSet result = statement.retrieve(condition); + +--- + +## auto_property + +データ登録時や更新時に毎回設定する値をSQLの実行直前に自動的に設定する機能。登録日時や更新日時といった項目への自動設定に使用する。この機能はBeanオブジェクトを入力とする場合のみ有効。 + +**classes**: + +- nablarch.core.db.statement.AutoPropertyHandler + +- nablarch.core.db.statement.autoproperty.CurrentDateTime + +- nablarch.core.db.statement.autoproperty.UserId + +- nablarch.core.db.statement.autoproperty.RequestId + + + +**annotations**: + +- @CurrentDateTime +- @UserId +- @RequestId + +**configuration_property**: updatePreHookObjectHandlerList + +**configuration_class**: nablarch.core.db.statement.BasicStatementFactory + +**example_entity**: public class UserEntity { + private String id; + + @CurrentDateTime + private Timestamp createdAt; // 登録時に自動設定 + + @CurrentDateTime + private String updatedAt; // 登録・更新時に自動設定 +} + +**example_sql**: insert into user ( + id, + createdAt, + updatedAt +) values ( + :id, + :createdAt, + :updatedAt +) + +**example_code**: UserEntity entity = new UserEntity(); +entity.setId(1); +// createdAtとupdatedAtには値を設定する必要はない + +ParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#insertUser"); +int result = statement.executeUpdateByObject(entity); +// 自動設定項目に値が設定される + +**notes**: 値を明示的に設定したとしても、SQL実行直前に値の自動設定機能により上書きされる。 + +--- + +## binary_column + +blob(データベース製品によりバイナリ型の型は異なる)などのバイナリ型のカラムへのアクセス方法。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `getBytes` | `byte[] getBytes(String columnName)` | バイナリ型のカラムの値をbyte配列として取得する | +| `setBytes` | `void setBytes(int parameterIndex, byte[] x)` | サイズの小さいバイナリ値を登録・更新する | +| `setBinaryStream` | `void setBinaryStream(int parameterIndex, InputStream x, int length)` | サイズが大きいバイナリ値をストリームから登録更新する | + +**getBytes**: + +パラメータ: +- `columnName` (String): カラム名 + +戻り値: byte配列 + +```java +SqlResultSet rows = statement.retrieve(); +SqlRow row = rows.get(0); +byte[] encryptedPassword = row.getBytes("password"); +``` + +**setBytes**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス +- `x` (byte[]): 設定する値 + +```java +SqlPStatement statement = getSqlPStatement("UPDATE_PASSWORD"); +statement.setBytes(1, new byte[] {0x30, 0x31, 0x32}); +int updateCount = statement.executeUpdate(); +``` + +**setBinaryStream**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス +- `x` (java.io.InputStream): 入力ストリーム +- `length` (int): データサイズ + +```java +final Path pdf = Paths.get("input.pdf"); +try (InputStream input = Files.newInputStream(pdf)) { + statement.setBinaryStream(1, input, (int) Files.size(pdf)); +} +``` + +**notes**: + +- getBytesを使用した場合、カラムの内容が全てJavaのヒープ上に展開される +- 非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる +- 大量データを読み込む場合には、Blobオブジェクトを使用して、ヒープを大量に消費しないようにすること + +**large_data_example**: SqlResultSet rows = select.retrieve(); +Blob pdf = (Blob) rows.get(0).get("PDF"); +try (InputStream input = pdf.getBinaryStream()) { + // InputStreamからデータを順次読み込み処理を行う +} + +--- + +## clob_column + +CLOBのような大きいサイズの文字列型カラムへのアクセス方法。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `getString` | `String getString(String columnName)` | CLOB型のカラムの値をString型として取得する | +| `setString` | `void setString(int parameterIndex, String x)` | サイズが小さい値を登録更新する | +| `setCharacterStream` | `void setCharacterStream(int parameterIndex, Reader reader, int length)` | サイズが大きい値をReaderから登録・更新する | + +**getString**: + +パラメータ: +- `columnName` (String): カラム名 + +戻り値: String値 + +```java +SqlResultSet rows = statement.retrieve(); +SqlRow row = rows.get(0); +String mailBody = row.getString("mailBody"); +``` + +**setString**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス +- `x` (String): 設定する値 + +```java +statement.setString(1, "値"); +statement.executeUpdate(); +``` + +**setCharacterStream**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス +- `reader` (java.io.Reader): Readerオブジェクト +- `length` (int): データサイズ + +```java +Path path = Paths.get(filePath); +try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + statement.setCharacterStream(1, reader, (int) Files.size(path)); +} +``` + +**notes**: + +- getStringを使用した場合、カラムの内容が全てJavaのヒープ上に展開される +- 非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる +- 大量データを読み込む場合には、Clobオブジェクトを使用して、ヒープを大量に消費しないようにすること + +**large_data_example**: SqlResultSet rows = select.retrieve(); +Clob mailBody = (Clob) rows.get(0).get("mailBody"); +try (Reader reader = mailBody.getCharacterStream()) { + // Readerからデータを順次読み込み処理を行う +} + +--- + +## stored_procedure + +ストアードプロシージャを実行する機能。基本的にはSQLを実行する場合と同じように実装するが、Beanオブジェクトを使用した実行(名前付きバインド変数)はサポートしない。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `prepareCallBySqlId` | `SqlCStatement prepareCallBySqlId(String sqlId)` | SQLIDを元にストアードプロシージャ実行用のステートメントを生成する | +| `registerOutParameter` | `void registerOutParameter(int parameterIndex, int sqlType)` | OUTパラメータを登録する | +| `execute` | `boolean execute()` | ストアードプロシージャを実行する | + +**prepareCallBySqlId**: + +パラメータ: +- `sqlId` (String): SQLID + +戻り値: SqlCStatementオブジェクト + +```java +SqlCStatement statement = connection.prepareCallBySqlId( + "jp.co.tis.sample.action.SampleAction#execute_sp"); +statement.registerOutParameter(1, Types.CHAR); +statement.execute(); +String result = statement.getString(1); +``` + +**registerOutParameter**: + +パラメータ: +- `parameterIndex` (int): パラメータインデックス +- `sqlType` (int): SQL型(java.sql.Types) + +**execute**: + +戻り値: 結果が存在する場合true + +**classes**: + +- nablarch.core.db.statement.SqlCStatement + + + +**notes**: ストアードプロシージャを使用した場合、ロジックがJavaとストアードプロシージャに分散してしまい、保守性を著しく低下させるため原則使用すべきではない。ただし、既存の資産などでどうしても使用しなければならないケースが想定されるため、非常に簡易的ではあるがAPIを提供している。 + +--- + +## separate_transaction + +データベース接続管理ハンドラ及びトランザクション制御ハンドラで開始したトランザクションではなく、個別のトランザクションを使用してデータベースアクセスを行う機能。業務処理が失敗した場合でも必ずデータベースへの変更を確定したい場合などに使用する。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `doTransaction` | `T doTransaction()` | トランザクション内で処理を実行する。SimpleDbTransactionExecutorを継承してexecuteメソッドを実装し、doTransactionメソッドを呼び出す。 | + +**doTransaction**: + +戻り値: executeメソッドの戻り値 + +```java +SimpleDbTransactionManager dbTransactionManager = + SystemRepository.get("update-login-failed-count-transaction"); + +SqlResultSet resultSet = new SimpleDbTransactionExecutor(dbTransactionManager) { + @Override + public SqlResultSet execute(AppDbConnection connection) { + SqlPStatement statement = connection.prepareStatementBySqlId( + "jp.co.tis.sample.action.SampleAction#findUser"); + statement.setLong(1, userId); + return statement.retrieve(); + } +}.doTransaction(); +``` + +**classes**: + +- nablarch.core.db.transaction.SimpleDbTransactionManager + +- nablarch.core.db.transaction.SimpleDbTransactionExecutor + + + +**configuration_properties**: + +- 項目 1: + **name**: connectionFactory + + **type**: nablarch.core.db.connection.ConnectionFactory + + **required**: True + + **description**: データベース接続を取得するConnectionFactory実装クラス + +- 項目 2: + **name**: transactionFactory + + **type**: nablarch.core.transaction.TransactionFactory + + **required**: True + + **description**: トランザクションを管理するTransactionFactory実装クラス + +- 項目 3: + **name**: dbTransactionName + + **type**: String + + **required**: True + + **description**: トランザクションを識別するための名前 + + +**configuration_example**: + + + + + +--- + +## cache + +実行したSQLと外部から取得した条件(バインド変数に設定した値)が等価である場合に、データベースにアクセスせずにキャッシュから検索結果を返却する機能。データベースの負荷を軽減させるために使用する。 + +**classes**: + +- nablarch.core.db.cache.InMemoryResultSetCache + +- nablarch.core.db.cache.statement.CacheableStatementFactory + +- nablarch.core.cache.expirable.BasicExpirationSetting + + + +**use_cases**: + +- 売り上げランキングのように結果が厳密に最新である必要が無く大量に参照されるデータ +- データ更新タイミングが夜間のみで日中は更新されないデータ + +**configuration_properties**: + +- 項目 1: + **name**: cacheSize + + **type**: int + + **required**: False + + **description**: キャッシュサイズ(InMemoryResultSetCache) + +- 項目 2: + **name**: expiration + + **type**: Map + + **required**: True + + **description**: SQLID毎のキャッシュ有効期限。keyにSQLID、valueに有効期限を設定(BasicExpirationSetting)。単位: ms(ミリ秒)、sec(秒)、min(分)、h(時) + +- 項目 3: + **name**: expirationSetting + + **type**: nablarch.core.cache.expirable.ExpirationSetting + + **required**: True + + **description**: 有効期限設定(CacheableStatementFactory) + +- 項目 4: + **name**: resultSetCache + + **type**: nablarch.core.db.cache.ResultSetCache + + **required**: True + + **description**: キャッシュ実装(CacheableStatementFactory) + + +**configuration_example**: + + + + + + + + + + + + + + + + + +**notes**: + +- この機能は、参照系のデータベースアクセスを省略可能な場合に省略し、システム負荷を軽減することを目的としており、データベースアクセス(SQL)の高速化を目的としているものではない +- この機能は、データベースの値の更新を監視してキャッシュの最新化を行うことはない。常に最新のデータを表示する必要がある機能では使用しないこと + +--- + +## schema_replacement + +SQL文中のスキーマを環境毎に切り替える機能。環境によって参照したいスキーマ名が異なるケースで使用する。 + +**classes**: + +- nablarch.core.db.statement.sqlloader.SchemaReplacer + + + +**placeholder**: #SCHEMA# + +**configuration_properties**: + +- 項目 1: + **name**: schemaName + + **type**: String + + **required**: True + + **description**: プレースホルダー #SCHEMA# を置き換える値 + + +**configuration_example**: + + + + + + + + + + + + + +**sql_example**: -- スキーマ名を指定してSELECT +SELECT * FROM #SCHEMA#.TABLE1 + +**notes**: 本機能によるSQL文中のスキーマ置き換えは単純な文字列置換処理であり、スキーマが存在するか、スキーマ置き換え後のSQLが妥当であるかといったチェックは行われない(SQL文実行時にエラーとなる)。 + +--- + +## configuration + +**classes**: + +- nablarch.core.db.connection.BasicDbConnectionFactoryForDataSource + +- nablarch.core.db.connection.BasicDbConnectionFactoryForJndi + +- nablarch.core.db.statement.BasicStatementFactory + +- nablarch.core.db.statement.BasicSqlLoader + + + +**connection_methods**: + +- javax.sql.DataSourceを使ったデータベース接続の生成(BasicDbConnectionFactoryForDataSource) +- アプリケーションサーバなどに登録されたデータソースを使ったデータベース接続の生成(BasicDbConnectionFactoryForJndi) + +**configuration_example_datasource**: + + + +**configuration_example_jndi**: + + + +**statement_factory_example**: + + + + + + + + +**notes**: + +- 上記に設定したクラスを直接使用することは基本的にない。データベースアクセスを必要とする場合には、データベース接続管理ハンドラを使用すること +- データベースを使用する場合はトランザクション管理も必要となる + +--- + +## exceptions + +**exception_types**: + +- **exception**: nablarch.core.db.DbAccessException +- **cause**: データベースアクセス時に発生する例外 +- **description**: データベースアクセス時の一般的なエラー +- 項目 2: + **exception**: nablarch.core.db.connection.exception.DbConnectionException + + **cause**: データベース接続エラーを示す例外 + + **description**: データベースアクセスエラー時の例外がデータベース接続エラーを示す場合に送出される。retry_handlerにより処理される。 + + **solution**: retry_handler未適用の場合には、実行時例外として扱われる + +- **exception**: nablarch.core.db.statement.exception.SqlStatementException +- **cause**: SQLの実行に失敗した時に発生する例外 +- **description**: SQL実行時の一般的なエラー +- 項目 4: + **exception**: nablarch.core.db.statement.exception.DuplicateStatementException + + **cause**: 一意制約違反を示す例外 + + **description**: SQL実行時の例外が一意制約違反を示す場合に送出される。一意制約違反の判定にはDialectが使用される。 + + **solution**: try-catchで補足して処理する。データベース製品によってはSQL実行時に例外が発生した場合に、ロールバックを行うまで一切のSQLを受け付けないものがあるので注意。 + + +**notes**: + +- これらの例外は全て非チェック例外のため、SQLExceptionのようにtry-catchで補足する必要はない +- データベース接続エラーの判定には、Dialectが使用される +- 一意制約違反の判定には、Dialectが使用される + +--- + +## anti-patterns + +| パターン | 理由 | 正しい方法 | +|----------|------|------------| +| SQL文字列を直接連結してクエリを構築する | SQLインジェクションの脆弱性を生む。PreparedStatementを使用せず、文字列連結でSQLを組み立てると、ユーザー入力値が直接SQL文に埋め込まれ、悪意ある入力により意図しないSQL文が実行される危険性がある。 | SQLファイルに定義し、名前付きバインド変数を使用する。どうしてもSQLファイルに定義できない場合でも、必ずPreparedStatementとバインド変数を使用する。 | +| SQLを複数機能で流用する | 複数機能で流用した場合、意図しない使われ方やSQLが変更されることにより思わぬ不具合が発生する原因となる。例えば、複数機能で使用していたSQL文に排他ロック用の for update が追加された場合、排他ロックが不要な機能でロックが取得され処理遅延の原因となる。 | SQLを複数機能で流用せずに、かならず機能毎に作成すること。 | +| 可変条件を使ってSQLを共通化する | 可変条件機能は、ウェブアプリケーションの検索画面のようにユーザの入力内容によって検索条件が変わるような場合に使うものである。条件だけが異なる複数のSQLを共通化するために使用するものではない。安易に共通化した場合、SQLを変更した場合に思わぬ不具合を埋め込む原因にもなる。 | 条件が異なる場合は必ずSQLを複数定義すること。 | +| ストアードプロシージャを多用する | ストアードプロシージャを使用した場合、ロジックがJavaとストアードプロシージャに分散してしまい、保守性を著しく低下させるため原則使用すべきではない。 | ロジックはJavaで実装する。既存の資産などでどうしても使用しなければならないケースのみ、ストアードプロシージャ実行APIを使用する。 | +| getBytesやgetStringでLOB型の大容量データを一括取得する | カラムの内容が全てJavaのヒープ上に展開されるため、非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる。 | 大量データを読み込む場合には、BlobオブジェクトやClobオブジェクトを使用して、InputStreamやReader経由で順次読み込み処理を行う。 | +| 検索結果のキャッシュをSQLの高速化目的で使用する | この機能は、参照系のデータベースアクセスを省略可能な場合に省略し、システム負荷を軽減することを目的としており、データベースアクセス(SQL)の高速化を目的としているものではない。 | SQLの高速化を目的とする場合には、SQLのチューニングを実施すること。 | +| java.sql.Connectionを直接使用する | java.sql.Connectionを使用した場合、チェック例外であるjava.sql.SQLExceptionをハンドリングして例外を制御する必要がある。この例外制御は実装を誤ると、障害が検知されなかったり障害時の調査ができないなどの問題が発生することがある。 | どうしてもjava.sql.Connectionを使わないと満たせない要件がない限り、この機能は使用しないこと。 | + +--- + +## tips + +**title**: 型変換の取扱い + +**description**: データベースアクセス(JDBCラッパー)は、データベースとの入出力に使用する変数の型変換をJDBCドライバに委譲する。よって、入出力に使用する変数の型は、データベースの型及び使用するJDBCドライバの仕様に応じて定義する必要がある。任意の型変換が必要な場合は、アプリケーション側で型変換する。 + +**title**: java.util.Mapも入力として使用可能 + +**description**: Beanの代わりにjava.util.Mapの実装クラスも指定できる。Mapを指定した場合は、Mapのキー値と一致するINパラメータに対して、Mapの値が設定される。 + +**title**: フィールドアクセスへの変更 + +**description**: Beanへのアクセス方法をプロパティからフィールドに変更できる。propertiesファイルに nablarch.dbAccess.isFieldAccess=true を設定する。ただし、本フレームワークのその他の機能ではプロパティアクセスで統一されているため、フィールドアクセスは推奨しない。 + +**title**: java.sql.Connectionの取得 + +**description**: JDBCのネイティブなデータベース接続(java.sql.Connection)を扱いたい場合は、DbConnectionContextから取得したTransactionManagerConnectionからjava.sql.Connectionを取得できる。ただし、どうしてもjava.sql.Connectionを使わないと満たせない要件がない限り使用しないこと。 + +**title**: 一意制約違反のハンドリング + +**description**: 一意制約違反時に何か処理を行う必要がある場合には、DuplicateStatementExceptionをtry-catchで補足し処理をする。ただし、データベース製品によってはSQL実行時に例外が発生した場合に、ロールバックを行うまで一切のSQLを受け付けないものがあるので注意。例えば、登録処理で一意制約違反が発生した場合に更新処理をしたい場合は、例外ハンドリングを行うのではなくmerge文を使用することでこの問題を回避できる。 + + +--- + +## limitations + +- この機能は、JDBC 3.0に依存しているため、使用するJDBCドライバがJDBC 3.0以上を実装している必要がある +- LOB型(BLOB型やCLOB型)のカラムを取得した場合、実際にDBに格納されたデータではなくLOBロケータが取得される。このLOBロケータの有効期間は、RDBMS毎の実装に依存しており、通常、ResultSetやConnectionがクローズされた時点でアクセスできなくなる。このため、ResultSetやConnectionよりも生存期間が長いキャッシュにはBLOB、CLOB型を含めることができない +- デフォルトで提供するキャッシュを保持するコンポーネントはJVMのヒープ上にキャッシュを保持する。このため、アプリケーションを冗長化構成とした場合、アプリケーションごとに検索結果がキャッシュされることになり、それぞれのアプリケーションで異なるキャッシュを保持する可能性がある +- ストアードプロシージャの実行では、Beanオブジェクトを使用した名前付きバインド変数はサポートしない + +--- + +## extensions + +**title**: データベースへの接続法を追加する + +**description**: OSSのコネクションプールライブラリを使用する場合など、データベースの接続方法を追加する場合は、ConnectionFactorySupportを継承し、データベース接続を生成するクラスを作成する。 + +**title**: ダイアレクトを追加する + +**description**: 使用するデータベース製品に対応したダイアレクトがない場合や、特定機能の使用可否を切り替えたい場合は、DefaultDialectを継承し、データベース製品に対応したダイアレクトを作成する。 + +**title**: データベースアクセス時の例外クラスを切り替える + +**description**: デッドロックエラーの例外クラスを変更したい場合など、DbAccessExceptionFactoryとSqlStatementExceptionFactoryの実装クラスを作成して、コンポーネント設定ファイルに定義する。 + + +--- diff --git a/.claude/skills/nabledge-6/docs/features/libraries/file-path-management.md b/.claude/skills/nabledge-6/docs/features/libraries/file-path-management.md new file mode 100644 index 0000000..e4383e9 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/libraries/file-path-management.md @@ -0,0 +1,168 @@ +# ファイルパス管理 + +システムで使用するファイルの入出力先のディレクトリや拡張子を管理するための機能を提供する + +**目的**: ディレクトリや拡張子を論理名で管理し、ファイルの入出力を行う機能では論理名を指定するだけでそのディレクトリ配下のファイルに対する入出力を実現できる + + +**モジュール**: +- `com.nablarch.framework:nablarch-core` + +**機能**: + +- ディレクトリを論理名で管理できる + +- 拡張子を論理名で管理できる + +- 論理名を指定するだけでファイルの入出力が可能 + + + +**classes**: + +- nablarch.core.util.FilePathSetting + + + +**annotations**: + + +**公式ドキュメント**: +- [ファイルパス管理](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/file_path_management.html) + +--- + +## configuration + +| プロパティ | 型 | 必須 | 説明 | +|-----------|-----|:----:|------| +| `basePathSettings` | `Map` | ✓ | ディレクトリの論理名とパスのマッピング。キーは論理名、値はファイルパス(スキーム付き) | +| `fileExtensions` | `Map` | | 拡張子の論理名と拡張子のマッピング。キーは論理名、値は拡張子 | + +**basePathSettingsの注記**: +- スキームは file と classpath が使用できる +- 省略した場合は classpath となる +- classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(jarなどのアーカイブされたファイル内のパスは指定できない) +- パスにはスペースを含めない(スペースが含まれているパスは指定できない) + +**fileExtensionsの注記**: +- 1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する +- 拡張子のないファイルの場合には、その論理名の拡張子設定を省略する + +**xml_example**: + +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +**component_name**: filePathSetting + +**component_class**: nablarch.core.util.FilePathSetting + +**configuration_points**: + +- FilePathSettingのコンポーネント名は filePathSetting とすること(固定) +- basePathSettingsにディレクトリを設定する +- fileExtensionsに拡張子を設定する +- 1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する +- 拡張子のないファイルの場合には、その論理名の拡張子設定を省略する + +--- + +## usage + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `getFileWithoutCreate` | `public File getFileWithoutCreate(String logicalPathName, String fileName)` | 論理名とファイル名から、ファイルパスを取得する。ファイルが存在しない場合でも、ファイルオブジェクトを生成して返す | +| `getBaseDirectory` | `public File getBaseDirectory(String logicalPathName)` | 論理名からベースディレクトリのパスを取得する | + +**getFileWithoutCreate**: + +パラメータ: +- `logicalPathName` (String): 論理名 +- `fileName` (String): ファイル名(拡張子なし) + +戻り値: Fileオブジェクト(ディレクトリパス + ファイル名 + 拡張子) + +```java +// /var/nablarch/input/users.csv +File users = filePathSetting.getFileWithoutCreate("csv-input", "users"); + +// /var/nablarch/input/users (拡張子なし) +File users = filePathSetting.getFileWithoutCreate("fixed-file-input", "users"); +``` + +**getBaseDirectory**: + +パラメータ: +- `logicalPathName` (String): 論理名 + +戻り値: Fileオブジェクト(ディレクトリパス) + +```java +// /var/nablarch/output +File csvOutputDir = filePathSetting.getBaseDirectory("csv-output"); +``` + +**typical_usage**: 論理名を使ってファイルパスを取得し、ファイル入出力処理に渡す。環境ごとに異なるディレクトリパスをコンポーネント設定ファイルで切り替えることで、コードを変更せずに複数環境に対応できる + +--- + +## anti-patterns + +| パターン | 理由 | 正しい方法 | +|----------|------|------------| +| classpathスキームを使用してウェブアプリケーションサーバ(JBoss、Wildfly等)で実行する | 一部のウェブアプリケーションサーバでは本機能を使用できない。これは、ウェブアプリケーションサーバが独自のファイルシステム(例: JbossやWildflyのvfsというバーチャルファイルシステム)を使用して、クラスパス配下のリソースなどを管理していることに起因する | fileスキームを使用する(classpathスキームではなくfileスキームを使用することを推奨) | +| パスにスペースを含める | スペースが含まれているパスは指定できない(仕様上の制限) | スペースを含まないパスを使用する | +| jarなどのアーカイブされたファイル内のパスをclasspathスキームで指定する | classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(アーカイブされたファイル内のパスは指定できない) | ディレクトリとして存在するパスを指定するか、fileスキームを使用する | + +--- + +## tips + +**title**: 拡張子のないファイルの扱い + +**description**: 拡張子のないファイルの場合には、その論理名のfileExtensions設定を省略する。getFileWithoutCreateメソッドを呼び出すと、拡張子なしのファイルパスが取得できる + +**title**: 1つのディレクトリに対する複数の拡張子の設定 + +**description**: 1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する。例えば、csv-inputとdat-inputで同じディレクトリを指定し、それぞれ異なる拡張子を設定する + +**title**: コンポーネント名の固定 + +**description**: FilePathSettingのコンポーネント名は filePathSetting とすること(固定)。この名前でコンポーネントを登録することで、フレームワークが自動的に参照できる + +**title**: スキームのデフォルト動作 + +**description**: スキームを省略した場合は classpath となる。ただし、classpathスキームには制限があるため、fileスキームの使用を推奨 + + +--- + +## limitations + +- classpathスキームを使用した場合、一部のウェブアプリケーションサーバ(JBoss、Wildfly等)では本機能を使用できない +- classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(jarなどのアーカイブされたファイル内のパスは指定できない) +- パスにはスペースを含めない(スペースが含まれているパスは指定できない) + +--- diff --git a/.claude/skills/nabledge-6/docs/features/libraries/universal-dao.md b/.claude/skills/nabledge-6/docs/features/libraries/universal-dao.md new file mode 100644 index 0000000..2d0b1e5 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/libraries/universal-dao.md @@ -0,0 +1,1107 @@ +# ユニバーサルDAO + +Jakarta Persistenceアノテーションを使った簡易的なO/Rマッパー。SQLを書かずに単純なCRUDを実行し、検索結果をBeanにマッピングできる + +**目的**: 単純なCRUD操作とBean検索を簡潔に実現する + + +**位置づけ**: 簡易的なO/Rマッパーとして位置付け。全てのデータベースアクセスをカバーする設計ではない。実現できない場合はDatabaseを使用 + + +**モジュール**: +- `com.nablarch.framework:nablarch-common-dao` + +**classes**: + +- nablarch.common.dao.UniversalDao + + + +**annotations**: + +- jakarta.persistence.* + +**prerequisites**: 内部でDatabaseを使用するため、Databaseの設定が必要 + +**limitations**: + +- 主キー以外の条件を指定した更新/削除は不可(Databaseを使用) +- 共通項目(登録ユーザ、更新ユーザ等)の自動設定機能は未提供 +- CRUDでの@Tableスキーマ指定時、replace_schema機能は使用不可 + +**tips**: + +- **title**: 共通項目の自動設定 +- **description**: Domaアダプタのエンティティリスナー機能を推奨。ユニバーサルDAO使用時はアプリケーションで明示的に設定 +- **title**: 基本方針 +- **description**: ユニバーサルDAOで実現できない場合は、素直にDatabaseを使う + +**公式ドキュメント**: +- [ユニバーサルDAO](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/database/universal_dao.html) + +--- + +## crud + +Jakarta PersistenceアノテーションをEntityに付けることで、SQLを書かずに単純なCRUDが可能。SQL文は実行時に自動構築 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `insert` | `UniversalDao.insert(T entity)` | エンティティを1件登録 | +| `batchInsert` | `UniversalDao.batchInsert(List entities)` | エンティティを一括登録 | +| `update` | `UniversalDao.update(T entity)` | 主キーを指定して1件更新 | +| `batchUpdate` | `UniversalDao.batchUpdate(List entities)` | 主キーを指定して一括更新(排他制御なし) ⚠️ 排他制御を行わない。バージョン不一致でも更新されず正常終了 | +| `delete` | `UniversalDao.delete(T entity)` | 主キーを指定して1件削除 | +| `batchDelete` | `UniversalDao.batchDelete(List entities)` | 主キーを指定して一括削除 | +| `findById` | `UniversalDao.findById(Class entityClass, Object... pk)` | 主キーを指定して1件検索 | +| `findAll` | `UniversalDao.findAll(Class entityClass)` | エンティティを全件検索 | +| `findAllBySqlFile` | `UniversalDao.findAllBySqlFile(Class entityClass, String sqlId)` | SQLファイルを使った全件検索 | +| `findAllBySqlFile` | `UniversalDao.findAllBySqlFile(Class entityClass, String sqlId, Object condition)` | 条件を指定したSQLファイル検索 | +| `findBySqlFile` | `UniversalDao.findBySqlFile(Class entityClass, String sqlId, Object condition)` | SQLファイルで1件検索(悲観的ロック用SELECT FOR UPDATEにも使用) | + +**insert**: + +パラメータ: +- `entity` (T): 登録するエンティティオブジェクト + +戻り値: void + +```java +UniversalDao.insert(user); +``` + +**batchInsert**: + +パラメータ: +- `entities` (List): 登録するエンティティリスト + +戻り値: void + +```java +UniversalDao.batchInsert(users); +``` + +**update**: + +パラメータ: +- `entity` (T): 更新するエンティティオブジェクト(主キー指定必須) + +戻り値: int(更新件数) + +```java +UniversalDao.update(user); +``` + +**batchUpdate**: + +パラメータ: +- `entities` (List): 更新するエンティティリスト + +戻り値: void + +```java +UniversalDao.batchUpdate(users); +``` + +**delete**: + +パラメータ: +- `entity` (T): 削除するエンティティオブジェクト(主キー指定必須) + +戻り値: int(削除件数) + +```java +UniversalDao.delete(user); +``` + +**batchDelete**: + +パラメータ: +- `entities` (List): 削除するエンティティリスト + +戻り値: void + +```java +UniversalDao.batchDelete(users); +``` + +**findById**: + +パラメータ: +- `entityClass` (Class): 検索結果をマッピングするエンティティクラス +- `pk` (Object...): 主キーの値(可変長引数) + +戻り値: T(エンティティオブジェクト) + +```java +User user = UniversalDao.findById(User.class, 1L); +``` + +**findAll**: + +パラメータ: +- `entityClass` (Class): 検索結果をマッピングするエンティティクラス + +戻り値: EntityList + +```java +EntityList users = UniversalDao.findAll(User.class); +``` + +**findAllBySqlFile**: + +パラメータ: +- `entityClass` (Class): 検索結果をマッピングするBeanクラス +- `sqlId` (String): SQL ID + +戻り値: EntityList + +```java +EntityList users = UniversalDao.findAllBySqlFile(User.class, "FIND_BY_NAME"); +``` + +**findAllBySqlFile**: + +パラメータ: +- `entityClass` (Class): 検索結果をマッピングするBeanクラス +- `sqlId` (String): SQL ID +- `condition` (Object): 検索条件オブジェクト + +戻り値: EntityList + +```java +EntityList projects = UniversalDao.findAllBySqlFile(Project.class, "SEARCH_PROJECT", condition); +``` + +**findBySqlFile**: + +パラメータ: +- `entityClass` (Class): 検索結果をマッピングするBeanクラス +- `sqlId` (String): SQL ID +- `condition` (Object): 検索条件オブジェクト + +戻り値: T + +```java +User user = UniversalDao.findBySqlFile(User.class, "FIND_USER_FOR_UPDATE", condition); +``` + +**annotations_required**: @Entity、@Table、@Id、@Column等のJakarta Persistenceアノテーションを使用 + +**sql_generation**: アノテーション情報を元に実行時にSQL文を構築 + +--- + +## sql-file + +任意のSQLで検索する場合、SQLファイルを作成しSQL IDを指定して検索 + +**method**: UniversalDao.findAllBySqlFile / findBySqlFile + +**sql_file_path_derivation**: 検索結果をマッピングするBeanのクラスから導出。sample.entity.User → sample/entity/User.sql + +**sql_id_with_hash**: + +**description**: SQL IDに#を含めると「SQLファイルのパス#SQL ID」と解釈 + +**example**: UniversalDao.findAllBySqlFile(GoldUser.class, "sample.entity.Member#FIND_BY_NAME") + +**sql_file_path**: sample/entity/Member.sql + +**sql_id**: FIND_BY_NAME + +**use_case**: 機能単位(Actionハンドラ単位)にSQLを集約したい場合 + +**recommendation**: 基本は#を付けない指定を使用(指定が煩雑になるため) + +**bean_mapping**: + +**description**: 検索結果をBean(Entity、Form、DTO)にマッピング + +**mapping_rule**: Beanのプロパティ名とSELECT句の名前が一致する項目をマッピング + +**typical_usage**: Database機能のuse_sql_fileと同様の使い方 + +--- + +## join + +複数テーブルをJOINした結果を取得する場合の対応 + +**use_case**: 一覧検索などで複数テーブルをJOINした結果を取得 + +**recommendation**: 非効率なため個別検索せず、1回で検索できるSQLとJOIN結果をマッピングするBeanを作成 + +**implementation**: + +- JOINした結果をマッピングするBean(DTO)を作成 +- SQLファイルに複数テーブルをJOINするSQLを記述 +- findAllBySqlFileでDTOにマッピング + +--- + +## lazy-load + +大量データでメモリ不足を防ぐための遅延ロード機能 + +**example**: + +```java +try (DeferredEntityList users = (DeferredEntityList) UniversalDao.defer().findAllBySqlFile(User.class, "FIND_BY_NAME")) { + for (User user : users) { + // userを使った処理 + } +} +``` + +**use_cases**: + +- ウェブで大量データをダウンロード +- バッチで大量データを処理 + +**method**: + +**name**: defer + +**signature**: UniversalDao.defer() + +**description**: 遅延ロードを有効化するメソッド。検索メソッドの前に呼び出す + +**returns**: UniversalDao(メソッドチェーン可能) + +**return_type**: DeferredEntityList + +**requires_close**: True + +**close_method**: DeferredEntityList.close()(try-with-resources推奨) + +**mechanism**: 内部でサーバサイドカーソルを使用。JDBCのフェッチサイズでメモリ使用量が変わる + +**fetch_size_note**: JDBCのフェッチサイズの詳細はデータベースベンダー提供のマニュアルを参照 + +**important**: RDBMSによってはカーソルオープン中にトランザクション制御が行われるとカーソルがクローズされる。遅延ロード使用中のトランザクション制御でエラーの可能性。ページングで回避またはカーソル挙動を調整 + +--- + +## search-condition + +検索画面のような条件指定検索 + +**example**: + +```java +ProjectSearchForm condition = context.getRequestScopedVar("form"); +List projects = UniversalDao.findAllBySqlFile(Project.class, "SEARCH_PROJECT", condition); +``` + +**method**: UniversalDao.findAllBySqlFile(Class, String sqlId, Object condition) + +**condition_object**: 検索条件を持つ専用のBean(Form等)。ただし1テーブルのみアクセスの場合はEntity指定も可 + +**important**: 検索条件はEntityではなく検索条件を持つ専用のBeanを指定。1テーブルのみの場合はEntity可 + +--- + +## type-conversion + +データベース型とJava型の変換 + +**temporal_annotation**: @Temporalでjava.util.Date/java.util.Calendar型のDBマッピング方法を指定可能 + +**other_types**: 任意のマッピングは不可。DBの型とJDBCドライバ仕様に応じてEntityプロパティを定義 + +**auto_generated_sql**: + +**description**: Entityから自動生成したSQL実行時 + +**output_to_db**: @Temporal設定プロパティは指定型へ変換。それ以外はDatabaseに委譲 + +**input_from_db**: @Temporal設定プロパティは指定型から変換。それ以外はEntity情報を元に変換 + +**custom_sql**: + +**description**: 任意のSQLで検索する場合 + +**output_to_db**: Databaseに委譲して変換 + +**input_from_db**: 自動生成SQLと同様の処理 + +**important**: + +- DB型とプロパティ型不一致で実行時型変換エラーの可能性 +- SQL実行時の暗黙的型変換でindex未使用による性能劣化の可能性 +- データベースとJavaのデータタイプマッピングはJDBCドライバマニュアルを参照 + +**type_examples**: + +- **db_type**: date +- **java_type**: java.sql.Date +- **db_type**: 数値型(integer, bigint, number) +- **java_type**: int (Integer), long (Long) + +--- + +## paging + +検索結果のページング機能 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `per` | `UniversalDao.per(long perPage)` | 1ページあたりの件数を指定 | +| `page` | `UniversalDao.page(long pageNumber)` | ページ番号を指定 | + +**per**: + +パラメータ: +- `perPage` (long): 1ページあたりの件数 + +戻り値: UniversalDao(メソッドチェーン可能) + +**page**: + +パラメータ: +- `pageNumber` (long): ページ番号 + +戻り値: UniversalDao(メソッドチェーン可能) + +**example**: + +```java +EntityList users = UniversalDao.per(3).page(1).findAllBySqlFile(User.class, "FIND_ALL_USERS"); +``` + +**pagination_info**: + +**class**: nablarch.common.dao.Pagination + +**description**: ページング画面表示に必要な検索結果件数等の情報を保持 + +**retrieval**: Pagination pagination = users.getPagination(); + +**internal**: Databaseの範囲指定検索機能を使用して実装 + +**count_sql**: + +**description**: 範囲指定レコード取得前に件数取得SQLが発行される + +**default_behavior**: 元のSQLをSELECT COUNT(*) FROMで包んだSQL + +**performance_note**: 件数取得SQLによる性能劣化時は拡張例を参照してカスタマイズ + +--- + +## surrogate-key + +サロゲートキーの自動採番機能 + +**annotations**: + +- @GeneratedValue +- @SequenceGenerator +- @TableGenerator + +**strategies**: + +- 項目 1: + **type**: GenerationType.AUTO + + **description**: Dialectを元に採番方法を自動選択 + + **priority**: IDENTITY → SEQUENCE → TABLE + + **sequence_name_rule**: SEQUENCE選択時、シーケンスオブジェクト名は<テーブル名>_<カラム名> + + **generator_note**: generator属性に対応するGenerator設定がある場合、そのGeneratorを使用 + + **example**: @Id +@Column(name = "USER_ID", length = 15) +@GeneratedValue(strategy = GenerationType.AUTO) +public Long getId() { return id; } + +- **type**: GenerationType.IDENTITY +- **description**: DB自動採番機能(IDENTITY)を使用 +- **example**: @Id +@Column(name = "USER_ID", length = 15) +@GeneratedValue(strategy = GenerationType.IDENTITY) +public Long getId() { return id; } +- 項目 3: + **type**: GenerationType.SEQUENCE + + **description**: シーケンスオブジェクトで採番 + + **sequence_generator_required**: True + + **sequence_name_config**: @SequenceGeneratorのsequenceName属性で指定。省略時は<テーブル名>_<カラム名> + + **example**: @Id +@Column(name = "USER_ID", length = 15) +@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq") +@SequenceGenerator(name = "seq", sequenceName = "USER_ID_SEQ") +public Long getId() { return id; } + +- 項目 4: + **type**: GenerationType.TABLE + + **description**: 採番テーブルで採番 + + **table_generator_required**: True + + **pk_value_config**: @TableGeneratorのpkColumnValue属性で指定。省略時は<テーブル名>_<カラム名> + + **example**: @Id +@Column(name = "USER_ID", length = 15) +@GeneratedValue(strategy = GenerationType.TABLE, generator = "table") +@TableGenerator(name = "table", pkColumnValue = "USER_ID") +public Long getId() { return id; } + + +**generator_configuration**: シーケンス/テーブル採番はGenerator機能を使用。別途設定が必要(generator参照) + +--- + +## batch-execute + +大量データの一括登録/更新/削除でバッチ実行 + +**目的**: アプリケーションサーバとDBサーバ間のラウンドトリップ回数削減によるパフォーマンス向上 + + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `batchInsert` | `UniversalDao.batchInsert(List entities)` | エンティティを一括登録 | +| `batchUpdate` | `UniversalDao.batchUpdate(List entities)` | エンティティを一括更新 ⚠️ 排他制御を行わない。更新対象EntityとDBのバージョン不一致でも、そのレコードは更新されず処理が正常終了 | +| `batchDelete` | `UniversalDao.batchDelete(List entities)` | エンティティを一括削除 | + +**batchInsert**: + +パラメータ: +- `entities` (List): 登録するエンティティリスト + +戻り値: void + +**batchUpdate**: + +パラメータ: +- `entities` (List): 更新するエンティティリスト + +戻り値: void + +**batchDelete**: + +パラメータ: +- `entities` (List): 削除するエンティティリスト + +戻り値: void + +**important**: batchUpdateは排他制御を行わない。排他制御が必要な更新は1レコード毎の更新処理を使用 + +--- + +## optimistic-lock + +@Version付きEntity更新時に自動で楽観的ロック実行 + +**annotation**: @Version + +**mechanism**: 更新処理時にバージョンカラムが条件に自動追加され楽観ロックが行われる + +**exception**: + +**class**: jakarta.persistence.OptimisticLockException + +**cause**: 排他エラー発生(バージョン不一致) + +**version_annotation_constraints**: + +- 数値型のプロパティのみ指定可(文字列型不可) +- Entity内に1つのみ指定可能 + +**error_handling**: + +**annotation**: @OnError + +**description**: 排他エラー時の画面遷移制御 + +**example**: @OnError(type = OptimisticLockException.class, path = "/WEB-INF/view/common/errorPages/userError.jsp") +public HttpResponse update(HttpRequest request, ExecutionContext context) { + UniversalDao.update(user); +} + +**batch_update_note**: batchUpdateでは楽観的ロックは使用できない + +--- + +## pessimistic-lock + +悲観的ロック機能は特に提供していない + +**example**: + +```java +User user = UniversalDao.findBySqlFile(User.class, "FIND_USER_FOR_UPDATE", condition); +``` + +**implementation**: データベースの行ロック(SELECT FOR UPDATE)を使用 + +**method**: + +**name**: findBySqlFile + +**signature**: UniversalDao.findBySqlFile(Class entityClass, String sqlId, Object condition) + +**description**: SELECT FOR UPDATEを記載したSQLファイルを実行 + +--- + +## exclusive-control + +排他制御の設計指針 + +**example**: + +```java +「ユーザ」単位でロックが業務的に許容されるなら、ユーザテーブルにバージョン番号を定義 +``` + +**principle**: バージョンカラムは排他制御を行う単位ごとに定義し、競合が許容される最大の単位で定義 + +**trade_off**: 単位を大きくすると競合可能性が高まり、更新失敗(楽観的ロック)や処理遅延(悲観的ロック)を招く + +**design_consideration**: 業務的観点で排他制御単位を決定する必要がある + +--- + +## binary-data + +OracleのBLOBのようなデータサイズの大きいバイナリデータの登録/更新 + +**limitation**: ユニバーサルDAOは全データをメモリに展開するため不向き + +**recommendation**: データベース提供機能を使ってファイルから直接登録/更新 + +**reference**: database-binary_column参照 + +--- + +## text-data + +OracleのCLOBのようなデータサイズの大きいテキストデータの登録/更新 + +**limitation**: ユニバーサルDAOは全データをメモリに展開するため不向き + +**recommendation**: データベース提供機能を使ってファイルから直接登録/更新 + +**reference**: database-clob_column参照 + +--- + +## transaction + +現在のトランザクションとは異なるトランザクションでDAO実行 + +**example**: + +```java +private static final class FindPersonsTransaction extends UniversalDao.Transaction { + private EntityList persons; + + FindPersonsTransaction() { + super("find-persons-transaction"); + } + + @Override + protected void execute() { + persons = UniversalDao.findAllBySqlFile(Person.class, "FIND_PERSONS"); + } + + public EntityList getPersons() { + return persons; + } +} + +FindPersonsTransaction tx = new FindPersonsTransaction(); +EntityList persons = tx.getPersons(); +``` + +**use_case**: Databaseのdatabase-new_transactionと同じことをユニバーサルDAOで実行 + +**steps**: + +- コンポーネント設定ファイルにSimpleDbTransactionManagerを定義 +- SimpleDbTransactionManagerを使用して新たなトランザクションでDAO実行 + +**component_configuration**: + +**component_name**: 任意の名前(例: find-persons-transaction) + +**class**: nablarch.core.db.transaction.SimpleDbTransactionManager + +**properties**: + +- 項目 1: + **name**: connectionFactory + + **type**: nablarch.core.db.connection.ConnectionFactory + + **required**: True + + **description**: ConnectionFactory実装クラス + +- 項目 2: + **name**: transactionFactory + + **type**: nablarch.core.transaction.TransactionFactory + + **required**: True + + **description**: TransactionFactory実装クラス + +- 項目 3: + **name**: dbTransactionName + + **type**: String + + **required**: True + + **description**: トランザクションを識別するための名前 + + +**xml_example**: + + + + + +**implementation**: + +**parent_class**: nablarch.common.dao.UniversalDao.Transaction + +**description**: UniversalDao.Transactionを継承したクラスを作成 + +**constructor**: super("transaction-name")でSimpleDbTransactionManagerの名前またはオブジェクトを指定 + +**execute_method**: + +**description**: executeメソッドにDAO処理を実装 + +**behavior**: 正常終了でコミット、例外/エラーでロールバック + +--- + +## configuration + +ユニバーサルDAO使用のための設定 + +**required_component**: + +**component_name**: daoContextFactory + +**class**: nablarch.common.dao.BasicDaoContextFactory + +**description**: コンポーネント定義に追加が必要 + +**xml_example**: + +**prerequisites**: Databaseの設定が必要(内部でDatabaseを使用) + +--- + +## extensions + +**metadata_extractor**: + +**description**: DatabaseMetaDataから主キー情報を取得できない場合の対応 + +**cause**: シノニム使用や権限問題 + +**impact**: 主キー指定検索が正しく動作しない + +**solution**: DatabaseMetaDataExtractorを継承したクラスを作成 + +**parent_class**: nablarch.common.dao.DatabaseMetaDataExtractor + +**configuration**: + +**component_name**: databaseMetaDataExtractor + +**example**: + +**count_sql_customization**: + +**description**: ページング処理の件数取得SQL変更 + +**use_case**: ORDER BY句等で処理負荷が大きい場合に負荷軽減(ORDER BY句を外す等) + +**default_behavior**: 元のSQLをSELECT COUNT(*) FROMで包んだSQL + +**implementation**: + +**method**: Dialect.convertCountSql(String sqlId, Object params, StatementFactory statementFactory)をオーバーライド + +**approach**: 使用中のDialectを継承し、元SQLと件数取得SQLのマッピングをコンポーネント設定 + +**important**: 件数取得SQLは元SQLと同一の検索条件が必要。検索条件に差分が発生しないよう注意 + +**example_class**: CustomH2Dialect extends H2Dialect + +**example_method**: @Override +public String convertCountSql(String sqlId, Object params, StatementFactory statementFactory) { + if (sqlMap.containsKey(sqlId)) { + return statementFactory.getVariableConditionSqlBySqlId(sqlMap.get(sqlId), params); + } + return convertCountSql(statementFactory.getVariableConditionSqlBySqlId(sqlId, params)); +} + +**configuration**: + +**component_name**: dialect + +**example**: + + + + + + + +--- + +## jpa-annotations + +Entityに使用できるJakarta Persistenceアノテーション + +**important**: 記載のないアノテーション/属性は機能しない + +**access_rule**: @Accessで明示的にフィールド指定した場合のみフィールドのアノテーションを参照 + +**getter_setter_required**: フィールドにアノテーション設定でもgetter/setter必須(値の取得/設定はプロパティ経由) + +**naming_rule**: フィールド名とプロパティ名(get〇〇/set〇〇の〇〇)は同一にすること + +**lombok_tip**: Lombokのようなボイラープレートコード生成ライブラリ使用時、フィールドにアノテーション設定でgetter自動生成の利点を活用可能 + +**class_annotations**: + +- 項目 1: + **name**: @Entity + + **package**: jakarta.persistence.Entity + + **description**: データベースのテーブルに対応したEntityクラスに設定 + + **table_name_derivation**: クラス名(パスカルケース)→スネークケース(大文字) + + **examples**: + + - **class**: Book + - **table**: BOOK + - **class**: BookAuthor + - **table**: BOOK_AUTHOR + + **tip**: クラス名からテーブル名を導出できない場合は@Tableで明示指定 + +- 項目 2: + **name**: @Table + + **package**: jakarta.persistence.Table + + **description**: テーブル名を明示指定するアノテーション + + **attributes**: + + **name**: + + **type**: String + + **required**: False + + **description**: テーブル名。指定した値がテーブル名として使用される + + **schema**: + + **type**: String + + **required**: False + + **description**: スキーマ名。指定されたスキーマ名を修飾子としてテーブルにアクセス。例: schema="work" → work.users_work + +- 項目 3: + **name**: @Access + + **package**: jakarta.persistence.Access + + **description**: アノテーション設定場所を指定するアノテーション + + **behavior**: 明示的にフィールド指定した場合のみフィールドのアノテーションを参照 + + +**property_annotations**: + +- 項目 1: + **name**: @Column + + **package**: jakarta.persistence.Column + + **description**: カラム名を指定するアノテーション + + **attributes**: + + **name**: + + **type**: String + + **required**: False + + **description**: カラム名。指定した値がカラム名として使用される + + **default_derivation**: 未設定時はプロパティ名からカラム名を導出(テーブル名導出と同じ方法) + +- 項目 2: + **name**: @Id + + **package**: jakarta.persistence.Id + + **description**: 主キーに設定するアノテーション + + **composite_key**: 複合主キーの場合は複数のgetterまたはフィールドに設定 + +- 項目 3: + **name**: @Version + + **package**: jakarta.persistence.Version + + **description**: 排他制御用バージョンカラムに設定するアノテーション + + **constraints**: + + - 数値型のプロパティのみ指定可(文字列型不可) + - Entity内に1つのみ指定可能 + + **behavior**: 更新処理時にバージョンカラムが条件に自動追加され楽観ロック実行 + +- 項目 4: + **name**: @Temporal + + **package**: jakarta.persistence.Temporal + + **description**: java.util.Date/java.util.Calendar型のDBマッピング方法を指定 + + **attributes**: + + **value**: + + **type**: TemporalType + + **required**: True + + **description**: データベース型(DATE, TIME, TIMESTAMP) + + **behavior**: value属性に指定されたDB型へJavaオブジェクトの値を変換してDB登録 + +- 項目 5: + **name**: @GeneratedValue + + **package**: jakarta.persistence.GeneratedValue + + **description**: 自動採番された値を登録することを示すアノテーション + + **attributes**: + + **strategy**: + + **type**: GenerationType + + **required**: False + + **default**: AUTO + + **description**: 採番方法(AUTO, IDENTITY, SEQUENCE, TABLE) + + **generator**: + + **type**: String + + **required**: False + + **description**: Generator設定名 + + **auto_behavior**: + + - generator属性に対応するGenerator設定がある場合、そのGeneratorを使用 + - generatorが未設定または対応設定がない場合、Dialectを元に選択(IDENTITY→SEQUENCE→TABLE) + + **default_name_rule**: シーケンス名/レコード識別値を取得できない場合、<テーブル名>_<カラム名>から導出 + +- 項目 6: + **name**: @SequenceGenerator + + **package**: jakarta.persistence.SequenceGenerator + + **description**: シーケンス採番を使用する場合に設定 + + **attributes**: + + **name**: + + **type**: String + + **required**: True + + **description**: @GeneratedValueのgenerator属性と同じ値 + + **sequenceName**: + + **type**: String + + **required**: False + + **default**: <テーブル名>_<カラム名> + + **description**: データベース上に作成されているシーケンスオブジェクト名 + + **note**: シーケンス採番はGenerator機能を使用。採番用の設定を別途行う必要がある + +- 項目 7: + **name**: @TableGenerator + + **package**: jakarta.persistence.TableGenerator + + **description**: テーブル採番を使用する場合に設定 + + **attributes**: + + **name**: + + **type**: String + + **required**: True + + **description**: @GeneratedValueのgenerator属性と同じ値 + + **pkColumnValue**: + + **type**: String + + **required**: False + + **default**: <テーブル名>_<カラム名> + + **description**: 採番テーブルのレコードを識別するための値 + + **note**: テーブル採番はGenerator機能を使用。採番用の設定を別途行う必要がある + + +--- + +## bean-data-types + +検索結果をマッピングするBeanに使用可能なデータタイプ + +**important**: 記載のないデータタイプへのマッピングは実行時例外 + +**types**: + +- **type**: java.lang.String +- **note**: +- **type**: java.lang.Short +- **primitive**: True +- **note**: プリミティブ型も指定可。プリミティブ型でnullは0として扱う +- **type**: java.lang.Integer +- **primitive**: True +- **note**: プリミティブ型も指定可。プリミティブ型でnullは0として扱う +- **type**: java.lang.Long +- **primitive**: True +- **note**: プリミティブ型も指定可。プリミティブ型でnullは0として扱う +- **type**: java.math.BigDecimal +- **note**: +- **type**: java.lang.Boolean +- **primitive**: True +- **note**: プリミティブ型も指定可。プリミティブ型でnullはfalseとして扱う。ラッパー型のリードメソッド名はgetから開始必須。プリミティブ型はisで開始可 +- **type**: java.util.Date +- **note**: @Temporalでデータベース上のデータ型を指定する必要がある +- **type**: java.sql.Date +- **note**: +- **type**: java.sql.Timestamp +- **note**: +- **type**: java.time.LocalDate +- **note**: +- **type**: java.time.LocalDateTime +- **note**: +- **type**: byte[] +- **note**: BLOB等の非常に大きいサイズのデータ型の値は、本機能でヒープ上に展開しないよう注意。非常に大きいサイズのバイナリデータを扱う場合は、Databaseを直接使用しStream経由でデータを参照 + +--- + +## anti-patterns + +| パターン | 理由 | 正しい方法 | +|----------|------|------------| +| 主キー以外の条件で更新/削除しようとする | ユニバーサルDAOは主キー指定の更新/削除のみ対応 | 主キー以外の条件が必要な場合はDatabaseを直接使用 | +| 検索条件にEntityを無条件に使用する | 複数テーブル検索時にEntityを使うと設計が不明瞭になる | 検索条件は専用のBean(Form等)を指定。ただし1テーブルのみアクセスの場合はEntity指定も可 | +| フィールドにアノテーション設定してgetter/setterを省略する | UniversalDaoは値の取得/設定をプロパティ経由で行うため、フィールドアノテーション設定でもgetter/setterが必要 | フィールドにアノテーションを設定する場合でもgetter/setterを必ず作成する | +| 共通項目(登録ユーザ、更新ユーザ等)の自動設定を期待する | 自動設定機能は未提供 | Domaアダプタのエンティティリスナー使用、またはアプリケーションで明示的に設定 | +| @Tableのスキーマ指定でreplace_schema機能を使用しようとする | ユニバーサルDAOのCRUD機能ではreplace_schema未対応 | 環境毎のスキーマ切替はDatabaseを使用 | +| batchUpdateで排他制御を期待する | batchUpdateは排他制御を行わない。バージョン不一致でも更新されず正常終了し、更新失敗に気付けない | 排他制御が必要な場合は1レコード毎の更新処理(update)を使用 | +| @Versionを文字列型プロパティに設定する | 数値型のみ対応。文字列型は正しく動作しない | @Versionは数値型プロパティに設定 | +| 大きいBLOB/CLOBデータをユニバーサルDAOで登録/更新する | 全データをメモリに展開するため、大容量データでメモリ不足になる | データベース提供機能でファイルから直接登録/更新 | +| 遅延ロード中にトランザクション制御を行う | RDBMSによってはカーソルオープン中のトランザクション制御でカーソルがクローズされエラーになる | ページングで回避、またはDBベンダマニュアルに沿ってカーソル挙動を調整 | +| JOIN対象のデータを個別に検索する | 複数回のクエリで非効率 | 1回で検索できるSQLとJOIN結果をマッピングするBeanを作成 | +| DeferredEntityListをcloseせずに放置する | 内部でサーバサイドカーソルを使用しており、リソースリークの原因になる | try-with-resourcesでclose呼び出し | +| フィールドとプロパティを異なる名前にする(@Accessでフィールド指定時) | フィールド名とプロパティ名で紐づいているため、異なるとフィールドのアノテーションをプロパティで参照できなくなる | フィールド名とプロパティ名(get〇〇/set〇〇の〇〇)は同一にする | +| 記載のないアノテーション/属性を使用する | Jakarta Persistenceの全機能には対応していない | 公式ドキュメント記載のアノテーション/属性のみ使用 | +| サポートされていないデータタイプにマッピングする | 実行時例外が発生する | bean-data-typesに記載のデータタイプを使用 | +| DB型とプロパティ型を不一致にする | 実行時型変換エラーや暗黙的型変換によるindex未使用で性能劣化 | JDBCドライバマニュアルを参照し適切な型でプロパティを定義 | + +--- + +## errors + +| 例外 | 原因 | 対処 | +|------|------|------| +| `jakarta.persistence.OptimisticLockException` | 楽観的ロックで排他エラー発生(@Version付きEntity更新時にバージョン不一致) | @OnErrorで画面遷移を制御。例: @OnError(type = OptimisticLockException.class, path = "/WEB-INF/view/common/errorPages/userError.jsp") | +| `型変換エラー(実行時例外)` | データベースの型とプロパティの型が不一致 | JDBCドライバのマニュアルを参照し、データベースとJavaのデータタイプマッピングに従って適切な型でプロパティを定義 | +| `実行時例外(マッピングエラー)` | サポートされていないデータタイプへのマッピング | bean-data-typesに記載のデータタイプを使用 | +| `主キー検索が正しく動作しない` | DatabaseMetaDataから主キー情報を取得できない(シノニム使用、権限問題) | DatabaseMetaDataExtractorを継承したクラスを作成し、databaseMetaDataExtractorコンポーネントとして設定 | + +--- + +## tips + +**title**: ユニバーサルDAOの位置付け + +**description**: 簡易的なO/Rマッパー。全てのDBアクセスをカバーする設計ではない。実現できない場合は素直にDatabaseを使用 + +**title**: 共通項目の自動設定 + +**description**: Domaアダプタのエンティティリスナー機能を推奨。ユニバーサルDAO使用時はアプリケーションで明示的に設定 + +**title**: SQLファイルのパス指定 + +**description**: #を含めた指定は機能単位にSQL集約に使えるが、基本は#なしを推奨(指定が煩雑になるため) + +**title**: ページングの内部実装 + +**description**: Databaseの範囲指定検索機能を使用。範囲指定レコード取得前に件数取得SQLが発行される + +**title**: シーケンス/テーブル採番の設定 + +**description**: Generator機能を使用するため、別途採番用の設定が必要 + +**title**: Lombokとの相性 + +**description**: フィールドにアノテーション設定でgetter自動生成の利点を活用可能 + + +--- + +## limitations + +- 主キー以外の条件を指定した更新/削除は不可 +- 共通項目の自動設定機能は未提供 +- CRUDでの@Tableスキーマ指定時、replace_schema機能は使用不可 +- batchUpdateでは排他制御不可 +- @Versionは数値型のみ対応(文字列型不可) +- 大容量BLOB/CLOBデータは全データをメモリ展開するため不向き +- Jakarta Persistenceの全機能には対応していない(記載のないアノテーション/属性は機能しない) + +--- diff --git a/.claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md b/.claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md new file mode 100644 index 0000000..01674de --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/processing/nablarch-batch.md @@ -0,0 +1,1082 @@ +# Nablarchバッチ(都度起動型・常駐型) + +Nablarchバッチアプリケーションは、DBやファイルに格納されたデータレコード1件ごとに処理を繰り返し実行するバッチ処理を構築するための機能を提供する。javaコマンドから直接起動するスタンドアロンアプリケーションとして実行する。 + +**機能**: + +- 大量データの効率的な処理 + +- トランザクション制御(コミット間隔の設定) + +- マルチスレッド実行による並列処理 + +- ファイル・データベースからのデータ読み込み + +- バリデーション機能 + +- エラーハンドリング・リラン機能 + +- 常駐型バッチの定期実行 + + + +**use_cases**: + +- ファイルからデータベースへの一括登録 +- データベースからファイルへの一括出力 +- データベース内のデータ更新・変換 +- 定期的なバッチ処理(日次・月次) +- オンライン処理で作成された要求データの一括処理 + +**公式ドキュメント**: +- [Nablarchバッチ(都度起動型・常駐型)](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/nablarch_batch/index.html) + +--- + +## batch-types + +**each_time_batch**: + +**name**: 都度起動バッチ + +**description**: 日次や月次など、定期的にプロセスを起動してバッチ処理を実行する + +**use_cases**: + +- 定期的なデータ処理(日次・月次) +- スケジューラからの起動によるバッチ実行 + +**resident_batch**: + +**name**: 常駐バッチ + +**description**: プロセスを起動しておき、一定間隔でバッチ処理を実行する。例えば、オンライン処理で作成された要求データを定期的に一括処理するような場合に使用する + +**use_cases**: + +- オンライン処理で作成された要求データの定期的な一括処理 +- データ監視と定期処理 + +**important_notes**: + +- 常駐バッチは、マルチスレッドで実行しても、処理が遅いスレッドの終了を他のスレッドが待つことにより、要求データの取り込み遅延が発生する可能性がある +- 新規開発プロジェクトでは、常駐バッチではなく、上記問題が発生しないdb_messagingを使用することを推奨する +- 既存プロジェクトにおいては、常駐バッチをこのまま稼働させることはできるが、上記問題が発生する可能性がある場合(既に発生している場合)には、db_messagingへの変更を検討すること + +--- + +## architecture + +Nablarchバッチアプリケーションはjavaコマンドから直接起動し、システムリポジトリやログの初期化処理を行い、ハンドラキューを実行する + +**コンポーネント**: + +- **Main**: + - responsibility: Nablarchバッチアプリケーションの起点となるメインクラス。javaコマンドから直接起動し、システムリポジトリやログの初期化処理を行い、ハンドラキューを実行する + - classes: nablarch.fw.launcher.Main +- **Handler Queue**: + - responsibility: リクエストの処理を行うハンドラの連鎖。往路処理、復路処理、例外処理を制御する + - classes: nablarch.fw.Handler +- **DataReader**: + - responsibility: 入力データを読み込み、データレコードを1件ずつ提供する + - classes: nablarch.fw.DataReader, nablarch.fw.reader.DatabaseRecordReader, nablarch.fw.reader.FileDataReader, nablarch.fw.reader.ValidatableFileDataReader, nablarch.fw.reader.ResumeDataReader +- **Action**: + - responsibility: DataReaderを生成し、DataReaderが読み込んだデータレコードを元に業務ロジックを実行し、Resultを返却する + - classes: nablarch.fw.action.BatchAction, nablarch.fw.action.FileBatchAction, nablarch.fw.action.NoInputDataBatchAction, nablarch.fw.messaging.action.AsyncMessageSendAction +- **Form**: + - responsibility: DataReaderが読み込んだデータレコードをマッピングし、バリデーションを行う。プロパティは全てStringで定義する(バイナリ項目を除く) + - notes: 外部から連携されるファイルなど、入力データが安全でない場合にバリデーションを行う, データベースなど、入力データが安全な場合は、Formクラスを使用せず、データレコードからEntityクラスを作成する +- **Entity**: + - responsibility: テーブルと1対1で対応するクラス。カラムに対応するプロパティを持つ + +**process_flow**: + +- 共通起動ランチャ(Main)がハンドラキューを実行する +- DataReaderが入力データを読み込み、データレコードを1件ずつ提供する +- DispatchHandlerが、コマンドライン引数(-requestPath)で指定するリクエストパスを元に処理すべきアクションクラスを特定し、ハンドラキューの末尾に追加する +- アクションクラスは、FormクラスやEntityクラスを使用して、データレコード1件ごとの業務ロジックを実行する +- アクションクラスは、処理結果を示すResultを返却する +- 処理対象データがなくなるまで繰り返す +- StatusCodeConvertHandlerが、処理結果のステータスコードをプロセス終了コードに変換し、バッチアプリケーションの処理結果としてプロセス終了コードが返される + +--- + +## responsibility + +**action**: + +**description**: アクションクラスは2つのことを行う + +**responsibilities**: + +- 入力データの読み込みに使うDataReaderを生成する(createReaderメソッド) +- DataReaderが読み込んだデータレコードを元に業務ロジックを実行し、Resultを返却する(handleメソッド) + +**example**: ファイルの取り込みバッチであれば、業務ロジックとして以下の処理を行う:データレコードからフォームクラスを作成してバリデーションを行う、フォームクラスからエンティティクラスを作成してデータベースにデータを追加する、処理結果としてSuccessを返す + +**form**: + +**description**: DataReaderが読み込んだデータレコードをマッピングするクラス + +**responsibilities**: + +- データレコードをバリデーションするためのアノテーションの設定 +- 相関バリデーションのロジックを持つ + +**rules**: + +- フォームクラスのプロパティは全てStringで定義する(バイナリ項目の場合はバイト配列で定義) +- 外部から連携されるファイルなど、入力データが安全でない場合に使用する +- データベースなど、入力データが安全な場合は、フォームクラスを使用せず、データレコードからエンティティクラスを作成して業務ロジックを実行する + +**notes**: + +- 外部からの入力データによっては、階層構造(formがformを持つ)となる場合もある + +**entity**: + +**description**: テーブルと1対1で対応するクラス。カラムに対応するプロパティを持つ + +--- + +## request-path + +Nablarchバッチアプリケーションでは、コマンドライン引数(-requestPath)で、実行するアクションとリクエストIDを指定する + +**example**: + +```java +-requestPath=com.sample.SampleBatchAction/BATCH0001 +``` + +**format**: -requestPath=アクションのクラス名/リクエストID + +**request_id**: + +**description**: リクエストIDは、各バッチプロセスの識別子として用いられる + +**use_case**: 同一の業務アクションクラスを実行するプロセスを複数起動する場合などは、このリクエストIDが識別子となる + +--- + +## handler-queue-each-time + +**db_enabled**: + +**description**: 都度起動バッチ(DB接続有り)の最小ハンドラ構成 + +**handlers**: + +- 項目 1: + **no**: 1 + + **name**: StatusCodeConvertHandler + + **thread**: メイン + + **forward**: + + **backward**: ステータスコードをプロセス終了コードに変換する + + **exception**: + + **reference**: status_code_convert_handler + +- 項目 2: + **no**: 2 + + **name**: GlobalErrorHandler + + **thread**: メイン + + **forward**: + + **backward**: + + **exception**: 実行時例外、またはエラーの場合、ログ出力を行う + + **reference**: global_error_handler + +- 項目 3: + **no**: 3 + + **name**: DatabaseConnectionManagementHandler(初期処理/終了処理用) + + **thread**: メイン + + **forward**: DB接続を取得する + + **backward**: DB接続を解放する + + **exception**: + + **reference**: database_connection_management_handler + +- 項目 4: + **no**: 4 + + **name**: TransactionManagementHandler(初期処理/終了処理用) + + **thread**: メイン + + **forward**: トランザクションを開始する + + **backward**: トランザクションをコミットする + + **exception**: トランザクションをロールバックする + + **reference**: transaction_management_handler + +- 項目 5: + **no**: 5 + + **name**: RequestPathJavaPackageMapping + + **thread**: メイン + + **forward**: コマンドライン引数をもとに呼び出すアクションを決定する + + **backward**: + + **exception**: + + **reference**: request_path_java_package_mapping + +- 項目 6: + **no**: 6 + + **name**: MultiThreadExecutionHandler + + **thread**: メイン + + **forward**: サブスレッドを作成し、後続ハンドラの処理を並行実行する + + **backward**: 全スレッドの正常終了まで待機する + + **exception**: 処理中のスレッドが完了するまで待機し起因例外を再送出する + + **reference**: multi_thread_execution_handler + +- 項目 7: + **no**: 7 + + **name**: DatabaseConnectionManagementHandler(業務処理用) + + **thread**: サブ + + **forward**: DB接続を取得する + + **backward**: DB接続を解放する + + **exception**: + + **reference**: database_connection_management_handler + +- 項目 8: + **no**: 8 + + **name**: LoopHandler + + **thread**: サブ + + **forward**: 業務トランザクションを開始する + + **backward**: コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する + + **exception**: 業務トランザクションをロールバックする + + **reference**: loop_handler + +- 項目 9: + **no**: 9 + + **name**: DataReadHandler + + **thread**: サブ + + **forward**: データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する + + **backward**: + + **exception**: 読み込んだレコードをログ出力した後、元例外を再送出する + + **reference**: data_read_handler + + +**notes**: + +- これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する + +**db_disabled**: + +**description**: 都度起動バッチ(DB接続無し)の最小ハンドラ構成。DB接続関連ハンドラが不要であり、ループ制御ハンドラでトランザクション制御が不要 + +**handlers**: + +- 項目 1: + **no**: 1 + + **name**: StatusCodeConvertHandler + + **thread**: メイン + + **forward**: + + **backward**: ステータスコードをプロセス終了コードに変換する + + **exception**: + + **reference**: status_code_convert_handler + +- 項目 2: + **no**: 2 + + **name**: GlobalErrorHandler + + **thread**: メイン + + **forward**: + + **backward**: + + **exception**: 実行時例外、またはエラーの場合、ログ出力を行う + + **reference**: global_error_handler + +- 項目 3: + **no**: 3 + + **name**: RequestPathJavaPackageMapping + + **thread**: メイン + + **forward**: コマンドライン引数をもとに呼び出すアクションを決定する + + **backward**: + + **exception**: + + **reference**: request_path_java_package_mapping + +- 項目 4: + **no**: 4 + + **name**: MultiThreadExecutionHandler + + **thread**: メイン + + **forward**: サブスレッドを作成し、後続ハンドラの処理を並行実行する + + **backward**: 全スレッドの正常終了まで待機する + + **exception**: 処理中のスレッドが完了するまで待機し起因例外を再送出する + + **reference**: multi_thread_execution_handler + +- 項目 5: + **no**: 5 + + **name**: DblessLoopHandler + + **thread**: サブ + + **forward**: + + **backward**: データリーダ上に処理対象データが残っていればループを継続する + + **exception**: + + **reference**: dbless_loop_handler + +- 項目 6: + **no**: 6 + + **name**: DataReadHandler + + **thread**: サブ + + **forward**: データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する + + **backward**: + + **exception**: 読み込んだレコードをログ出力した後、元例外を再送出する + + **reference**: data_read_handler + + +**notes**: + +- これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する + +--- + +## handler-queue-resident + +常駐バッチの最小ハンドラ構成。都度起動バッチに加えて、ThreadContextHandler、ThreadContextClearHandler、RetryHandler、ProcessResidentHandler、ProcessStopHandlerがメインスレッド側に追加されている + +**handlers**: + +- 項目 1: + **no**: 1 + + **name**: StatusCodeConvertHandler + + **thread**: メイン + + **forward**: + + **backward**: ステータスコードをプロセス終了コードに変換する + + **exception**: + + **reference**: status_code_convert_handler + +- 項目 2: + **no**: 2 + + **name**: ThreadContextClearHandler + + **thread**: メイン + + **forward**: + + **backward**: ThreadContextHandlerでスレッドローカル上に設定した値を全て削除する + + **exception**: + + **reference**: thread_context_clear_handler + +- 項目 3: + **no**: 3 + + **name**: GlobalErrorHandler + + **thread**: メイン + + **forward**: + + **backward**: + + **exception**: 実行時例外、またはエラーの場合、ログ出力を行う + + **reference**: global_error_handler + +- 項目 4: + **no**: 4 + + **name**: ThreadContextHandler + + **thread**: メイン + + **forward**: コマンドライン引数からリクエストID、ユーザID等のスレッドコンテキスト変数を初期化する + + **backward**: + + **exception**: + + **reference**: thread_context_handler + + **notes**: + + - ProcessStopHandlerのために必要 + +- 項目 5: + **no**: 5 + + **name**: RetryHandler + + **thread**: メイン + + **forward**: + + **backward**: + + **exception**: リトライ可能な実行時例外を捕捉し、かつリトライ上限に達していなければ後続のハンドラを再実行する + + **reference**: retry_handler + +- 項目 6: + **no**: 6 + + **name**: ProcessResidentHandler + + **thread**: メイン + + **forward**: データ監視間隔ごとに後続のハンドラを繰り返し実行する + + **backward**: ループを継続する + + **exception**: ログ出力を行い、実行時例外が送出された場合はリトライ可能例外にラップして送出する。エラーが送出された場合はそのまま再送出する + + **reference**: process_resident_handler + +- 項目 7: + **no**: 7 + + **name**: ProcessStopHandler + + **thread**: メイン + + **forward**: リクエストテーブル上の処理停止フラグがオンであった場合は、後続ハンドラの処理は行なわずにプロセス停止例外(ProcessStop)を送出する + + **backward**: + + **exception**: + + **reference**: process_stop_handler + +- 項目 8: + **no**: 8 + + **name**: DatabaseConnectionManagementHandler(初期処理/終了処理用) + + **thread**: メイン + + **forward**: DB接続を取得する + + **backward**: DB接続を解放する + + **exception**: + + **reference**: database_connection_management_handler + +- 項目 9: + **no**: 9 + + **name**: TransactionManagementHandler(初期処理/終了処理用) + + **thread**: メイン + + **forward**: トランザクションを開始する + + **backward**: トランザクションをコミットする + + **exception**: トランザクションをロールバックする + + **reference**: transaction_management_handler + +- 項目 10: + **no**: 10 + + **name**: RequestPathJavaPackageMapping + + **thread**: メイン + + **forward**: コマンドライン引数をもとに呼び出すアクションを決定する + + **backward**: + + **exception**: + + **reference**: request_path_java_package_mapping + +- 項目 11: + **no**: 11 + + **name**: MultiThreadExecutionHandler + + **thread**: メイン + + **forward**: サブスレッドを作成し、後続ハンドラの処理を並行実行する + + **backward**: 全スレッドの正常終了まで待機する + + **exception**: 処理中のスレッドが完了するまで待機し起因例外を再送出する + + **reference**: multi_thread_execution_handler + +- 項目 12: + **no**: 12 + + **name**: DatabaseConnectionManagementHandler(業務処理用) + + **thread**: サブ + + **forward**: DB接続を取得する + + **backward**: DB接続を解放する + + **exception**: + + **reference**: database_connection_management_handler + +- 項目 13: + **no**: 13 + + **name**: LoopHandler + + **thread**: サブ + + **forward**: 業務トランザクションを開始する + + **backward**: コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する + + **exception**: 業務トランザクションをロールバックする + + **reference**: loop_handler + +- 項目 14: + **no**: 14 + + **name**: DataReadHandler + + **thread**: サブ + + **forward**: データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する + + **backward**: + + **exception**: 読み込んだレコードをログ出力した後、元例外を再送出する + + **reference**: data_read_handler + + +**notes**: + +- 常駐バッチの最小ハンドラ構成は、ThreadContextHandler、ThreadContextClearHandler、RetryHandler、ProcessResidentHandler、ProcessStopHandlerがメインスレッド側に追加されている点を除けば都度起動バッチと同じ +- これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する + +--- + +## data-readers + +Nablarchでは、バッチアプリケーションを構築するために必要なデータリーダを標準で幾つか提供している + +**readers**: + +- 項目 1: + **name**: DatabaseRecordReader + + **class**: nablarch.fw.reader.DatabaseRecordReader + + **description**: データベースからデータを読み込むデータリーダ + + **use_case**: データベースからレコードを1件ずつ読み込む + +- 項目 2: + **name**: FileDataReader + + **class**: nablarch.fw.reader.FileDataReader + + **description**: ファイルからデータを読み込むデータリーダ。データへのアクセスにdata_formatを使用している + + **use_case**: ファイルからレコードを1件ずつ読み込む + + **important**: data_bindを使用する場合は、このデータリーダを使用しないこと + +- 項目 3: + **name**: ValidatableFileDataReader + + **class**: nablarch.fw.reader.ValidatableFileDataReader + + **description**: バリデーション機能付きファイル読み込みデータリーダ。データへのアクセスにdata_formatを使用している + + **use_case**: ファイルからレコードを1件ずつ読み込み、バリデーションを行う + + **important**: data_bindを使用する場合は、このデータリーダを使用しないこと + +- 項目 4: + **name**: ResumeDataReader + + **class**: nablarch.fw.reader.ResumeDataReader + + **description**: レジューム機能付き読み込みデータリーダ。障害発生ポイントからの再実行ができる + + **use_case**: ファイル入力で障害発生ポイントからの再実行が必要な場合 + + +**custom_reader**: + +**description**: 上記のデータリーダでプロジェクトの要件を満たせない場合は、DataReaderインタフェースを実装したクラスをプロジェクトで作成して対応する + +**interface**: nablarch.fw.DataReader + +**methods**: + +- **name**: read +- **signature**: T read(ExecutionContext ctx) +- **description**: 1件分のデータを返却する。このメソッドで読み込んだデータが業務アクションハンドラへ引き渡される +- **name**: hasNext +- **signature**: boolean hasNext(ExecutionContext ctx) +- **description**: 次のデータの有無を判定する。このメソッドがfalseを返却するとデータの読み込み処理は終了となる +- **name**: close +- **signature**: void close(ExecutionContext ctx) +- **description**: データの読み込み終了後のストリームのclose処理を実装する + +--- + +## actions + +Nablarchでは、バッチアプリケーションを構築するために必要なアクションクラスを標準で幾つか提供している + +**actions**: + +- 項目 1: + **name**: BatchAction + + **class**: nablarch.fw.action.BatchAction + + **description**: 汎用的なバッチアクションのテンプレートクラス + + **methods**: + + - **name**: createReader + - **signature**: DataReader createReader(ExecutionContext ctx) + - **description**: 使用するDataReaderのインスタンスを返却する + - **name**: handle + - **signature**: Result handle(TData inputData, ExecutionContext ctx) + - **description**: DataReaderから渡された1件分のデータに対する業務ロジックを実装する + +- 項目 2: + **name**: FileBatchAction + + **class**: nablarch.fw.action.FileBatchAction + + **description**: ファイル入力のバッチアクションのテンプレートクラス。データへのアクセスにdata_formatを使用している + + **important**: data_bindを使用する場合は、このアクションクラスを使用しないこと。他のアクションクラスを使用すること + +- **name**: NoInputDataBatchAction +- **class**: nablarch.fw.action.NoInputDataBatchAction +- **description**: 入力データを使用しないバッチアクションのテンプレートクラス +- **name**: AsyncMessageSendAction +- **class**: nablarch.fw.messaging.action.AsyncMessageSendAction +- **description**: 応答不要メッセージ送信用のアクションクラス + +--- + +## patterns-file-to-db + +ファイルからデータを読み込み、バリデーションを行い、データベースに登録するパターン + +**form**: ZipCodeForm.javaを参照。@Csv、@CsvFormat、@Domain、@Required、@LineNumberを使用 + +**reader**: ZipCodeFileReader.javaを参照。DataReaderインタフェースを実装し、read、hasNext、closeメソッドを実装 + +**action**: ImportZipCodeFileAction.javaを参照。BatchActionを継承し、createReaderとhandleメソッドを実装 + +**処理フロー**: + +- ファイルを受け付けるフォームクラスを作成する(data_bindを使用) +- DataReaderの実装クラスを作成する(ファイルを読み込んで一行ずつ業務アクションメソッドへ引き渡す) +- BatchActionを継承した業務アクションクラスを作成する +- createReaderメソッドで使用するDataReaderのインスタンスを返却する +- handleメソッドで、DataReaderから渡された一行分のデータをバリデーションし、データベースに登録する + +**name**: FILE to DB パターン + +**use_cases**: + +- CSVファイルからデータベースへの一括登録 +- 外部システムから連携されたファイルの取り込み + +**implementation_points**: + +- data_bindを用いてフォームにCSVをバインドするため、@Csvおよび@CsvFormatを付与する +- bean_validationを実施するために、バリデーション用のアノテーションを付与する +- 行数プロパティを定義し、ゲッタに@LineNumberを付与することで、対象データが何行目のデータであるかを自動的に設定できる +- DataReaderのreadメソッドに一行分のデータを返却する処理を実装する +- DataReaderのhasNextメソッドに次行の有無を判定する処理を実装する +- DataReaderのcloseメソッドにファイルの読み込み終了後のストリームのclose処理を実装する +- handleメソッドで、UniversalDao#insertを使用してエンティティをデータベースに登録する + +--- + +## patterns-db-to-file + +データベースからデータを読み込み、ファイルに出力するパターン + +**処理フロー**: + +- DatabaseRecordReaderを使用してデータベースからレコードを読み込む +- BatchActionを継承した業務アクションクラスを作成する +- createReaderメソッドでDatabaseRecordReaderのインスタンスを返却する +- handleメソッドで、読み込んだレコードをファイルに出力する + +**name**: DB to FILE パターン + +**use_cases**: + +- データベースからCSVファイルへの一括出力 +- 外部システムへのデータ連携ファイルの作成 + +**implementation_points**: + +- DatabaseRecordReaderにSQLを設定する +- ファイル出力にはFileRecordWriterやdata_bindを使用する +- 大量データの場合は、コミット間隔を適切に設定する + +--- + +## patterns-db-to-db + +データベースからデータを読み込み、加工・変換してデータベースに書き込むパターン + +**処理フロー**: + +- DatabaseRecordReaderを使用してデータベースからレコードを読み込む +- BatchActionを継承した業務アクションクラスを作成する +- createReaderメソッドでDatabaseRecordReaderのインスタンスを返却する +- handleメソッドで、読み込んだレコードを加工・変換し、UniversalDaoを使用してデータベースに更新する + +**name**: DB to DB パターン + +**use_cases**: + +- データベース内のデータ更新・変換 +- 集計処理・マスタメンテナンス + +**implementation_points**: + +- DatabaseRecordReaderにSQLを設定する +- UniversalDao#update、UniversalDao#insertなどを使用してデータベースに更新する +- 大量データの場合は、コミット間隔を適切に設定する + +--- + +## multithread + +バッチ処理をマルチスレッドで並列実行することで、処理性能を向上させる + +**handler**: + +**name**: MultiThreadExecutionHandler + +**class**: nablarch.fw.handler.MultiThreadExecutionHandler + +**description**: サブスレッドを作成し、後続ハンドラの処理を並行実行する + +**reference**: multi_thread_execution_handler + +**configuration**: + +**thread_count**: + +**description**: 並列実行するスレッド数を設定する + +**note**: スレッド数はCPUコア数やDB接続数を考慮して設定する + +**notes**: + +- マルチスレッドで実行されるバッチについては、アプリケーション側でスレッドセーフであることを保証する必要がある + +--- + +## transaction-control + +バッチ処理のコミット間隔を制御する + +**handler**: + +**name**: LoopHandler + +**class**: nablarch.fw.handler.LoopHandler + +**description**: 業務トランザクションを開始し、コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する + +**reference**: loop_handler + +**configuration**: + +**commit_interval**: + +**description**: コミット間隔(処理件数)を設定する + +**reference**: loop_handler-commit_interval + +**callback**: + +**description**: 処理成功や失敗時にステータスを変更する場合、LoopHandlerのコールバック機能を使用する + +**reference**: loop_handler-callback + +--- + +## error-handling + +**rerun**: + +**title**: バッチ処理をリランできるようにする + +**description**: Nablarchバッチアプリケーションでは、ファイル入力を除き、バッチ処理をリランできるようにする機能を提供していない + +**approach**: 処理対象レコードにステータスを持たせ、処理成功や失敗時にステータスを変更するといった、アプリケーションでの設計と実装が必要となる + +**file_input**: + +**description**: ファイル入力については、ResumeDataReader(レジューム機能付き読み込み)を使用することで、障害発生ポイントからの再実行ができる + +**class**: nablarch.fw.reader.ResumeDataReader + +**reference**: loop_handler-callback + +**continue**: + +**title**: バッチ処理でエラー発生時に処理を継続する + +**description**: エラー発生時の処理継続は、常駐バッチのみ対応している。都度起動バッチは対応していない + +**approach**: 常駐バッチでは、TransactionAbnormalEndを送出すると、RetryHandlerにより処理が継続される。ただし、バッチ処理がリランできるようになっている必要がある + +**exception**: nablarch.fw.results.TransactionAbnormalEnd + +**note**: 都度起動バッチでTransactionAbnormalEndが送出されると、バッチ処理が異常終了となる + +**abnormal_end**: + +**title**: バッチ処理を異常終了にする + +**description**: アプリケーションでエラーを検知した場合に、処理を継続せずにバッチ処理を異常終了させたい場合がある + +**approach**: Nablarchバッチアプリケーションでは、ProcessAbnormalEndを送出すると、バッチ処理を異常終了にできる。ProcessAbnormalEndが送出された場合、プロセス終了コードはこのクラスに指定された値となる + +**exception**: nablarch.fw.launcher.ProcessAbnormalEnd + +--- + +## pessimistic-lock + +Nablarchバッチアプリケーションで悲観的ロックを行うための実装方法。ロック時間が短縮され他プロセスへの影響を抑えることができる + +SampleAction.javaを参照 + +**reader**: DatabaseRecordReaderで主キーのみ取得する + +**handle**: handleメソッド内でUniversalDao.findBySqlFileを使用して悲観的ロックを行う + +**approach**: + +- データリーダでは処理対象レコードの主キーのみ取得する +- handleメソッド内で悲観的ロックを行う + +**reference**: universal_dao_jpa_pessimistic_lock + +--- + +## state-retention + +バッチアプリケーションの実行中の状態(登録件数や更新件数など)を保持する + +**approach**: バッチアクション内で状態を保持することで対応する + +**multithread**: + +**description**: マルチスレッドで実行されるバッチについては、アプリケーション側でスレッドセーフであることを保証する必要がある + +**example**: AtomicIntegerを使用してスレッドセーフを保証する + +**execution_context**: + +**description**: ExecutionContextのスコープを使用して同じことが実現できるが、どのような値を保持しているかが分かりづらいデメリットがある + +**recommendation**: ExecutionContextを使用するのではなく、バッチアクション側で状態を保持することを推奨する + +**scopes**: + +**request_scope**: スレッドごとに状態を保持する領域 + +**session_scope**: バッチ全体の状態を保持する領域 + +--- + +## multi-process + +常駐バッチアプリケーションのマルチプロセス化 + +**approach**: 基本的にはデータベースをキューとしたメッセージングのマルチプロセス化(db_messaging-multiple_process)と同様 + +**action_implementation**: + +**description**: Actionの実装についてはデータベースをキューとしたメッセージングとは異なる + +**points**: + +- プロセスIDを生成する(例: UUIDを使用) +- 自身が悲観ロックした未処理データを抽出するDatabaseRecordReaderを作成する +- DatabaseRecordReaderがデータ抽出前に行うコールバック処理に、悲観ロックSQLを実行する処理を登録する +- コールバック処理は別トランザクションで実行する必要がある + +**listener**: + +**interface**: DatabaseRecordListener + +**method**: beforeReadRecords + +**description**: DatabaseRecordReaderがデータ抽出前に実行するコールバック処理 + +**custom_reader**: + +**description**: Readerを自作している場合には、悲観ロック後に処理対象データを抽出するようにするとよい + +--- + +## configuration + +**system_repository**: + +**description**: システムリポジトリの初期化は、アプリケーション起動時にシステムリポジトリの設定ファイルのパスを指定することで行う + +**reference**: main-run_application + +**launch**: + +**description**: Nablarchバッチアプリケーションの起動方法 + +**command**: java -cp ... nablarch.fw.launcher.Main -requestPath=/ -diConfig= -userId= + +**parameters**: + +- **name**: requestPath +- **description**: 実行するアクションとリクエストIDを指定する。形式: アクションのクラス名/リクエストID +- **required**: True +- **name**: diConfig +- **description**: システムリポジトリの設定ファイルのパスを指定する +- **required**: True +- **name**: userId +- **description**: 実行ユーザIDを指定する +- **required**: False + +--- + +## anti-patterns + +| パターン | 理由 | 正しい方法 | +|----------|------|------------| +| FileDataReaderまたはValidatableFileDataReaderをdata_bindと併用する | FileDataReaderとValidatableFileDataReaderは、データへのアクセスにdata_formatを使用している。data_bindを使用する場合は、これらのデータリーダを使用しないこと | data_bindを使用する場合は、DataReaderインタフェースを実装したカスタムデータリーダを作成するか、他のアクションクラスを使用する | +| FileBatchActionをdata_bindと併用する | FileBatchActionは、データへのアクセスにdata_formatを使用している。data_bindを使用する場合は、このアクションクラスを使用しないこと | data_bindを使用する場合は、BatchActionや他のアクションクラスを使用する | +| フォームクラスのプロパティをString以外で定義する | Bean Validationの要件により、フォームクラスのプロパティは全てStringで定義する必要がある(バイナリ項目を除く) | フォームクラスのプロパティは全てStringで定義する。バイナリ項目の場合はバイト配列で定義する | +| データベースなど安全な入力データに対してもフォームクラスを使用する | フォームクラスは外部から連携されるファイルなど、入力データが安全でない場合にバリデーションを行うために使用する | データベースなど、入力データが安全な場合は、フォームクラスを使用せず、データレコードからエンティティクラスを作成して業務ロジックを実行する | +| 新規開発で常駐バッチを採用する | 常駐バッチは、マルチスレッドで実行しても、処理が遅いスレッドの終了を他のスレッドが待つことにより、要求データの取り込み遅延が発生する可能性がある | 新規開発プロジェクトでは、常駐バッチではなく、上記問題が発生しないdb_messagingを使用することを推奨する | +| ExecutionContextを使用して状態を保持する | ExecutionContextを使用した場合、どのような値を保持しているかが分かりづらいデメリットがある | ExecutionContextを使用するのではなく、バッチアクション側で状態を保持することを推奨する | +| 悲観的ロックをデータリーダで行う | データリーダで悲観的ロックを行うと、ロック時間が長くなり他プロセスへの影響が大きい | データリーダでは処理対象レコードの主キーのみ取得し、handleメソッド内で悲観的ロックを行う。これによりロック時間が短縮され他プロセスへの影響を抑えることができる | +| 都度起動バッチでTransactionAbnormalEndを送出してエラー継続を期待する | 都度起動バッチは、エラー発生時の処理継続に対応していない。TransactionAbnormalEndが送出されると、バッチ処理が異常終了となる | エラー発生時の処理継続は、常駐バッチのみ対応している。常駐バッチでTransactionAbnormalEndを送出すると、RetryHandlerにより処理が継続される | + +--- + +## errors + +| 例外 | 原因 | 対処 | +|------|------|------| +| `nablarch.fw.results.TransactionAbnormalEnd` | トランザクションの異常終了を示す例外 | | +| `nablarch.fw.launcher.ProcessAbnormalEnd` | プロセスの異常終了を示す例外 | | +| `nablarch.fw.handler.ProcessStopHandler.ProcessStop` | プロセスの停止を示す例外 | | + +**nablarch.fw.results.TransactionAbnormalEnd**: + +使用ケース: 常駐バッチでエラー発生時に処理を継続する場合に送出する + +動作: 常駐バッチでは、RetryHandlerにより処理が継続される。都度起動バッチでは、バッチ処理が異常終了となる + +**nablarch.fw.launcher.ProcessAbnormalEnd**: + +使用ケース: アプリケーションでエラーを検知した場合に、処理を継続せずにバッチ処理を異常終了させる場合に送出する + +動作: バッチ処理が異常終了となる。プロセス終了コードはこのクラスに指定された値となる + +**nablarch.fw.handler.ProcessStopHandler.ProcessStop**: + +使用ケース: ProcessStopHandlerがリクエストテーブル上の処理停止フラグがオンであることを検知した場合に送出される + +動作: 後続ハンドラの処理は行なわずにプロセスが停止する + +--- diff --git a/.claude/skills/nabledge-6/docs/features/tools/ntf-assertion.md b/.claude/skills/nabledge-6/docs/features/tools/ntf-assertion.md new file mode 100644 index 0000000..583d232 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/tools/ntf-assertion.md @@ -0,0 +1,255 @@ +# NTFアサーション・期待値検証 + +テスト結果と期待値の自動比較機能を提供する。データベース更新内容の確認、検索結果の確認、メッセージの確認、オブジェクトプロパティの確認など、多様なアサーション機能を提供する。 + +**assertion_types**: + +- DBアサーション(更新結果、検索結果) +- ファイルアサーション +- ログアサーション +- メッセージアサーション +- プロパティアサーション +- HTMLダンプ出力 + +**related_files**: + +- ntf-overview.json +- ntf-test-data.json +- ntf-batch-request-test.json + +**公式ドキュメント**: +- [NTFアサーション・期待値検証](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_DbAccessTest.html) +- [NTFアサーション・期待値検証](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_RequestUnitTest.html) +- [NTFアサーション・期待値検証](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/03_Tips.html) + +--- + +## db_assertion + +データベースの更新結果や検索結果を期待値と比較する機能 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `assertTableEquals` | `assertTableEquals(String sheetName)` | 指定されたシート内のデータタイプ"EXPECTED_TABLE"であるデータを全て比較する。データベースの更新結果が期待値と一致することを確認する。 | +| `assertTableEquals (with groupId)` | `assertTableEquals(String message, String sheetName, String groupId)` | グループIDを指定して、そのグループIDのデータのみをassert対象にする。複数のテストケースのデータを1つのシートに混在させる場合に使用。 | +| `assertSqlResultSetEquals` | `assertSqlResultSetEquals(String sheetName, String id, SqlResultSet actual)` | Excelに記載した期待値(LIST_MAP形式)と実際の検索結果(SqlResultSet)が等しいことを確認する。 | + +**assertTableEquals**: + +パラメータ: +- `sheetName` (String): 期待値を記載したExcelシート名 + +使い方: 更新系テストで使用。テスト対象メソッド実行後、commitTransactions()を呼び出してから本メソッドを実行する。 + +注意事項: 更新日付のようなjava.sql.Timestamp型のフォーマットは"yyyy-mm-dd hh:mm:ss.fffffffff"である(fffffffffはナノ秒)。ナノ秒が設定されていない場合でも、フォーマット上は0ナノ秒として表示される(例:2010-01-01 12:34:56.0)。Excelシートに期待値を記載する場合は、末尾の小数点+ゼロを付与しておく必要がある。 + +比較ルール: +- 期待値の記述で省略されたカラムは、比較対象外となる +- 比較実行時、レコードの順番が異なっていても主キーを突合して正しく比較ができる +- 1シート内に複数のテーブルを記述できる + +**assertTableEquals (with groupId)**: + +パラメータ: +- `message` (String): アサート失敗時に表示するメッセージ +- `sheetName` (String): 期待値を記載したExcelシート名 +- `groupId` (String): グループID + +使い方: 1つのシートに複数テストケースのデータを記載する場合に使用。EXPECTED_TABLE[groupId]=テーブル名の形式で記述する。 + +**assertSqlResultSetEquals**: + +パラメータ: +- `sheetName` (String): 期待値を記載したExcelシート名 +- `id` (String): 期待値のID(LIST_MAPのID) +- `actual` (SqlResultSet): 実際の検索結果 + +使い方: 参照系テストで使用。テスト対象メソッドが返すSqlResultSetを期待値と比較する。 + +注意事項: SELECT実行時はORDER BY指定がなされる場合がほとんどであり、順序についても厳密に比較する必要がある為、レコードの順序が異なる場合はアサート失敗となる。 + +比較ルール: +- SELECT文で指定された全てのカラム名(別名)が比較対象になる。ある特定のカラムを比較対象外にすることはできない +- レコードの順序が異なる場合は、等価でないとみなす(アサート失敗) + +--- + +## db_setup + +データベースに準備データを登録する機能 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `setUpDb` | `setUpDb(String sheetName)` | 指定されたシート内のデータタイプ"SETUP_TABLE"全てをデータベースに登録する。 | +| `setUpDb (with groupId)` | `setUpDb(String sheetName, String groupId)` | グループIDを指定して、そのグループIDのデータのみをデータベースに登録する。 | + +**setUpDb**: + +パラメータ: +- `sheetName` (String): 準備データを記載したExcelシート名 + +使い方: テスト対象メソッド実行前に呼び出す。 + +注意事項: +- Excelファイルには必ずしも全カラムを記述する必要はない。省略されたカラムには、デフォルト値が設定される +- Excelファイルの1シート内に複数のテーブルを記述できる。setUpDb(String sheetName)実行時、指定されたシート内のデータタイプ"SETUP_TABLE"全てが登録対象となる + +**setUpDb (with groupId)**: + +パラメータ: +- `sheetName` (String): 準備データを記載したExcelシート名 +- `groupId` (String): グループID + +使い方: 1つのシートに複数テストケースのデータを記載する場合に使用。SETUP_TABLE[groupId]=テーブル名の形式で記述する。 + +--- + +## transaction_control + +トランザクション制御機能。Nablarch Application Frameworkでは複数種類のトランザクションを併用することが前提となっているため、テスト対象クラス実行後にデータベースの内容を確認する際には、トランザクションをコミットしなければならない。 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `beginTransactions` | `beginTransactions()` | トランザクションを開始する。DbAccessTestSupportを継承している場合、@Beforeメソッドで自動的に呼び出される。 | +| `commitTransactions` | `commitTransactions()` | トランザクションをコミットする。 ⚠️ コミットしない場合、テスト結果の確認が正常に行われない。 | +| `endTransactions` | `endTransactions()` | トランザクションを終了する。DbAccessTestSupportを継承している場合、@Afterメソッドで自動的に呼び出される。 | + +**beginTransactions**: + +使い方: 通常は明示的に呼び出す必要はない。 + +**commitTransactions**: + +使い方: 更新系テストで、テスト対象メソッド実行後、データベースの内容を確認する前に呼び出す。 + +**endTransactions**: + +使い方: 通常は明示的に呼び出す必要はない。 + +**important**: 更新系テストの場合、テスト対象クラス実行後にcommitTransactions()を呼び出してからassertTableEquals()を実行する必要がある。参照系テストの場合はコミットを行う必要はない。 + +**automatic_control**: DbAccessTestSupportを継承している場合、テストメソッド実行前にトランザクション開始、テストメソッド終了後にトランザクション終了が自動的に行われる。 + +--- + +## message_assertion + +アプリケーション例外に格納されたメッセージIDを検証する機能(ウェブアプリケーションのリクエスト単体テストで使用) + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `assertApplicationMessageId` | `assertApplicationMessageId(String expectedCommaSeparated, ExecutionContext actual)` | アプリケーション例外に格納されたメッセージが想定通りであることを確認する。 | + +**assertApplicationMessageId**: + +パラメータ: +- `expectedCommaSeparated` (String): 期待するメッセージID(複数ある場合はカンマ区切りで指定) +- `actual` (ExecutionContext): テスト実行時に使用したExecutionContext + +使い方: リクエスト単体テストで、アプリケーション例外が発生した場合のメッセージIDを確認する。 + +動作: +- 例外が発生しなかった場合や、アプリケーション例外以外の例外が発生した場合は、アサート失敗となる +- メッセージIDの比較はIDをソートした状態で行うので、テストデータを記載する際に順序を気にする必要はない + +--- + +## property_assertion + +オブジェクトのプロパティを期待値と比較する機能 + +| メソッド | シグネチャ | 説明 | +|----------|-----------|------| +| `assertObjectPropertyEquals` | `assertObjectPropertyEquals(String message, String sheetName, String id, Object actual)` | オブジェクトのプロパティの値がExcelファイルに記載したデータとなっていることを検証する。 | +| `assertObjectArrayPropertyEquals` | `assertObjectArrayPropertyEquals(String message, String sheetName, String id, Object[] actual)` | オブジェクト配列の各要素のプロパティの値がExcelファイルに記載したデータとなっていることを検証する。 | +| `assertObjectListPropertyEquals` | `assertObjectListPropertyEquals(String message, String sheetName, String id, List actual)` | オブジェクトリストの各要素のプロパティの値がExcelファイルに記載したデータとなっていることを検証する。 | + +**assertObjectPropertyEquals**: + +パラメータ: +- `message` (String): エラー時に表示するメッセージ +- `sheetName` (String): 期待値を記載したExcelシート名 +- `id` (String): 期待値のID(LIST_MAPのID) +- `actual` (Object): 検証対象のオブジェクト + +使い方: Formオブジェクト、Entityオブジェクトなどのプロパティを検証する。Excelには、2行目にプロパティ名、3行目以降にプロパティの期待値を記述する。 + +**assertObjectArrayPropertyEquals**: + +パラメータ: +- `message` (String): エラー時に表示するメッセージ +- `sheetName` (String): 期待値を記載したExcelシート名 +- `id` (String): 期待値のID(LIST_MAPのID) +- `actual` (Object[]): 検証対象のオブジェクト配列 + +使い方: 複数のオブジェクトを配列で受け取る場合に使用。Excelには、2行目にプロパティ名、3行目以降に各オブジェクトのプロパティの期待値を記述する。 + +**assertObjectListPropertyEquals**: + +パラメータ: +- `message` (String): エラー時に表示するメッセージ +- `sheetName` (String): 期待値を記載したExcelシート名 +- `id` (String): 期待値のID(LIST_MAPのID) +- `actual` (List): 検証対象のオブジェクトリスト + +使い方: 複数のオブジェクトをリストで受け取る場合に使用。Excelには、2行目にプロパティ名、3行目以降に各オブジェクトのプロパティの期待値を記述する。 + +**excel_format**: + +**description**: プロパティアサーション用のExcelデータ記述方法 + +**format**: LIST_MAP= +プロパティ名1 プロパティ名2 プロパティ名3 +期待値1 期待値2 期待値3 + +**example**: LIST_MAP=expectedUsers +kanjiName kanaName mailAddress +漢字氏名 カナシメイ test@anydomain.com + +**notes**: プロパティ名はJavaBeansの命名規則に従う。複数のオブジェクトを検証する場合は、3行目以降に複数行記述する。 + +--- + +## html_dump + +ウェブアプリケーションのリクエスト単体テストで、HTMLレスポンスをファイル出力する機能 + +**目的**: 画面レイアウトの確認、レビュー時の証跡として使用する。 + + +**output_directory**: + +**default**: ./tmp/html_dump + +**structure**: テストクラス毎に同名のディレクトリが作成され、そのテストクラスで実行されたテストケース説明と同名のHTMLダンプファイルが出力される + +**backup**: html_dumpディレクトリが既に存在する場合は、html_dump_bkという名前でバックアップされる + +**html_resources**: HTMLダンプファイルが参照するHTMLリソース(スタイルシートや画像などのリソース)についてもこのディレクトリに出力される + +**automatic_execution**: リクエスト単体テストを実行すると、内蔵サーバが起動されHTMLレスポンスが自動的にファイル出力される。 + +**configuration**: + +- **property**: htmlDumpDir +- **description**: HTMLダンプファイルを出力するディレクトリを指定する +- **default**: ./tmp/html_dump +- **property**: dumpFileExtension +- **description**: ダンプファイルの拡張子 +- **default**: html +- **property**: htmlResourcesExtensionList +- **description**: ダンプディレクトリへコピーされるHTMLリソースの拡張子 +- **default**: css, jpg, js +- **property**: htmlResourcesCharset +- **description**: CSSファイル(スタイルシート)の文字コード +- **default**: UTF-8 +- **property**: backup +- **description**: ダンプディレクトリのバックアップOn/Off +- **default**: true +- **property**: dumpVariableItem +- **description**: HTMLダンプファイル出力時に可変項目(JSESSIONID、2重サブミット防止用のトークン)を出力するか否かを設定する。前回実行結果と差異がないことを確認したい場合等は、falseに設定する。 +- **default**: false + +**notes**: 1リクエスト1画面遷移のシンクライアント型ウェブアプリケーションを対象としている。Ajaxやリッチクライアントを利用したアプリケーションの場合、HTMLダンプによるレイアウト確認は使用できない。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/tools/ntf-batch-request-test.md b/.claude/skills/nabledge-6/docs/features/tools/ntf-batch-request-test.md new file mode 100644 index 0000000..2bd6364 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/tools/ntf-batch-request-test.md @@ -0,0 +1,219 @@ +# NTFバッチリクエスト単体テスト + +実際にバッチをコマンドラインから起動したときの動作を擬似的に再現し、テストを行う。 + +**目的**: バッチアクションのリクエスト単体テストをサポートし、入力ファイル作成から出力ファイル検証まで自動化する。 + + +**test_target**: バッチ処理(Actionクラス) + +**related_files**: + +- ntf-overview.json +- ntf-test-data.json +- ntf-assertion.json + +**公式ドキュメント**: +- [NTFバッチリクエスト単体テスト](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/RequestUnitTest_batch.html) + +--- + +## test_class + +バッチリクエスト単体テストのテストクラスの作成方法 + +**junit5_approach**: + +**inheritance**: 継承不要(JUnit 5 Extension使用) + +**annotations**: + +- @ExtendWith(BatchRequestTestExtension.class) + +**required_field**: BatchRequestTestSupport support + +**example**: @ExtendWith(PromanBatchRequestExtension.class) +class ExportProjectsInPeriodActionRequestTest { + PromanBatchRequestTestSupport support; + + @Test + void testNormalEnd() { + support.execute(support.testName.getMethodName()); + } +} + +**notes**: JUnit 5のExtension機構を使用することで、継承なしでテスト機能を利用できる。supportフィールドはExtensionによって自動的に初期化される。 + +**junit4_approach**: + +**inheritance**: BatchRequestTestSupportを継承 + +**example**: public class SampleBatchRequestTest extends BatchRequestTestSupport { + @Test + public void testNormalEnd() { + execute("testNormalEnd"); + } +} + +**notes**: JUnit 4を使用する場合は、BatchRequestTestSupportクラスを継承する。 + +--- + +## test_support_classes + +バッチリクエスト単体テストで使用する主要なクラス + +**classes**: + +- {'name': 'StandaloneTestSupportTemplate', 'description': 'バッチやメッセージング処理などコンテナ外で動作する処理のテスト実行環境を提供する。', 'responsibilities': ['テストデータを読み取り、全テストショット(TestShot)を実行'], 'creation_unit': 'フレームワーク提供'} + +- {'name': 'TestShot', 'description': '1テストショットの情報保持とテストショットを実行する。', 'responsibilities': ['入力データの準備(データベースのセットアップ)', 'メインクラス起動', '出力結果の確認(データベース更新内容確認、ログ出力結果確認、ステータスコード確認)'], 'customization': '入力データ準備や結果確認ロジックはバッチや各種メッセージング処理ごとに異なるので方式に応じたカスタマイズが可能。', 'creation_unit': 'フレームワーク提供'} + +- {'name': 'BatchRequestTestSupport', 'description': 'バッチ処理テスト用のスーパクラス。TestShotが提供する準備処理、結果確認に入力ファイル作成と出力ファイル確認機能を追加する。', 'inheritance': 'アプリケーションプログラマは本クラスを継承してテストクラスを作成する(JUnit 4の場合)。JUnit 5の場合はExtensionとして使用。', 'additional_features': ['入力ファイルの作成', '出力ファイルの内容確認'], 'benefits': 'リクエスト単体テストのテストソース、テストデータを定型化でき、テストソース記述量を大きく削減できる。', 'creation_unit': 'フレームワーク提供'} + +- {'name': 'MainForRequestTesting', 'description': 'リクエスト単体テスト用のメインクラス。', 'differences_from_production': ['テスト用のコンポーネント設定ファイルからシステムリポジトリを初期化する', '常駐化機能を無効化する'], 'creation_unit': 'フレームワーク提供'} + +- {'name': 'FileSupport', 'description': 'ファイルに関する操作を提供するクラス。主に入力ファイル作成とファイル内容比較を提供。', 'responsibilities': ['テストデータから入力ファイルを作成する', 'テストデータの期待値と実際に出力されたファイルの内容を比較する'], 'notes': 'ファイルに関する操作は、バッチ処理以外でも必要となるため(例えば、ファイルダウンロード等)、独立したクラスとして提供している。', 'creation_unit': 'フレームワーク提供'} + +- {'name': 'DbAccessTestSupport', 'description': '準備データ投入などデータベースを使用するテストに必要な機能を提供する。', 'creation_unit': 'フレームワーク提供'} + + + +--- + +## test_execution + +バッチリクエスト単体テストの実行方法 + +**method**: + +**name**: execute + +**signature**: support.execute(testCaseName) + +**description**: テストケースを実行する。指定されたテストケース名に対応するExcelシートからテストデータを読み込み、TestShotを実行する。 + +**parameters**: + +- **name**: testCaseName +- **type**: String +- **description**: テストケース名(テストメソッド名と同名のExcelシート名) + +**return_type**: void + +**test_shot_flow**: + +- 1. Excelシートからテストデータを読み込み +- 2. データベースに準備データをセットアップ +- 3. 入力ファイルを作成(固定長・可変長) +- 4. MainForRequestTestingを使用してバッチを実行 +- 5. ステータスコードを確認 +- 6. データベースの更新内容を確認 +- 7. 出力ファイルの内容を確認 +- 8. ログ出力結果を確認 + +**naming_convention**: testXxx形式(Xxxはテストシナリオ)。Excelシート名はテストメソッド名と同名にする。 + +--- + +## resident_batch_config + +常駐バッチのテスト用ハンドラ構成 + +**reason**: 常駐バッチのテストを実施する際には、プロダクション用ハンドラ構成をテスト用に変更する必要がある。この変更をせずにテストを実施した場合、テスト対象の常駐バッチアプリケーションの処理が終わらないため、テストが正常に実施できなくなる。 + +**handler_changes**: + +- **production_handler**: RequestThreadLoopHandler +- **test_handler**: OneShotLoopHandler +- **change_reason**: RequestThreadLoopHandlerでテストを実施すると、バッチ実行が終わらずにテストコードに制御が戻らなくなるため。OneShotLoopHandlerにハンドラを差し替えることで、テスト実行前にセットアップした要求データを全件処理後にバッチ実行が終了しテストコードに制御が戻るようになる。 + +**configuration_example**: + +**production**: + + + +**test**: + +**notes**: プロダクション用設定と同名でコンポーネントを設定し、テスト用のハンドラを使用するように上書きする。 + +--- + +## directive_defaults + +ファイルのディレクティブのデフォルト値設定 + +**目的**: ファイルのディレクティブがシステム内である程度統一されている場合、個々のテストデータに同じディレクティブを記載することは冗長である。デフォルトのディレクティブをコンポーネント設定ファイルに記載することで、個々のテストデータではディレクティブの記述を省略できる。 + + +**configuration_names**: + +- **name**: defaultDirectives +- **target**: 共通ディレクティブ +- **description**: 固定長・可変長ファイル共通のデフォルト値 +- **name**: fixedLengthDirectives +- **target**: 固定長ファイル +- **description**: 固定長ファイル固有のデフォルト値 +- **name**: variableLengthDirectives +- **target**: 可変長ファイル +- **description**: 可変長ファイル固有のデフォルト値 + +**configuration_example**: + + + + + + + + + + + + +**common_directives**: + +- **key**: text-encoding +- **description**: ファイルの文字エンコーディング +- **example_value**: Windows-31J +- **key**: record-separator +- **description**: レコード区切り文字 +- **example_values**: NONE, CRLF, LF +- **key**: quoting-delimiter +- **description**: 引用符(可変長ファイルのみ) +- **example_value**: "" + +--- + +## file_data + +バッチ処理固有のテストデータ + +**fixed_length**: + +**description**: 固定長ファイルのテストデータ記述方法 + +**padding**: + +**description**: 指定したフィールド長に対して、データのバイト長が短い場合、そのフィールドのデータ型に応じたパディングが行われる。 + +**algorithm**: パディングのアルゴリズムはNablarch Application Framework本体と同様 + +**binary_data**: + +**description**: バイナリデータを表現するには、16進数形式でテストデータを記述する。 + +**format**: 0xプレフィックス付き16進数(例:0x4AD) + +**example**: 0x4ADと記述した場合、0000 0100 1010 1101(0x04AD)という2バイトのバイト配列に解釈される。 + +**notes**: プレフィックス0xが付与されていない場合、そのデータを文字列とみなし、その文字列をディレクティブの文字コードでエンコードしてバイト配列に変換する。 + +**variable_length**: + +**description**: 可変長ファイルのテストデータ記述方法 + +**reference**: batch_request_testを参照 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/tools/ntf-overview.md b/.claude/skills/nabledge-6/docs/features/tools/ntf-overview.md new file mode 100644 index 0000000..aae191e --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/tools/ntf-overview.md @@ -0,0 +1,127 @@ +# NTF(Nablarch Testing Framework)概要 + +Nablarchアプリケーションの自動テストを効率的に実施するためのフレームワーク。JUnit4をベースとし、テストデータの外部化とNablarch特有の機能をサポート。 + +**目的**: リクエスト単体テスト、DBテスト、クラス単体テストを効率的に実施し、テストの可読性と保守性を向上させる。 + + +**related_files**: + +- ntf-batch-request-test.json +- ntf-test-data.json +- ntf-assertion.json + +**公式ドキュメント**: +- [NTF(Nablarch Testing Framework)概要](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/01_Abstract.html) + +--- + +## features + +NTFが提供する主要な特徴 + +**機能**: + +- {'name': 'JUnit4ベース', 'description': 'JUnit4をベースとしており、各種アノテーション、assertメソッド、Matcherクラスなど、JUnit4で提供されている機能を使用できる。', 'notes': 'JUnit 5上でも動作可能(JUnit Vintageを使用)'} + +- {'name': 'テストデータの外部化', 'description': 'テストデータをExcelファイルに記述でき、データベース準備データや期待するテスト結果などを記載したExcelファイルをAPIを通じて使用できる。', 'benefits': ['可読性の向上', '編集の容易さ', 'テストとロジックの分離']} + +- {'name': 'Nablarchに特化したテスト補助機能', 'description': 'トランザクション制御やシステム日付設定など、Nablarchアプリケーションに特化したAPIを提供する。', 'examples': ['トランザクション制御', 'システム日付固定', 'ThreadContext設定']} + + + +--- + +## architecture + +自動テストフレームワークの構成要素 + +**コンポーネント**: + +- **テストクラス**: テスト処理を記述する。DbAccessTestSupportやHttpRequestTestSupportなどのスーパークラスを継承する。 + - creator: アプリケーションプログラマ + - creation_unit: テスト対象クラスにつき1つ作成 +- **Excelファイル**: テストデータを記載する。自動テストフレームワークを使用することにより、データを読み取ることができる。 + - creator: アプリケーションプログラマ + - creation_unit: テストクラスにつき1つ作成 + - supported_formats: Excel2003形式(.xls), Excel2007以降形式(.xlsx) +- **テスト対象クラス**: テスト対象となるクラス(Action以降の業務ロジックを実装する各クラスを含む) + - creator: アプリケーションプログラマ +- **コンポーネント設定ファイル・環境設定ファイル**: テスト実行時の各種設定を記載する。 + - creator: アプリケーションプログラマ(個別のテストに固有の設定が必要な場合) +- **自動テストフレームワーク**: テストに必要な機能を提供する。DbAccessTestSupport、HttpRequestTestSupport、BatchRequestTestSupport等が含まれる。 +- **Nablarch Application Framework**: フレームワーク本体(本機能の対象外) + +--- + +## test_method + +テストメソッドの記述方法 + +**example**: + +```java +public class SampleTest { + @Test + public void testSomething() { + // テスト処理 + } +} +``` + +**annotation**: @Test + +**framework**: JUnit4 + +**notes**: @Beforeや@Afterなどのアノテーションも使用できる。これらを用いて、テストメソッド前後にリソースの取得解放などの共通処理を行うことが可能。 + +--- + +## junit5_support + +JUnit 5で自動テストフレームワークを動かす方法 + +**依存関係**: + +- `org.junit.jupiter:junit-jupiter` (scope: test) - JUnit 5のコアライブラリ +- `org.junit.vintage:junit-vintage-engine` (scope: test) - JUnit 4テストをJUnit 5上で実行するためのエンジン + +**mechanism**: JUnit Vintage + +**mechanism_description**: JUnit 5の上でJUnit 4で書かれたテストを実行できるようにするための機能。この機能を利用することで、自動テストフレームワークをJUnit 5の上で動かすことができる。 + +**important_notes**: この機能は、あくまでJUnit 4のテストをJUnit 4として動かしているにすぎない。したがって、JUnit 4のテストの中でJUnit 5の機能が使えるわけではない。JUnit 4からJUnit 5への移行を段階的進めるための補助として利用できる。 + +**prerequisites**: + +- **item**: maven-surefire-plugin +- **version**: 2.22.0以上 + +**configuration_example**: + + + org.junit + junit-bom + 5.8.2 + pom + import + + + + + + + org.junit.jupiter + junit-jupiter + test + + + org.junit.vintage + junit-vintage-engine + test + + + +**related_info**: JUnit 5のテストで自動テストフレームワークを使用する方法については、ntf_junit5_extensionを参照。 + +--- diff --git a/.claude/skills/nabledge-6/docs/features/tools/ntf-test-data.md b/.claude/skills/nabledge-6/docs/features/tools/ntf-test-data.md new file mode 100644 index 0000000..c2d5425 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/features/tools/ntf-test-data.md @@ -0,0 +1,399 @@ +# NTFテストデータ + +データベースの準備データやデータベース検索結果などのデータを表すには、Javaソースコードよりスプレッドシートのほうが可読性や編集のしやすさという点で有利である。Excelファイルを使用することにより、このようなデータをスプレッドシート形式で扱うことができる。 + +**supported_formats**: + +- Excel2003形式(.xls) +- Excel2007以降形式(.xlsx) + +**location**: src/test/java配下(デフォルト)。テストソースコードと同じディレクトリに配置することを推奨。 + +**benefits**: + +- 可読性の向上 +- 編集の容易さ +- テストケースの把握が容易 +- テストデータとテストロジックの役割分担が明確 + +**公式ドキュメント**: +- [NTFテストデータ](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/01_Abstract.html#excel) +- [NTFテストデータ](https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_DbAccessTest.html) + +--- + +## naming_conventions + +Excelファイル名、ファイルパスには推奨される規約が存在する。この規約に従うことにより、テストクラスで明示的にディレクトリ名やファイル名を指定してファイルを読み込む必要がなくなり、簡潔にテストソースコードを記述できる。 + +**file_conventions**: + +- **rule**: Excelファイル名は、テストソースコードと同じ名前にする(拡張子のみ異なる) +- **example**: + **test_class**: ExampleDbAccessTest.java + + **excel_file**: ExampleDbAccessTest.xlsx + +- **rule**: Excelファイルを、テストソースコードと同じディレクトリに配置する +- **example**: + **directory**: /test/jp/co/tis/example/db/ + + **files**: + + - ExampleDbAccessTest.java + - ExampleDbAccessTest.xlsx + + +**sheet_conventions**: + +- **rule**: 1テストメソッドにつき1シート用意する +- **notes**: この規約は制約事項ではない。テストメソッド名とExcelシート名が同名でなくても正しく動作する。 +- **rule**: シート名はテストメソッド名と同名にする +- **example**: + **test_method**: @Test public void testInsert() + + **sheet_name**: testInsert + +- **recommendation**: 今後の機能追加は上記規約をデフォルトとして開発されるので、命名規約に準拠することを推奨する。仮に命名規約を変更する場合であってもプロジェクト内で統一を図ること。 + +--- + +## data_types + +シート内には、データベースに格納するデータやデータベース検索結果など、さまざまな種類のデータを記載できる。テストデータの種類を判別するために「データタイプ」というメタ情報をテストデータに付与する必要がある。 + +**format**: データタイプ=値 + +**types**: + +- 項目 1: + **name**: SETUP_TABLE + + **description**: テスト実行前にデータベースに登録するデータ + + **value**: 登録対象のテーブル名 + + **format**: 1行目:SETUP_TABLE=<テーブル名>、2行目:カラム名、3行目以降:登録するレコード + + **example**: SETUP_TABLE=EMPLOYEE +ID EMP_NAME DEPT_CODE +00001 山田太郎 0001 +00002 田中一郎 0002 + +- 項目 2: + **name**: EXPECTED_TABLE + + **description**: テスト実行後の期待するデータベースのデータ。省略したカラムは、比較対象外となる。 + + **value**: 確認対象のテーブル名 + + **format**: 1行目:EXPECTED_TABLE=<テーブル名>、2行目:カラム名、3行目以降:期待する値 + + **notes**: 省略されたカラムは比較対象外となる。主キーカラムは省略できない。 + +- 項目 3: + **name**: EXPECTED_COMPLETE_TABLE + + **description**: テスト実行後の期待するデータベースのデータ。省略したカラムにはデフォルト値が設定されているものとして扱われる。 + + **value**: 確認対象のテーブル名 + + **format**: 1行目:EXPECTED_COMPLETE_TABLE=<テーブル名>、2行目:カラム名、3行目以降:期待する値 + + **notes**: EXPECTED_TABLEとの違い:省略されたカラムはデフォルト値が格納されているものとして比較が行われる。更新系テストで「無関係なカラムが更新されていないことを確認する」という観点で使用する。 + +- 項目 4: + **name**: LIST_MAP + + **description**: List>形式のデータ + + **value**: シート内で一意になるID(期待値のID、任意の文字列) + + **format**: 1行目:LIST_MAP=、2行目:Mapのキー、3行目以降:Mapの値 + + **usage**: 入力パラメータ、メソッドの戻り値に対する期待値などを記載する + +- **name**: SETUP_FIXED +- **description**: 事前準備用の固定長ファイル +- **value**: 準備ファイルの配置場所 +- **name**: EXPECTED_FIXED +- **description**: 期待値を示す固定長ファイル +- **value**: 比較対象ファイルの配置場所 +- **name**: SETUP_VARIABLE +- **description**: 事前準備用の可変長ファイル +- **value**: 準備ファイルの配置場所 +- **name**: EXPECTED_VARIABLE +- **description**: 期待値を示す可変長ファイル +- **value**: 比較対象ファイルの配置場所 +- **name**: MESSAGE +- **description**: メッセージング処理のテストで使用するデータ +- **value**: 固定値(setUpMessages または expectedMessages) +- **name**: EXPECTED_REQUEST_HEADER_MESSAGES +- **description**: 要求電文(ヘッダ)の期待値を示す固定長ファイル +- **value**: リクエストID +- **name**: EXPECTED_REQUEST_BODY_MESSAGES +- **description**: 要求電文(本文)の期待値を示す固定長ファイル +- **value**: リクエストID +- **name**: RESPONSE_HEADER_MESSAGES +- **description**: 応答電文(ヘッダ)を示す固定長ファイル +- **value**: リクエストID +- **name**: RESPONSE_BODY_MESSAGES +- **description**: 応答電文(本文)を示す固定長ファイル +- **value**: リクエストID + +**notes**: データの個数も複数記述できる。複数のデータタイプを使用する場合、使用するデータタイプごとにまとめてデータを記述すること。 + +--- + +## special_notation + +自動テストの利便性を向上させるために、いくつかの特殊記法を提供する。 + +**notations**: + +- 項目 1: + **notation**: null(大文字小文字の区別なし) + + **value**: null + + **description**: セル内に「null」と記述されている場合は、null値として扱う。データベースにnull値を登録したい場合や、期待値でnull値を設定したい場合に使用する。 + + **examples**: + + - null + - Null + - NULL + +- 項目 2: + **notation**: "null"(ダブルクォートで囲む) + + **value**: 文字列のnull + + **description**: 文字列の前後がダブルクォート(半角、全角問わず)で囲われている場合は、前後のダブルクォートを取り除いた文字列を扱う。「null」や「NULL」を文字列として扱う必要がある場合に使用。 + + **examples**: + + - "null" + - "NULL" + - "1 " + - " " + + **notes**: 本記述方法を利用した場合であっても、文字列中のダブルクォートをエスケープする必要はない。 + +- 項目 3: + **notation**: ""(空のダブルクォート) + + **value**: 空文字列 + + **description**: 空文字列を表す。空行を表現する場合にも使用可能。 + + **usage**: 可変長ファイルで空行を含めたい場合、行のうちのいずれか1セルに""を記載する。 + +- 項目 4: + **notation**: ${systemTime} + + **value**: システム日時(Timestamp) + + **description**: システム日時を記載したい場合に使用する。コンポーネント設定ファイルにて設定されたSystemTimeProvider実装クラスから取得したTimestampの文字列形式に変換される。 + + **format**: yyyy-MM-dd HH:mm:ss.fffffffff(例:2011-04-11 01:23:45.0) + +- **notation**: ${updateTime} +- **value**: システム日時(Timestamp) +- **description**: ${systemTime}の別名。特にデータベースのタイムスタンプ更新時の期待値として使用する。 +- **notation**: ${setUpTime} +- **value**: コンポーネント設定ファイルに記載された固定値 +- **description**: データベースセットアップ時のタイムスタンプに、決まった値を使用したい場合に使用する。 +- 項目 7: + **notation**: ${文字種,文字数} + + **value**: 指定した文字種を指定した文字数分まで増幅した値 + + **description**: 文字種と文字数を指定して、テストデータを生成する。 + + **available_types**: + + - 半角英字 + - 半角数字 + - 半角記号 + - 半角カナ + - 全角英字 + - 全角数字 + - 全角ひらがな + - 全角カタカナ + - 全角漢字 + - 全角記号その他 + - 外字 + + **examples**: + + - **notation**: ${半角英字,5} + - **result**: geDSfe(半角英字5文字に変換) + - **notation**: ${全角ひらがな,4} + - **result**: ぱさぇん(全角ひらがな4文字に変換) + - **notation**: ${半角数字,2}-${半角数字,4} + - **result**: 37-3425(-以外が変換) + - **notation**: ${全角漢字,4}123 + - **result**: 山川海森123(末尾123以外が変換) + + **notes**: 本記法は単独でも使用可能であるし、組み合わせても使用できる。 + +- **notation**: ${binaryFile:ファイルパス} +- **value**: BLOB列に格納するバイナリデータ +- **description**: BLOB列にファイルのデータを格納したい場合に使用する。ファイルパスはExcelファイルからの相対パスで記述する。 +- **notation**: \r +- **value**: CR(改行コード0x0D) +- **description**: 改行コードを明示的に記述する場合に使用する。 +- **notation**: \n +- **value**: LF(改行コード0x0A) +- **description**: 改行コードを明示的に記述する場合に使用する。Excelセル内の改行(Alt+Enter)もLFとして扱われる。 + +--- + +## cell_format + +セルの書式とExcelシートの記述に関する規約 + +**cell_format_rule**: + +**description**: セルの書式には、文字列のみを使用する。テストデータを作成する前に、全てのセルの書式を文字列に設定しておくこと。 + +**important**: Excelファイルに文字列以外の書式でデータを記述した場合、正しくデータが読み取れなくなる。 + +**formatting**: 罫線やセルの色付けについては任意に設定可能である。罫線やセルの色付けを行うことでデータが見やすくなり、レビュー品質や保守性の向上が期待できる。 + +**date_format**: + +**description**: 日付の記述形式 + +**supported_formats**: + +- **format**: yyyyMMddHHmmssSSS +- **example**: 20210123123456789 +- **result**: 2021年1月23日 12時34分56秒789 +- **format**: yyyy-MM-dd HH:mm:ss.SSS +- **example**: 2021-01-23 12:34:56.789 +- **result**: 2021年1月23日 12時34分56秒789 + +**omission_rules**: + +- **omission**: ミリ秒を省略(yyyyMMddHHmmss または yyyy-MM-dd HH:mm:ss) +- **behavior**: ミリ秒として0を指定したものとして扱われる +- **example**: 20210123123456 → 2021年1月23日 12時34分56秒000 +- **omission**: 時刻全部を省略(yyyyMMdd または yyyy-MM-dd) +- **behavior**: 時刻として0時0分0秒000を指定したものとして扱われる +- **example**: 20210123 → 2021年1月23日 00時00分00秒000 + +**comment**: + +**description**: セル内に"//"から開始する文字列を記載した場合、そのセルから右のセルは全て読み込み対象外となる。テストデータ自体には含めたくないが、可読性を向上させるために付加情報を記載したい場合には、コメント機能が使用できる。 + +**usage**: 可読性を向上させるために、テーブルの論理名や期待する結果についてコメントを付与する。 + +**marker_column**: + +**description**: 実際のデータには含めたくないがExcelシート上には記述しておきたい場合に使用する。カラム名が半角角括弧で囲まれている場合、そのカラムは「マーカーカラム」とみなされ、テスト実行時には読み込まれない。 + +**format**: [カラム名] + +**example**: LIST_MAP=EXAMPLE_MARKER_COLUMN +[no] id name +1 U0001 山田 +2 U0002 田中 + +**notes**: 全くの空行は無視されるため、それ以外のデータタイプでも同様に使用できる。左端のセルに[no]のようなマーカーカラムを記載することで、連番を振ることができる。 + +--- + +## column_omission + +データベースの準備データおよび期待値を記述する際、テストに関係の無いカラムについては記述を省略できる。省略したカラムには、自動テストフレームワークによりデフォルト値が設定される。この機能を使用することにより、テストデータの可読性が向上する。また、テーブル定義が変更された場合でも、関係無いカラムであればテストデータ修正作業は発生しなくなる為、保守性が向上する。 + +**setup_data_omission**: + +**description**: データベース準備データを記述する際にカラムを省略すると、省略されたカラムにはデフォルト値が設定されているものとして扱われる。 + +**important**: 主キーカラムは省略できない。 + +**usage**: 多くのカラムのうち一部のカラムだけを設定する場合、不要なカラムを省略できる。 + +**expected_data_omission**: + +**description**: DB期待値から単純に無関係なカラムを省略すると、省略されたカラムは比較対象外となる。 + +**expected_table**: + +**name**: EXPECTED_TABLE + +**behavior**: 省略されたカラムは比較対象外となる + +**usage**: 検索系テストで、検索対象カラムのみを確認する場合 + +**expected_complete_table**: + +**name**: EXPECTED_COMPLETE_TABLE + +**behavior**: 省略されたカラムにはデフォルト値が格納されているものとして比較が行われる + +**usage**: 更新系テストで「無関係なカラムが更新されていないことを確認する」という観点が必要な場合 + +**important**: データベース検索結果の期待値を記述する際は、検索対象カラム全てを記述しなければならない(レコードの主キーだけを確認する、というような確認方法は不可)。また、登録系テストの場合も、新規に登録されたレコードの全カラムを確認する必要があるので、カラムを省略できない。 + +**default_values**: + +**description**: 自動テストフレームワークのコンポーネント設定ファイルにて明示的に指定していない場合、デフォルト値には以下の値が使用される。 + +**values**: + +- **column_type**: 数値型 +- **default_value**: 0 +- **column_type**: 文字列型 +- **default_value**: 半角スペース +- **column_type**: 日付型 +- **default_value**: 1970-01-01 00:00:00.0 + +**customization**: + +**class**: nablarch.test.core.db.BasicDefaultValues + +**properties**: + +- 項目 1: + **name**: charValue + + **description**: 文字列型のデフォルト値 + + **value_type**: 1文字のASCII文字 + + **example**: a + +- 項目 2: + **name**: numberValue + + **description**: 数値型のデフォルト値 + + **value_type**: 0または正の整数 + + **example**: 1 + +- 項目 3: + **name**: dateValue + + **description**: 日付型のデフォルト値 + + **value_type**: JDBCタイムスタンプエスケープ形式(yyyy-mm-dd hh:mm:ss.fffffffff) + + **example**: 2000-01-01 12:34:56.123456789 + + +**configuration_example**: + + + + + + + + + +--- diff --git a/.claude/skills/nabledge-6/docs/overview.md b/.claude/skills/nabledge-6/docs/overview.md new file mode 100644 index 0000000..1cee89f --- /dev/null +++ b/.claude/skills/nabledge-6/docs/overview.md @@ -0,0 +1,279 @@ +# Nablarch概要 + +**公式ドキュメント**: +- [Nablarch概要](https://fintan.jp/page/1868/4/) +- [Nablarch概要](https://nablarch.github.io/docs/LATEST/doc/) +- [Nablarch概要](https://nablarch.github.io/docs/LATEST/doc/about_nablarch/versionup_policy.html) +- [Nablarch概要](https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/nablarch/architecture.html) +- [Nablarch概要](https://nablarch.github.io/docs/LATEST/doc/migration/index.html) +- [Nablarch概要](https://nablarch.github.io/docs/LATEST/doc/releases/index.html) + +--- + +## identity + +Nablarchは、TISの豊富な基幹システム構築経験から得られたナレッジを集約したJavaアプリケーション開発/実行基盤です。 + +**provider**: TIS株式会社 + +**license**: Apache License 2.0 + +**repository**: https://github.com/nablarch + +**characteristics**: + +- 金融・決済等のミッションクリティカルシステムでの豊富な導入実績 +- 包括的なドキュメント(フレームワーク、開発ガイド、開発標準、ツール) +- 長期的な安定性と信頼性の重視 +- アクティブなセキュリティ更新とメンテナンス +- 複数の実行環境をサポート(ウェブ、ウェブサービス、バッチ、メッセージング) + +--- + +## versioning + +**scheme**: メジャー.アップデート形式(例: 6u3)。プロダクトバージョン番号はマイナーバージョンアップ時にインクリメント、アップデート番号はリビジョンアップまたはバグフィックス時にインクリメントされる。 + +**current**: + +**version**: 6u3 + +**release_date**: 2025年3月27日 + +**note**: Nablarch 6の最新アップデートリリース。Jakarta EE 10対応、Java 17以上が必要。 + +**active_versions**: + +- 項目 1: + **version**: 6u3 + + **status**: 最新 + + **java**: 17以上 + + **ee**: Jakarta EE 10 + + **maintenance**: アクティブ + +- 項目 2: + **version**: 5u26 + + **release_date**: 2025年5月16日 + + **status**: メンテナンス中 + + **java**: 8以上(Java 11使用時は追加設定必要) + + **ee**: Java EE 7/8 + + **maintenance**: セキュリティパッチと不具合対応 + + +--- + +## requirements + +**nablarch6**: + +**java**: Java 17以上 + +**java_note**: Nablarch 6のモジュールはJava 17でコンパイルされているため、動作にはJava 17以上が必要 + +**ee**: Jakarta EE 10 + +**build_tool**: Maven 3.x以降 + +**namespace**: 名前空間がjavax.*からjakarta.*に変更 + +**nablarch5**: + +**java**: Java 8以上 + +**java_note**: Java 11以上で使用する場合は追加設定が必要(詳細は移行ガイド参照) + +**ee**: Java EE 7/8 + +**build_tool**: Maven + +--- + +## compatibility + +**policy**: フレームワークのバージョンアップは、公開APIに対して後方互換性を維持します。基本的にバージョンの差し替えと設定ファイルの変更のみでバージョンアップ可能です。 + +**public_api**: + +**definition**: @Publishedアノテーションが付与されたAPIが公開API + +**scope**: 公開APIのみ後方互換性を保証。非公開APIは後方互換性が維持されないバージョンアップを行う場合があるため、プロジェクトでは非公開APIを使用しないこと + +**compatibility_scope**: フレームワーク(アプリケーションフレームワークとテスティングフレームワーク)のみが対象。ドキュメント、開発標準、ツールは後方互換性維持の対象外 + +**exceptions**: + +- フレームワークが出力するログのレベル・文言に対する変更 +- 後方互換を維持したまま修正できない不具合への対応 +- JDKバージョンアップに起因する問題で後方互換を維持できない場合 +- セキュリティ対応 + +**upgrade_process**: 使用するNablarchのバージョンの差し替えと設定ファイルの変更が基本。後方互換性が維持されない変更の場合はリリースノートに内容と移行方法を明記 + +--- + +## environment + +Java実行環境があれば動作可能で、OS依存なし。 + +**app_servers**: + +**nablarch6**: + +- Jetty 12 +- Jakarta EE 10対応APサーバ + +**nablarch5**: + +- Tomcat 8 +- Jetty 6/9 +- Java EE 7/8対応APサーバ + +**databases**: + +**embedded**: H2 Database(開発・テスト用) + +**supported**: JDBCドライバが提供されるRDBMS全般 + +**verified**: + +- Oracle Database +- PostgreSQL +- Microsoft SQL Server +- IBM DB2 + +**os**: Java実行環境があればOSを問わず動作(Windows、Linux、macOS等で動作確認済み) + +--- + +## architecture + +**overview**: Nablarchアプリケーションフレームワークは、ハンドラキュー、インターセプタ、ライブラリの3つの主要構成要素から成ります。 + +**handler_queue**: + +**description**: リクエストやレスポンスに対する横断的な処理を行うハンドラ群を、予め定められた順序に沿って定義したキュー。サーブレットフィルタのチェーン実行と同様の方式で処理を実行 + +**responsibility**: リクエストのフィルタリング(アクセス権限制御等)、リクエスト・レスポンスの変換、リソースの取得・解放(データベース接続等) + +**interceptor**: + +**description**: 実行時に動的にハンドラキューに追加されるハンドラ。Jakarta EEのJakarta Contexts and Dependency Injectionで定義されているインターセプタと同じように処理を実行 + +**use_case**: 特定のリクエストの場合のみ処理を追加する場合や、リクエストごとに設定値を切り替えて処理を実行したい場合に適している + +**library**: + +**description**: データベースアクセス、ファイルアクセス、ログ出力など、ハンドラから呼び出されるコンポーネント群 + +**examples**: + +- UniversalDao(データベースアクセス) +- データバインド +- ファイルアクセス +- ログ出力 + +**configuration**: コンポーネント設定はXMLファイルで行い、システムリポジトリで管理される + +--- + +## processing-types + +**type**: ウェブアプリケーション + +**description**: Nablarchアプリケーションフレームワークを使用してウェブアプリケーションを開発するためのフレームワーク + +**use_case**: 画面を持つエンドユーザー向けのウェブシステム開発 + +**type**: RESTfulウェブサービス + +**description**: Jakarta RESTful Web Servicesで規定されているアノテーションを使用して容易にRESTfulウェブサービスを構築できるフレームワーク + +**use_case**: 外部システム連携、API提供、マイクロサービスアーキテクチャでのサービス間通信 + +**type**: Nablarchバッチ(都度起動) + +**description**: 日次や月次など、定期的にプロセスを起動してバッチ処理を実行する方式 + +**use_case**: 定期的なデータ処理、集計処理、レポート生成 + +**type**: Nablarchバッチ(常駐/テーブルキュー) + +**description**: プロセスを起動しておき、一定間隔でバッチ処理を実行する方式。ただし新規開発ではdb_messagingの使用を推奨 + +**use_case**: オンライン処理で作成された要求データを定期的に一括処理する場合(既存システムでの使用を想定) + +**type**: Jakarta Batch + +**description**: Jakarta Batch(旧JSR352)に準拠したバッチアプリケーションフレームワーク。情報が少なく有識者のアサインが難しいため、新規開発ではNablarchバッチの使用を推奨 + +**use_case**: Jakarta Batch標準への準拠が必要な場合、既存Jakarta Batch資産の活用 + +**type**: メッセージング + +**description**: MOM(Message Oriented Middleware)ベースとDBキューベースの2種類のメッセージングフレームワークを提供 + +**use_case**: 非同期処理、システム間の疎結合な連携、負荷分散された処理 + + +--- + +## ecosystem + +**official_contents**: + +- 項目 1: + **name**: Nablarch解説書 + + **url**: https://nablarch.github.io/docs/LATEST/doc/ + + **description**: Nablarchアプリケーションフレームワークの機能や使い方を詳細に解説した技術ドキュメント + + **target**: 開発者向け + +- 項目 2: + **name**: Nablarchシステム開発ガイド + + **url**: https://fintan.jp/page/252/ + + **description**: Nablarchを使ってシステムを開発するエンジニアに対して、開発開始前・開発中にすべきこと、参照すべきものを示すガイド + + **target**: プロジェクト全体向け + +- 項目 3: + **name**: 開発標準 + + **url**: https://fintan.jp/page/1868/#development-standards + + **description**: システム開発における成果物作成時に従うべきガイドライン。設計標準、設計書フォーマット・サンプルを含む + + **target**: プロジェクト全体向け + +- 項目 4: + **name**: 開発ツール + + **url**: https://nablarch.github.io/docs/LATEST/doc/development_tools/index.html + + **description**: 効率的なJava静的チェック、テスティングフレームワーク、アプリケーション開発時に使える便利なツール群 + + **target**: 開発者向け + +- 項目 5: + **name**: トレーニングコンテンツ + + **url**: https://fintan.jp/page/1868/ + + **description**: Nablarchの学習に役立つトレーニング資料や教育コンテンツ + + **target**: 学習者向け + + +--- diff --git a/.claude/skills/nabledge-6/docs/releases/6u3.md b/.claude/skills/nabledge-6/docs/releases/6u3.md new file mode 100644 index 0000000..8dbf306 --- /dev/null +++ b/.claude/skills/nabledge-6/docs/releases/6u3.md @@ -0,0 +1,482 @@ +# リリースノート 6u3 + +Nablarch 6u3のリリースノート。6u2からの変更点を記載 + +**主な変更点**: +- OpenAPI対応に伴うRESTful Webサービスの機能強化(親クラス・インタフェースでのリソース定義対応) +- EntityResponseに型パラメータ追加 +- マルチパートリクエスト用のBodyConverter追加 +- BeanUtilのDate and Time APIサポート拡充(OffsetDateTime追加) +- JSON読み取り不具合の修正(JSON区切り文字のみの値の解析) + +**公式ドキュメント**: +- [リリースノート 6u3](https://nablarch.github.io/docs/6u3/doc/releases/nablarch6u3-releasenote.xlsx) + +--- + +| No | カテゴリ | 種別 | タイトル | 影響 | +|----|----------|------|----------|------| +| 1 | RESTfulウェブサービス | 変更 | 親クラス・インタフェースでのリソース定義に対応 +(No.24.OpenAPI対応に伴う変更) | なし | +| 2 | RESTfulウェブサービス | 変更 | EntityResponseの型パラメータ追加 +(No.24.OpenAPI対応に伴う変更) | あり(開発) | +| 3 | BeanUtil | 変更 | Date and Time APIサポート拡充 +(No.24.OpenAPI対応に伴う変更) | なし | +| 4 | RESTfulウェブサービス | 変更 | マルチパート用のBodyConverter追加 +(No.24.OpenAPI対応に伴う変更) | なし | +| 5 | BeanUtil | 変更 | MapからBeanへ移送するメソッドのパフォーマンス改善 | なし | +| 6 | 汎用データフォーマット | 不具合 | JSONの読み取りに失敗する問題を修正 | あり(本番) | +| 7 | Bean Validation | 変更 | BeanValidationStrategyのバリデーション処理をカスタマイズできるように修正 | なし | +| 8 | 公開API | 変更 | 公開APIの追加 | なし | +| 9 | Nablarchバッチアプリケーション | 変更 | ResumeDataReaderのJavadoc改善 | なし | +| 10 | サロゲートキーの採番 | 変更 | TableIdGeneratorのJavadoc改善 | なし | +| 11 | 汎用ユーティリティ | 変更 | Base64UtilのJavadoc・解説書改善 | なし | +| 12 | 公開API | 変更 | PublishedアノテーションのJavadoc改善 | なし | +| 13 | コンポーネントの初期化 | 変更 | 初期化が必要なコンポーネントに対する説明の改善 | なし | +| 14 | RESTfulウェブサービス | 変更 | マルチパートリクエストのサポート | なし | +| 15 | ウェブアプリケーション +RESTfulウェブサービス | 変更 | Tomcatベースイメージの更新 | なし | +| 16 | 全般 | 変更 | gsp-dba-maven-pluginのバージョン更新 | なし | +| 17 | 全般 | 変更 | 使用不許可APIツールのバージョン更新 | なし | +| 18 | Jakarta RESTful Web Servicesアダプタ | 変更 | Date and Time APIのサポート +(No.24.OpenAPI対応に伴う変更) | なし | +| 19 | Jakarta RESTful Web Servicesアダプタ | 変更 | マルチパートリクエストのサポート +(No.24.OpenAPI対応に伴う変更) | あり | +| 20 | ウェブアプリケーション (JSP) | 変更 | jQuery、Bootstrapのバージョンアップ | なし | +| 21 | RESTfulウェブサービス | 変更 | マルチパートリクエストのサポート +(No.24.OpenAPI対応に伴う変更) | なし | +| 22 | 全般 | 変更 | gsp-dba-maven-pluginのバージョン更新 | なし | +| 23 | 検索結果の一覧表示 | 変更 | タグファイルのスタイル適用設定修正 | なし | +| 24 | Nablarch OpenAPI Generator | 追加 | Nablarch OpenAPI Generatorのリリース | なし | +| 25 | SQL Executor | 変更 | 解説書の手順と実際のモジュールの構成差異を修正 | なし | +| 26 | 使用不許可APIチェックツール | 不具合 | Java21でjava.lang.Objectのメソッドが許可できない場合がある問題に対応 | なし | + +### 1. 親クラス・インタフェースでのリソース定義に対応 +(No.24.OpenAPI対応に伴う変更) + +OpenAPIドキュメントから生成したインタフェースを使用してアクションクラスを実装できるように、インターフェースや親クラスでのリソース定義を引き継ぐように対応しました。 + +@PathなどのJakarta RESTful Web Servicesのアノテーションを使ってアクションクラスを実装している場合に、以下の条件でアクションクラスが実装しているインターフェースや親クラスのリソース定義を引き継ぎます。 + ・アクションクラスが親クラスを継承またはインターフェースを実装している + ・親クラスまたはインターフェースに@Pathアノテーションが注釈されている + ・親クラスまたはインターフェースにHTTPメソッドが定義されている + +また、本対応にはルーティングアダプタも修正する必要があったため、合わせて対応しました。 + +**モジュール**: nablarch-fw-jaxrs 2.2.0 +nablarch-router-adaptor 2.2.0 + +**JIRA**: NAB-618 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html + +--- + +### 2. EntityResponseの型パラメータ追加 +(No.24.OpenAPI対応に伴う変更) + +OpenAPIドキュメントとのマッピングに対応するため、EntityResponseに型パラメータを追加しました。 +これにより、どのようなエンティティの型をレスポンスとしているかをより明確に表現できるようになりました。 + +**モジュール**: nablarch-fw-jaxrs 2.2.0 + +**影響詳細**: すでにEntityResponseを使用している個所については型を指定していない状態になるため、コンパイル時に以下のメッセージが出力されるようになります。また、設定によってはIDEで同様の警告が出力されるようになります。 + +[INFO] (該当クラス)の操作は、未チェックまたは安全ではありません。 + +解消しなくても動作に影響はありませんが、EntityResponseを使用している個所で明示的に型を指定すると、メッセージおよび警告は解消されます。 + + +**JIRA**: NAB-619 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html + +--- + +### 3. Date and Time APIサポート拡充 +(No.24.OpenAPI対応に伴う変更) + +OpenAPIドキュメントとのマッピングに対応するため、Date and Time APIのサポートを拡充し、OffsetDateTimeのサポートを追加しました。 + + +**モジュール**: nablarch-core-beans 2.3.0 + +**JIRA**: NAB-620 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/bean_util.html + +--- + +### 4. マルチパート用のBodyConverter追加 +(No.24.OpenAPI対応に伴う変更) + +OpenAPIドキュメントとのマッピングに対応するため、Content-Typeがmultipart/form-dataのリクエストに対応するBodyConverterを追加しました。 + + +**モジュール**: nablarch-fw-jaxrs 2.2.0 + +**JIRA**: NAB-621 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html + +--- + +### 5. MapからBeanへ移送するメソッドのパフォーマンス改善 + +MapからBeanへ移送する際、ネストしたオブジェクト数が多い場合に処理が遅くなる事象が発生していたので、修正しました。 + + +**モジュール**: nablarch-core-beans 2.3.0 + +**JIRA**: NAB-634 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/bean_util.html + +--- + +### 6. JSONの読み取りに失敗する問題を修正 + +JSON内に含まれる値(""で囲われた項目)がJSON構文で意味を持つ区切り文字(:、[、{、, の4つ)のみで、かつその後にデータが続く場合、値とJSON構文の区切り文字の区別ができずに失敗していました。 + +①NGになる例(":"の後にデータが続く): + {"key1": ":", "key2": "value2"} + +②OKになる例(":"の後にデータが続かない): + {"key1": ":"} + +NGになっていた例も、正常に値として解析できるように修正しました。 + + +**モジュール**: nablarch-core-dataformat 2.0.3 + +**影響バージョン**: 1.3.1 + +**影響詳細**: 概要の①のようにJSONの区切り文字のみが値になるデータを解析できるようになります。 +本来は値として解析できることが正しい挙動であるため影響が無い想定ですが、もしこのようなJSONを読み込めるようになることでシステム影響がある場合、値の確認をして受け入れないようにするなどの修正を行ってください。 + +**JIRA**: NAB-639 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/data_io/data_format.html + +--- + +### 7. BeanValidationStrategyのバリデーション処理をカスタマイズできるように修正 + +BeanValidationStrategyをカスタマイズしやすくなるよう、公開APIを見直しました。 +それに伴い、バリデーションエラーのメッセージをソートするsortMessagesメソッドをオーバーライド可能にするため、static修飾子を除去しました。 + + +**モジュール**: nablarch-fw-web 2.3.0 + +**JIRA**: NAB-640 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/validation/bean_validation.html + +--- + +### 8. 公開APIの追加 + +解説書で継承を案内しているAPIの中で公開APIになっていないものがあったため、公開APIを追加しました。 + + +**モジュール**: nablarch-common-dao 2.3.0 +nablarch-common-databind 2.1.0 + +**JIRA**: NAB-641 + +--- + +### 9. ResumeDataReaderのJavadoc改善 + +ResumeDataReaderが内部的に使用するResumePointManagerは初期化が必要ですが、 +この点をResumeDataReaderに関する説明から読み取りづらかったため、ResumeDataReaderのJavadocに追記しました。 + + +**モジュール**: nablarch-fw-batch 2.0.1 + +**JIRA**: NAB-629 + +**参照**: https://nablarch.github.io/docs/6u3/javadoc/nablarch/fw/reader/ResumeDataReader.html + +--- + +### 10. TableIdGeneratorのJavadoc改善 + +採番の際に独立したトランザクションを用いるFastTableIdGeneratorは初期化が必要ですが、Javadoc上でそれがわからなかったため、その旨を追記しました。 +また類似のコンポーネントであるTableIdGeneratorのJavadocにも、記述を合わせるため同様の更新を行っています。 + + +**モジュール**: nablarch-common-idgenerator-jdbc 2.0.1 + +**JIRA**: NAB-629 + +**参照**: https://nablarch.github.io/docs/6u3/javadoc/nablarch/common/idgenerator/FastTableIdGenerator.html + + +--- + +### 11. Base64UtilのJavadoc・解説書改善 + +Base64UtilはRFC4648の「4. Base 64 Encoding」に準拠していますが、Javadoc上で明記できていなかったため、その旨を追記しました。 + +また、Java8以降ではBase64エンコーディングを行う標準APIが提供されており、Base64Utilを使用せずとも同様の処理を行えます。 +Base64Utilを使用する必要性が小さくなったため、Javadocで標準APIを案内し、Base64Utilは後方互換性のための位置付けとしました。 +そのため、Base64Utilは後方互換のために存在していることを解説書に追記しました。 +※現在Base64Utilを使用している個所を標準APIに置換する必要はありません。 + + +**モジュール**: nablarch-core-2.2.1 + +**JIRA**: NAB-626 + +**参照**: https://nablarch.github.io/docs/6u3/javadoc/nablarch/core/util/Base64Util.html + +--- + +### 12. PublishedアノテーションのJavadoc改善 + +PublishedアノテーションのJavadocで、オーバーライド可能なメソッドは公開APIとしていることについて追記しました。 + +**モジュール**: nablarch-core-2.2.1 + +**JIRA**: NAB-640 + +**参照**: https://nablarch.github.io/docs/6u3/javadoc/nablarch/core/util/annotation/Published.html + +--- + +### 13. 初期化が必要なコンポーネントに対する説明の改善 + +コンポーネントとして使用することを想定して提供しているクラスのうち、初期化が必要であるにも関わらず解説書への記載がないものがあったので、初期化が必要な旨や設定例を追記しました。 + +・Nablarchが提供するライブラリ + ・コード管理 + ・サロゲートキーの採番 + ・日付管理 + ・メール送信 + ・サービス提供可否チェック +・Nablarchの提供する標準ハンドラ + ・プロセス停止制御ハンドラ +・アダプタ + ・IBM MQアダプタ + + +**モジュール**: nablarch-document 6u3 + +**JIRA**: NAB-629 + +--- + +### 14. マルチパートリクエストのサポート + +No.4およびNo.19で対応したマルチパートリクエストのサポートを取り込み、マルチパートリクエストに対応しました。 + + +**モジュール**: nablarch-single-module-archetype 6u3 + +**JIRA**: NAB-621 + +--- + +### 15. Tomcatベースイメージの更新 + +10.1.33以前のApache Tomcatに脆弱性が検出されたため、ブランクプロジェクトのデフォルトのTomcatのベースイメージを以下に更新しました。 + + tomcat:10.1.34-jdk17-temurin + + +**モジュール**: nablarch-single-module-archetype 6u3 + +**JIRA**: NAB-627 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWeb.html + +--- + +### 16. gsp-dba-maven-pluginのバージョン更新 + +以下のMavenプラグインを記載のバージョンに更新しました。 +・gsp-dba-maven-plugin:5.2.0 + + +**モジュール**: nablarch-single-module-archetype 6u3 + +**JIRA**: NAB-636 + +--- + +### 17. 使用不許可APIツールのバージョン更新 + +No.26の対応に伴い、使用不許可APIツールのバージョンを以下に更新しました。 +・nablarch-unpublished-api-checker 1.0.1 + + +**モジュール**: nablarch-single-module-archetype 6u3 + +**JIRA**: NAB-630 + +--- + +### 18. Date and Time APIのサポート +(No.24.OpenAPI対応に伴う変更) + +OpenAPIドキュメントとのマッピングに対応するため、Jackson Java 8 Date/timeモジュールを追加してDate and Time APIを扱えるようになりました。 + +※JaxRsHandlerListFactory を独自に実装している場合、バージョンアップだけでは本機能は使用できません。本機能を使用したい場合は、nablarch-jersey-adaptorおよびnablarch-resteasy-adaptorの実装を参考にしてください。 + + +**モジュール**: nablarch-jaxrs-adaptor 2.2.0 +nablarch-jersey-adaptor 2.2.0 +nablarch-resteasy-adaptor 2.2.0 +nablarch-jackson-adaptor 2.2.0 + +**JIRA**: NAB-620 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/adaptors/jaxrs_adaptor.html + +--- + +### 19. マルチパートリクエストのサポート +(No.24.OpenAPI対応に伴う変更) + +No.4で追加したマルチパート用のBodyConverterをnablarch-jersey-adaptorおよびnablarch-resteasy-adaptorに追加しました。 + + + + +**モジュール**: nablarch-jaxrs-adaptor 2.2.0 +nablarch-jersey-adaptor 2.2.0 +nablarch-resteasy-adaptor 2.2.0 +nablarch-jackson-adaptor 2.2.0 + +**影響詳細**: 6u2以前からのバージョンアップで本機能を使用する場合は、設定変更が必要になります。詳しくは「マルチパートリクエストのサポート対応」シートを参照してください。 + +**JIRA**: NAB-621 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/adaptors/jaxrs_adaptor.html + +--- + +### 20. jQuery、Bootstrapのバージョンアップ + +jQueryおよびjQeuryに依存していたライブラリのバージョンを以下の通り更新しました。 +・jQuery 3.7.1 +・jQuery UI 1.14 +・Bootstrap 5.3.3 +また、Bootstrapのバージョンアップに伴ってMaterial Design for Bootstrapの使用を廃止し、画面デザインを調整しました。 + + +**モジュール**: nablarch-example-web 6u3 + +**影響バージョン**: - + +**JIRA**: NAB-616 + +**参照**: https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web/index.html + +--- + +### 21. マルチパートリクエストのサポート +(No.24.OpenAPI対応に伴う変更) + +No.4およびNo.19で対応したnablarch-fw-jaxrsおよびnablarch-jaxrs-adaptorの変更内容を取り込み、マルチパートリクエストに対応しました。 + + +**モジュール**: nablarch-example-rest 6u3 + +**JIRA**: NAB-621 + +--- + +### 22. gsp-dba-maven-pluginのバージョン更新 + +以下のMavenプラグインを記載のバージョンに更新しました。 +・gsp-dba-maven-plugin:5.2.0 + + +**モジュール**: nablarch-example-web 6u3 +nablarch-example-thymeleaf-web 6u3 +nablarch-example-rest 6u3 +nablarch-example-batch 6u3 +nablarch-example-batch-ee 6u3 +nablarch-example-http-messaging 6u3 +nablarch-example-http-messaging-send 6u3 +nablarch-example-db-queue 6u3 +nablarch-example-mom-delayed-receive 6u3 +nablarch-example-mom-delayed-send 6u3 +nablarch-example-mom-sync-receive 6u3 +nablarch-example-mom-sync-send-batch 6u3 + +**JIRA**: NAB-636 + +--- + +### 23. タグファイルのスタイル適用設定修正 + +ページングの現在表示中のページ番号部分に対して、カスタムタグで指定したスタイルが適用されていなかったため、表示中かどうかに関わらず設定したCSSが適用されるように修正しました。 + + +**モジュール**: nablarch-biz-sample-all 3.1.0 + +**影響バージョン**: - + +**JIRA**: NAB-616 + +**参照**: https://nablarch.github.io/docs/6u3/doc/biz_samples/03/index.html + +--- + +### 24. Nablarch OpenAPI Generatorのリリース + +OpenAPIドキュメントからアプリケーションのコード生成をサポートするツールである Nablarch OpenAPI Generator をリリースしました。 + + +**モジュール**: nablarch-openapi-generator 1.0.0 + +**影響バージョン**: - + +**JIRA**: NAB-624 + +**参照**: https://nablarch.github.io/docs/6u3/doc/development_tools/toolbox/NablarchOpenApiGenerator/NablarchOpenApiGenerator.html + +--- + +### 25. 解説書の手順と実際のモジュールの構成差異を修正 + +ツールの提供状態として設定すべき項目に不足があり、また解説書で案内している設定ファイル名と実際のファイル名に乖離がありました。 +このため解説書どおりに実行しても起動できないという問題が発生しており、解説書記載の手順で実行できるように設定ファイルの見直しを行いました。 + + +**モジュール**: sql-executor 1.3.1 + +**影響バージョン**: - + +**JIRA**: NAB-637 + +**参照**: https://nablarch.github.io/docs/6u3/doc/development_tools/toolbox/SqlExecutor/SqlExecutor.html + +--- + +### 26. Java21でjava.lang.Objectのメソッドが許可できない場合がある問題に対応 + +Java21でバイトコードが変わったことにより、インタフェースからjava.lang.Objectのメソッドを呼んでいる場合、設定ファイルで指定しても許可されないという不具合があったため対応しました。 + +例) +■使用不許可APIツールの設定ファイル +java.lang.Object + +■解析対象のjavaファイル +// toStringメソッドは本来許可されるはずだが不許可になる +Map headers = request.headers(); +headers.toString(); + + +**モジュール**: nablarch-unpublished-api-checker 1.0.1 + +**影響バージョン**: 1.0.0 + +**JIRA**: NAB-630 + +**参照**: https://nablarch.github.io/docs/LATEST/doc/development_tools/java_static_analysis/index.html#id6 + +--- diff --git a/.claude/skills/nabledge-6/knowledge/checks/security.json b/.claude/skills/nabledge-6/knowledge/checks/security.json new file mode 100644 index 0000000..de91f56 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/checks/security.json @@ -0,0 +1,476 @@ +{ + "id": "security", + "title": "セキュリティチェック項目", + "official_doc_urls": [ + "システム開発ガイド/設計書/Nablarch機能のセキュリティ対応表.xlsx" + ], + "index": [ + { + "id": "overview", + "hints": [ + "セキュリティ", + "脆弱性", + "IPA", + "チェック" + ] + }, + { + "id": "check_items", + "hints": [ + "チェック項目", + "セキュリティチェック", + "SQLインジェクション", + "OSコマンドインジェクション", + "パストラバーサル", + "セッション管理", + "XSS", + "CSRF", + "HTTPヘッダインジェクション", + "メールヘッダインジェクション", + "クリックジャッキング" + ] + } + ], + "sections": { + "overview": { + "description": "IPAで公開されている脆弱性の種類ごとにNablarchでの対応状況を記載", + "source": "IPA 安全なウェブサイトの作り方", + "nablarch_support": "Nablarchで対応できないものについては、プロジェクトで個別に対応を検討。根本的解決となっているものについては必ず対応すること" + }, + "check_items": [ + { + "id": 1, + "category": "SQLインジェクション", + "explanation": "Nablarchはデータベースアクセス機能として、簡易的なO/Rマッパーを実現するユニバーサルDAOと、JDBCを使いやすくしたJDBCラッパーを提供しています。どちらの機能でもSQL文を外部ファイルに記述し、PreparedStatement を使用したSQL実行の仕組みを提供しており、SQLインジェクションの脆弱性を排除できます。\nまた、使用不許可APIの使用を検出するツールも提供しており、このツールでチェックすることでNablarchの提供するデータベースアクセス以外の方式を検出することが可能です。\n\n上記に加え、HTTPエラー制御ハンドラを使用することでエラーメッセージやスタックトレースがユーザに表示されることを防ぎ、より強固なアプリケーションとすることが可能です。", + "items": [ + { + "type": "根本的解決", + "description": "SQL文の組み立ては全てプレースホルダで実装する。", + "nablarch_feature": "データベースアクセス(JDBCラッパー)\nユニバーサルDAO", + "nablarch_support": "〇", + "reference": "1-(i)-a", + "explanation": "Nablarchはデータベースアクセス機能として、簡易的なO/Rマッパーを実現するユニバーサルDAOと、JDBCを使いやすくしたJDBCラッパーを提供しています。どちらの機能でもSQL文を外部ファイルに記述し、PreparedStatement を使用したSQL実行の仕組みを提供しており、SQLインジェクションの脆弱性を排除できます。\nまた、使用不許可APIの使用を検出するツールも提供しており、このツールでチェックすることでNablarchの提供するデータベースアクセス以外の方式を検出することが可能です。\n\n上記に加え、HTTPエラー制御ハンドラを使用することでエラーメッセージやスタックトレースがユーザに表示されることを防ぎ、より強固なアプリケーションとすることが可能です。" + }, + { + "type": "", + "description": "SQL文の構成を文字列連結により行う場合は、アプリケーションの変数をSQL文のリテラルとして正しく構成する。", + "nablarch_feature": "データベースアクセス(JDBCラッパー)\nユニバーサルDAO", + "nablarch_support": "〇", + "reference": "1-(i)-b" + }, + { + "type": "根本的解決", + "description": "ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない。", + "nablarch_feature": "データベースアクセス(JDBCラッパー)\nユニバーサルDAO", + "nablarch_support": "〇", + "reference": "1-(ii)" + }, + { + "type": "保険的対策", + "description": "エラーメッセージをそのままブラウザに表示しない。", + "nablarch_feature": "HTTPエラー制御ハンドラ", + "nablarch_support": "〇", + "reference": "1-(iii)" + }, + { + "type": "保険的対策", + "description": "データベースアカウントに適切な権限を与える。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "1-(iv)" + } + ] + }, + { + "id": 2, + "category": "OSコマンド・インジェクション", + "explanation": "使用不許可APIの使用を検出するツールを提供しています。このツールでチェックすることでRuntimeなどOSコマンドを実行する機能の使用箇所を検出することができます。\nシステムとして一律OSコマンドの使用を禁止する場合は上記の対応で根本的解決が見込めます。\nシステム要件としてOSコマンドの使用が必要な場合には右記の保険的対策をプロジェクトの方式として取り入れるようにしてください。", + "items": [ + { + "type": "根本的解決", + "description": "シェルを起動できる言語機能の利用を避ける。", + "nablarch_feature": "許可していないAPIが使用されていないかチェックする", + "nablarch_support": "〇", + "reference": "2-(i)", + "explanation": "使用不許可APIの使用を検出するツールを提供しています。このツールでチェックすることでRuntimeなどOSコマンドを実行する機能の使用箇所を検出することができます。\nシステムとして一律OSコマンドの使用を禁止する場合は上記の対応で根本的解決が見込めます。\nシステム要件としてOSコマンドの使用が必要な場合には右記の保険的対策をプロジェクトの方式として取り入れるようにしてください。" + }, + { + "type": "保険的対策", + "description": "シェルを起動できる言語機能を利用する場合は、その引数を構成する全ての変数に対してチェックを行い、あらかじめ許可した処理のみを実行する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "2-(ii)" + } + ] + }, + { + "id": 3, + "category": "パス名パラメータの未チェック/ディレクトリ・トラバーサル", + "explanation": "Nablarchではファイルパス管理機能を提供しています。サーバ内のファイルへのアクセスにこの機能を使用することで、アクセス対象のベースディレクトリを指定することができます。これにより公開するディレクトリが限定されます。同時に、特定の拡張子のファイルのみにアクセスさせることがきます。\nファイル名をユーザに入力させる場合、上記に組み合わせて、入力値チェックで \".\"などの文字を許容しないことでディレクトリトラバーサルを防ぐことが可能となります。", + "items": [ + { + "type": "根本的解決", + "description": "外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。", + "nablarch_feature": "ファイルパス管理", + "nablarch_support": "〇", + "reference": "3-(i)-a", + "explanation": "Nablarchではファイルパス管理機能を提供しています。サーバ内のファイルへのアクセスにこの機能を使用することで、アクセス対象のベースディレクトリを指定することができます。これにより公開するディレクトリが限定されます。同時に、特定の拡張子のファイルのみにアクセスさせることがきます。\nファイル名をユーザに入力させる場合、上記に組み合わせて、入力値チェックで \".\"などの文字を許容しないことでディレクトリトラバーサルを防ぐことが可能となります。" + }, + { + "type": "", + "description": "ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする。", + "nablarch_feature": "ファイルパス管理", + "nablarch_support": "〇", + "reference": "3-(i)-b" + }, + { + "type": "保険的対策", + "description": "ウェブサーバ内のファイルへのアクセス権限の設定を正しく管理する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "3-(ii)" + }, + { + "type": "保険的対策", + "description": "ファイル名のチェックを行う。", + "nablarch_feature": "入力値のチェック", + "nablarch_support": "〇", + "reference": "3-(iii)" + } + ] + }, + { + "id": 4, + "category": "セッション管理の不備", + "explanation": "NablarchはHTTPセッションを抽象化したものとしてセッションストア機能を提供しています。\nセッションストアでは以下の機能を提供しており、セッション管理の脆弱性について根本的解決が見込めます。\n ・ セッションを追跡するためセッションIDをCookieに格納します。\n ・ セッションIDには推測困難なUUIDを使用しています。\n ・ セッションストアのデフォルト設定では、HTTPヘッダーのSet-Cookieにsecure属性を設定していません。\n   HTTPSを利用する際は設定でsecure属性を指定してください。\n ・ セッション作成ごとにセッションID採番を行っています。\n ・ セッションストアのデフォルト設定では、CookieにMaxAge属性を設定しません。\n   そのため、Cookieの有効期限はブラウザが閉じるまでとなります。\n\n4-(iv)についてはNablarchのExampleで提供している、ログイン処理の実装例を参考に、ログイン成功後に新しくセッションを開始するようプロジェクトで対応してください。\n\n", + "items": [ + { + "type": "根本的解決", + "description": "セッションIDを推測が困難なものにする。", + "nablarch_feature": "セッションストア", + "nablarch_support": "〇", + "reference": "4-(i)", + "explanation": "NablarchはHTTPセッションを抽象化したものとしてセッションストア機能を提供しています。\nセッションストアでは以下の機能を提供しており、セッション管理の脆弱性について根本的解決が見込めます。\n ・ セッションを追跡するためセッションIDをCookieに格納します。\n ・ セッションIDには推測困難なUUIDを使用しています。\n ・ セッションストアのデフォルト設定では、HTTPヘッダーのSet-Cookieにsecure属性を設定していません。\n   HTTPSを利用する際は設定でsecure属性を指定してください。\n ・ セッション作成ごとにセッションID採番を行っています。\n ・ セッションストアのデフォルト設定では、CookieにMaxAge属性を設定しません。\n   そのため、Cookieの有効期限はブラウザが閉じるまでとなります。\n\n4-(iv)についてはNablarchのExampleで提供している、ログイン処理の実装例を参考に、ログイン成功後に新しくセッションを開始するようプロジェクトで対応してください。\n\n" + }, + { + "type": "根本的解決", + "description": "セッションIDをURLパラメータに格納しない。", + "nablarch_feature": "セッションストア", + "nablarch_support": "〇", + "reference": "4-(ii)" + }, + { + "type": "根本的解決", + "description": "HTTPS通信で利用するCookieにはsecure属性を加える。", + "nablarch_feature": "セッションストア", + "nablarch_support": "〇", + "reference": "4-(iii)" + }, + { + "type": "根本的解決", + "description": "ログイン成功後に、新しくセッションを開始する。", + "nablarch_feature": "Nablarch Example", + "nablarch_support": "△", + "reference": "4-(iv)-a" + }, + { + "type": "", + "description": "ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する。", + "nablarch_feature": "4-(iv)-a の対策を実施する", + "nablarch_support": "", + "reference": "4-(iv)-b" + }, + { + "type": "保険的対策", + "description": "セッションIDを固定値にしない。", + "nablarch_feature": "セッションストア", + "nablarch_support": "〇", + "reference": "4-(v)" + }, + { + "type": "保険的対策", + "description": "セッションIDをCookieにセットする場合、有効期限の設定に注意する。", + "nablarch_feature": "セッションストア", + "nablarch_support": "〇", + "reference": "4-(vi)" + } + ] + }, + { + "id": 5, + "category": "クロスサイト・スクリプティング", + "explanation": "Nablarchのカスタムタグはサニタイジングを行います。これによりNablarchのカスタムタグを使った場合には5-(i)の根本的解決が可能です。\nまた、NablarchはJSPで使用を許可する構文とタグを規定し、許可する構文とタグのみを使用していることをチェックするJSP静的解析ツールを提供しています。このツールを使用することでカスタムタグ以外のタグを使用したことによるエスケープ漏れを防止することが可能です。\n\nhttps://nablarch.github.io/docs/LATEST/doc/development_tools/toolbox/JspStaticAnalysis/01_JspStaticAnalysis.html\n\n5-(ii)~(iv)の対策についてはプロジェクトで対応してください。", + "items": [ + { + "type": "根本的解決", + "description": "ウェブページに出力する全ての要素に対して、エスケープ処理を施す。", + "nablarch_feature": "カスタムタグ", + "nablarch_support": "〇", + "reference": "5-(i)", + "explanation": "Nablarchのカスタムタグはサニタイジングを行います。これによりNablarchのカスタムタグを使った場合には5-(i)の根本的解決が可能です。\nまた、NablarchはJSPで使用を許可する構文とタグを規定し、許可する構文とタグのみを使用していることをチェックするJSP静的解析ツールを提供しています。このツールを使用することでカスタムタグ以外のタグを使用したことによるエスケープ漏れを防止することが可能です。\n\nhttps://nablarch.github.io/docs/LATEST/doc/development_tools/toolbox/JspStaticAnalysis/01_JspStaticAnalysis.html\n\n5-(ii)~(iv)の対策についてはプロジェクトで対応してください。" + }, + { + "type": "根本的解決", + "description": "URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(ii)" + }, + { + "type": "根本的解決", + "description": " 要素の内容を動的に生成しない。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(iii)" + }, + { + "type": "根本的解決", + "description": "スタイルシートを任意のサイトから取り込めるようにしない。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(iv)" + }, + { + "type": "保険的対策", + "description": "入力値の内容チェックを行う。", + "nablarch_feature": "入力値のチェック", + "nablarch_support": "〇", + "reference": "5-(v)" + }, + { + "type": "根本的解決", + "description": "入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(vi)", + "explanation": "以下のような方法での対応を検討してください。\n\n・OSSのHTMLパーサを使用して入力された値をパースし、使用できないHTMLタグが含まれていないかをバリデーションする\n・簡易的な装飾であれば、利用者にはMarkdownで入力してもらい、 OSSのJavaScriptライブラリを使用してクライアントサイドでMarkdownからHTMLに変換する" + }, + { + "type": "保険的対策", + "description": "入力されたHTMLテキストから、スクリプトに該当する文字列を排除する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(vii)" + }, + { + "type": "根本的解決", + "description": "HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)の指定を行う。", + "nablarch_feature": "HTTP文字エンコード制御ハンドラ", + "nablarch_support": "〇", + "reference": "5-(viii)", + "explanation": "NablarchはHTTPレスポンスのHTTPヘッダのContent-TypeにMIME Type・文字コードを設定しています。これにより特定のブラウザで発生し得る 5-(i) の対策を回避したクロスサイト・スクリプティングを防ぐことができます。\nまた、Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、ユーザがクロスサイト・スクリプティングの脆弱性対策を無効にしていた場合でもサーバからブラウザの機能を有効にするよう指示することが可能です。" + }, + { + "type": "保険的対策", + "description": "Cookie情報の漏えい対策として、発行するCookieにHttpOnly属性を加え、TRACEメソッドを無効化する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "5-(ix)" + }, + { + "type": "保険的対策", + "description": "クロスサイト・スクリプティングの潜在的な脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す。", + "nablarch_feature": "セキュアハンドラ", + "nablarch_support": "〇", + "reference": "5-(x)" + } + ] + }, + { + "id": 6, + "category": "CSRF\n(クロスサイト・リクエスト・フォージェリ)", + "explanation": "CSRF対策として、NablarchのCSRF対策機能を使用できます。この機能は一意なトークンを発行し、サーバサイドでチェックすることで不正な画面遷移を防ぎます。\n\nNablarchのHttpSessionを使用した二重サブミット防止機能を使用した場合も、CSRF対策機能と同じ効果が得られCSRF対策として機能します。CSRF対策機能はハンドラを追加するだけで漏れなくチェックできるのに対し、二重サブミット防止機能はアプリケーションプログラマが明示的に実装する必要があり、CSRF対策が洩れる可能性があります。そのため、CSRF対策にはCSRF対策機能の使用を推奨します。\n\nデータベースを使用した二重サブミット防止機能はCSRF対策に対応していません。データベースを使用した二重サブミット防止機能を使用する場合はCSRF対策機能を使用してください。\n", + "items": [ + { + "type": "根本的解決", + "description": "処理を実行するページを POST メソッドでアクセスするようにし、その「hidden パラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する。", + "nablarch_feature": "CSRF対策", + "nablarch_support": "〇", + "reference": "6-(i)-a", + "explanation": "CSRF対策として、NablarchのCSRF対策機能を使用できます。この機能は一意なトークンを発行し、サーバサイドでチェックすることで不正な画面遷移を防ぎます。\n\nNablarchのHttpSessionを使用した二重サブミット防止機能を使用した場合も、CSRF対策機能と同じ効果が得られCSRF対策として機能します。CSRF対策機能はハンドラを追加するだけで漏れなくチェックできるのに対し、二重サブミット防止機能はアプリケーションプログラマが明示的に実装する必要があり、CSRF対策が洩れる可能性があります。そのため、CSRF対策にはCSRF対策機能の使用を推奨します。\n\nデータベースを使用した二重サブミット防止機能はCSRF対策に対応していません。データベースを使用した二重サブミット防止機能を使用する場合はCSRF対策機能を使用してください。\n" + }, + { + "type": "", + "description": "処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。", + "nablarch_feature": "6-(i)-a の対策を実施する", + "nablarch_support": "", + "reference": "6-(i)-b" + }, + { + "type": "", + "description": "Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する。", + "nablarch_feature": "6-(i)-a の対策を実施する", + "nablarch_support": "", + "reference": "6-(i)-c" + }, + { + "type": "保険的対策", + "description": "重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "6-(ii)" + } + ] + }, + { + "id": 7, + "category": "HTTPヘッダ・インジェクション", + "explanation": "Nablarchでのヘッダ出力はHttpServletResponseのAPIを使用しているため、Nablarchを使用する場合はヘッダにおける改行の扱いをAPIに移譲することでHTTPヘッダ・インジェクションの対策が可能です。", + "items": [ + { + "type": "根本的解決", + "description": "ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する。", + "nablarch_feature": "Nablarchで提供する機能全般", + "nablarch_support": "〇", + "reference": "7-(i)-a", + "explanation": "Nablarchでのヘッダ出力はHttpServletResponseのAPIを使用しているため、Nablarchを使用する場合はヘッダにおける改行の扱いをAPIに移譲することでHTTPヘッダ・インジェクションの対策が可能です。" + }, + { + "type": "", + "description": "改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないよう、開発者自身で適切な処理を実装する。", + "nablarch_feature": "7-(i)-a の対策を実施する", + "nablarch_support": "", + "reference": "7-(i)-b" + }, + { + "type": "保険的対策", + "description": "外部からの入力の全てについて、改行コードを削除する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "7-(ii)" + } + ] + }, + { + "id": 8, + "category": "メールヘッダ・インジェクション", + "explanation": "Nablarchはメール送信機能を提供しており、メールヘッダインジェクション攻撃への対策をガイドしています。\n ・メールヘッダは固定値を使用する。外部からの入力値を使用しない。\n ・プログラミング言語の標準APIを使用してメール送信を行う。Javaの場合は JavaMail APIを使用する。\n\n8-(ii)についてはプロジェクトで対応してください。", + "items": [ + { + "type": "根本的解決", + "description": "メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する。", + "nablarch_feature": "メール送信", + "nablarch_support": "△", + "reference": "8-(i)-a", + "explanation": "Nablarchはメール送信機能を提供しており、メールヘッダインジェクション攻撃への対策をガイドしています。\n ・メールヘッダは固定値を使用する。外部からの入力値を使用しない。\n ・プログラミング言語の標準APIを使用してメール送信を行う。Javaの場合は JavaMail APIを使用する。\n\n8-(ii)についてはプロジェクトで対応してください。" + }, + { + "type": "", + "description": "ウェブアプリケーションの実行環境や言語に用意されているメール送信用APIを使用する(8-(i) を採用できない場合)。", + "nablarch_feature": "メール送信", + "nablarch_support": "△", + "reference": "8-(i)-b" + }, + { + "type": "根本的解決", + "description": "HTMLで宛先を指定しない。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "8-(ii)" + }, + { + "type": "保険的対策", + "description": "外部からの入力の全てについて、改行コードを削除する。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "8-(iii)" + } + ] + }, + { + "id": 9, + "category": "クリックジャッキング", + "explanation": "Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、デフォルトで X-Frame-Options: SAMEORIGIN が出力されるため、クリックジャッキング対策が可能です。", + "items": [ + { + "type": "根本的解決", + "description": "HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する。", + "nablarch_feature": "セキュアハンドラ", + "nablarch_support": "〇", + "reference": "9-(i)-a", + "explanation": "Nablarchはセキュリティ関連のヘッダをレスポンスオブジェクトに設定するセキュアハンドラを提供しています。このハンドラにより、デフォルトで X-Frame-Options: SAMEORIGIN が出力されるため、クリックジャッキング対策が可能です。" + }, + { + "type": "", + "description": "処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。", + "nablarch_feature": "9-(i)-a の対策を実施する", + "nablarch_support": "", + "reference": "9-(i)-b" + }, + { + "type": "保険的対策", + "description": "重要な処理は、一連の操作をマウスのみで実行できないようにする。", + "nablarch_feature": "-", + "nablarch_support": "×", + "reference": "9-(ii)" + } + ] + }, + { + "id": 10, + "category": "バッファオーバーフロー", + "explanation": "NablarchはJavaで記述されているため、言語レベルでバッファオーバーフローの脆弱性はありません。", + "items": [ + { + "type": "根本的解決", + "description": "直接メモリにアクセスできない言語で記述する。", + "nablarch_feature": "Nablarchで提供する機能全般", + "nablarch_support": "〇", + "reference": "10-(i)-a", + "explanation": "NablarchはJavaで記述されているため、言語レベルでバッファオーバーフローの脆弱性はありません。" + }, + { + "type": "", + "description": "直接メモリにアクセスできる言語で記述する部分を最小限にする。", + "nablarch_feature": "Nablarchで提供する機能全般", + "nablarch_support": "〇", + "reference": "10-(i)-b" + }, + { + "type": "根本的解決", + "description": "脆弱性が修正されたバージョンのライブラリを使用する。", + "nablarch_feature": "Nablarchで提供する機能全般", + "nablarch_support": "〇", + "reference": "10-(ii)" + } + ] + }, + { + "id": 11, + "category": "アクセス制御や認可制御の欠落", + "explanation": "Nablarchは認証チェックを行う機能を提供していません。NablarchのExampleとして提供している実装例を参考に認証機能を実装してください。\nNablarchは認可チェック機能を提供しています。この機能は、細かく権限を設定できる反面、非常に細かいデータ設計が必要となり、 開発時の生産性低下やリリース後の運用負荷が高まる可能性があります。プロジェクトでは、システム要件に適合する場合に使用してください。", + "items": [ + { + "type": "根本的解決", + "description": "アクセス制御機能による防御措置が必要とされるウェブサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける。", + "nablarch_feature": "Nablarch Example", + "nablarch_support": "△", + "reference": "11-(i)", + "explanation": "Nablarchは認証チェックを行う機能を提供していません。NablarchのExampleとして提供している実装例を参考に認証機能を実装してください。\nNablarchは認可チェック機能を提供しています。この機能は、細かく権限を設定できる反面、非常に細かいデータ設計が必要となり、 開発時の生産性低下やリリース後の運用負荷が高まる可能性があります。プロジェクトでは、システム要件に適合する場合に使用してください。" + }, + { + "type": "根本的解決", + "description": "認証機能に加えて認可制御の処理を実装し、ログイン中の利用者が他人になりすましてアクセスできないようにする。", + "nablarch_feature": "認可チェック", + "nablarch_support": "〇", + "reference": "11-(ii)" + } + ] + } + ], + "tips": [ + { + "title": "チェック項目の実施方法", + "description": "※印のチェック項目は、実施項目のいずれかを実施すればよい(全てを実施する必要はない)" + }, + { + "title": "保険的対策の判断", + "description": "保険的対策については、システム要件に合わせて対応要否を判断すること。根本的解決が基本だが、実現困難な場合の補完として検討" + }, + { + "title": "根本的解決の優先", + "description": "根本的解決となっている対策は必ず実施すること。脆弱性の原因そのものを排除する対策であり、セキュリティの基本" + } + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/adapters/slf4j-adapter.json b/.claude/skills/nabledge-6/knowledge/features/adapters/slf4j-adapter.json new file mode 100644 index 0000000..f202624 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/adapters/slf4j-adapter.json @@ -0,0 +1,92 @@ +{ + "id": "slf4j-adapter", + "title": "SLF4Jアダプタ", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/adaptors/slf4j_adaptor.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "SLF4J", + "ログアダプタ", + "slf4j-nablarch-adaptor", + "OSSログ" + ] + }, + { + "id": "setup", + "hints": [ + "依存関係", + "Maven", + "pom.xml", + "slf4j-nablarch-adaptor" + ] + }, + { + "id": "usage", + "hints": [ + "使い方", + "自動検出", + "runtime" + ] + }, + { + "id": "notes", + "hints": [ + "バージョン", + "SLF4J 2.0", + "StaticLoggerBinder", + "注意事項" + ] + } + ], + "sections": { + "overview": { + "description": "SLF4J経由でNablarchのログ出力機能を使用するためのアダプタ", + "purpose": "SLF4Jを使用するOSSライブラリのログをNablarchのログ出力機能で統一管理", + "external_library": { + "name": "SLF4J", + "version": "2.0.11 (テスト済み)", + "url": "https://www.slf4j.org/" + }, + "nablarch_version": "6u1以降" + }, + "setup": { + "dependencies": [ + { + "groupId": "com.nablarch.integration", + "artifactId": "slf4j-nablarch-adaptor", + "scope": "runtime" + } + ], + "maven_example": "\n com.nablarch.integration\n slf4j-nablarch-adaptor\n runtime\n", + "gradle_example": "runtimeOnly 'com.nablarch.integration:slf4j-nablarch-adaptor'" + }, + "configuration": { + "description": "依存関係を追加するだけで使用可能(追加設定不要)", + "required_settings": [], + "log_output": "Nablarchのログ設定(log.properties)に従う" + }, + "usage": { + "description": "SLF4Jが実行時に必要なクラスを自動で検出するため、プロジェクトの依存モジュールに追加するだけで使用できる", + "examples": [ + { + "title": "SLF4Jを使用するOSSライブラリの例", + "description": "HibernateなどSLF4Jでログ出力するライブラリを使用する場合、自動的にNablarchのログ機能経由で出力される", + "code": "// ライブラリ側のコード(変更不要)\nLogger logger = LoggerFactory.getLogger(MyClass.class);\nlogger.info(\"message\");" + } + ], + "best_practices": [ + "依存関係の追加のみで動作する(最もシンプルなアダプタ)" + ] + }, + "notes": [ + "SLF4Jのバージョン2.0.11を使用してテストを行っている", + "バージョンを変更する場合は、プロジェクト側でテストを行い問題ないことを確認すること", + "SLF4Jのバージョン2.0.0以降はロギング実装の検索方法が変わっている", + "互換性のない1.7系のバージョンが使用された場合、\"Failed to load class org.slf4j.impl.StaticLoggerBinder\"のログが出力され、以降のログ出力が行われないため注意" + ], + "limitations": [] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/handlers/batch/data-read-handler.json b/.claude/skills/nabledge-6/knowledge/features/handlers/batch/data-read-handler.json new file mode 100644 index 0000000..a4315d7 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/handlers/batch/data-read-handler.json @@ -0,0 +1,114 @@ +{ + "id": "data-read-handler", + "title": "データリードハンドラ", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/standalone/data_read_handler.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "DataReadHandler", + "データリード", + "データリーダ", + "入力データ読み込み" + ] + }, + { + "id": "processing", + "hints": [ + "処理フロー", + "DataReader", + "順次読み込み", + "1件ずつ", + "NoMoreRecord" + ] + }, + { + "id": "setup", + "hints": [ + "設定", + "maxCount", + "最大処理件数", + "XML" + ] + }, + { + "id": "constraints", + "hints": [ + "制約", + "DataReader", + "ExecutionContext", + "前提条件" + ] + } + ], + "sections": { + "overview": { + "class_name": "nablarch.fw.handler.DataReadHandler", + "description": "データリーダを使用して、入力データの順次読み込みを行なうハンドラ。実行コンテキスト上のデータリーダを使用し、業務処理に対する入力データを1件ずつ読み込み、それを引数として後続ハンドラに処理を委譲する。", + "purpose": "バッチ処理における入力データの順次読み込みを制御し、データ終端の判定を行う", + "responsibilities": [ + "データリーダを使用して入力データの読み込み", + "実行時IDの採番", + "データ終端の判定(NoMoreRecordの返却)" + ], + "modules": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-fw-standalone" + } + ] + }, + "processing": { + "flow": [ + { + "step": "リクエスト処理前", + "description": "実行コンテキスト(ExecutionContext)上のデータリーダ(DataReader)を取得する。データリーダが設定されていない場合、処理対象データ無しとしてNoMoreRecordを返却して処理を終了する。" + }, + { + "step": "データ読み込みループ", + "description": "データリーダから入力データを1件読み込み、それを引数として後続ハンドラに処理を委譲する。最大処理件数(maxCount)が設定されている場合は、その件数に達するまで繰り返す。データリーダの終端に達した場合、またはmaxCountに達した場合はNoMoreRecordを返却する。" + }, + { + "step": "実行時ID採番", + "description": "各レコード処理時に実行時IDを採番する。" + } + ], + "data_reader": { + "interface": "nablarch.fw.DataReader", + "source": "ExecutionContextに設定されたDataReaderを使用", + "end_marker": "nablarch.fw.DataReader.NoMoreRecord" + } + }, + "setup": { + "component_name": "DataReadHandler", + "properties": [ + { + "name": "maxCount", + "type": "int", + "required": false, + "description": "最大の処理件数。この件数分のデータを処理し終わると、本ハンドラは処理対象レコードなしを示すNoMoreRecordを返却する。大量データを処理するバッチ処理を数日に分けて処理させる場合などに指定する。例えば、最大100万件を処理するバッチを、日次で最大10万件だけ処理をさせ10日間かけて全件を処理させることが実現できる。" + } + ], + "xml_example": "\n \n \n" + }, + "max_count": { + "description": "本ハンドラには、最大の処理件数を設定することが出来る。最大処理件数分のデータを処理し終わると、本ハンドラは処理対象レコードなしを示すNoMoreRecordを返却する。", + "use_case": "大量データを処理するバッチ処理を数日に分けて処理させる場合などに指定する。", + "example": "最大100万件を処理するバッチを、日次で最大10万件だけ処理をさせ10日間かけて全件を処理させることが実現できる。" + }, + "constraints": { + "handler_order": { + "before": [], + "after": [], + "reason": "本ハンドラ自体に順序制約はないが、実行コンテキストにDataReaderが設定されている必要があるため、DataReaderを設定するハンドラより後に配置する必要がある。" + }, + "limitations": [], + "notes": [ + "本ハンドラより手前のハンドラにて、ExecutionContextにDataReaderを設定する必要がある。", + "本ハンドラが呼び出されたタイミングでDataReaderが設定されていない場合、処理対象データ無しとして本ハンドラは処理を終了(NoMoreRecordを返却)する。" + ] + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/handlers/common/db-connection-management-handler.json b/.claude/skills/nabledge-6/knowledge/features/handlers/common/db-connection-management-handler.json new file mode 100644 index 0000000..557f210 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/handlers/common/db-connection-management-handler.json @@ -0,0 +1,137 @@ +{ + "id": "db-connection-management-handler", + "title": "データベース接続管理ハンドラ", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/common/database_connection_management_handler.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "DbConnectionManagementHandler", + "データベース接続管理", + "DB接続", + "接続取得", + "接続解放" + ] + }, + { + "id": "processing", + "hints": [ + "処理フロー", + "接続取得", + "接続解放", + "スレッド管理" + ] + }, + { + "id": "setup", + "hints": [ + "設定", + "connectionFactory", + "connectionName", + "XML", + "データベース接続先" + ] + }, + { + "id": "multiple_connections", + "hints": [ + "複数データベース", + "複数接続", + "connectionName", + "デフォルト接続" + ] + }, + { + "id": "constraints", + "hints": [ + "制約", + "TransactionManagementHandler", + "セット設定", + "トランザクション制御" + ] + } + ], + "sections": { + "overview": { + "class_name": "nablarch.common.handler.DbConnectionManagementHandler", + "description": "後続のハンドラ及びライブラリで使用するためのデータベース接続を、スレッド上で管理するハンドラ", + "purpose": "データベースアクセスに必要な接続オブジェクトをスレッド単位で管理し、後続処理で利用可能にする", + "responsibilities": [ + "データベース接続の取得", + "データベース接続の解放", + "スレッド上での接続管理" + ], + "modules": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core-jdbc" + }, + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-common-jdbc" + } + ] + }, + "processing": { + "flow": [ + { + "step": "リクエスト処理前", + "description": "connectionFactoryプロパティに設定されたファクトリクラス(ConnectionFactory実装クラス)を使用してデータベース接続を取得し、スレッド上で管理する。データベース接続名(connectionName)をキーとして管理する。" + }, + { + "step": "後続ハンドラ呼び出し", + "description": "次のハンドラに処理を委譲。後続ハンドラおよびライブラリはDbConnectionContext.getConnection()でスレッド上の接続を取得できる。" + }, + { + "step": "リクエスト処理後", + "description": "スレッド上で管理しているデータベース接続を解放する。" + } + ] + }, + "setup": { + "component_name": "DbConnectionManagementHandler", + "properties": [ + { + "name": "connectionFactory", + "type": "nablarch.core.db.connection.ConnectionFactory", + "required": true, + "description": "データベース接続オブジェクトを取得するファクトリクラス。BasicDbConnectionFactoryForDataSourceなどのConnectionFactory実装クラスを設定する。" + }, + { + "name": "connectionName", + "type": "String", + "required": false, + "description": "データベース接続名。スレッド内で一意とする必要がある。省略した場合、その接続はデフォルトのデータベース接続となる。複数のデータベース接続を使用する場合に、最もよく使う接続をデフォルトとし、それ以外に任意の名前をつけると良い。" + } + ], + "xml_example": "\n\n \n\n\n\n\n \n" + }, + "multiple_connections": { + "description": "1つのアプリケーションで複数のデータベース接続が必要となる場合、このハンドラをハンドラキュー上に複数設定することで対応する。", + "connection_naming": { + "default_connection": "connectionNameプロパティへの設定を省略した場合、その接続はデフォルトのデータベース接続となり簡易的に使用できる。DbConnectionContext.getConnection()を引数なしで呼び出すと、デフォルトの接続が戻される。", + "named_connection": "connectionNameプロパティに任意の名前を設定することで、名前付き接続として管理できる。DbConnectionContext.getConnection(String)に接続名を指定して呼び出すことで、対応する接続が取得できる。", + "recommendation": "最もよく使うデータベース接続をデフォルトとし、それ以外のデータベース接続に対して任意の名前をつけると良い。" + }, + "xml_example": "\n\n \n\n\n\n\n \n \n", + "usage_example": { + "default": "AppDbConnection connection = DbConnectionContext.getConnection(); // 引数なし", + "named": "AppDbConnection connection = DbConnectionContext.getConnection(\"userAccessLog\"); // 接続名を指定" + } + }, + "constraints": { + "handler_order": { + "before": [], + "after": [], + "reason": "このハンドラ自体には順序制約はない。ただし、データベースアクセスを行う全てのハンドラより前に配置する必要がある。" + }, + "limitations": [], + "notes": [ + "このハンドラを使用する場合は、TransactionManagementHandlerをセットで設定すること。トランザクション制御ハンドラが設定されていない場合、トランザクション制御が実施されないため後続で行ったデータベースへの変更は全て破棄される。", + "データベース接続オブジェクトを取得するためのファクトリクラスの詳細は、データベースアクセス機能を参照すること。" + ] + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/handlers/common/transaction-management-handler.json b/.claude/skills/nabledge-6/knowledge/features/handlers/common/transaction-management-handler.json new file mode 100644 index 0000000..4b30d8f --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/handlers/common/transaction-management-handler.json @@ -0,0 +1,191 @@ +{ + "id": "transaction-management-handler", + "title": "トランザクション制御ハンドラ", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/common/transaction_management_handler.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "TransactionManagementHandler", + "トランザクション制御", + "トランザクション管理", + "透過的トランザクション" + ] + }, + { + "id": "processing", + "hints": [ + "処理フロー", + "トランザクション開始", + "コミット", + "ロールバック", + "トランザクション境界" + ] + }, + { + "id": "setup", + "hints": [ + "設定", + "transactionFactory", + "transactionName", + "XML", + "JdbcTransactionFactory" + ] + }, + { + "id": "commit_exceptions", + "hints": [ + "例外", + "コミット", + "transactionCommitExceptions", + "ロールバック" + ] + }, + { + "id": "callback", + "hints": [ + "コールバック", + "TransactionEventCallback", + "transactionNormalEnd", + "transactionAbnormalEnd", + "トランザクション終了時" + ] + }, + { + "id": "multiple_transactions", + "hints": [ + "複数トランザクション", + "複数データベース", + "transactionName" + ] + }, + { + "id": "constraints", + "hints": [ + "制約", + "ハンドラ順序", + "DbConnectionManagementHandler", + "前後関係" + ] + } + ], + "sections": { + "overview": { + "class_name": "nablarch.common.handler.TransactionManagementHandler", + "description": "データベースやメッセージキューなどのトランザクションに対応したリソースを使用し、後続処理における透過的トランザクションを実現するハンドラ", + "purpose": "後続処理のトランザクション境界を管理し、正常終了時のコミット、異常終了時のロールバックを自動的に行う", + "responsibilities": [ + "トランザクションの開始", + "トランザクションの終了(コミットやロールバック)", + "トランザクションの終了時のコールバック" + ], + "modules": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core-transaction" + }, + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core-jdbc", + "note": "データベースに対するトランザクションを制御する場合のみ" + }, + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core", + "note": "トランザクション終了時に任意の処理を実行する場合のみ" + } + ] + }, + "processing": { + "flow": [ + { + "step": "リクエスト処理前", + "description": "transactionFactoryプロパティに設定されたファクトリクラス(TransactionFactory実装クラス)を使用してトランザクションの制御対象を取得し、トランザクションを開始する。トランザクションはスレッド上でtransactionName(デフォルトは'transaction')をキーとして管理される。" + }, + { + "step": "後続ハンドラ呼び出し", + "description": "次のハンドラに処理を委譲。後続ハンドラで実行される業務処理は、開始されたトランザクション内で実行される。" + }, + { + "step": "リクエスト処理後(正常)", + "description": "後続ハンドラが正常終了した場合、トランザクションをコミットする。コミット後、後続ハンドラの中でTransactionEventCallbackを実装しているハンドラに対してtransactionNormalEndをコールバックする。" + }, + { + "step": "リクエスト処理後(異常)", + "description": "後続ハンドラでエラーや例外が発生した場合、トランザクションをロールバックする。ロールバック後、新しいトランザクションを開始し、TransactionEventCallbackを実装しているハンドラに対してtransactionAbnormalEndをコールバックする。コールバックが正常終了するとコミットする。" + } + ], + "transaction_boundary": "後続ハンドラの処理全体がトランザクション境界となる。コールバック処理は、正常終了時は同一トランザクション内で実行されないが、ロールバック時は新しいトランザクション内で実行される。" + }, + "setup": { + "component_name": "TransactionManagementHandler", + "properties": [ + { + "name": "transactionFactory", + "type": "nablarch.core.transaction.TransactionFactory", + "required": true, + "description": "トランザクション制御を行うファクトリクラス。データベースに対するトランザクション制御を行う場合はJdbcTransactionFactoryを設定する。" + }, + { + "name": "transactionName", + "type": "String", + "required": false, + "default": "transaction", + "description": "トランザクションを識別するための名前。複数のトランザクションを使用する場合は必須。DbConnectionManagementHandlerのconnectionNameに設定した値と同じ値を設定すること。" + }, + { + "name": "transactionCommitExceptions", + "type": "List", + "required": false, + "description": "コミット対象の例外クラスのリスト(FQCN)。デフォルトでは全てのエラー及び例外がロールバック対象となるが、特定の例外の場合にトランザクションをコミットしたい場合に設定する。設定した例外クラスのサブクラスもコミット対象となる。" + } + ], + "xml_example": "\n\n \n \n\n\n\n\n \n" + }, + "commit_exceptions": { + "description": "デフォルト動作では、全てのエラー及び例外がロールバック対象となるが、発生した例外の内容によってはトランザクションをコミットしたい場合がある。", + "configuration": "transactionCommitExceptionsプロパティに対して、コミット対象の例外クラスを設定することで対応する。設定した例外クラスのサブクラスもコミット対象となる。", + "xml_example": "\n \n \n \n \n example.TransactionCommitException\n \n \n" + }, + "callback": { + "description": "トランザクション終了(コミットやロールバック)時に、コールバック処理を行う機能を提供する。", + "callback_interface": "nablarch.fw.TransactionEventCallback", + "callback_methods": [ + { + "method": "transactionNormalEnd", + "signature": "void transactionNormalEnd(TData data, ExecutionContext context)", + "description": "トランザクションコミット時のコールバック処理。正常終了時のコールバックは、トランザクションコミット後に実行される。" + }, + { + "method": "transactionAbnormalEnd", + "signature": "void transactionAbnormalEnd(Throwable e, TData data, ExecutionContext context)", + "description": "トランザクションロールバック時のコールバック処理。ロールバック後に新しいトランザクションで実行され、コールバックが正常に終了するとコミットされる。" + } + ], + "callback_target": "このハンドラより後続に設定されたハンドラの中で、TransactionEventCallbackを実装しているものがコールバック対象となる。複数のハンドラが実装している場合は、より手前に設定されているハンドラから順次コールバック処理を実行する。", + "callback_error_handling": "複数のハンドラがコールバック処理を実装していた場合で、コールバック処理中にエラーや例外が発生した場合は、残りのハンドラに対するコールバック処理は実行しない。", + "xml_example": "\n \n \n \n \n\n \n \n" + }, + "multiple_transactions": { + "description": "1つのアプリケーションで複数のトランザクション制御が必要となる場合、このハンドラをハンドラキュー上に複数設定することで対応する。", + "configuration_rule": "複数のトランザクションを使用する場合、transactionNameプロパティへの値の設定が必須となる。DbConnectionManagementHandlerで設定したデータベースに対するトランザクションを制御する場合は、DbConnectionManagementHandler#connectionNameに設定した値と同じ値をtransactionNameプロパティに設定すること。", + "xml_example": "\n\n \n\n\n\n\n \n \n\n\n\n\n \n\n\n\n\n \n \n\n\n\n\n \n \n \n\n \n \n \n" + }, + "constraints": { + "handler_order": { + "before": [], + "after": [ + "DbConnectionManagementHandler" + ], + "reason": "データベースに対するトランザクションを制御する場合には、トランザクション管理対象のデータベース接続がスレッド上に存在している必要がある。このため、本ハンドラはDbConnectionManagementHandlerより後ろに配置する必要がある。" + }, + "limitations": [], + "notes": [ + "DbConnectionManagementHandlerのconnectionNameに設定した値と同じ値をtransactionNameプロパティに設定すること。", + "connectionNameに値を設定していない場合は、transactionNameへの設定は省略して良い。" + ] + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/libraries/business-date.json b/.claude/skills/nabledge-6/knowledge/features/libraries/business-date.json new file mode 100644 index 0000000..9194b35 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/libraries/business-date.json @@ -0,0 +1,304 @@ +{ + "id": "business-date", + "title": "業務日付の管理", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/date.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "業務日付", + "システム日時", + "日付管理", + "SystemTimeProvider", + "BusinessDateProvider" + ] + }, + { + "id": "modules", + "hints": [ + "モジュール", + "依存", + "nablarch-core", + "nablarch-common-jdbc" + ] + }, + { + "id": "system_time_configuration", + "hints": [ + "システム日時", + "設定", + "BasicSystemTimeProvider", + "systemTimeProvider" + ] + }, + { + "id": "system_time_usage", + "hints": [ + "システム日時", + "取得", + "SystemTimeUtil" + ] + }, + { + "id": "business_date_configuration", + "hints": [ + "業務日付", + "設定", + "BasicBusinessDateProvider", + "businessDateProvider", + "データベース", + "テーブル", + "初期化" + ] + }, + { + "id": "business_date_usage", + "hints": [ + "業務日付", + "取得", + "BusinessDateUtil" + ] + }, + { + "id": "business_date_override", + "hints": [ + "業務日付", + "上書き", + "再実行", + "システムプロパティ", + "環境設定の上書き" + ] + }, + { + "id": "business_date_update", + "hints": [ + "業務日付", + "更新", + "setDate" + ] + }, + { + "id": "customization", + "hints": [ + "切り替え", + "拡張", + "カスタマイズ", + "テスト", + "SystemTimeProvider", + "BusinessDateProvider" + ] + } + ], + "sections": { + "overview": { + "classes": [ + "nablarch.core.date.SystemTimeProvider", + "nablarch.core.date.BasicSystemTimeProvider", + "nablarch.core.date.SystemTimeUtil", + "nablarch.core.date.BusinessDateProvider", + "nablarch.core.date.BasicBusinessDateProvider", + "nablarch.core.date.BusinessDateUtil" + ], + "description": "アプリケーションで使用するシステム日時(OS日時)と業務日付を一元的に管理する機能を提供する。コンポーネント定義で指定されたクラスを使用して、システム日時(OS日時)や業務日付を取得する。", + "purpose": "コンポーネント定義で指定するクラスを差し替えるだけで、アプリケーションで使用するシステム日時(OS日時)と業務日付の取得方法を切り替えることができる。この切り替えは、テストなどで一時的にシステム日時(OS日時)や業務日付を切り替えたい場合に使用できる。", + "features": [ + "システム日時(OS日時)の一元管理", + "業務日付の一元管理(データベース使用)", + "テスト時のシステム日時・業務日付の切り替え", + "複数の業務日付の管理(区分単位)", + "業務日付の上書き(プロセス単位)", + "業務日付の更新" + ] + }, + "modules": { + "dependencies": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core", + "required": true, + "description": "システム日時管理機能を使用する場合に必要" + }, + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-common-jdbc", + "required": false, + "description": "業務日付管理機能を使用する場合のみ必要" + } + ] + }, + "system_time_configuration": { + "description": "システム日時の管理機能を使うためには、BasicSystemTimeProviderの設定をコンポーネント定義に追加する。", + "component_name": "systemTimeProvider", + "class": "nablarch.core.date.BasicSystemTimeProvider", + "xml_example": "", + "properties": [] + }, + "system_time_usage": { + "description": "システム日時の取得は、SystemTimeUtilを使用する。", + "class": "nablarch.core.date.SystemTimeUtil", + "methods": [ + { + "name": "getDate", + "signature": "public static Date getDate()", + "description": "現在のシステム日時を取得する", + "returns": "現在のシステム日時", + "example": "Date systemDate = SystemTimeUtil.getDate();" + }, + { + "name": "getTimestamp", + "signature": "public static Timestamp getTimestamp()", + "description": "現在のシステム日時をTimestamp型で取得する", + "returns": "現在のシステム日時(Timestamp型)", + "example": "Timestamp systemTimestamp = SystemTimeUtil.getTimestamp();" + } + ] + }, + "business_date_configuration": { + "description": "業務日付管理機能では、データベースを使用して複数の業務日付を管理する。BasicBusinessDateProviderの設定をコンポーネント定義に追加し、初期化対象のリストに設定する。", + "component_name": "businessDateProvider", + "class": "nablarch.core.date.BasicBusinessDateProvider", + "initialization_required": true, + "database_table": { + "description": "業務日付を管理するためのテーブル", + "columns": [ + { + "name": "区分(PK)", + "type": "文字列型", + "description": "業務日付を識別するための値" + }, + { + "name": "日付", + "type": "文字列型", + "format": "yyyyMMdd", + "description": "業務日付" + } + ] + }, + "properties": [ + { + "name": "tableName", + "type": "String", + "required": true, + "description": "業務日付を管理するテーブル名", + "example": "BUSINESS_DATE" + }, + { + "name": "segmentColumnName", + "type": "String", + "required": true, + "description": "区分のカラム名", + "example": "SEGMENT" + }, + { + "name": "dateColumnName", + "type": "String", + "required": true, + "description": "日付のカラム名", + "example": "BIZ_DATE" + }, + { + "name": "defaultSegment", + "type": "String", + "required": true, + "description": "区分を省略して業務日付を取得した場合に使用される区分", + "example": "00" + }, + { + "name": "transactionManager", + "type": "TransactionManagerの参照", + "required": true, + "description": "データベースアクセスに使用するトランザクションマネージャ" + } + ], + "xml_example": "\n \n \n \n \n \n \n \n \n \n \n\n\n\n \n \n \n \n \n \n" + }, + "business_date_usage": { + "description": "業務日付の取得は、BusinessDateUtilを使用する。", + "class": "nablarch.core.date.BusinessDateUtil", + "methods": [ + { + "name": "getDate", + "signature": "public static String getDate()", + "description": "デフォルト区分の業務日付を取得する", + "returns": "業務日付(yyyyMMdd形式の文字列)", + "example": "String bizDate = BusinessDateUtil.getDate();" + }, + { + "name": "getDate", + "signature": "public static String getDate(String segment)", + "description": "指定した区分の業務日付を取得する", + "parameters": [ + { + "name": "segment", + "type": "String", + "description": "区分" + } + ], + "returns": "業務日付(yyyyMMdd形式の文字列)", + "example": "String bizDate = BusinessDateUtil.getDate(\"batch\");" + } + ] + }, + "business_date_override": { + "description": "バッチ処理で障害時の再実行時に、過去日付をバッチ実行時の業務日付としたい場合、再実行するプロセスのみ任意の日付を業務日付として実行できる。業務日付の上書きは、環境設定の上書き機能を使用して行う。", + "use_case": "バッチ処理の障害時の再実行で、過去日付を業務日付として実行したい場合", + "method": "システムプロパティで指定", + "format": "BasicBusinessDateProvider.<区分>=日付(yyyyMMdd形式)", + "example": { + "description": "区分が\"batch\"の日付を\"2016/03/17\"に上書きしたい場合", + "system_property": "-DBasicBusinessDateProvider.batch=20160317" + } + }, + "business_date_update": { + "description": "業務日付の更新は、BasicBusinessDateProviderを使用して行う。", + "class": "nablarch.core.date.BasicBusinessDateProvider", + "methods": [ + { + "name": "setDate", + "signature": "public void setDate(String segment, String date)", + "description": "指定した区分の業務日付を更新する", + "parameters": [ + { + "name": "segment", + "type": "String", + "description": "区分" + }, + { + "name": "date", + "type": "String", + "description": "更新する日付(yyyyMMdd形式)" + } + ], + "example": "// システムリポジトリからBasicBusinessDateProviderを取得する\nBusinessDateProvider provider = SystemRepository.get(\"businessDateProvider\");\n\n// setDateメソッドを呼び出し、更新する\nprovider.setDate(segment, date);" + } + ] + }, + "customization": { + "description": "ユニットテストの実行時など、システム日時や業務日付を切り替えたい場合、それぞれのProviderインターフェースを実装したクラスを作成し、コンポーネント定義で差し替える。", + "system_time_customization": { + "description": "システム日時を切り替える場合", + "steps": [ + "SystemTimeProviderを実装したクラスを作成する", + "システム日時の管理機能を使うための設定に従い、作成したクラスをコンポーネント定義に設定する" + ], + "interface": "nablarch.core.date.SystemTimeProvider" + }, + "business_date_customization": { + "description": "業務日付を切り替える場合", + "steps": [ + "BusinessDateProviderを実装したクラスを作成する", + "業務日付管理機能を使うための設定に従い、作成したクラスをコンポーネント定義に設定する" + ], + "interface": "nablarch.core.date.BusinessDateProvider" + } + }, + "tips": [ + { + "title": "ウェブアプリケーションでの業務日付の上書き", + "description": "ウェブアプリケーションのように、全ての機能が1プロセス内で実行される場合は、単純にデータベースで管理されている日付を変更すればよい。業務日付の上書き機能は、バッチ処理のように複数プロセスで実行される場合に有用。" + } + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/libraries/data-bind.json b/.claude/skills/nabledge-6/knowledge/features/libraries/data-bind.json new file mode 100644 index 0000000..bd828f6 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/libraries/data-bind.json @@ -0,0 +1,915 @@ +{ + "id": "data-bind", + "title": "データバインド", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/data_io/data_bind.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "データバインド", + "CSV", + "固定長", + "Java Beans", + "Map", + "ObjectMapper", + "ObjectMapperFactory" + ] + }, + { + "id": "modules", + "hints": [ + "モジュール", + "依存関係", + "nablarch-common-databind", + "nablarch-fw-web-extension", + "Maven" + ] + }, + { + "id": "csv_format_beans", + "hints": [ + "CSVフォーマット", + "@Csv", + "@CsvFormat", + "Csv.CsvType", + "フィールド区切り", + "ヘッダ行" + ] + }, + { + "id": "csv_format_map", + "hints": [ + "CsvDataBindConfig", + "withProperties", + "withHeaderTitles", + "プロパティ名", + "ヘッダタイトル" + ] + }, + { + "id": "fixed_length_format_beans", + "hints": [ + "固定長フォーマット", + "@FixedLength", + "@Field", + "offset", + "length", + "パディング", + "Lpad", + "Rpad", + "fillChar" + ] + }, + { + "id": "fixed_length_format_map", + "hints": [ + "FixedLengthDataBindConfig", + "FixedLengthDataBindConfigBuilder", + "singleLayout", + "field設定" + ] + }, + { + "id": "multi_layout", + "hints": [ + "マルチレイアウト", + "複数フォーマット", + "MultiLayout", + "RecordIdentifier", + "@Record", + "multiLayout属性" + ] + }, + { + "id": "formatter", + "hints": [ + "フォーマット", + "日付フォーマット", + "数値フォーマット", + "表示形式", + "format機能" + ] + }, + { + "id": "extension", + "hints": [ + "拡張", + "ファイル形式追加", + "ObjectMapper実装", + "ObjectMapperFactory継承", + "カスタムフォーマット" + ] + }, + { + "id": "csv_format_sets", + "hints": [ + "フォーマットセット", + "DEFAULT", + "RFC4180", + "EXCEL", + "TSV", + "クォートモード", + "NORMAL", + "ALL" + ] + }, + { + "id": "anti-patterns", + "hints": [ + "NGパターン", + "非推奨", + "注意事項", + "String型定義", + "スレッドセーフ" + ] + }, + { + "id": "errors", + "hints": [ + "例外", + "エラー", + "InvalidDataFormatException", + "型変換エラー", + "フォーマット不正" + ] + }, + { + "id": "tips", + "hints": [ + "Tips", + "ベストプラクティス", + "try-with-resources", + "null値出力", + "行番号制限" + ] + }, + { + "id": "usage", + "hints": [ + "使用方法", + "ファイル読み込み", + "ファイル書き込み", + "Java Beans", + "Map", + "ObjectMapper" + ] + }, + { + "id": "limitations", + "hints": [ + "制約事項", + "注意事項", + "制限" + ] + } + ], + "sections": { + "overview": { + "classes": [ + "nablarch.common.databind.ObjectMapper", + "nablarch.common.databind.ObjectMapperFactory", + "nablarch.common.databind.DataBindConfig", + "nablarch.core.beans.BeanUtil" + ], + "annotations": [ + "@Csv", + "@CsvFormat", + "@FixedLength", + "@Field", + "@LineNumber", + "@Record", + "@Lpad", + "@Rpad" + ], + "description": "CSVやTSV、固定長といったデータをJava BeansオブジェクトまたはMapオブジェクトとして扱う機能を提供する。データファイルとJavaオブジェクト間の双方向変換をサポートする。", + "purpose": "データファイルのデータをオブジェクト指向的に扱い、CSV/TSV/固定長ファイルの読み書きを簡潔に実装できるようにする。アノテーションまたはDataBindConfigでフォーマットを定義することで、様々な形式のファイルに対応可能。", + "features": [ + "データをJava Beansオブジェクトとして扱える(BeanUtilによる自動型変換)", + "データをMapオブジェクトとして扱える(値は全てString型)", + "フォーマット指定はアノテーションまたはDataBindConfigで定義", + "CSV/TSV/固定長ファイルをサポート", + "複数フォーマットを持つ固定長ファイル(マルチレイアウト)に対応", + "論理行番号の取得が可能(@LineNumber)", + "Bean Validationとの連携による入力値チェック", + "ファイルダウンロード/アップロード機能との連携" + ], + "modules": [ + "com.nablarch.framework:nablarch-common-databind" + ] + }, + "modules": { + "dependencies": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-common-databind", + "required": true, + "description": "データバインド機能のコアモジュール" + }, + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-fw-web-extension", + "required": false, + "description": "ファイルダウンロード機能を使用する場合に必要" + } + ] + }, + "usage": { + "methods": [ + { + "name": "ObjectMapperFactory.create (Java Beans読み込み用)", + "signature": "public static ObjectMapper create(Class entityClass, InputStream inputStream)", + "description": "Java Beansクラスにバインドしてデータを読み込むためのObjectMapperを生成する。Java Beansクラスに定義されたアノテーションをもとにフォーマットを決定する。", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "バインド対象のJava Beansクラス" + }, + { + "name": "inputStream", + "type": "InputStream", + "description": "読み込み元のストリーム" + } + ], + "returns": "ObjectMapper - データ読み込み用のマッパー", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n // 処理\n }\n}" + }, + { + "name": "ObjectMapperFactory.create (Java Beans書き込み用)", + "signature": "public static ObjectMapper create(Class entityClass, OutputStream outputStream)", + "description": "Java Beansオブジェクトをデータファイルに書き込むためのObjectMapperを生成する。Java Beansクラスに定義されたアノテーションをもとにフォーマットを決定する。", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "バインド対象のJava Beansクラス" + }, + { + "name": "outputStream", + "type": "OutputStream", + "description": "書き込み先のストリーム" + } + ], + "returns": "ObjectMapper - データ書き込み用のマッパー", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) {\n for (Person person : personList) {\n mapper.write(person);\n }\n}" + }, + { + "name": "ObjectMapperFactory.create (Map読み込み用)", + "signature": "public static ObjectMapper create(Class clazz, InputStream inputStream, DataBindConfig config)", + "description": "Mapオブジェクトにバインドしてデータを読み込むためのObjectMapperを生成する。DataBindConfigで指定したフォーマット設定をもとにデータを読み込む。", + "parameters": [ + { + "name": "clazz", + "type": "Class", + "description": "Map.classを指定" + }, + { + "name": "inputStream", + "type": "InputStream", + "description": "読み込み元のストリーム" + }, + { + "name": "config", + "type": "DataBindConfig", + "description": "フォーマット設定(CsvDataBindConfigまたはFixedLengthDataBindConfig)" + } + ], + "returns": "ObjectMapper - Map形式でのデータ読み込み用マッパー", + "example": "DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles(\"年齢\", \"名前\")\n .withProperties(\"age\", \"name\");\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) {\n Map person;\n while ((person = mapper.read()) != null) {\n // 処理\n }\n}" + }, + { + "name": "ObjectMapperFactory.create (Map書き込み用)", + "signature": "public static ObjectMapper create(Class clazz, OutputStream outputStream, DataBindConfig config)", + "description": "Mapオブジェクトをデータファイルに書き込むためのObjectMapperを生成する。DataBindConfigで指定したフォーマット設定をもとにデータを書き込む。", + "parameters": [ + { + "name": "clazz", + "type": "Class", + "description": "Map.classを指定" + }, + { + "name": "outputStream", + "type": "OutputStream", + "description": "書き込み先のストリーム" + }, + { + "name": "config", + "type": "DataBindConfig", + "description": "フォーマット設定(CsvDataBindConfigまたはFixedLengthDataBindConfig)" + } + ], + "returns": "ObjectMapper - Map形式でのデータ書き込み用マッパー", + "example": "DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles(\"年齢\", \"名前\")\n .withProperties(\"age\", \"name\");\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) {\n for (Map person : personList) {\n mapper.write(person);\n }\n}" + }, + { + "name": "ObjectMapper.read", + "signature": "public T read() throws IOException, InvalidDataFormatException", + "description": "データファイルから1データずつ読み込み、Java BeansまたはMapオブジェクトとして返却する。全データ読み込み後はnullを返す。", + "parameters": [], + "returns": "T - 読み込んだデータのオブジェクト(全データ読み込み後はnull)", + "throws": [ + "IOException - I/Oエラー発生時", + "InvalidDataFormatException - データフォーマット不正時" + ], + "example": "Person person;\nwhile ((person = mapper.read()) != null) {\n // Java Beansオブジェクトごとの処理\n}" + }, + { + "name": "ObjectMapper.write", + "signature": "public void write(T object) throws IOException", + "description": "Java BeansまたはMapオブジェクトの内容をデータファイルに1データずつ書き込む。プロパティ値がnullの場合は空文字が出力される。", + "parameters": [ + { + "name": "object", + "type": "T", + "description": "書き込むオブジェクト(Java BeansまたはMap)" + } + ], + "returns": "void", + "throws": [ + "IOException - I/Oエラー発生時" + ], + "example": "for (Person person : personList) {\n mapper.write(person);\n}" + }, + { + "name": "ObjectMapper.close", + "signature": "public void close() throws IOException", + "description": "ObjectMapperが使用しているリソースを解放する。全データの読み込み・書き込み完了後に必ず呼び出すこと。try-with-resourcesを使用することで自動的にクローズ処理が実行される。", + "parameters": [], + "returns": "void", + "throws": [ + "IOException - I/Oエラー発生時" + ], + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n // 処理\n} // 自動的にclose()が呼ばれる" + } + ], + "typical_usage": { + "file_to_bean": { + "description": "データファイルを先頭から1データずつ読み込み、Java Beansオブジェクトとして取得する。Java Beansクラスに定義されたアノテーションをもとにデータを読み込む。読み込み時にBeanUtilを使用して自動的に型変換が行われ、型変換に失敗した場合は例外が発生する。", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n // Java Beansオブジェクトごとの処理を記述\n }\n} catch (InvalidDataFormatException e) {\n // 読み込んだデータのフォーマットが不正な場合の処理を記述\n}" + }, + "bean_to_file": { + "description": "Java Beansオブジェクトの内容をデータファイルに1データずつ書き込む。Java Beansクラスに定義されたアノテーションをもとにデータを書き込む。プロパティの値がnullの場合は未入力を表す値(CSVファイルの場合は空文字)が出力される。", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) {\n for (Person person : personList) {\n mapper.write(person);\n }\n}" + }, + "file_to_map": { + "description": "データファイルを先頭から1データずつ読み込み、Mapオブジェクトとして取得する。DataBindConfigの設定値をもとにデータを読み込む。Mapオブジェクトへの変換時、値は全てString型で格納される。", + "example": "DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles(\"年齢\", \"名前\")\n .withProperties(\"age\", \"name\");\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) {\n Map person;\n while ((person = mapper.read()) != null) {\n // Mapオブジェクトごとの処理を記述\n }\n} catch (InvalidDataFormatException e) {\n // 読み込んだデータのフォーマットが不正な場合の処理を記述\n}" + }, + "map_to_file": { + "description": "Mapオブジェクトの内容をデータファイルに1データずつ書き込む。DataBindConfigの設定値をもとにデータを書き込む。Mapオブジェクトのvalue値がnullの場合は未入力を表す値(CSVファイルの場合は空文字)が出力される。", + "example": "DataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles(\"年齢\", \"名前\")\n .withProperties(\"age\", \"name\");\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) {\n for (Map person : personList) {\n mapper.write(person);\n }\n}" + }, + "line_number": { + "description": "ファイルのデータをJava Beansオブジェクトとして取得する際、Java Beansクラスにプロパティを定義して@LineNumberアノテーションを使用することで、データの論理行番号も一緒に取得できる。入力値チェック時にバリデーションエラーが発生したデータの行番号をログに出力したい場合などに使用する。", + "example": "// Java Beansクラスの定義\nprivate Long lineNumber;\n\n@LineNumber\npublic Long getLineNumber() {\n return lineNumber;\n}\n\n// 使用例\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n System.out.println(\"行番号: \" + person.getLineNumber());\n // 処理\n }\n}", + "note": "Mapオブジェクトとして取得する場合は、データの行番号を取得できない点に注意すること。" + }, + "validation": { + "description": "データをJava Beansオブジェクトとして読み込むことができるため、Bean Validationによる入力値チェックを行うことができる。", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n // 入力値チェックを実行\n ValidatorUtil.validate(person);\n // 後続の処理\n }\n} catch (InvalidDataFormatException e) {\n // データファイルのフォーマット不正時の処理を記述\n}" + }, + "file_download": { + "description": "ウェブアプリケーションで、Java Beansオブジェクトの内容をデータファイルとしてダウンロードする。データをメモリ上に展開すると大量データのダウンロード時などにメモリを圧迫する恐れがあるため、一時ファイルに出力する。FileResponseオブジェクト生成時にデータファイルを指定し、レスポンスにContent-Type及びContent-Dispositionを設定する。", + "example": "public HttpResponse download(HttpRequest request, ExecutionContext context) {\n // 業務処理\n\n final Path path = Files.createTempFile(null, null);\n try (ObjectMapper mapper =\n ObjectMapperFactory.create(Person.class, Files.newOutputStream(path))) {\n for (Person person : persons) {\n mapper.write(BeanUtil.createAndCopy(PersonDto.class, person));\n }\n }\n\n // ファイルをボディに設定する。\n FileResponse response = new FileResponse(path.toFile(), true);\n\n // Content-Typeヘッダ、Content-Dispositionヘッダを設定する\n response.setContentType(\"text/csv; charset=Shift_JIS\");\n response.setContentDisposition(\"person.csv\");\n\n return response;\n}", + "points": [ + "データをメモリ上に展開すると大量データのダウンロード時などにメモリを圧迫する恐れがあるため、一時ファイルに出力する", + "FileResponseのコンストラクタの第二引数にtrueを指定すると、リクエスト処理の終了時に自動的にファイルを削除する", + "レスポンスにContent-Type及びContent-Dispositionを設定する" + ] + }, + "upload_file": { + "description": "ウェブアプリケーションで、画面からアップロードされたデータファイルをJava Beansオブジェクトとして読み込む。PartInfo#getInputStreamを使用してアップロードファイルのストリームを取得し、不正なデータが入力されている可能性があるため、Bean Validationを使用して入力チェックを行う。", + "example": "List partInfoList = request.getPart(\"uploadFile\");\nif (partInfoList.isEmpty()) {\n // アップロードファイルが見つからない場合の処理を記述\n}\n\nPartInfo partInfo = partInfoList.get(0);\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, partInfo.getInputStream())) {\n Person person;\n while ((person = mapper.read()) != null) {\n // 入力値チェックを実行\n ValidatorUtil.validate(person);\n // 後続の処理は省略\n }\n} catch (InvalidDataFormatException e) {\n // データファイルのフォーマット不正時の処理を記述\n}", + "points": [ + "PartInfo#getInputStreamを使用して、アップロードファイルのストリームを取得する", + "不正なデータが入力されている可能性があるため、Bean Validationを使用して入力チェックを行う" + ] + } + } + }, + "csv_format_beans": { + "description": "Java BeansクラスにバインドしてCSVファイルを扱う場合、@Csvおよび@CsvFormatアノテーションを使用してフォーマットを指定する。CSVファイルのフォーマットは予め用意したフォーマットセットの中から選択できる。フォーマットセットのいずれにも当てはまらない場合は、@CsvFormatを使用して個別にフォーマットを指定できる。", + "annotations": [ + { + "name": "@Csv", + "class": "nablarch.common.databind.csv.Csv", + "attributes": [ + { + "name": "type", + "type": "Csv.CsvType", + "required": true, + "description": "CSVフォーマットのタイプ(DEFAULT, RFC4180, EXCEL, TSV, CUSTOM)" + }, + { + "name": "properties", + "type": "String[]", + "required": true, + "description": "バインドするプロパティ名の配列(CSV項目順)" + }, + { + "name": "headers", + "type": "String[]", + "required": false, + "description": "ヘッダタイトルの配列(CSV項目順)" + } + ], + "example": "@Csv(type = Csv.CsvType.DEFAULT, properties = {\"age\", \"name\"}, headers = {\"年齢\", \"氏名\"})\npublic class Person {\n private Integer age;\n private String name;\n // getter、setterは省略\n}" + }, + { + "name": "@CsvFormat", + "class": "nablarch.common.databind.csv.CsvFormat", + "description": "CSVフォーマットが予め用意したフォーマットセットのいずれにも当てはまらない場合に、個別にフォーマットを指定する。@CsvのtypeにCUSTOMを指定する必要がある。", + "attributes": [ + { + "name": "fieldSeparator", + "type": "char", + "required": false, + "default": ",", + "description": "列区切り文字" + }, + { + "name": "lineSeparator", + "type": "String", + "required": false, + "default": "\\r\\n", + "description": "行区切り文字" + }, + { + "name": "quote", + "type": "char", + "required": false, + "default": "\"", + "description": "フィールド囲み文字" + }, + { + "name": "ignoreEmptyLine", + "type": "boolean", + "required": false, + "default": "true", + "description": "空行を無視するか" + }, + { + "name": "requiredHeader", + "type": "boolean", + "required": false, + "default": "true", + "description": "ヘッダ行が必須か" + }, + { + "name": "charset", + "type": "String", + "required": false, + "default": "UTF-8", + "description": "文字コード" + }, + { + "name": "quoteMode", + "type": "CsvDataBindConfig.QuoteMode", + "required": false, + "default": "NORMAL", + "description": "クォートモード(NORMAL, ALL)" + }, + { + "name": "emptyToNull", + "type": "boolean", + "required": false, + "default": "false", + "description": "空文字をnullとして扱うか" + } + ], + "example": "@Csv(type = Csv.CsvType.CUSTOM, properties = {\"age\", \"name\"})\n@CsvFormat(\n fieldSeparator = '\\t',\n lineSeparator = \"\\r\\n\",\n quote = '\\'',\n ignoreEmptyLine = false,\n requiredHeader = false,\n charset = \"UTF-8\",\n quoteMode = CsvDataBindConfig.QuoteMode.ALL,\n emptyToNull = true)\npublic class Person {\n private Integer age;\n private String name;\n // getter、setterは省略\n}" + } + ], + "note": "Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、ObjectMapperの生成時にDataBindConfigを使用したフォーマットの指定はできない。" + }, + "csv_format_map": { + "description": "MapクラスにバインドしてCSVファイルを扱う場合、ObjectMapperの生成時にCsvDataBindConfigを使用してフォーマットを指定する。CsvDataBindConfig#withPropertiesで設定したプロパティ名がMapオブジェクトのキーとして使用される。CSVにヘッダ行が存在する場合は、プロパティ名の設定を省略することでヘッダタイトルをキーとして使用できる。", + "class": "nablarch.common.databind.csv.CsvDataBindConfig", + "methods": [ + { + "name": "withProperties", + "signature": "public CsvDataBindConfig withProperties(String... properties)", + "description": "プロパティ名を設定する。設定したプロパティ名がMapオブジェクトのキーとして使用される。", + "parameters": [ + { + "name": "properties", + "type": "String...", + "description": "プロパティ名(CSV項目順)" + } + ], + "returns": "CsvDataBindConfig" + }, + { + "name": "withHeaderTitles", + "signature": "public CsvDataBindConfig withHeaderTitles(String... headerTitles)", + "description": "ヘッダタイトルを設定する。", + "parameters": [ + { + "name": "headerTitles", + "type": "String...", + "description": "ヘッダタイトル(CSV項目順)" + } + ], + "returns": "CsvDataBindConfig" + } + ], + "example": "// ヘッダタイトル、プロパティ名はCSVの項目順と一致するように定義する\nDataBindConfig config = CsvDataBindConfig.DEFAULT.withHeaderTitles(\"年齢\", \"名前\")\n .withProperties(\"age\", \"name\");\nObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config);", + "point": "ヘッダタイトル、プロパティ名はCSVの項目順と一致するように定義すること" + }, + "fixed_length_format_beans": { + "description": "Java Beansクラスにバインドして固定長ファイルを扱う場合、@FixedLengthおよび@Fieldアノテーションを使用してフォーマットを指定する。各フィールドに対し、パディングやトリム等を変換するコンバータ(@Lpad, @Rpad等)を指定できる。未使用領域が存在するフォーマットの場合、固定長ファイルへの書き込み時にFixedLength#fillCharに設定した文字で自動的にパディングされる。", + "annotations": [ + { + "name": "@FixedLength", + "class": "nablarch.common.databind.fixedlength.FixedLength", + "attributes": [ + { + "name": "length", + "type": "int", + "required": true, + "description": "1レコードの長さ(バイト数)" + }, + { + "name": "charset", + "type": "String", + "required": false, + "default": "UTF-8", + "description": "文字コード" + }, + { + "name": "lineSeparator", + "type": "String", + "required": false, + "default": "\\r\\n", + "description": "行区切り文字" + }, + { + "name": "fillChar", + "type": "char", + "required": false, + "default": " (半角スペース)", + "description": "未使用領域のパディング文字" + }, + { + "name": "multiLayout", + "type": "boolean", + "required": false, + "default": "false", + "description": "複数フォーマットを持つファイルか" + } + ], + "example": "@FixedLength(length = 19, charset = \"MS932\", lineSeparator = \"\\r\\n\")\npublic class Person {\n @Field(offset = 1, length = 3)\n @Lpad\n private Integer age;\n\n @Field(offset = 4, length = 16)\n @Rpad\n private String name;\n // getter、setterは省略\n}" + }, + { + "name": "@Field", + "class": "nablarch.common.databind.fixedlength.Field", + "attributes": [ + { + "name": "offset", + "type": "int", + "required": true, + "description": "フィールドの開始位置(1始まり)" + }, + { + "name": "length", + "type": "int", + "required": true, + "description": "フィールドの長さ(バイト数)" + } + ] + }, + { + "name": "@Lpad", + "class": "nablarch.common.databind.fixedlength.converter.Lpad", + "description": "左詰めでパディング(読み込み時はトリム)を行うコンバータ" + }, + { + "name": "@Rpad", + "class": "nablarch.common.databind.fixedlength.converter.Rpad", + "description": "右詰めでパディング(読み込み時はトリム)を行うコンバータ" + } + ], + "converters": [ + "nablarch.common.databind.fixedlength.converter.Lpad - 左詰めパディング", + "nablarch.common.databind.fixedlength.converter.Rpad - 右詰めパディング", + "その他のコンバータはnablarch.common.databind.fixedlength.converterパッケージ配下を参照" + ], + "example": "@FixedLength(length = 24, charset = \"MS932\", lineSeparator = \"\\r\\n\", fillChar = '0')\npublic class Person {\n @Field(offset = 1, length = 3)\n @Lpad\n private Integer age;\n\n @Field(offset = 9, length = 16)\n @Rpad\n private String name;\n // getter、setterは省略\n}", + "note": "未使用領域(offset 4-8)は、fillCharに設定した文字(この例では'0')で自動的にパディングされる。" + }, + "fixed_length_format_map": { + "description": "Mapクラスにバインドして固定長ファイルを扱う場合、ObjectMapperの生成時にFixedLengthDataBindConfigを使用してフォーマットを指定する。FixedLengthDataBindConfigは、FixedLengthDataBindConfigBuilderを使用して生成できる。", + "class": "nablarch.common.databind.fixedlength.FixedLengthDataBindConfig", + "builder_class": "nablarch.common.databind.fixedlength.FixedLengthDataBindConfigBuilder", + "methods": [ + { + "name": "newBuilder", + "signature": "public static FixedLengthDataBindConfigBuilder newBuilder()", + "description": "ビルダーのインスタンスを生成する", + "returns": "FixedLengthDataBindConfigBuilder" + }, + { + "name": "length", + "signature": "public FixedLengthDataBindConfigBuilder length(int length)", + "description": "1レコードの長さを設定する", + "parameters": [ + { + "name": "length", + "type": "int", + "description": "1レコードの長さ(バイト数)" + } + ], + "returns": "FixedLengthDataBindConfigBuilder" + }, + { + "name": "charset", + "signature": "public FixedLengthDataBindConfigBuilder charset(Charset charset)", + "description": "文字コードを設定する", + "parameters": [ + { + "name": "charset", + "type": "Charset", + "description": "文字コード" + } + ], + "returns": "FixedLengthDataBindConfigBuilder" + }, + { + "name": "lineSeparator", + "signature": "public FixedLengthDataBindConfigBuilder lineSeparator(String lineSeparator)", + "description": "行区切り文字を設定する", + "parameters": [ + { + "name": "lineSeparator", + "type": "String", + "description": "行区切り文字" + } + ], + "returns": "FixedLengthDataBindConfigBuilder" + }, + { + "name": "singleLayout", + "signature": "public SingleLayoutBuilder singleLayout()", + "description": "シングルレイアウト(単一フォーマット)の設定を開始する", + "returns": "SingleLayoutBuilder" + }, + { + "name": "field", + "signature": "public SingleLayoutBuilder field(String name, int offset, int length, FieldConverter converter)", + "description": "フィールドを定義する", + "parameters": [ + { + "name": "name", + "type": "String", + "description": "フィールド名(Mapのキーとして使用)" + }, + { + "name": "offset", + "type": "int", + "description": "開始位置(1始まり)" + }, + { + "name": "length", + "type": "int", + "description": "長さ(バイト数)" + }, + { + "name": "converter", + "type": "FieldConverter", + "description": "コンバータ(Lpad.Converter, Rpad.RpadConverter等)" + } + ], + "returns": "SingleLayoutBuilder" + }, + { + "name": "build", + "signature": "public DataBindConfig build()", + "description": "FixedLengthDataBindConfigを生成する", + "returns": "DataBindConfig" + } + ], + "example": "final DataBindConfig config = FixedLengthDataBindConfigBuilder\n .newBuilder()\n .length(19)\n .charset(Charset.forName(\"MS932\"))\n .lineSeparator(\"\\r\\n\")\n .singleLayout()\n .field(\"age\", 1, 3, new Lpad.Converter('0'))\n .field(\"name\", 4, 16, new Rpad.RpadConverter(' '))\n .build();\n\nfinal ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config);" + }, + "multi_layout": { + "description": "複数のフォーマットを持つ固定長ファイルに対応する。Java BeansクラスまたはMapクラスにバインドできる。", + "beans_approach": { + "description": "フォーマットごとにJava Beansクラスを定義し、それらのJava Beansクラスをプロパティとして持つMultiLayoutの継承クラスを作成する。", + "class": "nablarch.common.databind.fixedlength.MultiLayout", + "steps": [ + "フォーマットごとにJava Beansクラスを定義する", + "上記のフォーマットを定義したJava Beansクラスをプロパティとして持つMultiLayoutの継承クラスを定義する", + "MultiLayoutの継承クラスに@FixedLengthアノテーションを設定し、multiLayout属性にtrueを設定する", + "MultiLayout#getRecordIdentifierメソッドをオーバーライドして、対象のデータがどのフォーマットに紐づくかを識別するRecordIdentifierの実装クラスを返却する" + ], + "annotations": [ + { + "name": "@Record", + "class": "nablarch.common.databind.fixedlength.Record", + "description": "フォーマットを表すJava Beansクラスのプロパティに付与する" + } + ], + "example": "@FixedLength(length = 20, charset = \"MS932\", lineSeparator = \"\\r\\n\", multiLayout = true)\npublic class Person extends MultiLayout {\n @Record\n private Header header;\n\n @Record\n private Data data;\n\n @Override\n public RecordIdentifier getRecordIdentifier() {\n return new RecordIdentifier() {\n @Override\n public RecordName identifyRecordName(byte[] record) {\n return record[0] == 0x31 ? RecordType.HEADER : RecordType.DATA;\n }\n };\n }\n // getter、setterは省略\n}\n\npublic class Header {\n @Field(offset = 1, length = 1)\n private Long id;\n\n @Rpad\n @Field(offset = 2, length = 19)\n private String field;\n // getter、setterは省略\n}\n\npublic class Data {\n @Field(offset = 1, length = 1)\n private Long id;\n\n @Lpad\n @Field(offset = 2, length = 3)\n private Long age;\n\n @Rpad\n @Field(offset = 5, length = 16)\n private String name;\n // getter、setterは省略\n}\n\nenum RecordType implements MultiLayoutConfig.RecordName {\n HEADER {\n @Override\n public String getRecordName() {\n return \"header\";\n }\n },\n DATA {\n @Override\n public String getRecordName() {\n return \"data\";\n }\n }\n}", + "usage_read": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n final Person person = mapper.read();\n if (RecordType.HEADER == person.getRecordName()) {\n final Header header = person.getHeader();\n // 後続の処理は省略\n }\n}", + "usage_write": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, outputStream)) {\n final Person person = new Person();\n person.setHeader(new Header(\"1\", \"test\"));\n mapper.write(person);\n}" + }, + "map_approach": { + "description": "FixedLengthDataBindConfigBuilderのmultiLayoutメソッドを使用して複数フォーマットを定義する。", + "methods": [ + { + "name": "multiLayout", + "signature": "public MultiLayoutBuilder multiLayout()", + "description": "マルチレイアウト用のDataBindConfigを生成する", + "returns": "MultiLayoutBuilder" + }, + { + "name": "record", + "signature": "public RecordBuilder record(String recordName)", + "description": "レコードタイプを定義する", + "parameters": [ + { + "name": "recordName", + "type": "String", + "description": "レコード名" + } + ], + "returns": "RecordBuilder" + }, + { + "name": "recordIdentifier", + "signature": "public MultiLayoutBuilder recordIdentifier(RecordIdentifier recordIdentifier)", + "description": "対象のデータがどのフォーマットに紐づくかを識別するRecordIdentifierを設定する", + "parameters": [ + { + "name": "recordIdentifier", + "type": "RecordIdentifier", + "description": "レコード識別子の実装" + } + ], + "returns": "MultiLayoutBuilder" + } + ], + "example": "final DataBindConfig config = FixedLengthDataBindConfigBuilder\n .newBuilder()\n .length(20)\n .charset(Charset.forName(\"MS932\"))\n .lineSeparator(\"\\r\\n\")\n .multiLayout()\n .record(\"header\")\n .field(\"id\", 1, 1, new DefaultConverter())\n .field(\"field\", 2, 19, new Rpad.RpadConverter(' '))\n .record(\"data\")\n .field(\"id\", 1, 1, new DefaultConverter())\n .field(\"age\", 2, 3, new Lpad.LpadConverter('0'))\n .field(\"name\", 5, 16, new Rpad.RpadConverter(' '))\n .recordIdentifier(new RecordIdentifier() {\n @Override\n public RecordName identifyRecordName(byte[] record) {\n return record[0] == 0x31 ? RecordType.HEADER : RecordType.DATA;\n }\n })\n .build();", + "usage_read": "try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, inputStream, config)) {\n final Map map = mapper.read();\n if (RecordType.HEADER == map.get(\"recordName\")) {\n final Map header = map.get(\"header\");\n // 後続の処理は省略\n }\n}", + "usage_write": "try (ObjectMapper mapper = ObjectMapperFactory.create(Map.class, outputStream, config)) {\n final Map header = new HashMap<>();\n header.put(\"id\", \"1\");\n header.put(\"field\", \"test\");\n\n final Map map = new HashMap<>();\n map.put(\"recordName\", RecordType.HEADER);\n map.put(\"header\", header);\n\n mapper.write(map);\n}" + } + }, + "formatter": { + "description": "データを出力する際に、format機能を使用することで日付や数値などのデータの表示形式をフォーマットできる。", + "reference": "詳細はformat機能のドキュメントを参照すること。" + }, + "extension": { + "description": "Java Beansクラスにバインドできるファイル形式を追加する方法", + "steps": [ + { + "step": 1, + "description": "指定した形式のファイルとJava Beansクラスをバインドさせるため、ObjectMapperの実装クラスを作成する" + }, + { + "step": 2, + "description": "ObjectMapperFactoryを継承したクラスを作成し、先ほど作成したObjectMapperの実装クラスを生成する処理を追加する" + }, + { + "step": 3, + "description": "ObjectMapperFactoryの継承クラスをコンポーネント設定ファイルに設定する。コンポーネント名はobjectMapperFactoryとすること。", + "example": "" + } + ] + }, + "csv_format_sets": { + "description": "デフォルトで提供しているCSVファイルのフォーマットセット及び設定値", + "format_sets": [ + { + "name": "DEFAULT", + "fieldSeparator": "カンマ(,)", + "lineSeparator": "改行(\\r\\n)", + "quote": "ダブルクォート(\")", + "ignoreEmptyLine": true, + "requiredHeader": true, + "charset": "UTF-8", + "quoteMode": "NORMAL" + }, + { + "name": "RFC4180", + "fieldSeparator": "カンマ(,)", + "lineSeparator": "改行(\\r\\n)", + "quote": "ダブルクォート(\")", + "ignoreEmptyLine": false, + "requiredHeader": false, + "charset": "UTF-8", + "quoteMode": "NORMAL" + }, + { + "name": "EXCEL", + "fieldSeparator": "カンマ(,)", + "lineSeparator": "改行(\\r\\n)", + "quote": "ダブルクォート(\")", + "ignoreEmptyLine": false, + "requiredHeader": false, + "charset": "UTF-8", + "quoteMode": "NORMAL" + }, + { + "name": "TSV", + "fieldSeparator": "タブ(\\t)", + "lineSeparator": "改行(\\r\\n)", + "quote": "ダブルクォート(\")", + "ignoreEmptyLine": false, + "requiredHeader": false, + "charset": "UTF-8", + "quoteMode": "NORMAL" + } + ], + "quote_modes": [ + { + "name": "NORMAL", + "description": "フィールド囲み文字、列区切り文字、改行のいずれかを含むフィールドのみフィールド囲み文字で囲む" + }, + { + "name": "ALL", + "description": "全てのフィールドをフィールド囲み文字で囲む" + } + ], + "note": "CSVファイルの読み込み時は、クォートモードは使用せずに自動的にフィールド囲み文字の有無を判定して読み込みを行う。" + }, + "anti-patterns": [ + { + "pattern": "外部から受け付けたアップロードファイルのデータをJava Beansとして読み込む際、Java BeansクラスのプロパティをIntegerやDate等の型で定義する", + "reason": "アップロードファイルなどの外部から受け付けたデータには不正なデータが含まれる可能性がある。型変換に失敗すると例外が発生しJava Beansオブジェクトが生成されないため、不正な値を業務エラーとして通知できず異常終了となってしまう。", + "correct": "外部から受け付けたデータを読み込む場合は、Java BeansクラスのプロパティをすべてString型で定義し、Bean Validationで入力値チェックを行うこと。", + "example_correct": "@Csv(type = Csv.CsvType.DEFAULT, properties = {\"age\", \"name\"})\npublic class Person {\n @NumberRange(min = 0, max = 150)\n private String age; // String型で定義\n\n @Required\n private String name; // String型で定義\n // getter、setterは省略\n}" + }, + { + "pattern": "ObjectMapperのclose()を呼び出さずにリソースを解放しない", + "reason": "ObjectMapperは内部でストリームなどのリソースを保持しているため、close()を呼び出さないとリソースリークが発生する。", + "correct": "try-with-resourcesを使用してObjectMapperを生成することで、自動的にclose()が呼ばれるようにする。", + "example_correct": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n // 処理\n} // 自動的にclose()が呼ばれる" + }, + { + "pattern": "ObjectMapperのインスタンスを複数スレッドで共有する", + "reason": "ObjectMapperの読み込み及び書き込みはスレッドアンセーフであるため、複数スレッドから同時に呼び出された場合の動作は保証されない。", + "correct": "ObjectMapperのインスタンスを複数スレッドで共有するような場合には、呼び出し元にて同期処理を行うこと。または、スレッドごとにObjectMapperのインスタンスを生成すること。" + }, + { + "pattern": "Java Beansクラスにバインドする際に、ObjectMapperの生成時にDataBindConfigを指定する", + "reason": "Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、DataBindConfigを使用したフォーマットの指定はできない。DataBindConfigはMapクラスにバインドする場合にのみ使用する。", + "correct": "Java Beansクラスにバインドする場合は、@Csvや@FixedLengthなどのアノテーションでフォーマットを指定すること。" + }, + { + "pattern": "ファイルダウンロード時にデータをメモリ上に全て展開してからレスポンスに設定する", + "reason": "大量データのダウンロード時にメモリを圧迫する恐れがある。", + "correct": "一時ファイルに出力し、FileResponseでファイルを指定する。FileResponseのコンストラクタの第二引数にtrueを指定すると、リクエスト処理の終了時に自動的にファイルを削除する。", + "example_correct": "final Path path = Files.createTempFile(null, null);\ntry (ObjectMapper mapper =\n ObjectMapperFactory.create(Person.class, Files.newOutputStream(path))) {\n for (Person person : persons) {\n mapper.write(person);\n }\n}\nFileResponse response = new FileResponse(path.toFile(), true);" + }, + { + "pattern": "CsvDataBindConfigやFixedLengthDataBindConfigで定義したプロパティ名やフィールド名の順序がファイルの項目順と一致していない", + "reason": "ヘッダタイトル、プロパティ名、フィールド定義はファイルの項目順と一致するように定義する必要がある。順序が一致していないと、データが正しくバインドされない。", + "correct": "ヘッダタイトル、プロパティ名、フィールド定義はファイルの項目順と一致するように定義すること。" + } + ], + "errors": [ + { + "exception": "nablarch.common.databind.InvalidDataFormatException", + "cause": "読み込んだデータのフォーマットが不正な場合に発生する。例えば、CSVファイルで囲み文字が閉じられていない、固定長ファイルでレコード長が不正、型変換に失敗した場合などに発生する。", + "solution": "データファイルのフォーマットを確認し、正しいフォーマットで作成されているか検証する。外部から受け付けるファイルの場合は、try-catchでInvalidDataFormatExceptionを捕捉し、ユーザーに適切なエラーメッセージを表示する。", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n // 処理\n }\n} catch (InvalidDataFormatException e) {\n // データファイルのフォーマット不正時の処理を記述\n log.error(\"データフォーマットが不正です: \" + e.getMessage());\n}" + }, + { + "exception": "型変換エラー(InvalidDataFormatExceptionの一種)", + "cause": "Java Beansクラスへの変換時、Java Beansクラスに定義されたプロパティの型に自動的に型変換するが、型変換に失敗した場合に発生する。例えば、Integerプロパティにアルファベットがバインドされようとした場合など。", + "solution": "外部から受け付けたデータを読み込む場合は、Java BeansクラスのプロパティはすべてString型で定義し、Bean Validationで入力値チェックを行うこと。", + "example": "// Java Beansクラスの定義\n@Csv(type = Csv.CsvType.DEFAULT, properties = {\"age\", \"name\"})\npublic class Person {\n @NumberRange(min = 0, max = 150)\n private String age; // String型で定義\n\n @Required\n private String name; // String型で定義\n}\n\n// 使用例\ntry (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n Person person;\n while ((person = mapper.read()) != null) {\n ValidatorUtil.validate(person); // Bean Validationで検証\n }\n}" + } + ], + "tips": [ + { + "title": "try-with-resourcesの使用", + "description": "全データの読み込みが完了したら、ObjectMapper#closeでリソースを解放すること。try-with-resourcesを使用することでクローズ処理を省略可能。", + "example": "try (ObjectMapper mapper = ObjectMapperFactory.create(Person.class, inputStream)) {\n // 処理\n} // 自動的にclose()が呼ばれる" + }, + { + "title": "null値の出力", + "description": "プロパティの値がnullの場合は、未入力を表す値が出力される。例えば、CSVファイルに書き込む場合は空文字が出力される。Mapオブジェクトの場合も同様に、value値がnullの場合は空文字が出力される。" + }, + { + "title": "Mapオブジェクトでは行番号取得不可", + "description": "論理行番号の取得は@LineNumberアノテーションを使用するが、これはJava Beansクラスにのみ適用可能。Mapオブジェクトとして取得する場合は、データの行番号を取得できない点に注意すること。" + }, + { + "title": "CSVファイル読み込み時のクォートモード", + "description": "CSVファイルの読み込み時は、クォートモードは使用せずに自動的にフィールド囲み文字の有無を判定して読み込みを行う。クォートモードはCSVファイル書き込み時にのみ使用される。" + }, + { + "title": "ヘッダタイトルをMapのキーとして使用", + "description": "MapクラスにバインドしてCSVを読み込む場合、CSVにヘッダ行が存在する場合は、CsvDataBindConfig#withPropertiesの設定を省略することでヘッダタイトルをMapのキーとして使用できる。" + } + ], + "limitations": [ + "ObjectMapperの読み込み及び書き込みはスレッドアンセーフであるため、複数スレッドから同時に呼び出された場合の動作は保証しない。ObjectMapperのインスタンスを複数スレッドで共有する場合には、呼び出し元にて同期処理を行うこと。", + "Java Beansクラスにバインドする場合、フォーマット指定はアノテーションで行うため、ObjectMapperの生成時にDataBindConfigを使用したフォーマットの指定はできない。", + "Mapオブジェクトとして取得する場合は、データの論理行番号を取得できない。行番号が必要な場合はJava Beansクラスを使用すること。", + "Mapオブジェクトへの変換時、値は全てString型で格納される。型変換が必要な場合は別途実装する必要がある。" + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/libraries/database-access.json b/.claude/skills/nabledge-6/knowledge/features/libraries/database-access.json new file mode 100644 index 0000000..76be8e0 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/libraries/database-access.json @@ -0,0 +1,1102 @@ +{ + "id": "database-access", + "title": "データベースアクセス(JDBCラッパー)", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/database/database.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "データベースアクセス", + "JDBCラッパー", + "AppDbConnection", + "PreparedStatement", + "JDBC" + ] + }, + { + "id": "dialect", + "hints": [ + "Dialect", + "ダイアレクト", + "データベース製品", + "方言", + "OracleDialect", + "PostgreSQLDialect" + ] + }, + { + "id": "sql_file", + "hints": [ + "SQLファイル", + "SQL管理", + "SQLID", + "sql拡張子", + "BasicSqlLoader" + ] + }, + { + "id": "execute_sql", + "hints": [ + "SQL実行", + "prepareStatementBySqlId", + "retrieve", + "executeUpdate", + "SqlPStatement", + "DbConnectionContext" + ] + }, + { + "id": "input_bean", + "hints": [ + "Beanオブジェクト", + "名前付きバインド変数", + "ParameterizedSqlPStatement", + "executeUpdateByObject", + "コロン記法" + ] + }, + { + "id": "paging", + "hints": [ + "ページング", + "範囲指定", + "SelectOption", + "offset", + "limit" + ] + }, + { + "id": "like_search", + "hints": [ + "like検索", + "前方一致", + "後方一致", + "途中一致", + "エスケープ", + "likeEscapeChar" + ] + }, + { + "id": "variable_condition", + "hints": [ + "可変条件", + "$if", + "動的SQL", + "条件分岐" + ] + }, + { + "id": "in_clause", + "hints": [ + "in句", + "可変in", + "配列", + "Collection", + "ブラケット記法" + ] + }, + { + "id": "order_by", + "hints": [ + "order by", + "ソート", + "$sort", + "動的ソート", + "ソートID" + ] + }, + { + "id": "auto_property", + "hints": [ + "自動設定", + "AutoPropertyHandler", + "CurrentDateTime", + "登録日時", + "更新日時" + ] + }, + { + "id": "binary_column", + "hints": [ + "バイナリ型", + "BLOB", + "setBinaryStream", + "getBinaryStream", + "byte配列" + ] + }, + { + "id": "clob_column", + "hints": [ + "CLOB", + "文字列型", + "setCharacterStream", + "getCharacterStream", + "大容量テキスト" + ] + }, + { + "id": "stored_procedure", + "hints": [ + "ストアードプロシージャ", + "prepareCallBySqlId", + "SqlCStatement", + "registerOutParameter" + ] + }, + { + "id": "separate_transaction", + "hints": [ + "別トランザクション", + "SimpleDbTransactionManager", + "SimpleDbTransactionExecutor", + "個別トランザクション" + ] + }, + { + "id": "cache", + "hints": [ + "検索結果キャッシュ", + "CacheableStatementFactory", + "InMemoryResultSetCache", + "有効期限" + ] + }, + { + "id": "schema_replacement", + "hints": [ + "スキーマ置換", + "SchemaReplacer", + "#SCHEMA#", + "環境切り替え" + ] + }, + { + "id": "configuration", + "hints": [ + "接続設定", + "BasicDbConnectionFactoryForDataSource", + "BasicDbConnectionFactoryForJndi", + "ConnectionFactory", + "DataSource" + ] + }, + { + "id": "exceptions", + "hints": [ + "DbAccessException", + "SqlStatementException", + "DuplicateStatementException", + "DbConnectionException", + "一意制約違反" + ] + }, + { + "id": "anti-patterns", + "hints": [ + "SQLインジェクション", + "SQL文字列連結", + "SQL共通化", + "ストアードプロシージャ" + ] + }, + { + "id": "tips", + "hints": [ + "型変換", + "java.sql.Connection", + "DatabaseMetaData", + "フィールドアクセス" + ] + }, + { + "id": "limitations", + "hints": [ + "JDBC 3.0", + "LOB型", + "キャッシュ制約", + "ResultSet" + ] + } + ], + "sections": { + "overview": { + "classes": [ + "nablarch.core.db.connection.AppDbConnection", + "nablarch.core.db.statement.SqlPStatement", + "nablarch.core.db.statement.ParameterizedSqlPStatement", + "nablarch.core.db.statement.SqlCStatement", + "nablarch.core.db.statement.SqlRow", + "nablarch.core.db.statement.SqlResultSet", + "nablarch.core.db.connection.DbConnectionContext" + ], + "description": "JDBCを使用してデータベースに対してSQL文を実行する機能を提供する。UniversalDao内部でも使用されており、データベースアクセスには必須の機能。", + "purpose": "JDBCをラップし、安全で簡潔なデータベースアクセスを実現する。SQLインジェクション対策、動的SQL構築、ページングなどの機能を提供。", + "modules": [ + "com.nablarch.framework:nablarch-core-jdbc" + ], + "key_features": [ + "SQLファイルによるSQL管理でSQLインジェクション脆弱性を排除", + "データベース製品の方言(Dialect)を意識せずに開発可能", + "Beanオブジェクトを使用した名前付きバインド変数", + "動的な条件構築($if、in句、order by)", + "like検索の自動エスケープ処理", + "検索結果のキャッシュ機能" + ], + "recommendation": "SQLの実行にはUniversalDaoの使用を推奨。JDBCラッパーは設定が必須で、UniversalDao内部でも使用される。" + }, + "dialect": { + "description": "データベース製品ごとの違い(方言)を吸収するためのDialectインタフェースを提供。製品に対応したDialectを設定することで、方言を意識せずにアプリケーション実装が可能。", + "classes": [ + "nablarch.core.db.dialect.Dialect", + "nablarch.core.db.dialect.DefaultDialect", + "nablarch.core.db.dialect.OracleDialect", + "nablarch.core.db.dialect.PostgreSQLDialect", + "nablarch.core.db.dialect.DB2Dialect", + "nablarch.core.db.dialect.SqlServerDialect", + "nablarch.core.db.dialect.H2Dialect" + ], + "methods": [ + { + "name": "supportsIdentity", + "signature": "boolean supportsIdentity()", + "description": "identityカラム(自動採番)を使用できるか否かを返す", + "returns": "使用可能な場合true" + }, + { + "name": "supportsIdentityWithBatchInsert", + "signature": "boolean supportsIdentityWithBatchInsert()", + "description": "identity(自動採番)カラムを持つテーブルに対してbatch insertが可能か否かを返す", + "returns": "可能な場合true" + }, + { + "name": "supportsSequence", + "signature": "boolean supportsSequence()", + "description": "シーケンスオブジェクトを使用できるか否かを返す", + "returns": "使用可能な場合true" + }, + { + "name": "supportsOffset", + "signature": "boolean supportsOffset()", + "description": "検索クエリーの範囲指定でoffset(またはoffsetと同等の機能)を使用できるか否かを返す", + "returns": "使用可能な場合true" + }, + { + "name": "isDuplicateException", + "signature": "boolean isDuplicateException(SQLException sqlException)", + "description": "一意制約違反を表すSQLExceptionか否かを判定する", + "parameters": [ + { + "name": "sqlException", + "type": "java.sql.SQLException", + "description": "判定対象の例外" + } + ], + "returns": "一意制約違反の場合true" + }, + { + "name": "isTransactionTimeoutError", + "signature": "boolean isTransactionTimeoutError(SQLException sqlException)", + "description": "トランザクションタイムアウト対象のSQLExceptionか否かを判定する", + "parameters": [ + { + "name": "sqlException", + "type": "java.sql.SQLException", + "description": "判定対象の例外" + } + ], + "returns": "トランザクションタイムアウトの場合true" + }, + { + "name": "buildSequenceGeneratorSql", + "signature": "String buildSequenceGeneratorSql(String sequenceName)", + "description": "シーケンスオブジェクトから次の値を取得するSQL文を生成する", + "parameters": [ + { + "name": "sequenceName", + "type": "String", + "description": "シーケンス名" + } + ], + "returns": "シーケンス値取得SQL" + }, + { + "name": "getResultSetConvertor", + "signature": "ResultSetConvertor getResultSetConvertor()", + "description": "ResultSetから値を取得するResultSetConvertorを返す", + "returns": "ResultSetConvertor実装" + }, + { + "name": "convertPaginationSql", + "signature": "String convertPaginationSql(String sql, SelectOption selectOption)", + "description": "検索クエリーを範囲指定(ページング用)SQLに変換する", + "parameters": [ + { + "name": "sql", + "type": "String", + "description": "元のSQL" + }, + { + "name": "selectOption", + "type": "nablarch.core.db.statement.SelectOption", + "description": "範囲指定オプション" + } + ], + "returns": "範囲指定SQL" + }, + { + "name": "convertCountSql", + "signature": "String convertCountSql(String sql)", + "description": "検索クエリーを件数取得SQLに変換する", + "parameters": [ + { + "name": "sql", + "type": "String", + "description": "元のSQL" + } + ], + "returns": "件数取得SQL" + }, + { + "name": "getPingSql", + "signature": "String getPingSql()", + "description": "Connectionがデータベースに接続されているかチェックを行うSQLを返す", + "returns": "接続確認SQL" + } + ], + "configuration_example": "dialectプロパティにデータベース製品対応のDialect実装クラスを設定する。例: OracleDialect、PostgreSQLDialect等。", + "notes": "設定しなかった場合はDefaultDialectが使用されるが、原則全ての機能が無効化されるため、必ずデータベース製品に対応したDialectを設定すること。" + }, + "sql_file": { + "description": "SQLはロジックに記述せず、SQLファイルに定義する。SQLファイルに記述することで、必ずPreparedStatementを使用するため、SQLインジェクションの脆弱性が排除できる。", + "file_rules": [ + "クラスパス配下に作成する", + "1つのSQLファイルに複数のSQLを記述できるが、SQLIDはファイル内で一意とする", + "SQLIDとSQLIDとの間には空行を挿入する(スペースが存在する行は空行とはみなさない)", + "SQLIDとSQLとの間には = を入れる", + "コメントは -- で記述する(ブロックコメントはサポートしない)", + "SQLは改行やスペース(tab)などで整形してもよい" + ], + "sql_id_format": "SQLIDの#までがSQLファイル名、#以降がSQLファイル内のSQLIDとなる。例: jp.co.tis.sample.action.SampleAction#findUser → ファイル名: jp.co.tis.sample.action.SampleAction.sql、SQLID: findUser", + "example": "-- XXXXX取得SQL\n-- SQL_ID:GET_XXXX_INFO\nGET_XXXX_INFO =\nselect\n col1,\n col2\nfrom\n test_table\nwhere\n col1 = :col1", + "configuration_class": "nablarch.core.db.statement.BasicSqlLoader", + "configuration_properties": [ + { + "name": "fileEncoding", + "type": "String", + "required": false, + "default": "utf-8", + "description": "SQLファイルのエンコーディング" + }, + { + "name": "extension", + "type": "String", + "required": false, + "default": "sql", + "description": "SQLファイルの拡張子" + } + ] + }, + "execute_sql": { + "description": "SQLIDを指定してSQLを実行する基本的な方法。DbConnectionContextからデータベース接続を取得し、prepareStatementBySqlIdでステートメントを生成して実行する。", + "methods": [ + { + "name": "prepareStatementBySqlId", + "signature": "SqlPStatement prepareStatementBySqlId(String sqlId)", + "description": "SQLIDを元にステートメントを生成する", + "parameters": [ + { + "name": "sqlId", + "type": "String", + "description": "SQLID(形式: パッケージ名.クラス名#SQLID)" + } + ], + "returns": "SqlPStatementオブジェクト", + "example": "SqlPStatement statement = connection.prepareStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#findUser\");\nstatement.setLong(1, userId);\nSqlResultSet result = statement.retrieve();" + }, + { + "name": "retrieve", + "signature": "SqlResultSet retrieve()", + "description": "検索処理を実行し、結果を返す", + "returns": "SqlResultSetオブジェクト(検索結果)" + }, + { + "name": "executeUpdate", + "signature": "int executeUpdate()", + "description": "更新系SQL(INSERT、UPDATE、DELETE)を実行する", + "returns": "更新件数" + }, + { + "name": "setLong", + "signature": "void setLong(int parameterIndex, long x)", + "description": "指定されたパラメータインデックスにlong値を設定する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス(1始まり)" + }, + { + "name": "x", + "type": "long", + "description": "設定する値" + } + ] + }, + { + "name": "setString", + "signature": "void setString(int parameterIndex, String x)", + "description": "指定されたパラメータインデックスにString値を設定する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス(1始まり)" + }, + { + "name": "x", + "type": "String", + "description": "設定する値" + } + ] + }, + { + "name": "setBytes", + "signature": "void setBytes(int parameterIndex, byte[] x)", + "description": "指定されたパラメータインデックスにbyte配列を設定する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス(1始まり)" + }, + { + "name": "x", + "type": "byte[]", + "description": "設定する値" + } + ] + } + ], + "usage_pattern": "AppDbConnection connection = DbConnectionContext.getConnection();\nSqlPStatement statement = connection.prepareStatementBySqlId(sqlId);\n// バインド変数設定\nSqlResultSet result = statement.retrieve();" + }, + "input_bean": { + "description": "Beanオブジェクトのプロパティ値をSQLのINパラメータに自動的にバインドする機能。名前付きバインド変数を使用することで、インデクスの管理が不要となり、INパラメータの増減に強い実装が可能。", + "bind_variable_format": "名前付きバインド変数は :プロパティ名 の形式で記述する。例: :id、:userName", + "methods": [ + { + "name": "prepareParameterizedSqlStatementBySqlId", + "signature": "ParameterizedSqlPStatement prepareParameterizedSqlStatementBySqlId(String sqlId)", + "description": "SQLIDを元にパラメータ化されたステートメントを生成する", + "parameters": [ + { + "name": "sqlId", + "type": "String", + "description": "SQLID" + } + ], + "returns": "ParameterizedSqlPStatementオブジェクト" + }, + { + "name": "executeUpdateByObject", + "signature": "int executeUpdateByObject(Object object)", + "description": "Beanオブジェクトのプロパティ値をバインド変数に設定してSQL(更新系)を実行する", + "parameters": [ + { + "name": "object", + "type": "Object", + "description": "BeanオブジェクトまたはMap" + } + ], + "returns": "更新件数", + "example": "UserEntity entity = new UserEntity();\nentity.setId(1);\nentity.setUserName(\"なまえ\");\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#insertUser\");\nint result = statement.executeUpdateByObject(entity);" + }, + { + "name": "retrieve", + "signature": "SqlResultSet retrieve(Object object)", + "description": "Beanオブジェクトのプロパティ値をバインド変数に設定してSQL(検索系)を実行する", + "parameters": [ + { + "name": "object", + "type": "Object", + "description": "BeanオブジェクトまたはMap" + } + ], + "returns": "SqlResultSet(検索結果)" + } + ], + "sql_example": "insert into user (\n id,\n name\n) values (\n :id,\n :userName\n)", + "notes": [ + "BeanオブジェクトはBeanUtilを使用してMapに変換後に処理される", + "Mapを指定した場合は、Mapのキー値と一致するINパラメータに対してMapの値が設定される", + "BeanUtilで対応していない型がBeanのプロパティに存在した場合、そのプロパティは使用できない", + "INパラメータをJDBC標準の?で記述した場合、Beanオブジェクトを入力としたSQL実行は動作しない" + ] + }, + "paging": { + "description": "ウェブシステムの一覧検索画面などで使用するページング機能。検索結果の範囲を指定することで、特定の範囲のレコードのみを取得できる。", + "classes": [ + "nablarch.core.db.statement.SelectOption" + ], + "methods": [ + { + "name": "SelectOption (constructor)", + "signature": "SelectOption(int offset, int limit)", + "description": "検索範囲を指定するSelectOptionオブジェクトを生成する", + "parameters": [ + { + "name": "offset", + "type": "int", + "description": "開始位置(1始まり)" + }, + { + "name": "limit", + "type": "int", + "description": "取得件数" + } + ] + }, + { + "name": "prepareStatementBySqlId (with SelectOption)", + "signature": "SqlPStatement prepareStatementBySqlId(String sqlId, SelectOption selectOption)", + "description": "SQLIDと検索範囲を指定してステートメントを生成する", + "parameters": [ + { + "name": "sqlId", + "type": "String", + "description": "SQLID" + }, + { + "name": "selectOption", + "type": "SelectOption", + "description": "検索範囲" + } + ], + "returns": "SqlPStatementオブジェクト", + "example": "SqlPStatement statement = connection.prepareStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#findUser\", new SelectOption(11, 10));\nSqlResultSet result = statement.retrieve();" + } + ], + "notes": "検索範囲が指定された場合、検索用のSQLを取得範囲指定のSQLに書き換えてから実行する。取得範囲指定のSQLはDialectにより生成される。" + }, + "like_search": { + "description": "like検索に対するescape句の挿入とワイルドカード文字のエスケープ処理を自動で行う機能。", + "syntax_rules": [ + "前方一致: 名前付きパラメータの末尾に % を記述(例: name like :userName%)", + "後方一致: 名前付きパラメータの先頭に % を記述(例: name like :%userName)", + "途中一致: 名前付きパラメータの前後に % を記述(例: name like :%userName%)" + ], + "configuration_properties": [ + { + "name": "likeEscapeChar", + "type": "String", + "required": false, + "default": "\\", + "description": "like検索時のエスケープ文字" + }, + { + "name": "likeEscapeTargetCharList", + "type": "String", + "required": false, + "default": "%,_", + "description": "like検索時のエスケープ対象文字(カンマ区切り)" + } + ], + "example_sql": "select * from user where name like :userName%", + "example_code": "UserEntity entity = new UserEntity();\nentity.setUserName(\"な\");\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#findUserByName\");\nint result = statement.retrieve(bean);\n// 実際の条件は name like 'な%' escape '\\' となる", + "notes": "エスケープ文字は自動的にエスケープ対象となるため、明示的にエスケープ対象文字に設定する必要はない。" + }, + "variable_condition": { + "description": "Beanオブジェクトの状態を元に、実行するSQL文を動的に組み立てる機能。条件の有無によって動的に条件を構築できる。", + "syntax": "$if(プロパティ名) {SQL文の条件}", + "exclusion_rules": [ + "配列やCollectionの場合は、プロパティ値がnullやサイズ0の場合に条件が除外される", + "上記以外の型の場合は、プロパティ値がnullや空文字列(Stringオブジェクトの場合)の場合に条件が除外される" + ], + "constraints": [ + "使用できる箇所はwhere句のみ", + "$if内に$ifを使用できない(ネスト不可)" + ], + "example_sql": "select\n user_id,\n user_name,\n user_kbn\nfrom\n user\nwhere\n $if (userName) {user_name like :userName%}\n and $if (userKbn) {user_kbn in ('1', '2')}\n and birthday = :birthday", + "example_code": "UserEntity entity = new UserEntity();\nentity.setUserName(\"なまえ\");\n// userKbnは設定しない(null)\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#insertUser\", entity);\n// userKbnの条件は除外される\nSqlResultSet result = statement.retrieve(entity);", + "methods": [ + { + "name": "prepareParameterizedSqlStatementBySqlId (with condition)", + "signature": "ParameterizedSqlPStatement prepareParameterizedSqlStatementBySqlId(String sqlId, Object condition)", + "description": "SQLIDと条件を持つBeanオブジェクトを指定してステートメントを生成する。Beanオブジェクトの状態を元にSQLの可変条件の組み立てが行われる。", + "parameters": [ + { + "name": "sqlId", + "type": "String", + "description": "SQLID" + }, + { + "name": "condition", + "type": "Object", + "description": "条件を持つBeanオブジェクト" + } + ], + "returns": "ParameterizedSqlPStatementオブジェクト" + } + ] + }, + "in_clause": { + "description": "in句の条件数が可変となるSQLを実行する機能。プロパティ値の要素数に応じてin句の条件が動的に構築される。", + "syntax": "条件の名前付きパラメータの末尾に [] を付加する。例: :userKbn[]", + "property_type": "配列またはjava.util.Collection(サブタイプ含む)", + "example_sql": "select\n user_id,\n user_name,\n user_kbn\nfrom\n user\nwhere\n $if (userKbn) {user_kbn in (:userKbn[])}", + "example_code": "UserSearchCondition condition = new UserSearchCondition();\ncondition.setUserKbn(Arrays.asList(\"1\", \"3\"));\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#searchUser\", condition);\n// 実行されるSQLの条件は userKbn in (?, ?) となる\nSqlResultSet result = statement.retrieve(condition);", + "notes": [ + "in句の条件となるプロパティ値がnullやサイズ0となる場合には、該当条件は必ず可変条件($if)として定義すること", + "可変条件としなかった場合でプロパティ値がnullの場合、条件が xxxx in (null) となるため、検索結果が正しく取得できない可能性がある", + "in句は、条件式(カッコの中)を空にできないため、サイズ0の配列やnullが指定された場合には、条件式を in (null) とする仕様" + ] + }, + "order_by": { + "description": "order byのソート項目を実行時に動的に切り替えてSQLを実行する機能。ソートIDに応じてorder by句が動的に構築される。", + "syntax": "$sort(プロパティ名) {(ケース1)(ケース2)・・・(ケースn)}", + "syntax_detail": [ + "プロパティ名: BeanオブジェクトのソートIDを保持するプロパティ名", + "ケース: order by句の切り替え候補。候補を一意に識別するソートIDとorder by句に指定する文字列(ケース本体)を記述", + "デフォルトのケースには、ソートIDに default を指定する" + ], + "syntax_rules": [ + "各ケースは、ソートIDとケース本体を半角丸括弧で囲んで表現する", + "ソートIDとケース本体は、半角スペースで区切る", + "ソートIDには半角スペースを使用不可", + "ケース本体には半角スペースを使用できる", + "括弧開き以降で最初に登場する文字列をソートIDとする", + "ソートID以降で括弧閉じまでの間をケース本体とする", + "ソートIDおよびケース本体はトリミングする" + ], + "example_sql": "select\n user_id,\n user_name\nfrom\n user\nwhere\n user_name = :userName\n$sort(sortId) {\n (user_id_asc user_id asc)\n (user_id_desc user_id desc)\n (name_asc user_name asc)\n (name_desc user_name desc)\n (default user_id)\n}", + "example_code": "UserSearchCondition condition = new UserSearchCondition();\ncondition.setUserName(\"なまえ\");\ncondition.setSortId(\"name_asc\");\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#searchUser\", condition);\n// order by句は order by user_name asc となる\nSqlResultSet result = statement.retrieve(condition);" + }, + "auto_property": { + "description": "データ登録時や更新時に毎回設定する値をSQLの実行直前に自動的に設定する機能。登録日時や更新日時といった項目への自動設定に使用する。この機能はBeanオブジェクトを入力とする場合のみ有効。", + "classes": [ + "nablarch.core.db.statement.AutoPropertyHandler", + "nablarch.core.db.statement.autoproperty.CurrentDateTime", + "nablarch.core.db.statement.autoproperty.UserId", + "nablarch.core.db.statement.autoproperty.RequestId" + ], + "annotations": [ + "@CurrentDateTime", + "@UserId", + "@RequestId" + ], + "configuration_property": "updatePreHookObjectHandlerList", + "configuration_class": "nablarch.core.db.statement.BasicStatementFactory", + "example_entity": "public class UserEntity {\n private String id;\n\n @CurrentDateTime\n private Timestamp createdAt; // 登録時に自動設定\n\n @CurrentDateTime\n private String updatedAt; // 登録・更新時に自動設定\n}", + "example_sql": "insert into user (\n id,\n createdAt,\n updatedAt\n) values (\n :id,\n :createdAt,\n :updatedAt\n)", + "example_code": "UserEntity entity = new UserEntity();\nentity.setId(1);\n// createdAtとupdatedAtには値を設定する必要はない\n\nParameterizedSqlPStatement statement = connection.prepareParameterizedSqlStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#insertUser\");\nint result = statement.executeUpdateByObject(entity);\n// 自動設定項目に値が設定される", + "notes": "値を明示的に設定したとしても、SQL実行直前に値の自動設定機能により上書きされる。" + }, + "binary_column": { + "description": "blob(データベース製品によりバイナリ型の型は異なる)などのバイナリ型のカラムへのアクセス方法。", + "methods": [ + { + "name": "getBytes", + "signature": "byte[] getBytes(String columnName)", + "description": "バイナリ型のカラムの値をbyte配列として取得する", + "parameters": [ + { + "name": "columnName", + "type": "String", + "description": "カラム名" + } + ], + "returns": "byte配列", + "example": "SqlResultSet rows = statement.retrieve();\nSqlRow row = rows.get(0);\nbyte[] encryptedPassword = row.getBytes(\"password\");" + }, + { + "name": "setBytes", + "signature": "void setBytes(int parameterIndex, byte[] x)", + "description": "サイズの小さいバイナリ値を登録・更新する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス" + }, + { + "name": "x", + "type": "byte[]", + "description": "設定する値" + } + ], + "example": "SqlPStatement statement = getSqlPStatement(\"UPDATE_PASSWORD\");\nstatement.setBytes(1, new byte[] {0x30, 0x31, 0x32});\nint updateCount = statement.executeUpdate();" + }, + { + "name": "setBinaryStream", + "signature": "void setBinaryStream(int parameterIndex, InputStream x, int length)", + "description": "サイズが大きいバイナリ値をストリームから登録更新する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス" + }, + { + "name": "x", + "type": "java.io.InputStream", + "description": "入力ストリーム" + }, + { + "name": "length", + "type": "int", + "description": "データサイズ" + } + ], + "example": "final Path pdf = Paths.get(\"input.pdf\");\ntry (InputStream input = Files.newInputStream(pdf)) {\n statement.setBinaryStream(1, input, (int) Files.size(pdf));\n}" + } + ], + "notes": [ + "getBytesを使用した場合、カラムの内容が全てJavaのヒープ上に展開される", + "非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる", + "大量データを読み込む場合には、Blobオブジェクトを使用して、ヒープを大量に消費しないようにすること" + ], + "large_data_example": "SqlResultSet rows = select.retrieve();\nBlob pdf = (Blob) rows.get(0).get(\"PDF\");\ntry (InputStream input = pdf.getBinaryStream()) {\n // InputStreamからデータを順次読み込み処理を行う\n}" + }, + "clob_column": { + "description": "CLOBのような大きいサイズの文字列型カラムへのアクセス方法。", + "methods": [ + { + "name": "getString", + "signature": "String getString(String columnName)", + "description": "CLOB型のカラムの値をString型として取得する", + "parameters": [ + { + "name": "columnName", + "type": "String", + "description": "カラム名" + } + ], + "returns": "String値", + "example": "SqlResultSet rows = statement.retrieve();\nSqlRow row = rows.get(0);\nString mailBody = row.getString(\"mailBody\");" + }, + { + "name": "setString", + "signature": "void setString(int parameterIndex, String x)", + "description": "サイズが小さい値を登録更新する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス" + }, + { + "name": "x", + "type": "String", + "description": "設定する値" + } + ], + "example": "statement.setString(1, \"値\");\nstatement.executeUpdate();" + }, + { + "name": "setCharacterStream", + "signature": "void setCharacterStream(int parameterIndex, Reader reader, int length)", + "description": "サイズが大きい値をReaderから登録・更新する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス" + }, + { + "name": "reader", + "type": "java.io.Reader", + "description": "Readerオブジェクト" + }, + { + "name": "length", + "type": "int", + "description": "データサイズ" + } + ], + "example": "Path path = Paths.get(filePath);\ntry (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {\n statement.setCharacterStream(1, reader, (int) Files.size(path));\n}" + } + ], + "notes": [ + "getStringを使用した場合、カラムの内容が全てJavaのヒープ上に展開される", + "非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる", + "大量データを読み込む場合には、Clobオブジェクトを使用して、ヒープを大量に消費しないようにすること" + ], + "large_data_example": "SqlResultSet rows = select.retrieve();\nClob mailBody = (Clob) rows.get(0).get(\"mailBody\");\ntry (Reader reader = mailBody.getCharacterStream()) {\n // Readerからデータを順次読み込み処理を行う\n}" + }, + "stored_procedure": { + "description": "ストアードプロシージャを実行する機能。基本的にはSQLを実行する場合と同じように実装するが、Beanオブジェクトを使用した実行(名前付きバインド変数)はサポートしない。", + "classes": [ + "nablarch.core.db.statement.SqlCStatement" + ], + "methods": [ + { + "name": "prepareCallBySqlId", + "signature": "SqlCStatement prepareCallBySqlId(String sqlId)", + "description": "SQLIDを元にストアードプロシージャ実行用のステートメントを生成する", + "parameters": [ + { + "name": "sqlId", + "type": "String", + "description": "SQLID" + } + ], + "returns": "SqlCStatementオブジェクト", + "example": "SqlCStatement statement = connection.prepareCallBySqlId(\n \"jp.co.tis.sample.action.SampleAction#execute_sp\");\nstatement.registerOutParameter(1, Types.CHAR);\nstatement.execute();\nString result = statement.getString(1);" + }, + { + "name": "registerOutParameter", + "signature": "void registerOutParameter(int parameterIndex, int sqlType)", + "description": "OUTパラメータを登録する", + "parameters": [ + { + "name": "parameterIndex", + "type": "int", + "description": "パラメータインデックス" + }, + { + "name": "sqlType", + "type": "int", + "description": "SQL型(java.sql.Types)" + } + ] + }, + { + "name": "execute", + "signature": "boolean execute()", + "description": "ストアードプロシージャを実行する", + "returns": "結果が存在する場合true" + } + ], + "notes": "ストアードプロシージャを使用した場合、ロジックがJavaとストアードプロシージャに分散してしまい、保守性を著しく低下させるため原則使用すべきではない。ただし、既存の資産などでどうしても使用しなければならないケースが想定されるため、非常に簡易的ではあるがAPIを提供している。" + }, + "separate_transaction": { + "description": "データベース接続管理ハンドラ及びトランザクション制御ハンドラで開始したトランザクションではなく、個別のトランザクションを使用してデータベースアクセスを行う機能。業務処理が失敗した場合でも必ずデータベースへの変更を確定したい場合などに使用する。", + "classes": [ + "nablarch.core.db.transaction.SimpleDbTransactionManager", + "nablarch.core.db.transaction.SimpleDbTransactionExecutor" + ], + "methods": [ + { + "name": "doTransaction", + "signature": "T doTransaction()", + "description": "トランザクション内で処理を実行する。SimpleDbTransactionExecutorを継承してexecuteメソッドを実装し、doTransactionメソッドを呼び出す。", + "returns": "executeメソッドの戻り値", + "example": "SimpleDbTransactionManager dbTransactionManager =\n SystemRepository.get(\"update-login-failed-count-transaction\");\n\nSqlResultSet resultSet = new SimpleDbTransactionExecutor(dbTransactionManager) {\n @Override\n public SqlResultSet execute(AppDbConnection connection) {\n SqlPStatement statement = connection.prepareStatementBySqlId(\n \"jp.co.tis.sample.action.SampleAction#findUser\");\n statement.setLong(1, userId);\n return statement.retrieve();\n }\n}.doTransaction();" + } + ], + "configuration_properties": [ + { + "name": "connectionFactory", + "type": "nablarch.core.db.connection.ConnectionFactory", + "required": true, + "description": "データベース接続を取得するConnectionFactory実装クラス" + }, + { + "name": "transactionFactory", + "type": "nablarch.core.transaction.TransactionFactory", + "required": true, + "description": "トランザクションを管理するTransactionFactory実装クラス" + }, + { + "name": "dbTransactionName", + "type": "String", + "required": true, + "description": "トランザクションを識別するための名前" + } + ], + "configuration_example": "\n \n \n \n" + }, + "cache": { + "description": "実行したSQLと外部から取得した条件(バインド変数に設定した値)が等価である場合に、データベースにアクセスせずにキャッシュから検索結果を返却する機能。データベースの負荷を軽減させるために使用する。", + "classes": [ + "nablarch.core.db.cache.InMemoryResultSetCache", + "nablarch.core.db.cache.statement.CacheableStatementFactory", + "nablarch.core.cache.expirable.BasicExpirationSetting" + ], + "use_cases": [ + "売り上げランキングのように結果が厳密に最新である必要が無く大量に参照されるデータ", + "データ更新タイミングが夜間のみで日中は更新されないデータ" + ], + "configuration_properties": [ + { + "name": "cacheSize", + "type": "int", + "required": false, + "description": "キャッシュサイズ(InMemoryResultSetCache)" + }, + { + "name": "expiration", + "type": "Map", + "required": true, + "description": "SQLID毎のキャッシュ有効期限。keyにSQLID、valueに有効期限を設定(BasicExpirationSetting)。単位: ms(ミリ秒)、sec(秒)、min(分)、h(時)" + }, + { + "name": "expirationSetting", + "type": "nablarch.core.cache.expirable.ExpirationSetting", + "required": true, + "description": "有効期限設定(CacheableStatementFactory)" + }, + { + "name": "resultSetCache", + "type": "nablarch.core.db.cache.ResultSetCache", + "required": true, + "description": "キャッシュ実装(CacheableStatementFactory)" + } + ], + "configuration_example": "\n \n\n\n\n \n \n \n \n \n \n\n\n\n \n \n", + "notes": [ + "この機能は、参照系のデータベースアクセスを省略可能な場合に省略し、システム負荷を軽減することを目的としており、データベースアクセス(SQL)の高速化を目的としているものではない", + "この機能は、データベースの値の更新を監視してキャッシュの最新化を行うことはない。常に最新のデータを表示する必要がある機能では使用しないこと" + ] + }, + "schema_replacement": { + "description": "SQL文中のスキーマを環境毎に切り替える機能。環境によって参照したいスキーマ名が異なるケースで使用する。", + "classes": [ + "nablarch.core.db.statement.sqlloader.SchemaReplacer" + ], + "placeholder": "#SCHEMA#", + "configuration_properties": [ + { + "name": "schemaName", + "type": "String", + "required": true, + "description": "プレースホルダー #SCHEMA# を置き換える値" + } + ], + "configuration_example": "\n \n \n \n \n \n \n \n \n \n \n \n", + "sql_example": "-- スキーマ名を指定してSELECT\nSELECT * FROM #SCHEMA#.TABLE1", + "notes": "本機能によるSQL文中のスキーマ置き換えは単純な文字列置換処理であり、スキーマが存在するか、スキーマ置き換え後のSQLが妥当であるかといったチェックは行われない(SQL文実行時にエラーとなる)。" + }, + "configuration": { + "classes": [ + "nablarch.core.db.connection.BasicDbConnectionFactoryForDataSource", + "nablarch.core.db.connection.BasicDbConnectionFactoryForJndi", + "nablarch.core.db.statement.BasicStatementFactory", + "nablarch.core.db.statement.BasicSqlLoader" + ], + "connection_methods": [ + "javax.sql.DataSourceを使ったデータベース接続の生成(BasicDbConnectionFactoryForDataSource)", + "アプリケーションサーバなどに登録されたデータソースを使ったデータベース接続の生成(BasicDbConnectionFactoryForJndi)" + ], + "configuration_example_datasource": "\n \n", + "configuration_example_jndi": "\n \n", + "statement_factory_example": "\n \n \n \n \n \n \n", + "notes": [ + "上記に設定したクラスを直接使用することは基本的にない。データベースアクセスを必要とする場合には、データベース接続管理ハンドラを使用すること", + "データベースを使用する場合はトランザクション管理も必要となる" + ] + }, + "exceptions": { + "exception_types": [ + { + "exception": "nablarch.core.db.DbAccessException", + "cause": "データベースアクセス時に発生する例外", + "description": "データベースアクセス時の一般的なエラー" + }, + { + "exception": "nablarch.core.db.connection.exception.DbConnectionException", + "cause": "データベース接続エラーを示す例外", + "description": "データベースアクセスエラー時の例外がデータベース接続エラーを示す場合に送出される。retry_handlerにより処理される。", + "solution": "retry_handler未適用の場合には、実行時例外として扱われる" + }, + { + "exception": "nablarch.core.db.statement.exception.SqlStatementException", + "cause": "SQLの実行に失敗した時に発生する例外", + "description": "SQL実行時の一般的なエラー" + }, + { + "exception": "nablarch.core.db.statement.exception.DuplicateStatementException", + "cause": "一意制約違反を示す例外", + "description": "SQL実行時の例外が一意制約違反を示す場合に送出される。一意制約違反の判定にはDialectが使用される。", + "solution": "try-catchで補足して処理する。データベース製品によってはSQL実行時に例外が発生した場合に、ロールバックを行うまで一切のSQLを受け付けないものがあるので注意。" + } + ], + "notes": [ + "これらの例外は全て非チェック例外のため、SQLExceptionのようにtry-catchで補足する必要はない", + "データベース接続エラーの判定には、Dialectが使用される", + "一意制約違反の判定には、Dialectが使用される" + ] + }, + "anti-patterns": [ + { + "pattern": "SQL文字列を直接連結してクエリを構築する", + "reason": "SQLインジェクションの脆弱性を生む。PreparedStatementを使用せず、文字列連結でSQLを組み立てると、ユーザー入力値が直接SQL文に埋め込まれ、悪意ある入力により意図しないSQL文が実行される危険性がある。", + "correct": "SQLファイルに定義し、名前付きバインド変数を使用する。どうしてもSQLファイルに定義できない場合でも、必ずPreparedStatementとバインド変数を使用する。" + }, + { + "pattern": "SQLを複数機能で流用する", + "reason": "複数機能で流用した場合、意図しない使われ方やSQLが変更されることにより思わぬ不具合が発生する原因となる。例えば、複数機能で使用していたSQL文に排他ロック用の for update が追加された場合、排他ロックが不要な機能でロックが取得され処理遅延の原因となる。", + "correct": "SQLを複数機能で流用せずに、かならず機能毎に作成すること。" + }, + { + "pattern": "可変条件を使ってSQLを共通化する", + "reason": "可変条件機能は、ウェブアプリケーションの検索画面のようにユーザの入力内容によって検索条件が変わるような場合に使うものである。条件だけが異なる複数のSQLを共通化するために使用するものではない。安易に共通化した場合、SQLを変更した場合に思わぬ不具合を埋め込む原因にもなる。", + "correct": "条件が異なる場合は必ずSQLを複数定義すること。" + }, + { + "pattern": "ストアードプロシージャを多用する", + "reason": "ストアードプロシージャを使用した場合、ロジックがJavaとストアードプロシージャに分散してしまい、保守性を著しく低下させるため原則使用すべきではない。", + "correct": "ロジックはJavaで実装する。既存の資産などでどうしても使用しなければならないケースのみ、ストアードプロシージャ実行APIを使用する。" + }, + { + "pattern": "getBytesやgetStringでLOB型の大容量データを一括取得する", + "reason": "カラムの内容が全てJavaのヒープ上に展開されるため、非常に大きいサイズのデータを読み込んだ場合、ヒープ領域を圧迫し、システムダウンなどの障害の原因となる。", + "correct": "大量データを読み込む場合には、BlobオブジェクトやClobオブジェクトを使用して、InputStreamやReader経由で順次読み込み処理を行う。" + }, + { + "pattern": "検索結果のキャッシュをSQLの高速化目的で使用する", + "reason": "この機能は、参照系のデータベースアクセスを省略可能な場合に省略し、システム負荷を軽減することを目的としており、データベースアクセス(SQL)の高速化を目的としているものではない。", + "correct": "SQLの高速化を目的とする場合には、SQLのチューニングを実施すること。" + }, + { + "pattern": "java.sql.Connectionを直接使用する", + "reason": "java.sql.Connectionを使用した場合、チェック例外であるjava.sql.SQLExceptionをハンドリングして例外を制御する必要がある。この例外制御は実装を誤ると、障害が検知されなかったり障害時の調査ができないなどの問題が発生することがある。", + "correct": "どうしてもjava.sql.Connectionを使わないと満たせない要件がない限り、この機能は使用しないこと。" + } + ], + "tips": [ + { + "title": "型変換の取扱い", + "description": "データベースアクセス(JDBCラッパー)は、データベースとの入出力に使用する変数の型変換をJDBCドライバに委譲する。よって、入出力に使用する変数の型は、データベースの型及び使用するJDBCドライバの仕様に応じて定義する必要がある。任意の型変換が必要な場合は、アプリケーション側で型変換する。" + }, + { + "title": "java.util.Mapも入力として使用可能", + "description": "Beanの代わりにjava.util.Mapの実装クラスも指定できる。Mapを指定した場合は、Mapのキー値と一致するINパラメータに対して、Mapの値が設定される。" + }, + { + "title": "フィールドアクセスへの変更", + "description": "Beanへのアクセス方法をプロパティからフィールドに変更できる。propertiesファイルに nablarch.dbAccess.isFieldAccess=true を設定する。ただし、本フレームワークのその他の機能ではプロパティアクセスで統一されているため、フィールドアクセスは推奨しない。" + }, + { + "title": "java.sql.Connectionの取得", + "description": "JDBCのネイティブなデータベース接続(java.sql.Connection)を扱いたい場合は、DbConnectionContextから取得したTransactionManagerConnectionからjava.sql.Connectionを取得できる。ただし、どうしてもjava.sql.Connectionを使わないと満たせない要件がない限り使用しないこと。" + }, + { + "title": "一意制約違反のハンドリング", + "description": "一意制約違反時に何か処理を行う必要がある場合には、DuplicateStatementExceptionをtry-catchで補足し処理をする。ただし、データベース製品によってはSQL実行時に例外が発生した場合に、ロールバックを行うまで一切のSQLを受け付けないものがあるので注意。例えば、登録処理で一意制約違反が発生した場合に更新処理をしたい場合は、例外ハンドリングを行うのではなくmerge文を使用することでこの問題を回避できる。" + } + ], + "limitations": [ + "この機能は、JDBC 3.0に依存しているため、使用するJDBCドライバがJDBC 3.0以上を実装している必要がある", + "LOB型(BLOB型やCLOB型)のカラムを取得した場合、実際にDBに格納されたデータではなくLOBロケータが取得される。このLOBロケータの有効期間は、RDBMS毎の実装に依存しており、通常、ResultSetやConnectionがクローズされた時点でアクセスできなくなる。このため、ResultSetやConnectionよりも生存期間が長いキャッシュにはBLOB、CLOB型を含めることができない", + "デフォルトで提供するキャッシュを保持するコンポーネントはJVMのヒープ上にキャッシュを保持する。このため、アプリケーションを冗長化構成とした場合、アプリケーションごとに検索結果がキャッシュされることになり、それぞれのアプリケーションで異なるキャッシュを保持する可能性がある", + "ストアードプロシージャの実行では、Beanオブジェクトを使用した名前付きバインド変数はサポートしない" + ], + "extensions": [ + { + "title": "データベースへの接続法を追加する", + "description": "OSSのコネクションプールライブラリを使用する場合など、データベースの接続方法を追加する場合は、ConnectionFactorySupportを継承し、データベース接続を生成するクラスを作成する。" + }, + { + "title": "ダイアレクトを追加する", + "description": "使用するデータベース製品に対応したダイアレクトがない場合や、特定機能の使用可否を切り替えたい場合は、DefaultDialectを継承し、データベース製品に対応したダイアレクトを作成する。" + }, + { + "title": "データベースアクセス時の例外クラスを切り替える", + "description": "デッドロックエラーの例外クラスを変更したい場合など、DbAccessExceptionFactoryとSqlStatementExceptionFactoryの実装クラスを作成して、コンポーネント設定ファイルに定義する。" + } + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/libraries/file-path-management.json b/.claude/skills/nabledge-6/knowledge/features/libraries/file-path-management.json new file mode 100644 index 0000000..3c9d5c2 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/libraries/file-path-management.json @@ -0,0 +1,198 @@ +{ + "id": "file-path-management", + "title": "ファイルパス管理", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/file_path_management.html" + ], + "index": [ + { + "id": "overview", + "hints": [ + "FilePathSetting", + "ファイルパス管理", + "論理名", + "ディレクトリ管理" + ] + }, + { + "id": "configuration", + "hints": [ + "basePathSettings", + "fileExtensions", + "file", + "classpath", + "スキーム" + ] + }, + { + "id": "usage", + "hints": [ + "getFileWithoutCreate", + "getBaseDirectory", + "論理名", + "ファイルパス取得" + ] + }, + { + "id": "anti-patterns", + "hints": [ + "classpath", + "JBoss", + "Wildfly", + "vfs", + "スペース" + ] + }, + { + "id": "tips", + "hints": [ + "拡張子なし", + "論理名複数", + "filePathSetting" + ] + }, + { + "id": "limitations", + "hints": [ + "制約事項", + "注意事項", + "制限" + ] + } + ], + "sections": { + "overview": { + "classes": [ + "nablarch.core.util.FilePathSetting" + ], + "annotations": [], + "description": "システムで使用するファイルの入出力先のディレクトリや拡張子を管理するための機能を提供する", + "purpose": "ディレクトリや拡張子を論理名で管理し、ファイルの入出力を行う機能では論理名を指定するだけでそのディレクトリ配下のファイルに対する入出力を実現できる", + "modules": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-core" + } + ], + "features": [ + "ディレクトリを論理名で管理できる", + "拡張子を論理名で管理できる", + "論理名を指定するだけでファイルの入出力が可能" + ] + }, + "configuration": { + "component_name": "filePathSetting", + "component_class": "nablarch.core.util.FilePathSetting", + "properties": [ + { + "name": "basePathSettings", + "type": "Map", + "required": true, + "description": "ディレクトリの論理名とパスのマッピング。キーは論理名、値はファイルパス(スキーム付き)", + "notes": [ + "スキームは file と classpath が使用できる", + "省略した場合は classpath となる", + "classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(jarなどのアーカイブされたファイル内のパスは指定できない)", + "パスにはスペースを含めない(スペースが含まれているパスは指定できない)" + ] + }, + { + "name": "fileExtensions", + "type": "Map", + "required": false, + "description": "拡張子の論理名と拡張子のマッピング。キーは論理名、値は拡張子", + "notes": [ + "1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する", + "拡張子のないファイルの場合には、その論理名の拡張子設定を省略する" + ] + } + ], + "xml_example": "\n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n", + "configuration_points": [ + "FilePathSettingのコンポーネント名は filePathSetting とすること(固定)", + "basePathSettingsにディレクトリを設定する", + "fileExtensionsに拡張子を設定する", + "1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する", + "拡張子のないファイルの場合には、その論理名の拡張子設定を省略する" + ] + }, + "usage": { + "methods": [ + { + "name": "getFileWithoutCreate", + "signature": "public File getFileWithoutCreate(String logicalPathName, String fileName)", + "description": "論理名とファイル名から、ファイルパスを取得する。ファイルが存在しない場合でも、ファイルオブジェクトを生成して返す", + "parameters": [ + { + "name": "logicalPathName", + "type": "String", + "description": "論理名" + }, + { + "name": "fileName", + "type": "String", + "description": "ファイル名(拡張子なし)" + } + ], + "returns": "Fileオブジェクト(ディレクトリパス + ファイル名 + 拡張子)", + "example": "// /var/nablarch/input/users.csv\nFile users = filePathSetting.getFileWithoutCreate(\"csv-input\", \"users\");\n\n// /var/nablarch/input/users (拡張子なし)\nFile users = filePathSetting.getFileWithoutCreate(\"fixed-file-input\", \"users\");" + }, + { + "name": "getBaseDirectory", + "signature": "public File getBaseDirectory(String logicalPathName)", + "description": "論理名からベースディレクトリのパスを取得する", + "parameters": [ + { + "name": "logicalPathName", + "type": "String", + "description": "論理名" + } + ], + "returns": "Fileオブジェクト(ディレクトリパス)", + "example": "// /var/nablarch/output\nFile csvOutputDir = filePathSetting.getBaseDirectory(\"csv-output\");" + } + ], + "typical_usage": "論理名を使ってファイルパスを取得し、ファイル入出力処理に渡す。環境ごとに異なるディレクトリパスをコンポーネント設定ファイルで切り替えることで、コードを変更せずに複数環境に対応できる" + }, + "anti-patterns": [ + { + "pattern": "classpathスキームを使用してウェブアプリケーションサーバ(JBoss、Wildfly等)で実行する", + "reason": "一部のウェブアプリケーションサーバでは本機能を使用できない。これは、ウェブアプリケーションサーバが独自のファイルシステム(例: JbossやWildflyのvfsというバーチャルファイルシステム)を使用して、クラスパス配下のリソースなどを管理していることに起因する", + "correct": "fileスキームを使用する(classpathスキームではなくfileスキームを使用することを推奨)" + }, + { + "pattern": "パスにスペースを含める", + "reason": "スペースが含まれているパスは指定できない(仕様上の制限)", + "correct": "スペースを含まないパスを使用する" + }, + { + "pattern": "jarなどのアーカイブされたファイル内のパスをclasspathスキームで指定する", + "reason": "classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(アーカイブされたファイル内のパスは指定できない)", + "correct": "ディレクトリとして存在するパスを指定するか、fileスキームを使用する" + } + ], + "tips": [ + { + "title": "拡張子のないファイルの扱い", + "description": "拡張子のないファイルの場合には、その論理名のfileExtensions設定を省略する。getFileWithoutCreateメソッドを呼び出すと、拡張子なしのファイルパスが取得できる" + }, + { + "title": "1つのディレクトリに対する複数の拡張子の設定", + "description": "1つのディレクトリに対して複数の拡張子を設定する場合には、論理名を複数設定する。例えば、csv-inputとdat-inputで同じディレクトリを指定し、それぞれ異なる拡張子を設定する" + }, + { + "title": "コンポーネント名の固定", + "description": "FilePathSettingのコンポーネント名は filePathSetting とすること(固定)。この名前でコンポーネントを登録することで、フレームワークが自動的に参照できる" + }, + { + "title": "スキームのデフォルト動作", + "description": "スキームを省略した場合は classpath となる。ただし、classpathスキームには制限があるため、fileスキームの使用を推奨" + } + ], + "limitations": [ + "classpathスキームを使用した場合、一部のウェブアプリケーションサーバ(JBoss、Wildfly等)では本機能を使用できない", + "classpathスキームの場合、そのパスがディレクトリとして存在している必要がある(jarなどのアーカイブされたファイル内のパスは指定できない)", + "パスにはスペースを含めない(スペースが含まれているパスは指定できない)" + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/libraries/universal-dao.json b/.claude/skills/nabledge-6/knowledge/features/libraries/universal-dao.json new file mode 100644 index 0000000..529afb0 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/libraries/universal-dao.json @@ -0,0 +1,936 @@ +{ + "id": "universal-dao", + "title": "ユニバーサルDAO", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/database/universal_dao.html" + ], + "index": [ + { "id": "overview", "hints": ["ユニバーサルDAO", "UniversalDao", "O/Rマッパー", "Jakarta Persistence", "JPA"] }, + { "id": "crud", "hints": ["登録", "更新", "削除", "insert", "update", "delete", "findById", "主キー検索"] }, + { "id": "sql-file", "hints": ["SQLファイル", "findAllBySqlFile", "SQL ID", "任意SQL", "検索"] }, + { "id": "join", "hints": ["JOIN", "テーブル結合", "複数テーブル", "一覧検索"] }, + { "id": "lazy-load", "hints": ["遅延ロード", "defer", "DeferredEntityList", "大量データ", "フェッチサイズ", "カーソル"] }, + { "id": "search-condition", "hints": ["条件検索", "検索条件", "Form", "検索画面"] }, + { "id": "type-conversion", "hints": ["型変換", "@Temporal", "Date", "Calendar", "マッピング", "データ型"] }, + { "id": "paging", "hints": ["ページング", "per", "page", "Pagination", "EntityList", "件数取得"] }, + { "id": "surrogate-key", "hints": ["サロゲートキー", "採番", "@GeneratedValue", "シーケンス", "IDENTITY", "TABLE", "AUTO"] }, + { "id": "batch-execute", "hints": ["バッチ実行", "一括登録", "一括更新", "一括削除", "batchInsert", "batchUpdate", "batchDelete"] }, + { "id": "optimistic-lock", "hints": ["楽観的ロック", "@Version", "OptimisticLockException", "排他制御", "バージョンカラム"] }, + { "id": "pessimistic-lock", "hints": ["悲観的ロック", "行ロック", "SELECT FOR UPDATE"] }, + { "id": "exclusive-control", "hints": ["排他制御", "バージョンカラム", "ロック単位", "設計指針"] }, + { "id": "binary-data", "hints": ["バイナリデータ", "BLOB", "大容量データ", "Stream"] }, + { "id": "text-data", "hints": ["テキストデータ", "CLOB", "大容量テキスト"] }, + { "id": "transaction", "hints": ["別トランザクション", "SimpleDbTransactionManager", "UniversalDao.Transaction", "個別トランザクション"] }, + { "id": "anti-patterns", "hints": ["アンチパターン", "注意点", "制限事項", "できないこと"] }, + { "id": "errors", "hints": ["例外", "エラー", "OptimisticLockException", "型変換エラー"] } + ], + "sections": { + "overview": { + "classes": ["nablarch.common.dao.UniversalDao"], + "annotations": ["jakarta.persistence.*"], + "description": "Jakarta Persistenceアノテーションを使った簡易的なO/Rマッパー。SQLを書かずに単純なCRUDを実行し、検索結果をBeanにマッピングできる", + "purpose": "単純なCRUD操作とBean検索を簡潔に実現する", + "modules": [ + { + "groupId": "com.nablarch.framework", + "artifactId": "nablarch-common-dao" + } + ], + "positioning": "簡易的なO/Rマッパーとして位置付け。全てのデータベースアクセスをカバーする設計ではない。実現できない場合はDatabaseを使用", + "prerequisites": "内部でDatabaseを使用するため、Databaseの設定が必要", + "limitations": [ + "主キー以外の条件を指定した更新/削除は不可(Databaseを使用)", + "共通項目(登録ユーザ、更新ユーザ等)の自動設定機能は未提供", + "CRUDでの@Tableスキーマ指定時、replace_schema機能は使用不可" + ], + "tips": [ + { + "title": "共通項目の自動設定", + "description": "Domaアダプタのエンティティリスナー機能を推奨。ユニバーサルDAO使用時はアプリケーションで明示的に設定" + }, + { + "title": "基本方針", + "description": "ユニバーサルDAOで実現できない場合は、素直にDatabaseを使う" + } + ] + }, + "crud": { + "description": "Jakarta PersistenceアノテーションをEntityに付けることで、SQLを書かずに単純なCRUDが可能。SQL文は実行時に自動構築", + "methods": [ + { + "name": "insert", + "signature": "UniversalDao.insert(T entity)", + "description": "エンティティを1件登録", + "parameters": [ + { + "name": "entity", + "type": "T", + "description": "登録するエンティティオブジェクト" + } + ], + "returns": "void", + "example": "UniversalDao.insert(user);" + }, + { + "name": "batchInsert", + "signature": "UniversalDao.batchInsert(List entities)", + "description": "エンティティを一括登録", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "登録するエンティティリスト" + } + ], + "returns": "void", + "example": "UniversalDao.batchInsert(users);" + }, + { + "name": "update", + "signature": "UniversalDao.update(T entity)", + "description": "主キーを指定して1件更新", + "parameters": [ + { + "name": "entity", + "type": "T", + "description": "更新するエンティティオブジェクト(主キー指定必須)" + } + ], + "returns": "int(更新件数)", + "example": "UniversalDao.update(user);" + }, + { + "name": "batchUpdate", + "signature": "UniversalDao.batchUpdate(List entities)", + "description": "主キーを指定して一括更新(排他制御なし)", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "更新するエンティティリスト" + } + ], + "returns": "void", + "example": "UniversalDao.batchUpdate(users);", + "important": "排他制御を行わない。バージョン不一致でも更新されず正常終了" + }, + { + "name": "delete", + "signature": "UniversalDao.delete(T entity)", + "description": "主キーを指定して1件削除", + "parameters": [ + { + "name": "entity", + "type": "T", + "description": "削除するエンティティオブジェクト(主キー指定必須)" + } + ], + "returns": "int(削除件数)", + "example": "UniversalDao.delete(user);" + }, + { + "name": "batchDelete", + "signature": "UniversalDao.batchDelete(List entities)", + "description": "主キーを指定して一括削除", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "削除するエンティティリスト" + } + ], + "returns": "void", + "example": "UniversalDao.batchDelete(users);" + }, + { + "name": "findById", + "signature": "UniversalDao.findById(Class entityClass, Object... pk)", + "description": "主キーを指定して1件検索", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "検索結果をマッピングするエンティティクラス" + }, + { + "name": "pk", + "type": "Object...", + "description": "主キーの値(可変長引数)" + } + ], + "returns": "T(エンティティオブジェクト)", + "example": "User user = UniversalDao.findById(User.class, 1L);" + }, + { + "name": "findAll", + "signature": "UniversalDao.findAll(Class entityClass)", + "description": "エンティティを全件検索", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "検索結果をマッピングするエンティティクラス" + } + ], + "returns": "EntityList", + "example": "EntityList users = UniversalDao.findAll(User.class);" + }, + { + "name": "findAllBySqlFile", + "signature": "UniversalDao.findAllBySqlFile(Class entityClass, String sqlId)", + "description": "SQLファイルを使った全件検索", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "検索結果をマッピングするBeanクラス" + }, + { + "name": "sqlId", + "type": "String", + "description": "SQL ID" + } + ], + "returns": "EntityList", + "example": "EntityList users = UniversalDao.findAllBySqlFile(User.class, \"FIND_BY_NAME\");" + }, + { + "name": "findAllBySqlFile", + "signature": "UniversalDao.findAllBySqlFile(Class entityClass, String sqlId, Object condition)", + "description": "条件を指定したSQLファイル検索", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "検索結果をマッピングするBeanクラス" + }, + { + "name": "sqlId", + "type": "String", + "description": "SQL ID" + }, + { + "name": "condition", + "type": "Object", + "description": "検索条件オブジェクト" + } + ], + "returns": "EntityList", + "example": "EntityList projects = UniversalDao.findAllBySqlFile(Project.class, \"SEARCH_PROJECT\", condition);" + }, + { + "name": "findBySqlFile", + "signature": "UniversalDao.findBySqlFile(Class entityClass, String sqlId, Object condition)", + "description": "SQLファイルで1件検索(悲観的ロック用SELECT FOR UPDATEにも使用)", + "parameters": [ + { + "name": "entityClass", + "type": "Class", + "description": "検索結果をマッピングするBeanクラス" + }, + { + "name": "sqlId", + "type": "String", + "description": "SQL ID" + }, + { + "name": "condition", + "type": "Object", + "description": "検索条件オブジェクト" + } + ], + "returns": "T", + "example": "User user = UniversalDao.findBySqlFile(User.class, \"FIND_USER_FOR_UPDATE\", condition);" + } + ], + "annotations_required": "@Entity、@Table、@Id、@Column等のJakarta Persistenceアノテーションを使用", + "sql_generation": "アノテーション情報を元に実行時にSQL文を構築" + }, + "sql-file": { + "description": "任意のSQLで検索する場合、SQLファイルを作成しSQL IDを指定して検索", + "method": "UniversalDao.findAllBySqlFile / findBySqlFile", + "sql_file_path_derivation": "検索結果をマッピングするBeanのクラスから導出。sample.entity.User → sample/entity/User.sql", + "sql_id_with_hash": { + "description": "SQL IDに#を含めると「SQLファイルのパス#SQL ID」と解釈", + "example": "UniversalDao.findAllBySqlFile(GoldUser.class, \"sample.entity.Member#FIND_BY_NAME\")", + "sql_file_path": "sample/entity/Member.sql", + "sql_id": "FIND_BY_NAME", + "use_case": "機能単位(Actionハンドラ単位)にSQLを集約したい場合", + "recommendation": "基本は#を付けない指定を使用(指定が煩雑になるため)" + }, + "bean_mapping": { + "description": "検索結果をBean(Entity、Form、DTO)にマッピング", + "mapping_rule": "Beanのプロパティ名とSELECT句の名前が一致する項目をマッピング" + }, + "typical_usage": "Database機能のuse_sql_fileと同様の使い方" + }, + "join": { + "description": "複数テーブルをJOINした結果を取得する場合の対応", + "use_case": "一覧検索などで複数テーブルをJOINした結果を取得", + "recommendation": "非効率なため個別検索せず、1回で検索できるSQLとJOIN結果をマッピングするBeanを作成", + "implementation": [ + "JOINした結果をマッピングするBean(DTO)を作成", + "SQLファイルに複数テーブルをJOINするSQLを記述", + "findAllBySqlFileでDTOにマッピング" + ] + }, + "lazy-load": { + "description": "大量データでメモリ不足を防ぐための遅延ロード機能", + "use_cases": [ + "ウェブで大量データをダウンロード", + "バッチで大量データを処理" + ], + "method": { + "name": "defer", + "signature": "UniversalDao.defer()", + "description": "遅延ロードを有効化するメソッド。検索メソッドの前に呼び出す", + "returns": "UniversalDao(メソッドチェーン可能)" + }, + "return_type": "DeferredEntityList", + "requires_close": true, + "close_method": "DeferredEntityList.close()(try-with-resources推奨)", + "mechanism": "内部でサーバサイドカーソルを使用。JDBCのフェッチサイズでメモリ使用量が変わる", + "example": "try (DeferredEntityList users = (DeferredEntityList) UniversalDao.defer().findAllBySqlFile(User.class, \"FIND_BY_NAME\")) {\n for (User user : users) {\n // userを使った処理\n }\n}", + "fetch_size_note": "JDBCのフェッチサイズの詳細はデータベースベンダー提供のマニュアルを参照", + "important": "RDBMSによってはカーソルオープン中にトランザクション制御が行われるとカーソルがクローズされる。遅延ロード使用中のトランザクション制御でエラーの可能性。ページングで回避またはカーソル挙動を調整" + }, + "search-condition": { + "description": "検索画面のような条件指定検索", + "method": "UniversalDao.findAllBySqlFile(Class, String sqlId, Object condition)", + "condition_object": "検索条件を持つ専用のBean(Form等)。ただし1テーブルのみアクセスの場合はEntity指定も可", + "example": "ProjectSearchForm condition = context.getRequestScopedVar(\"form\");\nList projects = UniversalDao.findAllBySqlFile(Project.class, \"SEARCH_PROJECT\", condition);", + "important": "検索条件はEntityではなく検索条件を持つ専用のBeanを指定。1テーブルのみの場合はEntity可" + }, + "type-conversion": { + "description": "データベース型とJava型の変換", + "temporal_annotation": "@Temporalでjava.util.Date/java.util.Calendar型のDBマッピング方法を指定可能", + "other_types": "任意のマッピングは不可。DBの型とJDBCドライバ仕様に応じてEntityプロパティを定義", + "auto_generated_sql": { + "description": "Entityから自動生成したSQL実行時", + "output_to_db": "@Temporal設定プロパティは指定型へ変換。それ以外はDatabaseに委譲", + "input_from_db": "@Temporal設定プロパティは指定型から変換。それ以外はEntity情報を元に変換" + }, + "custom_sql": { + "description": "任意のSQLで検索する場合", + "output_to_db": "Databaseに委譲して変換", + "input_from_db": "自動生成SQLと同様の処理" + }, + "important": [ + "DB型とプロパティ型不一致で実行時型変換エラーの可能性", + "SQL実行時の暗黙的型変換でindex未使用による性能劣化の可能性", + "データベースとJavaのデータタイプマッピングはJDBCドライバマニュアルを参照" + ], + "type_examples": [ + { + "db_type": "date", + "java_type": "java.sql.Date" + }, + { + "db_type": "数値型(integer, bigint, number)", + "java_type": "int (Integer), long (Long)" + } + ] + }, + "paging": { + "description": "検索結果のページング機能", + "methods": [ + { + "name": "per", + "signature": "UniversalDao.per(long perPage)", + "description": "1ページあたりの件数を指定", + "parameters": [ + { + "name": "perPage", + "type": "long", + "description": "1ページあたりの件数" + } + ], + "returns": "UniversalDao(メソッドチェーン可能)" + }, + { + "name": "page", + "signature": "UniversalDao.page(long pageNumber)", + "description": "ページ番号を指定", + "parameters": [ + { + "name": "pageNumber", + "type": "long", + "description": "ページ番号" + } + ], + "returns": "UniversalDao(メソッドチェーン可能)" + } + ], + "example": "EntityList users = UniversalDao.per(3).page(1).findAllBySqlFile(User.class, \"FIND_ALL_USERS\");", + "pagination_info": { + "class": "nablarch.common.dao.Pagination", + "description": "ページング画面表示に必要な検索結果件数等の情報を保持", + "retrieval": "Pagination pagination = users.getPagination();" + }, + "internal": "Databaseの範囲指定検索機能を使用して実装", + "count_sql": { + "description": "範囲指定レコード取得前に件数取得SQLが発行される", + "default_behavior": "元のSQLをSELECT COUNT(*) FROMで包んだSQL", + "performance_note": "件数取得SQLによる性能劣化時は拡張例を参照してカスタマイズ" + } + }, + "surrogate-key": { + "description": "サロゲートキーの自動採番機能", + "annotations": ["@GeneratedValue", "@SequenceGenerator", "@TableGenerator"], + "strategies": [ + { + "type": "GenerationType.AUTO", + "description": "Dialectを元に採番方法を自動選択", + "priority": "IDENTITY → SEQUENCE → TABLE", + "sequence_name_rule": "SEQUENCE選択時、シーケンスオブジェクト名は<テーブル名>_<カラム名>", + "generator_note": "generator属性に対応するGenerator設定がある場合、そのGeneratorを使用", + "example": "@Id\n@Column(name = \"USER_ID\", length = 15)\n@GeneratedValue(strategy = GenerationType.AUTO)\npublic Long getId() { return id; }" + }, + { + "type": "GenerationType.IDENTITY", + "description": "DB自動採番機能(IDENTITY)を使用", + "example": "@Id\n@Column(name = \"USER_ID\", length = 15)\n@GeneratedValue(strategy = GenerationType.IDENTITY)\npublic Long getId() { return id; }" + }, + { + "type": "GenerationType.SEQUENCE", + "description": "シーケンスオブジェクトで採番", + "sequence_generator_required": true, + "sequence_name_config": "@SequenceGeneratorのsequenceName属性で指定。省略時は<テーブル名>_<カラム名>", + "example": "@Id\n@Column(name = \"USER_ID\", length = 15)\n@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = \"seq\")\n@SequenceGenerator(name = \"seq\", sequenceName = \"USER_ID_SEQ\")\npublic Long getId() { return id; }" + }, + { + "type": "GenerationType.TABLE", + "description": "採番テーブルで採番", + "table_generator_required": true, + "pk_value_config": "@TableGeneratorのpkColumnValue属性で指定。省略時は<テーブル名>_<カラム名>", + "example": "@Id\n@Column(name = \"USER_ID\", length = 15)\n@GeneratedValue(strategy = GenerationType.TABLE, generator = \"table\")\n@TableGenerator(name = \"table\", pkColumnValue = \"USER_ID\")\npublic Long getId() { return id; }" + } + ], + "generator_configuration": "シーケンス/テーブル採番はGenerator機能を使用。別途設定が必要(generator参照)" + }, + "batch-execute": { + "description": "大量データの一括登録/更新/削除でバッチ実行", + "purpose": "アプリケーションサーバとDBサーバ間のラウンドトリップ回数削減によるパフォーマンス向上", + "methods": [ + { + "name": "batchInsert", + "signature": "UniversalDao.batchInsert(List entities)", + "description": "エンティティを一括登録", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "登録するエンティティリスト" + } + ], + "returns": "void" + }, + { + "name": "batchUpdate", + "signature": "UniversalDao.batchUpdate(List entities)", + "description": "エンティティを一括更新", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "更新するエンティティリスト" + } + ], + "returns": "void", + "important": "排他制御を行わない。更新対象EntityとDBのバージョン不一致でも、そのレコードは更新されず処理が正常終了" + }, + { + "name": "batchDelete", + "signature": "UniversalDao.batchDelete(List entities)", + "description": "エンティティを一括削除", + "parameters": [ + { + "name": "entities", + "type": "List", + "description": "削除するエンティティリスト" + } + ], + "returns": "void" + } + ], + "important": "batchUpdateは排他制御を行わない。排他制御が必要な更新は1レコード毎の更新処理を使用" + }, + "optimistic-lock": { + "description": "@Version付きEntity更新時に自動で楽観的ロック実行", + "annotation": "@Version", + "mechanism": "更新処理時にバージョンカラムが条件に自動追加され楽観ロックが行われる", + "exception": { + "class": "jakarta.persistence.OptimisticLockException", + "cause": "排他エラー発生(バージョン不一致)" + }, + "version_annotation_constraints": [ + "数値型のプロパティのみ指定可(文字列型不可)", + "Entity内に1つのみ指定可能" + ], + "error_handling": { + "annotation": "@OnError", + "description": "排他エラー時の画面遷移制御", + "example": "@OnError(type = OptimisticLockException.class, path = \"/WEB-INF/view/common/errorPages/userError.jsp\")\npublic HttpResponse update(HttpRequest request, ExecutionContext context) {\n UniversalDao.update(user);\n}" + }, + "batch_update_note": "batchUpdateでは楽観的ロックは使用できない" + }, + "pessimistic-lock": { + "description": "悲観的ロック機能は特に提供していない", + "implementation": "データベースの行ロック(SELECT FOR UPDATE)を使用", + "method": { + "name": "findBySqlFile", + "signature": "UniversalDao.findBySqlFile(Class entityClass, String sqlId, Object condition)", + "description": "SELECT FOR UPDATEを記載したSQLファイルを実行" + }, + "example": "User user = UniversalDao.findBySqlFile(User.class, \"FIND_USER_FOR_UPDATE\", condition);" + }, + "exclusive-control": { + "description": "排他制御の設計指針", + "principle": "バージョンカラムは排他制御を行う単位ごとに定義し、競合が許容される最大の単位で定義", + "example": "「ユーザ」単位でロックが業務的に許容されるなら、ユーザテーブルにバージョン番号を定義", + "trade_off": "単位を大きくすると競合可能性が高まり、更新失敗(楽観的ロック)や処理遅延(悲観的ロック)を招く", + "design_consideration": "業務的観点で排他制御単位を決定する必要がある" + }, + "binary-data": { + "description": "OracleのBLOBのようなデータサイズの大きいバイナリデータの登録/更新", + "limitation": "ユニバーサルDAOは全データをメモリに展開するため不向き", + "recommendation": "データベース提供機能を使ってファイルから直接登録/更新", + "reference": "database-binary_column参照" + }, + "text-data": { + "description": "OracleのCLOBのようなデータサイズの大きいテキストデータの登録/更新", + "limitation": "ユニバーサルDAOは全データをメモリに展開するため不向き", + "recommendation": "データベース提供機能を使ってファイルから直接登録/更新", + "reference": "database-clob_column参照" + }, + "transaction": { + "description": "現在のトランザクションとは異なるトランザクションでDAO実行", + "use_case": "Databaseのdatabase-new_transactionと同じことをユニバーサルDAOで実行", + "steps": [ + "コンポーネント設定ファイルにSimpleDbTransactionManagerを定義", + "SimpleDbTransactionManagerを使用して新たなトランザクションでDAO実行" + ], + "component_configuration": { + "component_name": "任意の名前(例: find-persons-transaction)", + "class": "nablarch.core.db.transaction.SimpleDbTransactionManager", + "properties": [ + { + "name": "connectionFactory", + "type": "nablarch.core.db.connection.ConnectionFactory", + "required": true, + "description": "ConnectionFactory実装クラス" + }, + { + "name": "transactionFactory", + "type": "nablarch.core.transaction.TransactionFactory", + "required": true, + "description": "TransactionFactory実装クラス" + }, + { + "name": "dbTransactionName", + "type": "String", + "required": true, + "description": "トランザクションを識別するための名前" + } + ], + "xml_example": "\n \n \n \n" + }, + "implementation": { + "parent_class": "nablarch.common.dao.UniversalDao.Transaction", + "description": "UniversalDao.Transactionを継承したクラスを作成", + "constructor": "super(\"transaction-name\")でSimpleDbTransactionManagerの名前またはオブジェクトを指定", + "execute_method": { + "description": "executeメソッドにDAO処理を実装", + "behavior": "正常終了でコミット、例外/エラーでロールバック" + } + }, + "example": "private static final class FindPersonsTransaction extends UniversalDao.Transaction {\n private EntityList persons;\n\n FindPersonsTransaction() {\n super(\"find-persons-transaction\");\n }\n\n @Override\n protected void execute() {\n persons = UniversalDao.findAllBySqlFile(Person.class, \"FIND_PERSONS\");\n }\n\n public EntityList getPersons() {\n return persons;\n }\n}\n\nFindPersonsTransaction tx = new FindPersonsTransaction();\nEntityList persons = tx.getPersons();" + }, + "configuration": { + "description": "ユニバーサルDAO使用のための設定", + "required_component": { + "component_name": "daoContextFactory", + "class": "nablarch.common.dao.BasicDaoContextFactory", + "description": "コンポーネント定義に追加が必要", + "xml_example": "" + }, + "prerequisites": "Databaseの設定が必要(内部でDatabaseを使用)" + }, + "extensions": { + "metadata_extractor": { + "description": "DatabaseMetaDataから主キー情報を取得できない場合の対応", + "cause": "シノニム使用や権限問題", + "impact": "主キー指定検索が正しく動作しない", + "solution": "DatabaseMetaDataExtractorを継承したクラスを作成", + "parent_class": "nablarch.common.dao.DatabaseMetaDataExtractor", + "configuration": { + "component_name": "databaseMetaDataExtractor", + "example": "" + } + }, + "count_sql_customization": { + "description": "ページング処理の件数取得SQL変更", + "use_case": "ORDER BY句等で処理負荷が大きい場合に負荷軽減(ORDER BY句を外す等)", + "default_behavior": "元のSQLをSELECT COUNT(*) FROMで包んだSQL", + "implementation": { + "method": "Dialect.convertCountSql(String sqlId, Object params, StatementFactory statementFactory)をオーバーライド", + "approach": "使用中のDialectを継承し、元SQLと件数取得SQLのマッピングをコンポーネント設定" + }, + "important": "件数取得SQLは元SQLと同一の検索条件が必要。検索条件に差分が発生しないよう注意", + "example_class": "CustomH2Dialect extends H2Dialect", + "example_method": "@Override\npublic String convertCountSql(String sqlId, Object params, StatementFactory statementFactory) {\n if (sqlMap.containsKey(sqlId)) {\n return statementFactory.getVariableConditionSqlBySqlId(sqlMap.get(sqlId), params);\n }\n return convertCountSql(statementFactory.getVariableConditionSqlBySqlId(sqlId, params));\n}", + "configuration": { + "component_name": "dialect", + "example": "\n \n \n \n \n \n" + } + } + }, + "jpa-annotations": { + "description": "Entityに使用できるJakarta Persistenceアノテーション", + "important": "記載のないアノテーション/属性は機能しない", + "access_rule": "@Accessで明示的にフィールド指定した場合のみフィールドのアノテーションを参照", + "getter_setter_required": "フィールドにアノテーション設定でもgetter/setter必須(値の取得/設定はプロパティ経由)", + "naming_rule": "フィールド名とプロパティ名(get〇〇/set〇〇の〇〇)は同一にすること", + "lombok_tip": "Lombokのようなボイラープレートコード生成ライブラリ使用時、フィールドにアノテーション設定でgetter自動生成の利点を活用可能", + "class_annotations": [ + { + "name": "@Entity", + "package": "jakarta.persistence.Entity", + "description": "データベースのテーブルに対応したEntityクラスに設定", + "table_name_derivation": "クラス名(パスカルケース)→スネークケース(大文字)", + "examples": [ + { + "class": "Book", + "table": "BOOK" + }, + { + "class": "BookAuthor", + "table": "BOOK_AUTHOR" + } + ], + "tip": "クラス名からテーブル名を導出できない場合は@Tableで明示指定" + }, + { + "name": "@Table", + "package": "jakarta.persistence.Table", + "description": "テーブル名を明示指定するアノテーション", + "attributes": { + "name": { + "type": "String", + "required": false, + "description": "テーブル名。指定した値がテーブル名として使用される" + }, + "schema": { + "type": "String", + "required": false, + "description": "スキーマ名。指定されたスキーマ名を修飾子としてテーブルにアクセス。例: schema=\"work\" → work.users_work" + } + } + }, + { + "name": "@Access", + "package": "jakarta.persistence.Access", + "description": "アノテーション設定場所を指定するアノテーション", + "behavior": "明示的にフィールド指定した場合のみフィールドのアノテーションを参照" + } + ], + "property_annotations": [ + { + "name": "@Column", + "package": "jakarta.persistence.Column", + "description": "カラム名を指定するアノテーション", + "attributes": { + "name": { + "type": "String", + "required": false, + "description": "カラム名。指定した値がカラム名として使用される" + } + }, + "default_derivation": "未設定時はプロパティ名からカラム名を導出(テーブル名導出と同じ方法)" + }, + { + "name": "@Id", + "package": "jakarta.persistence.Id", + "description": "主キーに設定するアノテーション", + "composite_key": "複合主キーの場合は複数のgetterまたはフィールドに設定" + }, + { + "name": "@Version", + "package": "jakarta.persistence.Version", + "description": "排他制御用バージョンカラムに設定するアノテーション", + "constraints": [ + "数値型のプロパティのみ指定可(文字列型不可)", + "Entity内に1つのみ指定可能" + ], + "behavior": "更新処理時にバージョンカラムが条件に自動追加され楽観ロック実行" + }, + { + "name": "@Temporal", + "package": "jakarta.persistence.Temporal", + "description": "java.util.Date/java.util.Calendar型のDBマッピング方法を指定", + "attributes": { + "value": { + "type": "TemporalType", + "required": true, + "description": "データベース型(DATE, TIME, TIMESTAMP)" + } + }, + "behavior": "value属性に指定されたDB型へJavaオブジェクトの値を変換してDB登録" + }, + { + "name": "@GeneratedValue", + "package": "jakarta.persistence.GeneratedValue", + "description": "自動採番された値を登録することを示すアノテーション", + "attributes": { + "strategy": { + "type": "GenerationType", + "required": false, + "default": "AUTO", + "description": "採番方法(AUTO, IDENTITY, SEQUENCE, TABLE)" + }, + "generator": { + "type": "String", + "required": false, + "description": "Generator設定名" + } + }, + "auto_behavior": [ + "generator属性に対応するGenerator設定がある場合、そのGeneratorを使用", + "generatorが未設定または対応設定がない場合、Dialectを元に選択(IDENTITY→SEQUENCE→TABLE)" + ], + "default_name_rule": "シーケンス名/レコード識別値を取得できない場合、<テーブル名>_<カラム名>から導出" + }, + { + "name": "@SequenceGenerator", + "package": "jakarta.persistence.SequenceGenerator", + "description": "シーケンス採番を使用する場合に設定", + "attributes": { + "name": { + "type": "String", + "required": true, + "description": "@GeneratedValueのgenerator属性と同じ値" + }, + "sequenceName": { + "type": "String", + "required": false, + "default": "<テーブル名>_<カラム名>", + "description": "データベース上に作成されているシーケンスオブジェクト名" + } + }, + "note": "シーケンス採番はGenerator機能を使用。採番用の設定を別途行う必要がある" + }, + { + "name": "@TableGenerator", + "package": "jakarta.persistence.TableGenerator", + "description": "テーブル採番を使用する場合に設定", + "attributes": { + "name": { + "type": "String", + "required": true, + "description": "@GeneratedValueのgenerator属性と同じ値" + }, + "pkColumnValue": { + "type": "String", + "required": false, + "default": "<テーブル名>_<カラム名>", + "description": "採番テーブルのレコードを識別するための値" + } + }, + "note": "テーブル採番はGenerator機能を使用。採番用の設定を別途行う必要がある" + } + ] + }, + "bean-data-types": { + "description": "検索結果をマッピングするBeanに使用可能なデータタイプ", + "important": "記載のないデータタイプへのマッピングは実行時例外", + "types": [ + { + "type": "java.lang.String", + "note": null + }, + { + "type": "java.lang.Short", + "primitive": true, + "note": "プリミティブ型も指定可。プリミティブ型でnullは0として扱う" + }, + { + "type": "java.lang.Integer", + "primitive": true, + "note": "プリミティブ型も指定可。プリミティブ型でnullは0として扱う" + }, + { + "type": "java.lang.Long", + "primitive": true, + "note": "プリミティブ型も指定可。プリミティブ型でnullは0として扱う" + }, + { + "type": "java.math.BigDecimal", + "note": null + }, + { + "type": "java.lang.Boolean", + "primitive": true, + "note": "プリミティブ型も指定可。プリミティブ型でnullはfalseとして扱う。ラッパー型のリードメソッド名はgetから開始必須。プリミティブ型はisで開始可" + }, + { + "type": "java.util.Date", + "note": "@Temporalでデータベース上のデータ型を指定する必要がある" + }, + { + "type": "java.sql.Date", + "note": null + }, + { + "type": "java.sql.Timestamp", + "note": null + }, + { + "type": "java.time.LocalDate", + "note": null + }, + { + "type": "java.time.LocalDateTime", + "note": null + }, + { + "type": "byte[]", + "note": "BLOB等の非常に大きいサイズのデータ型の値は、本機能でヒープ上に展開しないよう注意。非常に大きいサイズのバイナリデータを扱う場合は、Databaseを直接使用しStream経由でデータを参照" + } + ] + }, + "anti-patterns": [ + { + "pattern": "主キー以外の条件で更新/削除しようとする", + "reason": "ユニバーサルDAOは主キー指定の更新/削除のみ対応", + "correct": "主キー以外の条件が必要な場合はDatabaseを直接使用" + }, + { + "pattern": "検索条件にEntityを無条件に使用する", + "reason": "複数テーブル検索時にEntityを使うと設計が不明瞭になる", + "correct": "検索条件は専用のBean(Form等)を指定。ただし1テーブルのみアクセスの場合はEntity指定も可" + }, + { + "pattern": "フィールドにアノテーション設定してgetter/setterを省略する", + "reason": "UniversalDaoは値の取得/設定をプロパティ経由で行うため、フィールドアノテーション設定でもgetter/setterが必要", + "correct": "フィールドにアノテーションを設定する場合でもgetter/setterを必ず作成する" + }, + { + "pattern": "共通項目(登録ユーザ、更新ユーザ等)の自動設定を期待する", + "reason": "自動設定機能は未提供", + "correct": "Domaアダプタのエンティティリスナー使用、またはアプリケーションで明示的に設定" + }, + { + "pattern": "@Tableのスキーマ指定でreplace_schema機能を使用しようとする", + "reason": "ユニバーサルDAOのCRUD機能ではreplace_schema未対応", + "correct": "環境毎のスキーマ切替はDatabaseを使用" + }, + { + "pattern": "batchUpdateで排他制御を期待する", + "reason": "batchUpdateは排他制御を行わない。バージョン不一致でも更新されず正常終了し、更新失敗に気付けない", + "correct": "排他制御が必要な場合は1レコード毎の更新処理(update)を使用" + }, + { + "pattern": "@Versionを文字列型プロパティに設定する", + "reason": "数値型のみ対応。文字列型は正しく動作しない", + "correct": "@Versionは数値型プロパティに設定" + }, + { + "pattern": "大きいBLOB/CLOBデータをユニバーサルDAOで登録/更新する", + "reason": "全データをメモリに展開するため、大容量データでメモリ不足になる", + "correct": "データベース提供機能でファイルから直接登録/更新" + }, + { + "pattern": "遅延ロード中にトランザクション制御を行う", + "reason": "RDBMSによってはカーソルオープン中のトランザクション制御でカーソルがクローズされエラーになる", + "correct": "ページングで回避、またはDBベンダマニュアルに沿ってカーソル挙動を調整" + }, + { + "pattern": "JOIN対象のデータを個別に検索する", + "reason": "複数回のクエリで非効率", + "correct": "1回で検索できるSQLとJOIN結果をマッピングするBeanを作成" + }, + { + "pattern": "DeferredEntityListをcloseせずに放置する", + "reason": "内部でサーバサイドカーソルを使用しており、リソースリークの原因になる", + "correct": "try-with-resourcesでclose呼び出し" + }, + { + "pattern": "フィールドとプロパティを異なる名前にする(@Accessでフィールド指定時)", + "reason": "フィールド名とプロパティ名で紐づいているため、異なるとフィールドのアノテーションをプロパティで参照できなくなる", + "correct": "フィールド名とプロパティ名(get〇〇/set〇〇の〇〇)は同一にする" + }, + { + "pattern": "記載のないアノテーション/属性を使用する", + "reason": "Jakarta Persistenceの全機能には対応していない", + "correct": "公式ドキュメント記載のアノテーション/属性のみ使用" + }, + { + "pattern": "サポートされていないデータタイプにマッピングする", + "reason": "実行時例外が発生する", + "correct": "bean-data-typesに記載のデータタイプを使用" + }, + { + "pattern": "DB型とプロパティ型を不一致にする", + "reason": "実行時型変換エラーや暗黙的型変換によるindex未使用で性能劣化", + "correct": "JDBCドライバマニュアルを参照し適切な型でプロパティを定義" + } + ], + "errors": [ + { + "exception": "jakarta.persistence.OptimisticLockException", + "cause": "楽観的ロックで排他エラー発生(@Version付きEntity更新時にバージョン不一致)", + "solution": "@OnErrorで画面遷移を制御。例: @OnError(type = OptimisticLockException.class, path = \"/WEB-INF/view/common/errorPages/userError.jsp\")" + }, + { + "exception": "型変換エラー(実行時例外)", + "cause": "データベースの型とプロパティの型が不一致", + "solution": "JDBCドライバのマニュアルを参照し、データベースとJavaのデータタイプマッピングに従って適切な型でプロパティを定義" + }, + { + "exception": "実行時例外(マッピングエラー)", + "cause": "サポートされていないデータタイプへのマッピング", + "solution": "bean-data-typesに記載のデータタイプを使用" + }, + { + "exception": "主キー検索が正しく動作しない", + "cause": "DatabaseMetaDataから主キー情報を取得できない(シノニム使用、権限問題)", + "solution": "DatabaseMetaDataExtractorを継承したクラスを作成し、databaseMetaDataExtractorコンポーネントとして設定" + } + ], + "tips": [ + { + "title": "ユニバーサルDAOの位置付け", + "description": "簡易的なO/Rマッパー。全てのDBアクセスをカバーする設計ではない。実現できない場合は素直にDatabaseを使用" + }, + { + "title": "共通項目の自動設定", + "description": "Domaアダプタのエンティティリスナー機能を推奨。ユニバーサルDAO使用時はアプリケーションで明示的に設定" + }, + { + "title": "SQLファイルのパス指定", + "description": "#を含めた指定は機能単位にSQL集約に使えるが、基本は#なしを推奨(指定が煩雑になるため)" + }, + { + "title": "ページングの内部実装", + "description": "Databaseの範囲指定検索機能を使用。範囲指定レコード取得前に件数取得SQLが発行される" + }, + { + "title": "シーケンス/テーブル採番の設定", + "description": "Generator機能を使用するため、別途採番用の設定が必要" + }, + { + "title": "Lombokとの相性", + "description": "フィールドにアノテーション設定でgetter自動生成の利点を活用可能" + } + ], + "limitations": [ + "主キー以外の条件を指定した更新/削除は不可", + "共通項目の自動設定機能は未提供", + "CRUDでの@Tableスキーマ指定時、replace_schema機能は使用不可", + "batchUpdateでは排他制御不可", + "@Versionは数値型のみ対応(文字列型不可)", + "大容量BLOB/CLOBデータは全データをメモリ展開するため不向き", + "Jakarta Persistenceの全機能には対応していない(記載のないアノテーション/属性は機能しない)" + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/processing/nablarch-batch.json b/.claude/skills/nabledge-6/knowledge/features/processing/nablarch-batch.json new file mode 100644 index 0000000..3d3c83a --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/processing/nablarch-batch.json @@ -0,0 +1,881 @@ +{ + "id": "nablarch-batch", + "title": "Nablarchバッチ(都度起動型・常駐型)", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/nablarch_batch/index.html" + ], + "index": [ + { + "id": "overview", + "hints": ["Nablarchバッチ", "バッチアプリケーション", "都度起動", "常駐バッチ", "大量データ処理"] + }, + { + "id": "architecture", + "hints": ["アーキテクチャ", "ハンドラキュー", "DataReader", "BatchAction", "処理フロー"] + }, + { + "id": "batch-types", + "hints": ["都度起動バッチ", "常駐バッチ", "定期実行", "プロセス起動", "db_messaging"] + }, + { + "id": "responsibility", + "hints": ["責務配置", "Action", "Form", "Entity", "DataReader", "業務ロジック"] + }, + { + "id": "handler-queue-each-time", + "hints": ["都度起動バッチ", "ハンドラ構成", "最小構成", "DB接続有り", "DB接続無し"] + }, + { + "id": "handler-queue-resident", + "hints": ["常駐バッチ", "ハンドラ構成", "ProcessResidentHandler", "ProcessStopHandler", "RetryHandler"] + }, + { + "id": "data-readers", + "hints": ["DataReader", "DatabaseRecordReader", "FileDataReader", "ValidatableFileDataReader", "ResumeDataReader"] + }, + { + "id": "actions", + "hints": ["BatchAction", "FileBatchAction", "NoInputDataBatchAction", "AsyncMessageSendAction", "createReader"] + }, + { + "id": "patterns-file-to-db", + "hints": ["FILE to DB", "ファイル取り込み", "CSV登録", "バリデーション", "データバインド"] + }, + { + "id": "patterns-db-to-file", + "hints": ["DB to FILE", "ファイル出力", "データ抽出", "DatabaseRecordReader"] + }, + { + "id": "patterns-db-to-db", + "hints": ["DB to DB", "データ更新", "データ変換", "UniversalDao"] + }, + { + "id": "request-path", + "hints": ["リクエストパス", "requestPath", "アクション指定", "リクエストID", "コマンドライン引数"] + }, + { + "id": "multithread", + "hints": ["マルチスレッド", "並列実行", "MultiThreadExecutionHandler", "スレッド数", "パフォーマンス"] + }, + { + "id": "transaction-control", + "hints": ["トランザクション制御", "コミット間隔", "LoopHandler", "commit interval"] + }, + { + "id": "error-handling", + "hints": ["エラー処理", "リラン", "処理継続", "TransactionAbnormalEnd", "ProcessAbnormalEnd", "異常終了"] + }, + { + "id": "pessimistic-lock", + "hints": ["悲観的ロック", "排他制御", "UniversalDao", "ロック時間短縮", "マルチプロセス"] + }, + { + "id": "state-retention", + "hints": ["状態保持", "登録件数", "更新件数", "AtomicInteger", "ExecutionContext"] + }, + { + "id": "multi-process", + "hints": ["マルチプロセス化", "常駐バッチ", "DatabaseRecordListener", "beforeReadRecords", "プロセスID"] + }, + { + "id": "configuration", + "hints": ["設定", "システムリポジトリ", "diConfig", "ハンドラキュー設定"] + }, + { + "id": "anti-patterns", + "hints": ["アンチパターン", "NG例", "注意点", "推奨しない"] + }, + { + "id": "errors", + "hints": ["例外", "エラー", "ProcessAbnormalEnd", "TransactionAbnormalEnd"] + } + ], + "sections": { + "overview": { + "description": "Nablarchバッチアプリケーションは、DBやファイルに格納されたデータレコード1件ごとに処理を繰り返し実行するバッチ処理を構築するための機能を提供する。javaコマンドから直接起動するスタンドアロンアプリケーションとして実行する。", + "use_cases": [ + "ファイルからデータベースへの一括登録", + "データベースからファイルへの一括出力", + "データベース内のデータ更新・変換", + "定期的なバッチ処理(日次・月次)", + "オンライン処理で作成された要求データの一括処理" + ], + "features": [ + "大量データの効率的な処理", + "トランザクション制御(コミット間隔の設定)", + "マルチスレッド実行による並列処理", + "ファイル・データベースからのデータ読み込み", + "バリデーション機能", + "エラーハンドリング・リラン機能", + "常駐型バッチの定期実行" + ] + }, + "batch-types": { + "each_time_batch": { + "name": "都度起動バッチ", + "description": "日次や月次など、定期的にプロセスを起動してバッチ処理を実行する", + "use_cases": [ + "定期的なデータ処理(日次・月次)", + "スケジューラからの起動によるバッチ実行" + ] + }, + "resident_batch": { + "name": "常駐バッチ", + "description": "プロセスを起動しておき、一定間隔でバッチ処理を実行する。例えば、オンライン処理で作成された要求データを定期的に一括処理するような場合に使用する", + "use_cases": [ + "オンライン処理で作成された要求データの定期的な一括処理", + "データ監視と定期処理" + ], + "important_notes": [ + "常駐バッチは、マルチスレッドで実行しても、処理が遅いスレッドの終了を他のスレッドが待つことにより、要求データの取り込み遅延が発生する可能性がある", + "新規開発プロジェクトでは、常駐バッチではなく、上記問題が発生しないdb_messagingを使用することを推奨する", + "既存プロジェクトにおいては、常駐バッチをこのまま稼働させることはできるが、上記問題が発生する可能性がある場合(既に発生している場合)には、db_messagingへの変更を検討すること" + ] + } + }, + "architecture": { + "description": "Nablarchバッチアプリケーションはjavaコマンドから直接起動し、システムリポジトリやログの初期化処理を行い、ハンドラキューを実行する", + "components": [ + { + "name": "Main", + "responsibility": "Nablarchバッチアプリケーションの起点となるメインクラス。javaコマンドから直接起動し、システムリポジトリやログの初期化処理を行い、ハンドラキューを実行する", + "classes": ["nablarch.fw.launcher.Main"] + }, + { + "name": "Handler Queue", + "responsibility": "リクエストの処理を行うハンドラの連鎖。往路処理、復路処理、例外処理を制御する", + "classes": [ + "nablarch.fw.Handler" + ] + }, + { + "name": "DataReader", + "responsibility": "入力データを読み込み、データレコードを1件ずつ提供する", + "classes": [ + "nablarch.fw.DataReader", + "nablarch.fw.reader.DatabaseRecordReader", + "nablarch.fw.reader.FileDataReader", + "nablarch.fw.reader.ValidatableFileDataReader", + "nablarch.fw.reader.ResumeDataReader" + ] + }, + { + "name": "Action", + "responsibility": "DataReaderを生成し、DataReaderが読み込んだデータレコードを元に業務ロジックを実行し、Resultを返却する", + "classes": [ + "nablarch.fw.action.BatchAction", + "nablarch.fw.action.FileBatchAction", + "nablarch.fw.action.NoInputDataBatchAction", + "nablarch.fw.messaging.action.AsyncMessageSendAction" + ] + }, + { + "name": "Form", + "responsibility": "DataReaderが読み込んだデータレコードをマッピングし、バリデーションを行う。プロパティは全てStringで定義する(バイナリ項目を除く)", + "notes": [ + "外部から連携されるファイルなど、入力データが安全でない場合にバリデーションを行う", + "データベースなど、入力データが安全な場合は、Formクラスを使用せず、データレコードからEntityクラスを作成する" + ] + }, + { + "name": "Entity", + "responsibility": "テーブルと1対1で対応するクラス。カラムに対応するプロパティを持つ" + } + ], + "process_flow": [ + "共通起動ランチャ(Main)がハンドラキューを実行する", + "DataReaderが入力データを読み込み、データレコードを1件ずつ提供する", + "DispatchHandlerが、コマンドライン引数(-requestPath)で指定するリクエストパスを元に処理すべきアクションクラスを特定し、ハンドラキューの末尾に追加する", + "アクションクラスは、FormクラスやEntityクラスを使用して、データレコード1件ごとの業務ロジックを実行する", + "アクションクラスは、処理結果を示すResultを返却する", + "処理対象データがなくなるまで繰り返す", + "StatusCodeConvertHandlerが、処理結果のステータスコードをプロセス終了コードに変換し、バッチアプリケーションの処理結果としてプロセス終了コードが返される" + ] + }, + "responsibility": { + "action": { + "description": "アクションクラスは2つのことを行う", + "responsibilities": [ + "入力データの読み込みに使うDataReaderを生成する(createReaderメソッド)", + "DataReaderが読み込んだデータレコードを元に業務ロジックを実行し、Resultを返却する(handleメソッド)" + ], + "example": "ファイルの取り込みバッチであれば、業務ロジックとして以下の処理を行う:データレコードからフォームクラスを作成してバリデーションを行う、フォームクラスからエンティティクラスを作成してデータベースにデータを追加する、処理結果としてSuccessを返す" + }, + "form": { + "description": "DataReaderが読み込んだデータレコードをマッピングするクラス", + "responsibilities": [ + "データレコードをバリデーションするためのアノテーションの設定", + "相関バリデーションのロジックを持つ" + ], + "rules": [ + "フォームクラスのプロパティは全てStringで定義する(バイナリ項目の場合はバイト配列で定義)", + "外部から連携されるファイルなど、入力データが安全でない場合に使用する", + "データベースなど、入力データが安全な場合は、フォームクラスを使用せず、データレコードからエンティティクラスを作成して業務ロジックを実行する" + ], + "notes": [ + "外部からの入力データによっては、階層構造(formがformを持つ)となる場合もある" + ] + }, + "entity": { + "description": "テーブルと1対1で対応するクラス。カラムに対応するプロパティを持つ" + } + }, + "request-path": { + "description": "Nablarchバッチアプリケーションでは、コマンドライン引数(-requestPath)で、実行するアクションとリクエストIDを指定する", + "format": "-requestPath=アクションのクラス名/リクエストID", + "example": "-requestPath=com.sample.SampleBatchAction/BATCH0001", + "request_id": { + "description": "リクエストIDは、各バッチプロセスの識別子として用いられる", + "use_case": "同一の業務アクションクラスを実行するプロセスを複数起動する場合などは、このリクエストIDが識別子となる" + } + }, + "handler-queue-each-time": { + "db_enabled": { + "description": "都度起動バッチ(DB接続有り)の最小ハンドラ構成", + "handlers": [ + { + "no": 1, + "name": "StatusCodeConvertHandler", + "thread": "メイン", + "forward": "", + "backward": "ステータスコードをプロセス終了コードに変換する", + "exception": "", + "reference": "status_code_convert_handler" + }, + { + "no": 2, + "name": "GlobalErrorHandler", + "thread": "メイン", + "forward": "", + "backward": "", + "exception": "実行時例外、またはエラーの場合、ログ出力を行う", + "reference": "global_error_handler" + }, + { + "no": 3, + "name": "DatabaseConnectionManagementHandler(初期処理/終了処理用)", + "thread": "メイン", + "forward": "DB接続を取得する", + "backward": "DB接続を解放する", + "exception": "", + "reference": "database_connection_management_handler" + }, + { + "no": 4, + "name": "TransactionManagementHandler(初期処理/終了処理用)", + "thread": "メイン", + "forward": "トランザクションを開始する", + "backward": "トランザクションをコミットする", + "exception": "トランザクションをロールバックする", + "reference": "transaction_management_handler" + }, + { + "no": 5, + "name": "RequestPathJavaPackageMapping", + "thread": "メイン", + "forward": "コマンドライン引数をもとに呼び出すアクションを決定する", + "backward": "", + "exception": "", + "reference": "request_path_java_package_mapping" + }, + { + "no": 6, + "name": "MultiThreadExecutionHandler", + "thread": "メイン", + "forward": "サブスレッドを作成し、後続ハンドラの処理を並行実行する", + "backward": "全スレッドの正常終了まで待機する", + "exception": "処理中のスレッドが完了するまで待機し起因例外を再送出する", + "reference": "multi_thread_execution_handler" + }, + { + "no": 7, + "name": "DatabaseConnectionManagementHandler(業務処理用)", + "thread": "サブ", + "forward": "DB接続を取得する", + "backward": "DB接続を解放する", + "exception": "", + "reference": "database_connection_management_handler" + }, + { + "no": 8, + "name": "LoopHandler", + "thread": "サブ", + "forward": "業務トランザクションを開始する", + "backward": "コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する", + "exception": "業務トランザクションをロールバックする", + "reference": "loop_handler" + }, + { + "no": 9, + "name": "DataReadHandler", + "thread": "サブ", + "forward": "データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する", + "backward": "", + "exception": "読み込んだレコードをログ出力した後、元例外を再送出する", + "reference": "data_read_handler" + } + ], + "notes": [ + "これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する" + ] + }, + "db_disabled": { + "description": "都度起動バッチ(DB接続無し)の最小ハンドラ構成。DB接続関連ハンドラが不要であり、ループ制御ハンドラでトランザクション制御が不要", + "handlers": [ + { + "no": 1, + "name": "StatusCodeConvertHandler", + "thread": "メイン", + "forward": "", + "backward": "ステータスコードをプロセス終了コードに変換する", + "exception": "", + "reference": "status_code_convert_handler" + }, + { + "no": 2, + "name": "GlobalErrorHandler", + "thread": "メイン", + "forward": "", + "backward": "", + "exception": "実行時例外、またはエラーの場合、ログ出力を行う", + "reference": "global_error_handler" + }, + { + "no": 3, + "name": "RequestPathJavaPackageMapping", + "thread": "メイン", + "forward": "コマンドライン引数をもとに呼び出すアクションを決定する", + "backward": "", + "exception": "", + "reference": "request_path_java_package_mapping" + }, + { + "no": 4, + "name": "MultiThreadExecutionHandler", + "thread": "メイン", + "forward": "サブスレッドを作成し、後続ハンドラの処理を並行実行する", + "backward": "全スレッドの正常終了まで待機する", + "exception": "処理中のスレッドが完了するまで待機し起因例外を再送出する", + "reference": "multi_thread_execution_handler" + }, + { + "no": 5, + "name": "DblessLoopHandler", + "thread": "サブ", + "forward": "", + "backward": "データリーダ上に処理対象データが残っていればループを継続する", + "exception": "", + "reference": "dbless_loop_handler" + }, + { + "no": 6, + "name": "DataReadHandler", + "thread": "サブ", + "forward": "データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する", + "backward": "", + "exception": "読み込んだレコードをログ出力した後、元例外を再送出する", + "reference": "data_read_handler" + } + ], + "notes": [ + "これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する" + ] + } + }, + "handler-queue-resident": { + "description": "常駐バッチの最小ハンドラ構成。都度起動バッチに加えて、ThreadContextHandler、ThreadContextClearHandler、RetryHandler、ProcessResidentHandler、ProcessStopHandlerがメインスレッド側に追加されている", + "handlers": [ + { + "no": 1, + "name": "StatusCodeConvertHandler", + "thread": "メイン", + "forward": "", + "backward": "ステータスコードをプロセス終了コードに変換する", + "exception": "", + "reference": "status_code_convert_handler" + }, + { + "no": 2, + "name": "ThreadContextClearHandler", + "thread": "メイン", + "forward": "", + "backward": "ThreadContextHandlerでスレッドローカル上に設定した値を全て削除する", + "exception": "", + "reference": "thread_context_clear_handler" + }, + { + "no": 3, + "name": "GlobalErrorHandler", + "thread": "メイン", + "forward": "", + "backward": "", + "exception": "実行時例外、またはエラーの場合、ログ出力を行う", + "reference": "global_error_handler" + }, + { + "no": 4, + "name": "ThreadContextHandler", + "thread": "メイン", + "forward": "コマンドライン引数からリクエストID、ユーザID等のスレッドコンテキスト変数を初期化する", + "backward": "", + "exception": "", + "reference": "thread_context_handler", + "notes": ["ProcessStopHandlerのために必要"] + }, + { + "no": 5, + "name": "RetryHandler", + "thread": "メイン", + "forward": "", + "backward": "", + "exception": "リトライ可能な実行時例外を捕捉し、かつリトライ上限に達していなければ後続のハンドラを再実行する", + "reference": "retry_handler" + }, + { + "no": 6, + "name": "ProcessResidentHandler", + "thread": "メイン", + "forward": "データ監視間隔ごとに後続のハンドラを繰り返し実行する", + "backward": "ループを継続する", + "exception": "ログ出力を行い、実行時例外が送出された場合はリトライ可能例外にラップして送出する。エラーが送出された場合はそのまま再送出する", + "reference": "process_resident_handler" + }, + { + "no": 7, + "name": "ProcessStopHandler", + "thread": "メイン", + "forward": "リクエストテーブル上の処理停止フラグがオンであった場合は、後続ハンドラの処理は行なわずにプロセス停止例外(ProcessStop)を送出する", + "backward": "", + "exception": "", + "reference": "process_stop_handler" + }, + { + "no": 8, + "name": "DatabaseConnectionManagementHandler(初期処理/終了処理用)", + "thread": "メイン", + "forward": "DB接続を取得する", + "backward": "DB接続を解放する", + "exception": "", + "reference": "database_connection_management_handler" + }, + { + "no": 9, + "name": "TransactionManagementHandler(初期処理/終了処理用)", + "thread": "メイン", + "forward": "トランザクションを開始する", + "backward": "トランザクションをコミットする", + "exception": "トランザクションをロールバックする", + "reference": "transaction_management_handler" + }, + { + "no": 10, + "name": "RequestPathJavaPackageMapping", + "thread": "メイン", + "forward": "コマンドライン引数をもとに呼び出すアクションを決定する", + "backward": "", + "exception": "", + "reference": "request_path_java_package_mapping" + }, + { + "no": 11, + "name": "MultiThreadExecutionHandler", + "thread": "メイン", + "forward": "サブスレッドを作成し、後続ハンドラの処理を並行実行する", + "backward": "全スレッドの正常終了まで待機する", + "exception": "処理中のスレッドが完了するまで待機し起因例外を再送出する", + "reference": "multi_thread_execution_handler" + }, + { + "no": 12, + "name": "DatabaseConnectionManagementHandler(業務処理用)", + "thread": "サブ", + "forward": "DB接続を取得する", + "backward": "DB接続を解放する", + "exception": "", + "reference": "database_connection_management_handler" + }, + { + "no": 13, + "name": "LoopHandler", + "thread": "サブ", + "forward": "業務トランザクションを開始する", + "backward": "コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する", + "exception": "業務トランザクションをロールバックする", + "reference": "loop_handler" + }, + { + "no": 14, + "name": "DataReadHandler", + "thread": "サブ", + "forward": "データリーダを使用してレコードを1件読み込み、後続ハンドラの引数として渡す。また実行時IDを採番する", + "backward": "", + "exception": "読み込んだレコードをログ出力した後、元例外を再送出する", + "reference": "data_read_handler" + } + ], + "notes": [ + "常駐バッチの最小ハンドラ構成は、ThreadContextHandler、ThreadContextClearHandler、RetryHandler、ProcessResidentHandler、ProcessStopHandlerがメインスレッド側に追加されている点を除けば都度起動バッチと同じ", + "これは必要最小限のハンドラキュー構成であり、プロジェクト要件に従ってNablarchの標準ハンドラやプロジェクトで作成したカスタムハンドラを追加する" + ] + }, + "data-readers": { + "description": "Nablarchでは、バッチアプリケーションを構築するために必要なデータリーダを標準で幾つか提供している", + "readers": [ + { + "name": "DatabaseRecordReader", + "class": "nablarch.fw.reader.DatabaseRecordReader", + "description": "データベースからデータを読み込むデータリーダ", + "use_case": "データベースからレコードを1件ずつ読み込む" + }, + { + "name": "FileDataReader", + "class": "nablarch.fw.reader.FileDataReader", + "description": "ファイルからデータを読み込むデータリーダ。データへのアクセスにdata_formatを使用している", + "use_case": "ファイルからレコードを1件ずつ読み込む", + "important": "data_bindを使用する場合は、このデータリーダを使用しないこと" + }, + { + "name": "ValidatableFileDataReader", + "class": "nablarch.fw.reader.ValidatableFileDataReader", + "description": "バリデーション機能付きファイル読み込みデータリーダ。データへのアクセスにdata_formatを使用している", + "use_case": "ファイルからレコードを1件ずつ読み込み、バリデーションを行う", + "important": "data_bindを使用する場合は、このデータリーダを使用しないこと" + }, + { + "name": "ResumeDataReader", + "class": "nablarch.fw.reader.ResumeDataReader", + "description": "レジューム機能付き読み込みデータリーダ。障害発生ポイントからの再実行ができる", + "use_case": "ファイル入力で障害発生ポイントからの再実行が必要な場合" + } + ], + "custom_reader": { + "description": "上記のデータリーダでプロジェクトの要件を満たせない場合は、DataReaderインタフェースを実装したクラスをプロジェクトで作成して対応する", + "interface": "nablarch.fw.DataReader", + "methods": [ + { + "name": "read", + "signature": "T read(ExecutionContext ctx)", + "description": "1件分のデータを返却する。このメソッドで読み込んだデータが業務アクションハンドラへ引き渡される" + }, + { + "name": "hasNext", + "signature": "boolean hasNext(ExecutionContext ctx)", + "description": "次のデータの有無を判定する。このメソッドがfalseを返却するとデータの読み込み処理は終了となる" + }, + { + "name": "close", + "signature": "void close(ExecutionContext ctx)", + "description": "データの読み込み終了後のストリームのclose処理を実装する" + } + ] + } + }, + "actions": { + "description": "Nablarchでは、バッチアプリケーションを構築するために必要なアクションクラスを標準で幾つか提供している", + "actions": [ + { + "name": "BatchAction", + "class": "nablarch.fw.action.BatchAction", + "description": "汎用的なバッチアクションのテンプレートクラス", + "methods": [ + { + "name": "createReader", + "signature": "DataReader createReader(ExecutionContext ctx)", + "description": "使用するDataReaderのインスタンスを返却する" + }, + { + "name": "handle", + "signature": "Result handle(TData inputData, ExecutionContext ctx)", + "description": "DataReaderから渡された1件分のデータに対する業務ロジックを実装する" + } + ] + }, + { + "name": "FileBatchAction", + "class": "nablarch.fw.action.FileBatchAction", + "description": "ファイル入力のバッチアクションのテンプレートクラス。データへのアクセスにdata_formatを使用している", + "important": "data_bindを使用する場合は、このアクションクラスを使用しないこと。他のアクションクラスを使用すること" + }, + { + "name": "NoInputDataBatchAction", + "class": "nablarch.fw.action.NoInputDataBatchAction", + "description": "入力データを使用しないバッチアクションのテンプレートクラス" + }, + { + "name": "AsyncMessageSendAction", + "class": "nablarch.fw.messaging.action.AsyncMessageSendAction", + "description": "応答不要メッセージ送信用のアクションクラス" + } + ] + }, + "patterns-file-to-db": { + "name": "FILE to DB パターン", + "description": "ファイルからデータを読み込み、バリデーションを行い、データベースに登録するパターン", + "use_cases": [ + "CSVファイルからデータベースへの一括登録", + "外部システムから連携されたファイルの取り込み" + ], + "flow": [ + "ファイルを受け付けるフォームクラスを作成する(data_bindを使用)", + "DataReaderの実装クラスを作成する(ファイルを読み込んで一行ずつ業務アクションメソッドへ引き渡す)", + "BatchActionを継承した業務アクションクラスを作成する", + "createReaderメソッドで使用するDataReaderのインスタンスを返却する", + "handleメソッドで、DataReaderから渡された一行分のデータをバリデーションし、データベースに登録する" + ], + "implementation_points": [ + "data_bindを用いてフォームにCSVをバインドするため、@Csvおよび@CsvFormatを付与する", + "bean_validationを実施するために、バリデーション用のアノテーションを付与する", + "行数プロパティを定義し、ゲッタに@LineNumberを付与することで、対象データが何行目のデータであるかを自動的に設定できる", + "DataReaderのreadメソッドに一行分のデータを返却する処理を実装する", + "DataReaderのhasNextメソッドに次行の有無を判定する処理を実装する", + "DataReaderのcloseメソッドにファイルの読み込み終了後のストリームのclose処理を実装する", + "handleメソッドで、UniversalDao#insertを使用してエンティティをデータベースに登録する" + ], + "example": { + "form": "ZipCodeForm.javaを参照。@Csv、@CsvFormat、@Domain、@Required、@LineNumberを使用", + "reader": "ZipCodeFileReader.javaを参照。DataReaderインタフェースを実装し、read、hasNext、closeメソッドを実装", + "action": "ImportZipCodeFileAction.javaを参照。BatchActionを継承し、createReaderとhandleメソッドを実装" + } + }, + "patterns-db-to-file": { + "name": "DB to FILE パターン", + "description": "データベースからデータを読み込み、ファイルに出力するパターン", + "use_cases": [ + "データベースからCSVファイルへの一括出力", + "外部システムへのデータ連携ファイルの作成" + ], + "flow": [ + "DatabaseRecordReaderを使用してデータベースからレコードを読み込む", + "BatchActionを継承した業務アクションクラスを作成する", + "createReaderメソッドでDatabaseRecordReaderのインスタンスを返却する", + "handleメソッドで、読み込んだレコードをファイルに出力する" + ], + "implementation_points": [ + "DatabaseRecordReaderにSQLを設定する", + "ファイル出力にはFileRecordWriterやdata_bindを使用する", + "大量データの場合は、コミット間隔を適切に設定する" + ] + }, + "patterns-db-to-db": { + "name": "DB to DB パターン", + "description": "データベースからデータを読み込み、加工・変換してデータベースに書き込むパターン", + "use_cases": [ + "データベース内のデータ更新・変換", + "集計処理・マスタメンテナンス" + ], + "flow": [ + "DatabaseRecordReaderを使用してデータベースからレコードを読み込む", + "BatchActionを継承した業務アクションクラスを作成する", + "createReaderメソッドでDatabaseRecordReaderのインスタンスを返却する", + "handleメソッドで、読み込んだレコードを加工・変換し、UniversalDaoを使用してデータベースに更新する" + ], + "implementation_points": [ + "DatabaseRecordReaderにSQLを設定する", + "UniversalDao#update、UniversalDao#insertなどを使用してデータベースに更新する", + "大量データの場合は、コミット間隔を適切に設定する" + ] + }, + "multithread": { + "description": "バッチ処理をマルチスレッドで並列実行することで、処理性能を向上させる", + "handler": { + "name": "MultiThreadExecutionHandler", + "class": "nablarch.fw.handler.MultiThreadExecutionHandler", + "description": "サブスレッドを作成し、後続ハンドラの処理を並行実行する", + "reference": "multi_thread_execution_handler" + }, + "configuration": { + "thread_count": { + "description": "並列実行するスレッド数を設定する", + "note": "スレッド数はCPUコア数やDB接続数を考慮して設定する" + } + }, + "notes": [ + "マルチスレッドで実行されるバッチについては、アプリケーション側でスレッドセーフであることを保証する必要がある" + ] + }, + "transaction-control": { + "description": "バッチ処理のコミット間隔を制御する", + "handler": { + "name": "LoopHandler", + "class": "nablarch.fw.handler.LoopHandler", + "description": "業務トランザクションを開始し、コミット間隔毎に業務トランザクションをコミットする。また、データリーダ上に処理対象データが残っていればループを継続する", + "reference": "loop_handler" + }, + "configuration": { + "commit_interval": { + "description": "コミット間隔(処理件数)を設定する", + "reference": "loop_handler-commit_interval" + } + }, + "callback": { + "description": "処理成功や失敗時にステータスを変更する場合、LoopHandlerのコールバック機能を使用する", + "reference": "loop_handler-callback" + } + }, + "error-handling": { + "rerun": { + "title": "バッチ処理をリランできるようにする", + "description": "Nablarchバッチアプリケーションでは、ファイル入力を除き、バッチ処理をリランできるようにする機能を提供していない", + "approach": "処理対象レコードにステータスを持たせ、処理成功や失敗時にステータスを変更するといった、アプリケーションでの設計と実装が必要となる", + "file_input": { + "description": "ファイル入力については、ResumeDataReader(レジューム機能付き読み込み)を使用することで、障害発生ポイントからの再実行ができる", + "class": "nablarch.fw.reader.ResumeDataReader" + }, + "reference": "loop_handler-callback" + }, + "continue": { + "title": "バッチ処理でエラー発生時に処理を継続する", + "description": "エラー発生時の処理継続は、常駐バッチのみ対応している。都度起動バッチは対応していない", + "approach": "常駐バッチでは、TransactionAbnormalEndを送出すると、RetryHandlerにより処理が継続される。ただし、バッチ処理がリランできるようになっている必要がある", + "exception": "nablarch.fw.results.TransactionAbnormalEnd", + "note": "都度起動バッチでTransactionAbnormalEndが送出されると、バッチ処理が異常終了となる" + }, + "abnormal_end": { + "title": "バッチ処理を異常終了にする", + "description": "アプリケーションでエラーを検知した場合に、処理を継続せずにバッチ処理を異常終了させたい場合がある", + "approach": "Nablarchバッチアプリケーションでは、ProcessAbnormalEndを送出すると、バッチ処理を異常終了にできる。ProcessAbnormalEndが送出された場合、プロセス終了コードはこのクラスに指定された値となる", + "exception": "nablarch.fw.launcher.ProcessAbnormalEnd" + } + }, + "pessimistic-lock": { + "description": "Nablarchバッチアプリケーションで悲観的ロックを行うための実装方法。ロック時間が短縮され他プロセスへの影響を抑えることができる", + "approach": [ + "データリーダでは処理対象レコードの主キーのみ取得する", + "handleメソッド内で悲観的ロックを行う" + ], + "example": { + "description": "SampleAction.javaを参照", + "reader": "DatabaseRecordReaderで主キーのみ取得する", + "handle": "handleメソッド内でUniversalDao.findBySqlFileを使用して悲観的ロックを行う" + }, + "reference": "universal_dao_jpa_pessimistic_lock" + }, + "state-retention": { + "description": "バッチアプリケーションの実行中の状態(登録件数や更新件数など)を保持する", + "approach": "バッチアクション内で状態を保持することで対応する", + "multithread": { + "description": "マルチスレッドで実行されるバッチについては、アプリケーション側でスレッドセーフであることを保証する必要がある", + "example": "AtomicIntegerを使用してスレッドセーフを保証する" + }, + "execution_context": { + "description": "ExecutionContextのスコープを使用して同じことが実現できるが、どのような値を保持しているかが分かりづらいデメリットがある", + "recommendation": "ExecutionContextを使用するのではなく、バッチアクション側で状態を保持することを推奨する", + "scopes": { + "request_scope": "スレッドごとに状態を保持する領域", + "session_scope": "バッチ全体の状態を保持する領域" + } + } + }, + "multi-process": { + "description": "常駐バッチアプリケーションのマルチプロセス化", + "approach": "基本的にはデータベースをキューとしたメッセージングのマルチプロセス化(db_messaging-multiple_process)と同様", + "action_implementation": { + "description": "Actionの実装についてはデータベースをキューとしたメッセージングとは異なる", + "points": [ + "プロセスIDを生成する(例: UUIDを使用)", + "自身が悲観ロックした未処理データを抽出するDatabaseRecordReaderを作成する", + "DatabaseRecordReaderがデータ抽出前に行うコールバック処理に、悲観ロックSQLを実行する処理を登録する", + "コールバック処理は別トランザクションで実行する必要がある" + ], + "listener": { + "interface": "DatabaseRecordListener", + "method": "beforeReadRecords", + "description": "DatabaseRecordReaderがデータ抽出前に実行するコールバック処理" + } + }, + "custom_reader": { + "description": "Readerを自作している場合には、悲観ロック後に処理対象データを抽出するようにするとよい" + } + }, + "configuration": { + "system_repository": { + "description": "システムリポジトリの初期化は、アプリケーション起動時にシステムリポジトリの設定ファイルのパスを指定することで行う", + "reference": "main-run_application" + }, + "launch": { + "description": "Nablarchバッチアプリケーションの起動方法", + "command": "java -cp ... nablarch.fw.launcher.Main -requestPath=/ -diConfig= -userId=", + "parameters": [ + { + "name": "requestPath", + "description": "実行するアクションとリクエストIDを指定する。形式: アクションのクラス名/リクエストID", + "required": true + }, + { + "name": "diConfig", + "description": "システムリポジトリの設定ファイルのパスを指定する", + "required": true + }, + { + "name": "userId", + "description": "実行ユーザIDを指定する", + "required": false + } + ] + } + }, + "anti-patterns": [ + { + "pattern": "FileDataReaderまたはValidatableFileDataReaderをdata_bindと併用する", + "reason": "FileDataReaderとValidatableFileDataReaderは、データへのアクセスにdata_formatを使用している。data_bindを使用する場合は、これらのデータリーダを使用しないこと", + "correct": "data_bindを使用する場合は、DataReaderインタフェースを実装したカスタムデータリーダを作成するか、他のアクションクラスを使用する" + }, + { + "pattern": "FileBatchActionをdata_bindと併用する", + "reason": "FileBatchActionは、データへのアクセスにdata_formatを使用している。data_bindを使用する場合は、このアクションクラスを使用しないこと", + "correct": "data_bindを使用する場合は、BatchActionや他のアクションクラスを使用する" + }, + { + "pattern": "フォームクラスのプロパティをString以外で定義する", + "reason": "Bean Validationの要件により、フォームクラスのプロパティは全てStringで定義する必要がある(バイナリ項目を除く)", + "correct": "フォームクラスのプロパティは全てStringで定義する。バイナリ項目の場合はバイト配列で定義する" + }, + { + "pattern": "データベースなど安全な入力データに対してもフォームクラスを使用する", + "reason": "フォームクラスは外部から連携されるファイルなど、入力データが安全でない場合にバリデーションを行うために使用する", + "correct": "データベースなど、入力データが安全な場合は、フォームクラスを使用せず、データレコードからエンティティクラスを作成して業務ロジックを実行する" + }, + { + "pattern": "新規開発で常駐バッチを採用する", + "reason": "常駐バッチは、マルチスレッドで実行しても、処理が遅いスレッドの終了を他のスレッドが待つことにより、要求データの取り込み遅延が発生する可能性がある", + "correct": "新規開発プロジェクトでは、常駐バッチではなく、上記問題が発生しないdb_messagingを使用することを推奨する" + }, + { + "pattern": "ExecutionContextを使用して状態を保持する", + "reason": "ExecutionContextを使用した場合、どのような値を保持しているかが分かりづらいデメリットがある", + "correct": "ExecutionContextを使用するのではなく、バッチアクション側で状態を保持することを推奨する" + }, + { + "pattern": "悲観的ロックをデータリーダで行う", + "reason": "データリーダで悲観的ロックを行うと、ロック時間が長くなり他プロセスへの影響が大きい", + "correct": "データリーダでは処理対象レコードの主キーのみ取得し、handleメソッド内で悲観的ロックを行う。これによりロック時間が短縮され他プロセスへの影響を抑えることができる" + }, + { + "pattern": "都度起動バッチでTransactionAbnormalEndを送出してエラー継続を期待する", + "reason": "都度起動バッチは、エラー発生時の処理継続に対応していない。TransactionAbnormalEndが送出されると、バッチ処理が異常終了となる", + "correct": "エラー発生時の処理継続は、常駐バッチのみ対応している。常駐バッチでTransactionAbnormalEndを送出すると、RetryHandlerにより処理が継続される" + } + ], + "errors": [ + { + "exception": "nablarch.fw.results.TransactionAbnormalEnd", + "cause": "トランザクションの異常終了を示す例外", + "use_case": "常駐バッチでエラー発生時に処理を継続する場合に送出する", + "behavior": "常駐バッチでは、RetryHandlerにより処理が継続される。都度起動バッチでは、バッチ処理が異常終了となる", + "note": "バッチ処理がリランできるようになっている必要がある" + }, + { + "exception": "nablarch.fw.launcher.ProcessAbnormalEnd", + "cause": "プロセスの異常終了を示す例外", + "use_case": "アプリケーションでエラーを検知した場合に、処理を継続せずにバッチ処理を異常終了させる場合に送出する", + "behavior": "バッチ処理が異常終了となる。プロセス終了コードはこのクラスに指定された値となる" + }, + { + "exception": "nablarch.fw.handler.ProcessStopHandler.ProcessStop", + "cause": "プロセスの停止を示す例外", + "use_case": "ProcessStopHandlerがリクエストテーブル上の処理停止フラグがオンであることを検知した場合に送出される", + "behavior": "後続ハンドラの処理は行なわずにプロセスが停止する" + } + ] + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/tools/ntf-assertion.json b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-assertion.json new file mode 100644 index 0000000..fe64e2b --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-assertion.json @@ -0,0 +1,360 @@ +{ + "id": "ntf-assertion", + "title": "NTFアサーション・期待値検証", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_DbAccessTest.html", + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_RequestUnitTest.html", + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/03_Tips.html" + ], + "index": [ + { + "id": "overview", + "hints": ["アサーション", "期待値検証", "結果確認", "assert", "テスト結果"] + }, + { + "id": "db_assertion", + "hints": ["データベース", "assertTableEquals", "assertSqlResultSetEquals", "EXPECTED_TABLE", "DB確認"] + }, + { + "id": "db_setup", + "hints": ["準備データ", "setUpDb", "SETUP_TABLE", "データ投入", "セットアップ"] + }, + { + "id": "transaction_control", + "hints": ["トランザクション", "commit", "commitTransactions", "beginTransactions", "endTransactions"] + }, + { + "id": "message_assertion", + "hints": ["メッセージ", "assertApplicationMessageId", "アプリケーション例外", "メッセージID"] + }, + { + "id": "property_assertion", + "hints": ["プロパティ", "assertObjectPropertyEquals", "assertObjectArrayPropertyEquals", "assertObjectListPropertyEquals", "オブジェクト検証"] + }, + { + "id": "html_dump", + "hints": ["HTMLダンプ", "html_dump", "レイアウト確認", "画面確認", "HTMLリソース"] + } + ], + "sections": { + "overview": { + "description": "テスト結果と期待値の自動比較機能を提供する。データベース更新内容の確認、検索結果の確認、メッセージの確認、オブジェクトプロパティの確認など、多様なアサーション機能を提供する。", + "assertion_types": [ + "DBアサーション(更新結果、検索結果)", + "ファイルアサーション", + "ログアサーション", + "メッセージアサーション", + "プロパティアサーション", + "HTMLダンプ出力" + ], + "related_files": ["ntf-overview.json", "ntf-test-data.json", "ntf-batch-request-test.json"] + }, + "db_assertion": { + "description": "データベースの更新結果や検索結果を期待値と比較する機能", + "methods": [ + { + "name": "assertTableEquals", + "signature": "assertTableEquals(String sheetName)", + "description": "指定されたシート内のデータタイプ\"EXPECTED_TABLE\"であるデータを全て比較する。データベースの更新結果が期待値と一致することを確認する。", + "parameters": [ + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + } + ], + "usage": "更新系テストで使用。テスト対象メソッド実行後、commitTransactions()を呼び出してから本メソッドを実行する。", + "comparison_rules": [ + "期待値の記述で省略されたカラムは、比較対象外となる", + "比較実行時、レコードの順番が異なっていても主キーを突合して正しく比較ができる", + "1シート内に複数のテーブルを記述できる" + ], + "notes": "更新日付のようなjava.sql.Timestamp型のフォーマットは\"yyyy-mm-dd hh:mm:ss.fffffffff\"である(fffffffffはナノ秒)。ナノ秒が設定されていない場合でも、フォーマット上は0ナノ秒として表示される(例:2010-01-01 12:34:56.0)。Excelシートに期待値を記載する場合は、末尾の小数点+ゼロを付与しておく必要がある。" + }, + { + "name": "assertTableEquals (with groupId)", + "signature": "assertTableEquals(String message, String sheetName, String groupId)", + "description": "グループIDを指定して、そのグループIDのデータのみをassert対象にする。複数のテストケースのデータを1つのシートに混在させる場合に使用。", + "parameters": [ + { + "name": "message", + "type": "String", + "description": "アサート失敗時に表示するメッセージ" + }, + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + }, + { + "name": "groupId", + "type": "String", + "description": "グループID" + } + ], + "usage": "1つのシートに複数テストケースのデータを記載する場合に使用。EXPECTED_TABLE[groupId]=テーブル名の形式で記述する。" + }, + { + "name": "assertSqlResultSetEquals", + "signature": "assertSqlResultSetEquals(String sheetName, String id, SqlResultSet actual)", + "description": "Excelに記載した期待値(LIST_MAP形式)と実際の検索結果(SqlResultSet)が等しいことを確認する。", + "parameters": [ + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + }, + { + "name": "id", + "type": "String", + "description": "期待値のID(LIST_MAPのID)" + }, + { + "name": "actual", + "type": "SqlResultSet", + "description": "実際の検索結果" + } + ], + "usage": "参照系テストで使用。テスト対象メソッドが返すSqlResultSetを期待値と比較する。", + "comparison_rules": [ + "SELECT文で指定された全てのカラム名(別名)が比較対象になる。ある特定のカラムを比較対象外にすることはできない", + "レコードの順序が異なる場合は、等価でないとみなす(アサート失敗)" + ], + "notes": "SELECT実行時はORDER BY指定がなされる場合がほとんどであり、順序についても厳密に比較する必要がある為、レコードの順序が異なる場合はアサート失敗となる。" + } + ] + }, + "db_setup": { + "description": "データベースに準備データを登録する機能", + "methods": [ + { + "name": "setUpDb", + "signature": "setUpDb(String sheetName)", + "description": "指定されたシート内のデータタイプ\"SETUP_TABLE\"全てをデータベースに登録する。", + "parameters": [ + { + "name": "sheetName", + "type": "String", + "description": "準備データを記載したExcelシート名" + } + ], + "usage": "テスト対象メソッド実行前に呼び出す。", + "notes": [ + "Excelファイルには必ずしも全カラムを記述する必要はない。省略されたカラムには、デフォルト値が設定される", + "Excelファイルの1シート内に複数のテーブルを記述できる。setUpDb(String sheetName)実行時、指定されたシート内のデータタイプ\"SETUP_TABLE\"全てが登録対象となる" + ] + }, + { + "name": "setUpDb (with groupId)", + "signature": "setUpDb(String sheetName, String groupId)", + "description": "グループIDを指定して、そのグループIDのデータのみをデータベースに登録する。", + "parameters": [ + { + "name": "sheetName", + "type": "String", + "description": "準備データを記載したExcelシート名" + }, + { + "name": "groupId", + "type": "String", + "description": "グループID" + } + ], + "usage": "1つのシートに複数テストケースのデータを記載する場合に使用。SETUP_TABLE[groupId]=テーブル名の形式で記述する。" + } + ] + }, + "transaction_control": { + "description": "トランザクション制御機能。Nablarch Application Frameworkでは複数種類のトランザクションを併用することが前提となっているため、テスト対象クラス実行後にデータベースの内容を確認する際には、トランザクションをコミットしなければならない。", + "important": "更新系テストの場合、テスト対象クラス実行後にcommitTransactions()を呼び出してからassertTableEquals()を実行する必要がある。参照系テストの場合はコミットを行う必要はない。", + "methods": [ + { + "name": "beginTransactions", + "signature": "beginTransactions()", + "description": "トランザクションを開始する。DbAccessTestSupportを継承している場合、@Beforeメソッドで自動的に呼び出される。", + "usage": "通常は明示的に呼び出す必要はない。" + }, + { + "name": "commitTransactions", + "signature": "commitTransactions()", + "description": "トランザクションをコミットする。", + "usage": "更新系テストで、テスト対象メソッド実行後、データベースの内容を確認する前に呼び出す。", + "important": "コミットしない場合、テスト結果の確認が正常に行われない。" + }, + { + "name": "endTransactions", + "signature": "endTransactions()", + "description": "トランザクションを終了する。DbAccessTestSupportを継承している場合、@Afterメソッドで自動的に呼び出される。", + "usage": "通常は明示的に呼び出す必要はない。" + } + ], + "automatic_control": "DbAccessTestSupportを継承している場合、テストメソッド実行前にトランザクション開始、テストメソッド終了後にトランザクション終了が自動的に行われる。" + }, + "message_assertion": { + "description": "アプリケーション例外に格納されたメッセージIDを検証する機能(ウェブアプリケーションのリクエスト単体テストで使用)", + "methods": [ + { + "name": "assertApplicationMessageId", + "signature": "assertApplicationMessageId(String expectedCommaSeparated, ExecutionContext actual)", + "description": "アプリケーション例外に格納されたメッセージが想定通りであることを確認する。", + "parameters": [ + { + "name": "expectedCommaSeparated", + "type": "String", + "description": "期待するメッセージID(複数ある場合はカンマ区切りで指定)" + }, + { + "name": "actual", + "type": "ExecutionContext", + "description": "テスト実行時に使用したExecutionContext" + } + ], + "usage": "リクエスト単体テストで、アプリケーション例外が発生した場合のメッセージIDを確認する。", + "behavior": [ + "例外が発生しなかった場合や、アプリケーション例外以外の例外が発生した場合は、アサート失敗となる", + "メッセージIDの比較はIDをソートした状態で行うので、テストデータを記載する際に順序を気にする必要はない" + ] + } + ] + }, + "property_assertion": { + "description": "オブジェクトのプロパティを期待値と比較する機能", + "methods": [ + { + "name": "assertObjectPropertyEquals", + "signature": "assertObjectPropertyEquals(String message, String sheetName, String id, Object actual)", + "description": "オブジェクトのプロパティの値がExcelファイルに記載したデータとなっていることを検証する。", + "parameters": [ + { + "name": "message", + "type": "String", + "description": "エラー時に表示するメッセージ" + }, + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + }, + { + "name": "id", + "type": "String", + "description": "期待値のID(LIST_MAPのID)" + }, + { + "name": "actual", + "type": "Object", + "description": "検証対象のオブジェクト" + } + ], + "usage": "Formオブジェクト、Entityオブジェクトなどのプロパティを検証する。Excelには、2行目にプロパティ名、3行目以降にプロパティの期待値を記述する。" + }, + { + "name": "assertObjectArrayPropertyEquals", + "signature": "assertObjectArrayPropertyEquals(String message, String sheetName, String id, Object[] actual)", + "description": "オブジェクト配列の各要素のプロパティの値がExcelファイルに記載したデータとなっていることを検証する。", + "parameters": [ + { + "name": "message", + "type": "String", + "description": "エラー時に表示するメッセージ" + }, + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + }, + { + "name": "id", + "type": "String", + "description": "期待値のID(LIST_MAPのID)" + }, + { + "name": "actual", + "type": "Object[]", + "description": "検証対象のオブジェクト配列" + } + ], + "usage": "複数のオブジェクトを配列で受け取る場合に使用。Excelには、2行目にプロパティ名、3行目以降に各オブジェクトのプロパティの期待値を記述する。" + }, + { + "name": "assertObjectListPropertyEquals", + "signature": "assertObjectListPropertyEquals(String message, String sheetName, String id, List actual)", + "description": "オブジェクトリストの各要素のプロパティの値がExcelファイルに記載したデータとなっていることを検証する。", + "parameters": [ + { + "name": "message", + "type": "String", + "description": "エラー時に表示するメッセージ" + }, + { + "name": "sheetName", + "type": "String", + "description": "期待値を記載したExcelシート名" + }, + { + "name": "id", + "type": "String", + "description": "期待値のID(LIST_MAPのID)" + }, + { + "name": "actual", + "type": "List", + "description": "検証対象のオブジェクトリスト" + } + ], + "usage": "複数のオブジェクトをリストで受け取る場合に使用。Excelには、2行目にプロパティ名、3行目以降に各オブジェクトのプロパティの期待値を記述する。" + } + ], + "excel_format": { + "description": "プロパティアサーション用のExcelデータ記述方法", + "format": "LIST_MAP=\nプロパティ名1 プロパティ名2 プロパティ名3\n期待値1 期待値2 期待値3", + "example": "LIST_MAP=expectedUsers\nkanjiName kanaName mailAddress\n漢字氏名 カナシメイ test@anydomain.com", + "notes": "プロパティ名はJavaBeansの命名規則に従う。複数のオブジェクトを検証する場合は、3行目以降に複数行記述する。" + } + }, + "html_dump": { + "description": "ウェブアプリケーションのリクエスト単体テストで、HTMLレスポンスをファイル出力する機能", + "output_directory": { + "default": "./tmp/html_dump", + "structure": "テストクラス毎に同名のディレクトリが作成され、そのテストクラスで実行されたテストケース説明と同名のHTMLダンプファイルが出力される", + "backup": "html_dumpディレクトリが既に存在する場合は、html_dump_bkという名前でバックアップされる", + "html_resources": "HTMLダンプファイルが参照するHTMLリソース(スタイルシートや画像などのリソース)についてもこのディレクトリに出力される" + }, + "automatic_execution": "リクエスト単体テストを実行すると、内蔵サーバが起動されHTMLレスポンスが自動的にファイル出力される。", + "purpose": "画面レイアウトの確認、レビュー時の証跡として使用する。", + "configuration": [ + { + "property": "htmlDumpDir", + "description": "HTMLダンプファイルを出力するディレクトリを指定する", + "default": "./tmp/html_dump" + }, + { + "property": "dumpFileExtension", + "description": "ダンプファイルの拡張子", + "default": "html" + }, + { + "property": "htmlResourcesExtensionList", + "description": "ダンプディレクトリへコピーされるHTMLリソースの拡張子", + "default": ["css", "jpg", "js"] + }, + { + "property": "htmlResourcesCharset", + "description": "CSSファイル(スタイルシート)の文字コード", + "default": "UTF-8" + }, + { + "property": "backup", + "description": "ダンプディレクトリのバックアップOn/Off", + "default": "true" + }, + { + "property": "dumpVariableItem", + "description": "HTMLダンプファイル出力時に可変項目(JSESSIONID、2重サブミット防止用のトークン)を出力するか否かを設定する。前回実行結果と差異がないことを確認したい場合等は、falseに設定する。", + "default": "false" + } + ], + "notes": "1リクエスト1画面遷移のシンクライアント型ウェブアプリケーションを対象としている。Ajaxやリッチクライアントを利用したアプリケーションの場合、HTMLダンプによるレイアウト確認は使用できない。" + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/tools/ntf-batch-request-test.json b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-batch-request-test.json new file mode 100644 index 0000000..37ea1b1 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-batch-request-test.json @@ -0,0 +1,217 @@ +{ + "id": "ntf-batch-request-test", + "title": "NTFバッチリクエスト単体テスト", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/RequestUnitTest_batch.html" + ], + "index": [ + { + "id": "overview", + "hints": ["バッチリクエスト単体テスト", "バッチ処理", "リクエスト単体テスト", "コマンドライン起動", "BatchRequestTestSupport"] + }, + { + "id": "test_class", + "hints": ["テストクラス", "継承", "@ExtendWith", "JUnit 5", "Extension", "BatchRequestTestSupport"] + }, + { + "id": "test_support_classes", + "hints": ["StandaloneTestSupportTemplate", "TestShot", "MainForRequestTesting", "FileSupport", "DbAccessTestSupport"] + }, + { + "id": "test_execution", + "hints": ["execute", "テスト実行", "テストショット", "入力データ準備", "結果確認"] + }, + { + "id": "resident_batch_config", + "hints": ["常駐バッチ", "RequestThreadLoopHandler", "OneShotLoopHandler", "ハンドラ構成", "テスト用設定"] + }, + { + "id": "directive_defaults", + "hints": ["ディレクティブ", "デフォルト値", "固定長ファイル", "可変長ファイル", "text-encoding", "record-separator"] + } + ], + "sections": { + "overview": { + "description": "実際にバッチをコマンドラインから起動したときの動作を擬似的に再現し、テストを行う。", + "purpose": "バッチアクションのリクエスト単体テストをサポートし、入力ファイル作成から出力ファイル検証まで自動化する。", + "test_target": "バッチ処理(Actionクラス)", + "related_files": ["ntf-overview.json", "ntf-test-data.json", "ntf-assertion.json"] + }, + "test_class": { + "description": "バッチリクエスト単体テストのテストクラスの作成方法", + "junit5_approach": { + "inheritance": "継承不要(JUnit 5 Extension使用)", + "annotations": ["@ExtendWith(BatchRequestTestExtension.class)"], + "required_field": "BatchRequestTestSupport support", + "example": "@ExtendWith(PromanBatchRequestExtension.class)\nclass ExportProjectsInPeriodActionRequestTest {\n PromanBatchRequestTestSupport support;\n\n @Test\n void testNormalEnd() {\n support.execute(support.testName.getMethodName());\n }\n}", + "notes": "JUnit 5のExtension機構を使用することで、継承なしでテスト機能を利用できる。supportフィールドはExtensionによって自動的に初期化される。" + }, + "junit4_approach": { + "inheritance": "BatchRequestTestSupportを継承", + "example": "public class SampleBatchRequestTest extends BatchRequestTestSupport {\n @Test\n public void testNormalEnd() {\n execute(\"testNormalEnd\");\n }\n}", + "notes": "JUnit 4を使用する場合は、BatchRequestTestSupportクラスを継承する。" + } + }, + "test_support_classes": { + "description": "バッチリクエスト単体テストで使用する主要なクラス", + "classes": [ + { + "name": "StandaloneTestSupportTemplate", + "description": "バッチやメッセージング処理などコンテナ外で動作する処理のテスト実行環境を提供する。", + "responsibilities": [ + "テストデータを読み取り、全テストショット(TestShot)を実行" + ], + "creation_unit": "フレームワーク提供" + }, + { + "name": "TestShot", + "description": "1テストショットの情報保持とテストショットを実行する。", + "responsibilities": [ + "入力データの準備(データベースのセットアップ)", + "メインクラス起動", + "出力結果の確認(データベース更新内容確認、ログ出力結果確認、ステータスコード確認)" + ], + "customization": "入力データ準備や結果確認ロジックはバッチや各種メッセージング処理ごとに異なるので方式に応じたカスタマイズが可能。", + "creation_unit": "フレームワーク提供" + }, + { + "name": "BatchRequestTestSupport", + "description": "バッチ処理テスト用のスーパクラス。TestShotが提供する準備処理、結果確認に入力ファイル作成と出力ファイル確認機能を追加する。", + "inheritance": "アプリケーションプログラマは本クラスを継承してテストクラスを作成する(JUnit 4の場合)。JUnit 5の場合はExtensionとして使用。", + "additional_features": [ + "入力ファイルの作成", + "出力ファイルの内容確認" + ], + "benefits": "リクエスト単体テストのテストソース、テストデータを定型化でき、テストソース記述量を大きく削減できる。", + "creation_unit": "フレームワーク提供" + }, + { + "name": "MainForRequestTesting", + "description": "リクエスト単体テスト用のメインクラス。", + "differences_from_production": [ + "テスト用のコンポーネント設定ファイルからシステムリポジトリを初期化する", + "常駐化機能を無効化する" + ], + "creation_unit": "フレームワーク提供" + }, + { + "name": "FileSupport", + "description": "ファイルに関する操作を提供するクラス。主に入力ファイル作成とファイル内容比較を提供。", + "responsibilities": [ + "テストデータから入力ファイルを作成する", + "テストデータの期待値と実際に出力されたファイルの内容を比較する" + ], + "notes": "ファイルに関する操作は、バッチ処理以外でも必要となるため(例えば、ファイルダウンロード等)、独立したクラスとして提供している。", + "creation_unit": "フレームワーク提供" + }, + { + "name": "DbAccessTestSupport", + "description": "準備データ投入などデータベースを使用するテストに必要な機能を提供する。", + "creation_unit": "フレームワーク提供" + } + ] + }, + "test_execution": { + "description": "バッチリクエスト単体テストの実行方法", + "method": { + "name": "execute", + "signature": "support.execute(testCaseName)", + "description": "テストケースを実行する。指定されたテストケース名に対応するExcelシートからテストデータを読み込み、TestShotを実行する。", + "parameters": [ + { + "name": "testCaseName", + "type": "String", + "description": "テストケース名(テストメソッド名と同名のExcelシート名)" + } + ], + "return_type": "void" + }, + "test_shot_flow": [ + "1. Excelシートからテストデータを読み込み", + "2. データベースに準備データをセットアップ", + "3. 入力ファイルを作成(固定長・可変長)", + "4. MainForRequestTestingを使用してバッチを実行", + "5. ステータスコードを確認", + "6. データベースの更新内容を確認", + "7. 出力ファイルの内容を確認", + "8. ログ出力結果を確認" + ], + "naming_convention": "testXxx形式(Xxxはテストシナリオ)。Excelシート名はテストメソッド名と同名にする。" + }, + "resident_batch_config": { + "description": "常駐バッチのテスト用ハンドラ構成", + "reason": "常駐バッチのテストを実施する際には、プロダクション用ハンドラ構成をテスト用に変更する必要がある。この変更をせずにテストを実施した場合、テスト対象の常駐バッチアプリケーションの処理が終わらないため、テストが正常に実施できなくなる。", + "handler_changes": [ + { + "production_handler": "RequestThreadLoopHandler", + "test_handler": "OneShotLoopHandler", + "change_reason": "RequestThreadLoopHandlerでテストを実施すると、バッチ実行が終わらずにテストコードに制御が戻らなくなるため。OneShotLoopHandlerにハンドラを差し替えることで、テスト実行前にセットアップした要求データを全件処理後にバッチ実行が終了しテストコードに制御が戻るようになる。" + } + ], + "configuration_example": { + "production": "\n \n", + "test": "", + "notes": "プロダクション用設定と同名でコンポーネントを設定し、テスト用のハンドラを使用するように上書きする。" + } + }, + "directive_defaults": { + "description": "ファイルのディレクティブのデフォルト値設定", + "purpose": "ファイルのディレクティブがシステム内である程度統一されている場合、個々のテストデータに同じディレクティブを記載することは冗長である。デフォルトのディレクティブをコンポーネント設定ファイルに記載することで、個々のテストデータではディレクティブの記述を省略できる。", + "configuration_names": [ + { + "name": "defaultDirectives", + "target": "共通ディレクティブ", + "description": "固定長・可変長ファイル共通のデフォルト値" + }, + { + "name": "fixedLengthDirectives", + "target": "固定長ファイル", + "description": "固定長ファイル固有のデフォルト値" + }, + { + "name": "variableLengthDirectives", + "target": "可変長ファイル", + "description": "可変長ファイル固有のデフォルト値" + } + ], + "configuration_example": "\n \n\n\n\n \n\n\n\n \n \n", + "common_directives": [ + { + "key": "text-encoding", + "description": "ファイルの文字エンコーディング", + "example_value": "Windows-31J" + }, + { + "key": "record-separator", + "description": "レコード区切り文字", + "example_values": ["NONE", "CRLF", "LF"] + }, + { + "key": "quoting-delimiter", + "description": "引用符(可変長ファイルのみ)", + "example_value": "\"\"" + } + ] + }, + "file_data": { + "description": "バッチ処理固有のテストデータ", + "fixed_length": { + "description": "固定長ファイルのテストデータ記述方法", + "padding": { + "description": "指定したフィールド長に対して、データのバイト長が短い場合、そのフィールドのデータ型に応じたパディングが行われる。", + "algorithm": "パディングのアルゴリズムはNablarch Application Framework本体と同様" + }, + "binary_data": { + "description": "バイナリデータを表現するには、16進数形式でテストデータを記述する。", + "format": "0xプレフィックス付き16進数(例:0x4AD)", + "example": "0x4ADと記述した場合、0000 0100 1010 1101(0x04AD)という2バイトのバイト配列に解釈される。", + "notes": "プレフィックス0xが付与されていない場合、そのデータを文字列とみなし、その文字列をディレクティブの文字コードでエンコードしてバイト配列に変換する。" + } + }, + "variable_length": { + "description": "可変長ファイルのテストデータ記述方法", + "reference": "batch_request_testを参照" + } + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/tools/ntf-overview.json b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-overview.json new file mode 100644 index 0000000..97a24c4 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-overview.json @@ -0,0 +1,127 @@ +{ + "id": "ntf-overview", + "title": "NTF(Nablarch Testing Framework)概要", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/01_Abstract.html" + ], + "index": [ + { + "id": "overview", + "hints": ["NTF", "Nablarch Testing Framework", "自動テストフレームワーク", "テスト", "JUnit"] + }, + { + "id": "features", + "hints": ["特徴", "JUnit4", "テストデータ外部化", "Excel", "Nablarch特化"] + }, + { + "id": "architecture", + "hints": ["構成", "テストクラス", "Excelファイル", "DbAccessTestSupport", "コンポーネント"] + }, + { + "id": "test_method", + "hints": ["テストメソッド", "@Test", "JUnit", "アノテーション"] + }, + { + "id": "junit5_support", + "hints": ["JUnit 5", "JUnit Vintage", "junit-jupiter", "junit-vintage-engine", "移行"] + } + ], + "sections": { + "overview": { + "description": "Nablarchアプリケーションの自動テストを効率的に実施するためのフレームワーク。JUnit4をベースとし、テストデータの外部化とNablarch特有の機能をサポート。", + "purpose": "リクエスト単体テスト、DBテスト、クラス単体テストを効率的に実施し、テストの可読性と保守性を向上させる。", + "related_files": ["ntf-batch-request-test.json", "ntf-test-data.json", "ntf-assertion.json"] + }, + "features": { + "description": "NTFが提供する主要な特徴", + "features": [ + { + "name": "JUnit4ベース", + "description": "JUnit4をベースとしており、各種アノテーション、assertメソッド、Matcherクラスなど、JUnit4で提供されている機能を使用できる。", + "notes": "JUnit 5上でも動作可能(JUnit Vintageを使用)" + }, + { + "name": "テストデータの外部化", + "description": "テストデータをExcelファイルに記述でき、データベース準備データや期待するテスト結果などを記載したExcelファイルをAPIを通じて使用できる。", + "benefits": ["可読性の向上", "編集の容易さ", "テストとロジックの分離"] + }, + { + "name": "Nablarchに特化したテスト補助機能", + "description": "トランザクション制御やシステム日付設定など、Nablarchアプリケーションに特化したAPIを提供する。", + "examples": ["トランザクション制御", "システム日付固定", "ThreadContext設定"] + } + ] + }, + "architecture": { + "description": "自動テストフレームワークの構成要素", + "components": [ + { + "name": "テストクラス", + "description": "テスト処理を記述する。DbAccessTestSupportやHttpRequestTestSupportなどのスーパークラスを継承する。", + "creator": "アプリケーションプログラマ", + "creation_unit": "テスト対象クラスにつき1つ作成" + }, + { + "name": "Excelファイル", + "description": "テストデータを記載する。自動テストフレームワークを使用することにより、データを読み取ることができる。", + "creator": "アプリケーションプログラマ", + "creation_unit": "テストクラスにつき1つ作成", + "supported_formats": ["Excel2003形式(.xls)", "Excel2007以降形式(.xlsx)"] + }, + { + "name": "テスト対象クラス", + "description": "テスト対象となるクラス(Action以降の業務ロジックを実装する各クラスを含む)", + "creator": "アプリケーションプログラマ" + }, + { + "name": "コンポーネント設定ファイル・環境設定ファイル", + "description": "テスト実行時の各種設定を記載する。", + "creator": "アプリケーションプログラマ(個別のテストに固有の設定が必要な場合)" + }, + { + "name": "自動テストフレームワーク", + "description": "テストに必要な機能を提供する。DbAccessTestSupport、HttpRequestTestSupport、BatchRequestTestSupport等が含まれる。" + }, + { + "name": "Nablarch Application Framework", + "description": "フレームワーク本体(本機能の対象外)" + } + ] + }, + "test_method": { + "description": "テストメソッドの記述方法", + "annotation": "@Test", + "framework": "JUnit4", + "example": "public class SampleTest {\n @Test\n public void testSomething() {\n // テスト処理\n }\n}", + "notes": "@Beforeや@Afterなどのアノテーションも使用できる。これらを用いて、テストメソッド前後にリソースの取得解放などの共通処理を行うことが可能。" + }, + "junit5_support": { + "description": "JUnit 5で自動テストフレームワークを動かす方法", + "mechanism": "JUnit Vintage", + "mechanism_description": "JUnit 5の上でJUnit 4で書かれたテストを実行できるようにするための機能。この機能を利用することで、自動テストフレームワークをJUnit 5の上で動かすことができる。", + "important_notes": "この機能は、あくまでJUnit 4のテストをJUnit 4として動かしているにすぎない。したがって、JUnit 4のテストの中でJUnit 5の機能が使えるわけではない。JUnit 4からJUnit 5への移行を段階的進めるための補助として利用できる。", + "prerequisites": [ + { + "item": "maven-surefire-plugin", + "version": "2.22.0以上" + } + ], + "dependencies": [ + { + "groupId": "org.junit.jupiter", + "artifactId": "junit-jupiter", + "scope": "test", + "description": "JUnit 5のコアライブラリ" + }, + { + "groupId": "org.junit.vintage", + "artifactId": "junit-vintage-engine", + "scope": "test", + "description": "JUnit 4テストをJUnit 5上で実行するためのエンジン" + } + ], + "configuration_example": "\n \n \n org.junit\n junit-bom\n 5.8.2\n pom\n import\n \n \n\n\n\n \n org.junit.jupiter\n junit-jupiter\n test\n \n \n org.junit.vintage\n junit-vintage-engine\n test\n \n", + "related_info": "JUnit 5のテストで自動テストフレームワークを使用する方法については、ntf_junit5_extensionを参照。" + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/features/tools/ntf-test-data.json b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-test-data.json new file mode 100644 index 0000000..9866433 --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/features/tools/ntf-test-data.json @@ -0,0 +1,355 @@ +{ + "id": "ntf-test-data", + "title": "NTFテストデータ", + "official_doc_urls": [ + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/01_Abstract.html#excel", + "https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/guide/development_guide/06_TestFWGuide/02_DbAccessTest.html" + ], + "index": [ + { + "id": "overview", + "hints": ["テストデータ", "Excel", "Excelファイル", "スプレッドシート", "外部化"] + }, + { + "id": "naming_conventions", + "hints": ["命名規約", "ファイル名", "シート名", "配置", "ディレクトリ"] + }, + { + "id": "data_types", + "hints": ["データタイプ", "SETUP_TABLE", "EXPECTED_TABLE", "LIST_MAP", "SETUP_FIXED", "EXPECTED_VARIABLE"] + }, + { + "id": "special_notation", + "hints": ["特殊記法", "null", "systemTime", "setUpTime", "文字種", "binaryFile", "改行"] + }, + { + "id": "cell_format", + "hints": ["セル", "書式", "文字列", "日付", "コメント", "マーカーカラム"] + }, + { + "id": "column_omission", + "hints": ["カラム省略", "EXPECTED_COMPLETE_TABLE", "デフォルト値", "省略記述", "可読性"] + } + ], + "sections": { + "overview": { + "description": "データベースの準備データやデータベース検索結果などのデータを表すには、Javaソースコードよりスプレッドシートのほうが可読性や編集のしやすさという点で有利である。Excelファイルを使用することにより、このようなデータをスプレッドシート形式で扱うことができる。", + "supported_formats": ["Excel2003形式(.xls)", "Excel2007以降形式(.xlsx)"], + "location": "src/test/java配下(デフォルト)。テストソースコードと同じディレクトリに配置することを推奨。", + "benefits": ["可読性の向上", "編集の容易さ", "テストケースの把握が容易", "テストデータとテストロジックの役割分担が明確"] + }, + "naming_conventions": { + "description": "Excelファイル名、ファイルパスには推奨される規約が存在する。この規約に従うことにより、テストクラスで明示的にディレクトリ名やファイル名を指定してファイルを読み込む必要がなくなり、簡潔にテストソースコードを記述できる。", + "file_conventions": [ + { + "rule": "Excelファイル名は、テストソースコードと同じ名前にする(拡張子のみ異なる)", + "example": { + "test_class": "ExampleDbAccessTest.java", + "excel_file": "ExampleDbAccessTest.xlsx" + } + }, + { + "rule": "Excelファイルを、テストソースコードと同じディレクトリに配置する", + "example": { + "directory": "/test/jp/co/tis/example/db/", + "files": ["ExampleDbAccessTest.java", "ExampleDbAccessTest.xlsx"] + } + } + ], + "sheet_conventions": [ + { + "rule": "1テストメソッドにつき1シート用意する", + "notes": "この規約は制約事項ではない。テストメソッド名とExcelシート名が同名でなくても正しく動作する。" + }, + { + "rule": "シート名はテストメソッド名と同名にする", + "example": { + "test_method": "@Test public void testInsert()", + "sheet_name": "testInsert" + }, + "recommendation": "今後の機能追加は上記規約をデフォルトとして開発されるので、命名規約に準拠することを推奨する。仮に命名規約を変更する場合であってもプロジェクト内で統一を図ること。" + } + ] + }, + "data_types": { + "description": "シート内には、データベースに格納するデータやデータベース検索結果など、さまざまな種類のデータを記載できる。テストデータの種類を判別するために「データタイプ」というメタ情報をテストデータに付与する必要がある。", + "format": "データタイプ=値", + "types": [ + { + "name": "SETUP_TABLE", + "description": "テスト実行前にデータベースに登録するデータ", + "value": "登録対象のテーブル名", + "format": "1行目:SETUP_TABLE=<テーブル名>、2行目:カラム名、3行目以降:登録するレコード", + "example": "SETUP_TABLE=EMPLOYEE\nID EMP_NAME DEPT_CODE\n00001 山田太郎 0001\n00002 田中一郎 0002" + }, + { + "name": "EXPECTED_TABLE", + "description": "テスト実行後の期待するデータベースのデータ。省略したカラムは、比較対象外となる。", + "value": "確認対象のテーブル名", + "format": "1行目:EXPECTED_TABLE=<テーブル名>、2行目:カラム名、3行目以降:期待する値", + "notes": "省略されたカラムは比較対象外となる。主キーカラムは省略できない。" + }, + { + "name": "EXPECTED_COMPLETE_TABLE", + "description": "テスト実行後の期待するデータベースのデータ。省略したカラムにはデフォルト値が設定されているものとして扱われる。", + "value": "確認対象のテーブル名", + "format": "1行目:EXPECTED_COMPLETE_TABLE=<テーブル名>、2行目:カラム名、3行目以降:期待する値", + "notes": "EXPECTED_TABLEとの違い:省略されたカラムはデフォルト値が格納されているものとして比較が行われる。更新系テストで「無関係なカラムが更新されていないことを確認する」という観点で使用する。" + }, + { + "name": "LIST_MAP", + "description": "List>形式のデータ", + "value": "シート内で一意になるID(期待値のID、任意の文字列)", + "format": "1行目:LIST_MAP=、2行目:Mapのキー、3行目以降:Mapの値", + "usage": "入力パラメータ、メソッドの戻り値に対する期待値などを記載する" + }, + { + "name": "SETUP_FIXED", + "description": "事前準備用の固定長ファイル", + "value": "準備ファイルの配置場所" + }, + { + "name": "EXPECTED_FIXED", + "description": "期待値を示す固定長ファイル", + "value": "比較対象ファイルの配置場所" + }, + { + "name": "SETUP_VARIABLE", + "description": "事前準備用の可変長ファイル", + "value": "準備ファイルの配置場所" + }, + { + "name": "EXPECTED_VARIABLE", + "description": "期待値を示す可変長ファイル", + "value": "比較対象ファイルの配置場所" + }, + { + "name": "MESSAGE", + "description": "メッセージング処理のテストで使用するデータ", + "value": "固定値(setUpMessages または expectedMessages)" + }, + { + "name": "EXPECTED_REQUEST_HEADER_MESSAGES", + "description": "要求電文(ヘッダ)の期待値を示す固定長ファイル", + "value": "リクエストID" + }, + { + "name": "EXPECTED_REQUEST_BODY_MESSAGES", + "description": "要求電文(本文)の期待値を示す固定長ファイル", + "value": "リクエストID" + }, + { + "name": "RESPONSE_HEADER_MESSAGES", + "description": "応答電文(ヘッダ)を示す固定長ファイル", + "value": "リクエストID" + }, + { + "name": "RESPONSE_BODY_MESSAGES", + "description": "応答電文(本文)を示す固定長ファイル", + "value": "リクエストID" + } + ], + "notes": "データの個数も複数記述できる。複数のデータタイプを使用する場合、使用するデータタイプごとにまとめてデータを記述すること。" + }, + "special_notation": { + "description": "自動テストの利便性を向上させるために、いくつかの特殊記法を提供する。", + "notations": [ + { + "notation": "null(大文字小文字の区別なし)", + "value": "null", + "description": "セル内に「null」と記述されている場合は、null値として扱う。データベースにnull値を登録したい場合や、期待値でnull値を設定したい場合に使用する。", + "examples": ["null", "Null", "NULL"] + }, + { + "notation": "\"null\"(ダブルクォートで囲む)", + "value": "文字列のnull", + "description": "文字列の前後がダブルクォート(半角、全角問わず)で囲われている場合は、前後のダブルクォートを取り除いた文字列を扱う。「null」や「NULL」を文字列として扱う必要がある場合に使用。", + "examples": ["\"null\"", "\"NULL\"", "\"1 \"", "\" \""], + "notes": "本記述方法を利用した場合であっても、文字列中のダブルクォートをエスケープする必要はない。" + }, + { + "notation": "\"\"(空のダブルクォート)", + "value": "空文字列", + "description": "空文字列を表す。空行を表現する場合にも使用可能。", + "usage": "可変長ファイルで空行を含めたい場合、行のうちのいずれか1セルに\"\"を記載する。" + }, + { + "notation": "${systemTime}", + "value": "システム日時(Timestamp)", + "description": "システム日時を記載したい場合に使用する。コンポーネント設定ファイルにて設定されたSystemTimeProvider実装クラスから取得したTimestampの文字列形式に変換される。", + "format": "yyyy-MM-dd HH:mm:ss.fffffffff(例:2011-04-11 01:23:45.0)" + }, + { + "notation": "${updateTime}", + "value": "システム日時(Timestamp)", + "description": "${systemTime}の別名。特にデータベースのタイムスタンプ更新時の期待値として使用する。" + }, + { + "notation": "${setUpTime}", + "value": "コンポーネント設定ファイルに記載された固定値", + "description": "データベースセットアップ時のタイムスタンプに、決まった値を使用したい場合に使用する。" + }, + { + "notation": "${文字種,文字数}", + "value": "指定した文字種を指定した文字数分まで増幅した値", + "description": "文字種と文字数を指定して、テストデータを生成する。", + "available_types": [ + "半角英字", + "半角数字", + "半角記号", + "半角カナ", + "全角英字", + "全角数字", + "全角ひらがな", + "全角カタカナ", + "全角漢字", + "全角記号その他", + "外字" + ], + "examples": [ + { + "notation": "${半角英字,5}", + "result": "geDSfe(半角英字5文字に変換)" + }, + { + "notation": "${全角ひらがな,4}", + "result": "ぱさぇん(全角ひらがな4文字に変換)" + }, + { + "notation": "${半角数字,2}-${半角数字,4}", + "result": "37-3425(-以外が変換)" + }, + { + "notation": "${全角漢字,4}123", + "result": "山川海森123(末尾123以外が変換)" + } + ], + "notes": "本記法は単独でも使用可能であるし、組み合わせても使用できる。" + }, + { + "notation": "${binaryFile:ファイルパス}", + "value": "BLOB列に格納するバイナリデータ", + "description": "BLOB列にファイルのデータを格納したい場合に使用する。ファイルパスはExcelファイルからの相対パスで記述する。" + }, + { + "notation": "\\r", + "value": "CR(改行コード0x0D)", + "description": "改行コードを明示的に記述する場合に使用する。" + }, + { + "notation": "\\n", + "value": "LF(改行コード0x0A)", + "description": "改行コードを明示的に記述する場合に使用する。Excelセル内の改行(Alt+Enter)もLFとして扱われる。" + } + ] + }, + "cell_format": { + "description": "セルの書式とExcelシートの記述に関する規約", + "cell_format_rule": { + "description": "セルの書式には、文字列のみを使用する。テストデータを作成する前に、全てのセルの書式を文字列に設定しておくこと。", + "important": "Excelファイルに文字列以外の書式でデータを記述した場合、正しくデータが読み取れなくなる。", + "formatting": "罫線やセルの色付けについては任意に設定可能である。罫線やセルの色付けを行うことでデータが見やすくなり、レビュー品質や保守性の向上が期待できる。" + }, + "date_format": { + "description": "日付の記述形式", + "supported_formats": [ + { + "format": "yyyyMMddHHmmssSSS", + "example": "20210123123456789", + "result": "2021年1月23日 12時34分56秒789" + }, + { + "format": "yyyy-MM-dd HH:mm:ss.SSS", + "example": "2021-01-23 12:34:56.789", + "result": "2021年1月23日 12時34分56秒789" + } + ], + "omission_rules": [ + { + "omission": "ミリ秒を省略(yyyyMMddHHmmss または yyyy-MM-dd HH:mm:ss)", + "behavior": "ミリ秒として0を指定したものとして扱われる", + "example": "20210123123456 → 2021年1月23日 12時34分56秒000" + }, + { + "omission": "時刻全部を省略(yyyyMMdd または yyyy-MM-dd)", + "behavior": "時刻として0時0分0秒000を指定したものとして扱われる", + "example": "20210123 → 2021年1月23日 00時00分00秒000" + } + ] + }, + "comment": { + "description": "セル内に\"//\"から開始する文字列を記載した場合、そのセルから右のセルは全て読み込み対象外となる。テストデータ自体には含めたくないが、可読性を向上させるために付加情報を記載したい場合には、コメント機能が使用できる。", + "usage": "可読性を向上させるために、テーブルの論理名や期待する結果についてコメントを付与する。" + }, + "marker_column": { + "description": "実際のデータには含めたくないがExcelシート上には記述しておきたい場合に使用する。カラム名が半角角括弧で囲まれている場合、そのカラムは「マーカーカラム」とみなされ、テスト実行時には読み込まれない。", + "format": "[カラム名]", + "example": "LIST_MAP=EXAMPLE_MARKER_COLUMN\n[no] id name\n1 U0001 山田\n2 U0002 田中", + "notes": "全くの空行は無視されるため、それ以外のデータタイプでも同様に使用できる。左端のセルに[no]のようなマーカーカラムを記載することで、連番を振ることができる。" + } + }, + "column_omission": { + "description": "データベースの準備データおよび期待値を記述する際、テストに関係の無いカラムについては記述を省略できる。省略したカラムには、自動テストフレームワークによりデフォルト値が設定される。この機能を使用することにより、テストデータの可読性が向上する。また、テーブル定義が変更された場合でも、関係無いカラムであればテストデータ修正作業は発生しなくなる為、保守性が向上する。", + "setup_data_omission": { + "description": "データベース準備データを記述する際にカラムを省略すると、省略されたカラムにはデフォルト値が設定されているものとして扱われる。", + "important": "主キーカラムは省略できない。", + "usage": "多くのカラムのうち一部のカラムだけを設定する場合、不要なカラムを省略できる。" + }, + "expected_data_omission": { + "description": "DB期待値から単純に無関係なカラムを省略すると、省略されたカラムは比較対象外となる。", + "expected_table": { + "name": "EXPECTED_TABLE", + "behavior": "省略されたカラムは比較対象外となる", + "usage": "検索系テストで、検索対象カラムのみを確認する場合" + }, + "expected_complete_table": { + "name": "EXPECTED_COMPLETE_TABLE", + "behavior": "省略されたカラムにはデフォルト値が格納されているものとして比較が行われる", + "usage": "更新系テストで「無関係なカラムが更新されていないことを確認する」という観点が必要な場合" + }, + "important": "データベース検索結果の期待値を記述する際は、検索対象カラム全てを記述しなければならない(レコードの主キーだけを確認する、というような確認方法は不可)。また、登録系テストの場合も、新規に登録されたレコードの全カラムを確認する必要があるので、カラムを省略できない。" + }, + "default_values": { + "description": "自動テストフレームワークのコンポーネント設定ファイルにて明示的に指定していない場合、デフォルト値には以下の値が使用される。", + "values": [ + { + "column_type": "数値型", + "default_value": "0" + }, + { + "column_type": "文字列型", + "default_value": "半角スペース" + }, + { + "column_type": "日付型", + "default_value": "1970-01-01 00:00:00.0" + } + ], + "customization": { + "class": "nablarch.test.core.db.BasicDefaultValues", + "properties": [ + { + "name": "charValue", + "description": "文字列型のデフォルト値", + "value_type": "1文字のASCII文字", + "example": "a" + }, + { + "name": "numberValue", + "description": "数値型のデフォルト値", + "value_type": "0または正の整数", + "example": "1" + }, + { + "name": "dateValue", + "description": "日付型のデフォルト値", + "value_type": "JDBCタイムスタンプエスケープ形式(yyyy-mm-dd hh:mm:ss.fffffffff)", + "example": "2000-01-01 12:34:56.123456789" + } + ], + "configuration_example": "\n \n \n \n \n \n \n \n" + } + } + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/index.toon b/.claude/skills/nabledge-6/knowledge/index.toon new file mode 100644 index 0000000..61772eb --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/index.toon @@ -0,0 +1,103 @@ +# Nabledge-6 Knowledge Index + +files[93,]{title,hints,path}: + Nablarchバッチ(都度起動型・常駐型), バッチ 都度起動 常駐 大量データ処理 アーキテクチャ ハンドラ DataReader, features/processing/nablarch-batch.json + JSR352準拠バッチ(Jakarta Batch), バッチ JSR352 Jakarta Batch Batchlet Chunk 標準仕様, not yet created + ユニバーサルDAO, データベース DAO O/Rマッパー CRUD JPA 検索 ページング 排他制御, features/libraries/universal-dao.json + データベースアクセス(JDBCラッパー), データベース JDBC SQL 接続 PreparedStatement Dialect, features/libraries/database-access.json + データベースコードジェネレータ, データベース コード生成 自動生成 Entity DAO スキーマ, not yet created + データバインド, ファイル データ変換 CSV TSV 固定長 JavaBeans Map, features/libraries/data-bind.json + 汎用データフォーマット, ファイル データ形式 CSV 固定長 JSON XML マルチレイアウト, not yet created + ログ出力, ログ ロギング Logger LogWriter ファイル出力 ローテーション, not yet created + SLF4Jアダプタ, ログ SLF4J アダプタ log4j logback ロギングフレームワーク, features/adapters/slf4j-adapter.json + 入力値のチェック, バリデーション 入力チェック Bean Validation Nablarch Validation 妥当性検証, not yet created + トランザクション管理, トランザクション データベース コミット ロールバック リソース制御, not yet created + コード管理, コード マスタ 区分値 名称 国際化 静的データ, not yet created + メッセージ管理, メッセージ 国際化 エラーメッセージ プロパティ フォーマット, not yet created + 排他制御, 排他制御 楽観的ロック 悲観的ロック バージョン番号 同時更新, not yet created + 業務日付, 日付 業務日付 システム日付 日時管理, features/libraries/business-date.json + ファイルパス管理, ファイル パス管理 ファイルパス 論理名 物理パス, features/libraries/file-path-management.json + リポジトリ, リポジトリ DI 依存性注入 コンポーネント定義 設定管理, not yet created + データベース管理, データベース スキーマ管理 マイグレーション DDL 初期データ, not yet created + データコンバータ, データ変換 型変換 フォーマット 文字列変換, not yet created + システム間連携メッセージング, メッセージング システム連携 HTTP MOM JMS キュー, not yet created + メール送信, メール SMTP 送信 テンプレート 添付ファイル, not yet created + 静的データキャッシュ, キャッシュ 静的データ メモリ 初期化 マスタデータ, not yet created + サービス提供可否チェック, サービス可否 稼働状態 メンテナンス時間 閉塞制御, not yet created + セッションストア, セッション HTTP セッション管理 状態保持 分散環境, not yet created + ステートレスWebアプリケーション, Web ステートレス 隠し項目 画面遷移 状態管理, not yet created + カスタムタグ, タグ JSPタグ UI部品 画面表示 入力フォーム, not yet created + 二重サブミット防止, 二重サブミット トークン 画面 フォーム送信, not yet created + BeanUtil, Bean ユーティリティ プロパティ コピー 型変換, not yet created + ユーティリティ, ユーティリティ 共通機能 文字列 コレクション 変換, not yet created + フォーマット, フォーマット 数値 日付 文字列 変換 表示形式, not yet created + 認可チェック(Permission Check), 認可 権限チェック Permission アクセス制御 セキュリティ, not yet created + ロールベース認可, 認可 ロール 権限 アクセス制御 セキュリティ, not yet created + データベース接続管理ハンドラ, ハンドラ データベース 接続管理 接続取得 接続解放 コネクション, features/handlers/common/db-connection-management-handler.json + トランザクション管理ハンドラ, ハンドラ トランザクション コミット ロールバック データベース, features/handlers/common/transaction-management-handler.json + グローバルエラーハンドラ, ハンドラ エラーハンドリング 例外処理 共通エラー処理, not yet created + ファイルレコードライタ破棄ハンドラ, ハンドラ ファイル 出力 リソース解放 クローズ処理, not yet created + リクエストパスJavaパッケージマッピング, ハンドラ ルーティング パス マッピング ディスパッチ, not yet created + リクエストハンドラエントリ, ハンドラ リクエスト処理 エントリポイント ディスパッチ, not yet created + スレッドコンテキストハンドラ, ハンドラ スレッド コンテキスト リクエスト情報 実行時情報, not yet created + スレッドコンテキストクリアハンドラ, ハンドラ スレッド コンテキスト クリア リソース解放, not yet created + 権限チェックハンドラ, ハンドラ 認可 権限チェック アクセス制御 セキュリティ, not yet created + サービス提供可否チェックハンドラ, ハンドラ サービス可否 稼働状態 メンテナンス 閉塞, not yet created + プロセス常駐化ハンドラ, ハンドラ バッチ 常駐プロセス 定期実行 監視, not yet created + ループ制御ハンドラ, ハンドラ バッチ ループ データベース レコード処理, not yet created + データベースレスループ制御ハンドラ, ハンドラ バッチ ループ データベースなし 繰り返し処理, not yet created + データリードハンドラ, ハンドラ バッチ データ読み込み ファイル データベース, features/handlers/batch/data-read-handler.json + メインクラス, ハンドラ スタンドアロン Main エントリポイント 起動, not yet created + リトライハンドラ, ハンドラ リトライ 再試行 エラーハンドリング 例外処理, not yet created + ステータスコード変換ハンドラ, ハンドラ ステータスコード 終了コード リターンコード 変換, not yet created + プロセス停止ハンドラ, ハンドラ プロセス停止 シャットダウン 終了処理, not yet created + 二重起動防止ハンドラ, ハンドラ 二重起動防止 プロセス制御 ロック 排他制御, not yet created + マルチスレッド実行制御ハンドラ, ハンドラ マルチスレッド 並列処理 スレッドプール 同時実行, not yet created + リクエストスレッドループ制御ハンドラ, ハンドラ スレッド ループ制御 リクエスト処理, not yet created + HTTPエラー制御ハンドラ, ハンドラ Web HTTP エラー 例外処理 画面遷移, not yet created + セッションストアハンドラ, ハンドラ Web セッション 状態保持 セッション管理, not yet created + CSRFトークン検証ハンドラ, ハンドラ Web セキュリティ CSRF トークン 検証, not yet created + フォワーディングハンドラ, ハンドラ Web フォワード ディスパッチ 画面遷移, not yet created + ヘルスチェックエンドポイントハンドラ, ハンドラ Web ヘルスチェック 監視 稼働確認 死活監視, not yet created + ホットデプロイハンドラ, ハンドラ Web ホットデプロイ 開発支援 自動リロード, not yet created + HTTPアクセスログハンドラ, ハンドラ Web ログ アクセスログ HTTP リクエストログ, not yet created + HTTP文字エンコーディングハンドラ, ハンドラ Web 文字エンコーディング 文字コード リクエスト レスポンス, not yet created + HTTPリクエストJavaパッケージマッピング, ハンドラ Web ルーティング パス マッピング ディスパッチ, not yet created + HTTPレスポンスハンドラ, ハンドラ Web レスポンス 画面表示 出力, not yet created + HTTPリライトハンドラ, ハンドラ Web URL書き換え リライト リダイレクト, not yet created + 携帯電話対応ハンドラ, ハンドラ Web モバイル 携帯電話 ガラケー 端末判定, not yet created + マルチパートハンドラ, ハンドラ Web ファイルアップロード マルチパート フォーム, not yet created + Nablarchカスタムタグ制御ハンドラ, ハンドラ Web カスタムタグ JSP 画面制御, not yet created + 正規化ハンドラ, ハンドラ Web 正規化 サニタイジング 入力値, not yet created + 二重サブミット防止ハンドラ, ハンドラ Web 二重サブミット トークン フォーム, not yet created + 静的リソースマッピング, ハンドラ Web 静的リソース CSS JavaScript 画像, not yet created + セキュアハンドラ, ハンドラ Web セキュリティ HTTPS SSL/TLS, not yet created + セッション同時アクセス制御ハンドラ, ハンドラ Web セッション 同時アクセス 排他制御, not yet created + InjectFormインターセプタ, インターセプタ Web フォーム 入力値 バインド, not yet created + OnDoubleSubmissionインターセプタ, インターセプタ Web 二重サブミット エラー処理, not yet created + OnErrorインターセプタ, インターセプタ Web エラー処理 例外ハンドリング 画面遷移, not yet created + OnErrorsインターセプタ, インターセプタ Web エラー処理 入力チェック バリデーション, not yet created + UseTokenインターセプタ, インターセプタ Web トークン CSRF 二重サブミット, not yet created + ボディ変換ハンドラ, ハンドラ REST JSON XML 変換 シリアライズ, not yet created + CORSプリフライトリクエストハンドラ, ハンドラ REST CORS プリフライト オプション OPTIONS, not yet created + JAX-RSアクセスログハンドラ, ハンドラ REST ログ アクセスログ JAX-RS, not yet created + JAX-RS BeanValidationハンドラ, ハンドラ REST バリデーション Bean Validation 入力チェック, not yet created + JAX-RSレスポンスハンドラ, ハンドラ REST レスポンス JSON エラー処理, not yet created + HTTPメッセージングエラーハンドラ, ハンドラ メッセージング HTTP エラー処理 同期応答, not yet created + HTTPメッセージング要求電文解析ハンドラ, ハンドラ メッセージング HTTP 電文解析 リクエスト パース, not yet created + HTTPメッセージング応答電文構築ハンドラ, ハンドラ メッセージング HTTP 電文構築 レスポンス 応答, not yet created + メッセージ応答ハンドラ, ハンドラ メッセージング MOM 応答 返信 メッセージキュー, not yet created + メッセージ再送ハンドラ, ハンドラ メッセージング MOM 再送 リトライ エラー処理, not yet created + メッセージングコンテキストハンドラ, ハンドラ メッセージング MOM コンテキスト メッセージ情報, not yet created + 自動テストフレームワーク概要, テスト NTF テストフレームワーク 自動テスト JUnit, features/tools/ntf-overview.json + データベースアクセステスト, テスト NTF データベース DAO CRUD テストデータ, not yet created + リクエスト単体テスト(Web), テスト NTF Web リクエスト 画面 単体テスト, not yet created + リクエスト単体テスト(REST), テスト NTF REST API リクエスト 単体テスト, not yet created + リクエスト単体テスト(バッチ), テスト NTF バッチ リクエスト 単体テスト, features/tools/ntf-batch-request-test.json + リクエスト単体テスト(メッセージング), テスト NTF メッセージング リクエスト 単体テスト, not yet created + テストデータ管理, テスト NTF テストデータ Excel データベース セットアップ, features/tools/ntf-test-data.json + アサーション機能, テスト NTF アサーション 検証 期待値 実測値, features/tools/ntf-assertion.json + マスタデータリストア, テスト NTF マスタデータ リストア バックアップ テスト環境, not yet created + JUnit5拡張機能, テスト NTF JUnit5 拡張 アノテーション テスト実行, not yet created + セキュリティチェックリスト, セキュリティ チェック項目 脆弱性 PCIDSS OWASP, checks/security.json + リリースノート6u3, リリースノート バージョン6 アップデート 変更点 新機能, releases/6u3.json diff --git a/.claude/skills/nabledge-6/knowledge/overview.json b/.claude/skills/nabledge-6/knowledge/overview.json new file mode 100644 index 0000000..e16369c --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/overview.json @@ -0,0 +1,187 @@ +{ + "id": "overview", + "title": "Nablarch概要", + "official_doc_urls": [ + "https://fintan.jp/page/1868/4/", + "https://nablarch.github.io/docs/LATEST/doc/", + "https://nablarch.github.io/docs/LATEST/doc/about_nablarch/versionup_policy.html", + "https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/nablarch/architecture.html", + "https://nablarch.github.io/docs/LATEST/doc/migration/index.html", + "https://nablarch.github.io/docs/LATEST/doc/releases/index.html" + ], + "index": [ + { "id": "identity", "hints": ["Nablarch", "TIS", "提供元", "ライセンス", "Apache"] }, + { "id": "versioning", "hints": ["バージョン", "6u3", "5u26", "現行", "リリース"] }, + { "id": "requirements", "hints": ["Java", "Jakarta EE", "Java EE", "要件", "Maven", "Java 17"] }, + { "id": "compatibility", "hints": ["後方互換性", "Published", "公開API", "@Published", "非公開API"] }, + { "id": "environment", "hints": ["動作環境", "APサーバ", "データベース", "OS", "Jetty", "Tomcat"] }, + { "id": "architecture", "hints": ["アーキテクチャ", "ハンドラキュー", "インターセプタ", "ライブラリ", "コンポーネント"] }, + { "id": "processing-types", "hints": ["処理方式", "ウェブ", "REST", "バッチ", "メッセージング", "Jakarta Batch"] }, + { "id": "ecosystem", "hints": ["解説書", "システム開発ガイド", "開発標準", "Fintan", "トレーニング"] } + ], + "sections": { + "identity": { + "description": "Nablarchは、TISの豊富な基幹システム構築経験から得られたナレッジを集約したJavaアプリケーション開発/実行基盤です。", + "provider": "TIS株式会社", + "license": "Apache License 2.0", + "repository": "https://github.com/nablarch", + "characteristics": [ + "金融・決済等のミッションクリティカルシステムでの豊富な導入実績", + "包括的なドキュメント(フレームワーク、開発ガイド、開発標準、ツール)", + "長期的な安定性と信頼性の重視", + "アクティブなセキュリティ更新とメンテナンス", + "複数の実行環境をサポート(ウェブ、ウェブサービス、バッチ、メッセージング)" + ] + }, + "versioning": { + "scheme": "メジャー.アップデート形式(例: 6u3)。プロダクトバージョン番号はマイナーバージョンアップ時にインクリメント、アップデート番号はリビジョンアップまたはバグフィックス時にインクリメントされる。", + "current": { + "version": "6u3", + "release_date": "2025年3月27日", + "note": "Nablarch 6の最新アップデートリリース。Jakarta EE 10対応、Java 17以上が必要。" + }, + "active_versions": [ + { + "version": "6u3", + "status": "最新", + "java": "17以上", + "ee": "Jakarta EE 10", + "maintenance": "アクティブ" + }, + { + "version": "5u26", + "release_date": "2025年5月16日", + "status": "メンテナンス中", + "java": "8以上(Java 11使用時は追加設定必要)", + "ee": "Java EE 7/8", + "maintenance": "セキュリティパッチと不具合対応" + } + ] + }, + "requirements": { + "nablarch6": { + "java": "Java 17以上", + "java_note": "Nablarch 6のモジュールはJava 17でコンパイルされているため、動作にはJava 17以上が必要", + "ee": "Jakarta EE 10", + "build_tool": "Maven 3.x以降", + "namespace": "名前空間がjavax.*からjakarta.*に変更" + }, + "nablarch5": { + "java": "Java 8以上", + "java_note": "Java 11以上で使用する場合は追加設定が必要(詳細は移行ガイド参照)", + "ee": "Java EE 7/8", + "build_tool": "Maven" + } + }, + "compatibility": { + "policy": "フレームワークのバージョンアップは、公開APIに対して後方互換性を維持します。基本的にバージョンの差し替えと設定ファイルの変更のみでバージョンアップ可能です。", + "public_api": { + "definition": "@Publishedアノテーションが付与されたAPIが公開API", + "scope": "公開APIのみ後方互換性を保証。非公開APIは後方互換性が維持されないバージョンアップを行う場合があるため、プロジェクトでは非公開APIを使用しないこと" + }, + "compatibility_scope": "フレームワーク(アプリケーションフレームワークとテスティングフレームワーク)のみが対象。ドキュメント、開発標準、ツールは後方互換性維持の対象外", + "exceptions": [ + "フレームワークが出力するログのレベル・文言に対する変更", + "後方互換を維持したまま修正できない不具合への対応", + "JDKバージョンアップに起因する問題で後方互換を維持できない場合", + "セキュリティ対応" + ], + "upgrade_process": "使用するNablarchのバージョンの差し替えと設定ファイルの変更が基本。後方互換性が維持されない変更の場合はリリースノートに内容と移行方法を明記" + }, + "environment": { + "description": "Java実行環境があれば動作可能で、OS依存なし。", + "app_servers": { + "nablarch6": ["Jetty 12", "Jakarta EE 10対応APサーバ"], + "nablarch5": ["Tomcat 8", "Jetty 6/9", "Java EE 7/8対応APサーバ"] + }, + "databases": { + "embedded": "H2 Database(開発・テスト用)", + "supported": "JDBCドライバが提供されるRDBMS全般", + "verified": ["Oracle Database", "PostgreSQL", "Microsoft SQL Server", "IBM DB2"] + }, + "os": "Java実行環境があればOSを問わず動作(Windows、Linux、macOS等で動作確認済み)" + }, + "architecture": { + "overview": "Nablarchアプリケーションフレームワークは、ハンドラキュー、インターセプタ、ライブラリの3つの主要構成要素から成ります。", + "handler_queue": { + "description": "リクエストやレスポンスに対する横断的な処理を行うハンドラ群を、予め定められた順序に沿って定義したキュー。サーブレットフィルタのチェーン実行と同様の方式で処理を実行", + "responsibility": "リクエストのフィルタリング(アクセス権限制御等)、リクエスト・レスポンスの変換、リソースの取得・解放(データベース接続等)" + }, + "interceptor": { + "description": "実行時に動的にハンドラキューに追加されるハンドラ。Jakarta EEのJakarta Contexts and Dependency Injectionで定義されているインターセプタと同じように処理を実行", + "use_case": "特定のリクエストの場合のみ処理を追加する場合や、リクエストごとに設定値を切り替えて処理を実行したい場合に適している" + }, + "library": { + "description": "データベースアクセス、ファイルアクセス、ログ出力など、ハンドラから呼び出されるコンポーネント群", + "examples": ["UniversalDao(データベースアクセス)", "データバインド", "ファイルアクセス", "ログ出力"] + }, + "configuration": "コンポーネント設定はXMLファイルで行い、システムリポジトリで管理される" + }, + "processing-types": [ + { + "type": "ウェブアプリケーション", + "description": "Nablarchアプリケーションフレームワークを使用してウェブアプリケーションを開発するためのフレームワーク", + "use_case": "画面を持つエンドユーザー向けのウェブシステム開発" + }, + { + "type": "RESTfulウェブサービス", + "description": "Jakarta RESTful Web Servicesで規定されているアノテーションを使用して容易にRESTfulウェブサービスを構築できるフレームワーク", + "use_case": "外部システム連携、API提供、マイクロサービスアーキテクチャでのサービス間通信" + }, + { + "type": "Nablarchバッチ(都度起動)", + "description": "日次や月次など、定期的にプロセスを起動してバッチ処理を実行する方式", + "use_case": "定期的なデータ処理、集計処理、レポート生成" + }, + { + "type": "Nablarchバッチ(常駐/テーブルキュー)", + "description": "プロセスを起動しておき、一定間隔でバッチ処理を実行する方式。ただし新規開発ではdb_messagingの使用を推奨", + "use_case": "オンライン処理で作成された要求データを定期的に一括処理する場合(既存システムでの使用を想定)" + }, + { + "type": "Jakarta Batch", + "description": "Jakarta Batch(旧JSR352)に準拠したバッチアプリケーションフレームワーク。情報が少なく有識者のアサインが難しいため、新規開発ではNablarchバッチの使用を推奨", + "use_case": "Jakarta Batch標準への準拠が必要な場合、既存Jakarta Batch資産の活用" + }, + { + "type": "メッセージング", + "description": "MOM(Message Oriented Middleware)ベースとDBキューベースの2種類のメッセージングフレームワークを提供", + "use_case": "非同期処理、システム間の疎結合な連携、負荷分散された処理" + } + ], + "ecosystem": { + "official_contents": [ + { + "name": "Nablarch解説書", + "url": "https://nablarch.github.io/docs/LATEST/doc/", + "description": "Nablarchアプリケーションフレームワークの機能や使い方を詳細に解説した技術ドキュメント", + "target": "開発者向け" + }, + { + "name": "Nablarchシステム開発ガイド", + "url": "https://fintan.jp/page/252/", + "description": "Nablarchを使ってシステムを開発するエンジニアに対して、開発開始前・開発中にすべきこと、参照すべきものを示すガイド", + "target": "プロジェクト全体向け" + }, + { + "name": "開発標準", + "url": "https://fintan.jp/page/1868/#development-standards", + "description": "システム開発における成果物作成時に従うべきガイドライン。設計標準、設計書フォーマット・サンプルを含む", + "target": "プロジェクト全体向け" + }, + { + "name": "開発ツール", + "url": "https://nablarch.github.io/docs/LATEST/doc/development_tools/index.html", + "description": "効率的なJava静的チェック、テスティングフレームワーク、アプリケーション開発時に使える便利なツール群", + "target": "開発者向け" + }, + { + "name": "トレーニングコンテンツ", + "url": "https://fintan.jp/page/1868/", + "description": "Nablarchの学習に役立つトレーニング資料や教育コンテンツ", + "target": "学習者向け" + } + ] + } + } +} diff --git a/.claude/skills/nabledge-6/knowledge/releases/6u3.json b/.claude/skills/nabledge-6/knowledge/releases/6u3.json new file mode 100644 index 0000000..1e0b93c --- /dev/null +++ b/.claude/skills/nabledge-6/knowledge/releases/6u3.json @@ -0,0 +1,385 @@ +{ + "id": "release-6u3", + "title": "リリースノート 6u3", + "version": "6u3", + "official_doc_urls": [ + "https://nablarch.github.io/docs/6u3/doc/releases/nablarch6u3-releasenote.xlsx" + ], + "index": [ + { + "id": "overview", + "hints": [ + "6u3", + "リリース", + "6u2", + "変更点" + ] + }, + { + "id": "changes", + "hints": [ + "変更内容", + "リリースノート", + "不具合修正", + "機能追加", + "OpenAPI", + "BeanUtil", + "JSON", + "バリデーション", + "APIドキュメント" + ] + } + ], + "sections": { + "overview": { + "summary": "Nablarch 6u3のリリースノート。6u2からの変更点を記載", + "highlights": [ + "OpenAPI対応に伴うRESTful Webサービスの機能強化(親クラス・インタフェースでのリソース定義対応)", + "EntityResponseに型パラメータ追加", + "マルチパートリクエスト用のBodyConverter追加", + "BeanUtilのDate and Time APIサポート拡充(OffsetDateTime追加)", + "JSON読み取り不具合の修正(JSON区切り文字のみの値の解析)" + ] + }, + "changes": [ + { + "no": 1, + "category": "RESTfulウェブサービス", + "type": "変更", + "title": "親クラス・インタフェースでのリソース定義に対応\n(No.24.OpenAPI対応に伴う変更)", + "description": "OpenAPIドキュメントから生成したインタフェースを使用してアクションクラスを実装できるように、インターフェースや親クラスでのリソース定義を引き継ぐように対応しました。\n\n@PathなどのJakarta RESTful Web Servicesのアノテーションを使ってアクションクラスを実装している場合に、以下の条件でアクションクラスが実装しているインターフェースや親クラスのリソース定義を引き継ぎます。\n ・アクションクラスが親クラスを継承またはインターフェースを実装している\n ・親クラスまたはインターフェースに@Pathアノテーションが注釈されている\n ・親クラスまたはインターフェースにHTTPメソッドが定義されている\n\nまた、本対応にはルーティングアダプタも修正する必要があったため、合わせて対応しました。", + "module": "nablarch-fw-jaxrs 2.2.0\nnablarch-router-adaptor 2.2.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html", + "jira": "NAB-618" + }, + { + "no": 2, + "category": "RESTfulウェブサービス", + "type": "変更", + "title": "EntityResponseの型パラメータ追加\n(No.24.OpenAPI対応に伴う変更)", + "description": "OpenAPIドキュメントとのマッピングに対応するため、EntityResponseに型パラメータを追加しました。\nこれにより、どのようなエンティティの型をレスポンスとしているかをより明確に表現できるようになりました。", + "module": "nablarch-fw-jaxrs 2.2.0", + "affected_version": "", + "impact": "あり(開発)", + "impact_detail": "すでにEntityResponseを使用している個所については型を指定していない状態になるため、コンパイル時に以下のメッセージが出力されるようになります。また、設定によってはIDEで同様の警告が出力されるようになります。\n\n[INFO] (該当クラス)の操作は、未チェックまたは安全ではありません。\n\n解消しなくても動作に影響はありませんが、EntityResponseを使用している個所で明示的に型を指定すると、メッセージおよび警告は解消されます。\n", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html", + "jira": "NAB-619" + }, + { + "no": 3, + "category": "BeanUtil", + "type": "変更", + "title": "Date and Time APIサポート拡充\n(No.24.OpenAPI対応に伴う変更)", + "description": "OpenAPIドキュメントとのマッピングに対応するため、Date and Time APIのサポートを拡充し、OffsetDateTimeのサポートを追加しました。\n", + "module": "nablarch-core-beans 2.3.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/bean_util.html", + "jira": "NAB-620" + }, + { + "no": 4, + "category": "RESTfulウェブサービス", + "type": "変更", + "title": "マルチパート用のBodyConverter追加\n(No.24.OpenAPI対応に伴う変更)", + "description": "OpenAPIドキュメントとのマッピングに対応するため、Content-Typeがmultipart/form-dataのリクエストに対応するBodyConverterを追加しました。\n", + "module": "nablarch-fw-jaxrs 2.2.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web_service/rest/feature_details/resource_signature.html", + "jira": "NAB-621" + }, + { + "no": 5, + "category": "BeanUtil", + "type": "変更", + "title": "MapからBeanへ移送するメソッドのパフォーマンス改善", + "description": "MapからBeanへ移送する際、ネストしたオブジェクト数が多い場合に処理が遅くなる事象が発生していたので、修正しました。\n", + "module": "nablarch-core-beans 2.3.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/bean_util.html", + "jira": "NAB-634" + }, + { + "no": 6, + "category": "汎用データフォーマット", + "type": "不具合", + "title": "JSONの読み取りに失敗する問題を修正", + "description": "JSON内に含まれる値(\"\"で囲われた項目)がJSON構文で意味を持つ区切り文字(:、[、{、, の4つ)のみで、かつその後にデータが続く場合、値とJSON構文の区切り文字の区別ができずに失敗していました。\n\n①NGになる例(\":\"の後にデータが続く):\n {\"key1\": \":\", \"key2\": \"value2\"}\n\n②OKになる例(\":\"の後にデータが続かない):\n {\"key1\": \":\"}\n\nNGになっていた例も、正常に値として解析できるように修正しました。\n", + "module": "nablarch-core-dataformat 2.0.3", + "affected_version": "1.3.1", + "impact": "あり(本番)", + "impact_detail": "概要の①のようにJSONの区切り文字のみが値になるデータを解析できるようになります。\n本来は値として解析できることが正しい挙動であるため影響が無い想定ですが、もしこのようなJSONを読み込めるようになることでシステム影響がある場合、値の確認をして受け入れないようにするなどの修正を行ってください。", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/data_io/data_format.html", + "jira": "NAB-639" + }, + { + "no": 7, + "category": "Bean Validation", + "type": "変更", + "title": "BeanValidationStrategyのバリデーション処理をカスタマイズできるように修正", + "description": "BeanValidationStrategyをカスタマイズしやすくなるよう、公開APIを見直しました。\nそれに伴い、バリデーションエラーのメッセージをソートするsortMessagesメソッドをオーバーライド可能にするため、static修飾子を除去しました。\n", + "module": "nablarch-fw-web 2.3.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/libraries/validation/bean_validation.html", + "jira": "NAB-640" + }, + { + "no": 8, + "category": "公開API", + "type": "変更", + "title": "公開APIの追加", + "description": "解説書で継承を案内しているAPIの中で公開APIになっていないものがあったため、公開APIを追加しました。\n", + "module": "nablarch-common-dao 2.3.0\nnablarch-common-databind 2.1.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-641" + }, + { + "no": 9, + "category": "Nablarchバッチアプリケーション", + "type": "変更", + "title": "ResumeDataReaderのJavadoc改善", + "description": "ResumeDataReaderが内部的に使用するResumePointManagerは初期化が必要ですが、\nこの点をResumeDataReaderに関する説明から読み取りづらかったため、ResumeDataReaderのJavadocに追記しました。\n", + "module": "nablarch-fw-batch 2.0.1", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/javadoc/nablarch/fw/reader/ResumeDataReader.html", + "jira": "NAB-629" + }, + { + "no": 10, + "category": "サロゲートキーの採番", + "type": "変更", + "title": "TableIdGeneratorのJavadoc改善", + "description": "採番の際に独立したトランザクションを用いるFastTableIdGeneratorは初期化が必要ですが、Javadoc上でそれがわからなかったため、その旨を追記しました。\nまた類似のコンポーネントであるTableIdGeneratorのJavadocにも、記述を合わせるため同様の更新を行っています。\n", + "module": "nablarch-common-idgenerator-jdbc 2.0.1", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/javadoc/nablarch/common/idgenerator/FastTableIdGenerator.html\n", + "jira": "NAB-629" + }, + { + "no": 11, + "category": "汎用ユーティリティ", + "type": "変更", + "title": "Base64UtilのJavadoc・解説書改善", + "description": "Base64UtilはRFC4648の「4. Base 64 Encoding」に準拠していますが、Javadoc上で明記できていなかったため、その旨を追記しました。\n\nまた、Java8以降ではBase64エンコーディングを行う標準APIが提供されており、Base64Utilを使用せずとも同様の処理を行えます。\nBase64Utilを使用する必要性が小さくなったため、Javadocで標準APIを案内し、Base64Utilは後方互換性のための位置付けとしました。\nそのため、Base64Utilは後方互換のために存在していることを解説書に追記しました。\n※現在Base64Utilを使用している個所を標準APIに置換する必要はありません。\n", + "module": "nablarch-core-2.2.1", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/javadoc/nablarch/core/util/Base64Util.html", + "jira": "NAB-626" + }, + { + "no": 12, + "category": "公開API", + "type": "変更", + "title": "PublishedアノテーションのJavadoc改善", + "description": "PublishedアノテーションのJavadocで、オーバーライド可能なメソッドは公開APIとしていることについて追記しました。", + "module": "nablarch-core-2.2.1", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/javadoc/nablarch/core/util/annotation/Published.html", + "jira": "NAB-640" + }, + { + "no": 13, + "category": "コンポーネントの初期化", + "type": "変更", + "title": "初期化が必要なコンポーネントに対する説明の改善", + "description": "コンポーネントとして使用することを想定して提供しているクラスのうち、初期化が必要であるにも関わらず解説書への記載がないものがあったので、初期化が必要な旨や設定例を追記しました。\n\n・Nablarchが提供するライブラリ\n ・コード管理\n ・サロゲートキーの採番\n ・日付管理\n ・メール送信\n ・サービス提供可否チェック\n・Nablarchの提供する標準ハンドラ\n ・プロセス停止制御ハンドラ\n・アダプタ\n ・IBM MQアダプタ\n", + "module": "nablarch-document 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-629" + }, + { + "no": 14, + "category": "RESTfulウェブサービス", + "type": "変更", + "title": "マルチパートリクエストのサポート", + "description": "No.4およびNo.19で対応したマルチパートリクエストのサポートを取り込み、マルチパートリクエストに対応しました。\n", + "module": "nablarch-single-module-archetype 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-621" + }, + { + "no": 15, + "category": "ウェブアプリケーション\nRESTfulウェブサービス", + "type": "変更", + "title": "Tomcatベースイメージの更新", + "description": "10.1.33以前のApache Tomcatに脆弱性が検出されたため、ブランクプロジェクトのデフォルトのTomcatのベースイメージを以下に更新しました。\n\n tomcat:10.1.34-jdk17-temurin\n", + "module": "nablarch-single-module-archetype 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/blank_project/setup_containerBlankProject/setup_ContainerWeb.html", + "jira": "NAB-627" + }, + { + "no": 16, + "category": "全般", + "type": "変更", + "title": "gsp-dba-maven-pluginのバージョン更新", + "description": "以下のMavenプラグインを記載のバージョンに更新しました。\n・gsp-dba-maven-plugin:5.2.0\n", + "module": "nablarch-single-module-archetype 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-636" + }, + { + "no": 17, + "category": "全般", + "type": "変更", + "title": "使用不許可APIツールのバージョン更新", + "description": "No.26の対応に伴い、使用不許可APIツールのバージョンを以下に更新しました。\n・nablarch-unpublished-api-checker 1.0.1\n", + "module": "nablarch-single-module-archetype 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-630" + }, + { + "no": 18, + "category": "Jakarta RESTful Web Servicesアダプタ", + "type": "変更", + "title": "Date and Time APIのサポート\n(No.24.OpenAPI対応に伴う変更)", + "description": "OpenAPIドキュメントとのマッピングに対応するため、Jackson Java 8 Date/timeモジュールを追加してDate and Time APIを扱えるようになりました。\n\n※JaxRsHandlerListFactory を独自に実装している場合、バージョンアップだけでは本機能は使用できません。本機能を使用したい場合は、nablarch-jersey-adaptorおよびnablarch-resteasy-adaptorの実装を参考にしてください。\n", + "module": "nablarch-jaxrs-adaptor 2.2.0\nnablarch-jersey-adaptor 2.2.0\nnablarch-resteasy-adaptor 2.2.0\nnablarch-jackson-adaptor 2.2.0", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/adaptors/jaxrs_adaptor.html", + "jira": "NAB-620" + }, + { + "no": 19, + "category": "Jakarta RESTful Web Servicesアダプタ", + "type": "変更", + "title": "マルチパートリクエストのサポート\n(No.24.OpenAPI対応に伴う変更)", + "description": "No.4で追加したマルチパート用のBodyConverterをnablarch-jersey-adaptorおよびnablarch-resteasy-adaptorに追加しました。\n\n\n", + "module": "nablarch-jaxrs-adaptor 2.2.0\nnablarch-jersey-adaptor 2.2.0\nnablarch-resteasy-adaptor 2.2.0\nnablarch-jackson-adaptor 2.2.0", + "affected_version": "", + "impact": "あり", + "impact_detail": "6u2以前からのバージョンアップで本機能を使用する場合は、設定変更が必要になります。詳しくは「マルチパートリクエストのサポート対応」シートを参照してください。", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/adaptors/jaxrs_adaptor.html", + "jira": "NAB-621" + }, + { + "no": 20, + "category": "ウェブアプリケーション (JSP)", + "type": "変更", + "title": "jQuery、Bootstrapのバージョンアップ", + "description": "jQueryおよびjQeuryに依存していたライブラリのバージョンを以下の通り更新しました。\n・jQuery 3.7.1\n・jQuery UI 1.14\n・Bootstrap 5.3.3\nまた、Bootstrapのバージョンアップに伴ってMaterial Design for Bootstrapの使用を廃止し、画面デザインを調整しました。\n", + "module": "nablarch-example-web 6u3", + "affected_version": "-", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/application_framework/application_framework/web/index.html", + "jira": "NAB-616" + }, + { + "no": 21, + "category": "RESTfulウェブサービス", + "type": "変更", + "title": "マルチパートリクエストのサポート\n(No.24.OpenAPI対応に伴う変更)", + "description": "No.4およびNo.19で対応したnablarch-fw-jaxrsおよびnablarch-jaxrs-adaptorの変更内容を取り込み、マルチパートリクエストに対応しました。\n", + "module": "nablarch-example-rest 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-621" + }, + { + "no": 22, + "category": "全般", + "type": "変更", + "title": "gsp-dba-maven-pluginのバージョン更新", + "description": "以下のMavenプラグインを記載のバージョンに更新しました。\n・gsp-dba-maven-plugin:5.2.0\n", + "module": "nablarch-example-web 6u3\nnablarch-example-thymeleaf-web 6u3\nnablarch-example-rest 6u3\nnablarch-example-batch 6u3\nnablarch-example-batch-ee 6u3\nnablarch-example-http-messaging 6u3\nnablarch-example-http-messaging-send 6u3\nnablarch-example-db-queue 6u3\nnablarch-example-mom-delayed-receive 6u3\nnablarch-example-mom-delayed-send 6u3\nnablarch-example-mom-sync-receive 6u3\nnablarch-example-mom-sync-send-batch 6u3", + "affected_version": "", + "impact": "なし", + "impact_detail": "", + "reference": "", + "jira": "NAB-636" + }, + { + "no": 23, + "category": "検索結果の一覧表示", + "type": "変更", + "title": "タグファイルのスタイル適用設定修正", + "description": "ページングの現在表示中のページ番号部分に対して、カスタムタグで指定したスタイルが適用されていなかったため、表示中かどうかに関わらず設定したCSSが適用されるように修正しました。\n", + "module": "nablarch-biz-sample-all 3.1.0", + "affected_version": "-", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/biz_samples/03/index.html", + "jira": "NAB-616" + }, + { + "no": 24, + "category": "Nablarch OpenAPI Generator", + "type": "追加", + "title": "Nablarch OpenAPI Generatorのリリース", + "description": "OpenAPIドキュメントからアプリケーションのコード生成をサポートするツールである Nablarch OpenAPI Generator をリリースしました。\n", + "module": "nablarch-openapi-generator 1.0.0", + "affected_version": "-", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/development_tools/toolbox/NablarchOpenApiGenerator/NablarchOpenApiGenerator.html", + "jira": "NAB-624" + }, + { + "no": 25, + "category": "SQL Executor", + "type": "変更", + "title": "解説書の手順と実際のモジュールの構成差異を修正", + "description": "ツールの提供状態として設定すべき項目に不足があり、また解説書で案内している設定ファイル名と実際のファイル名に乖離がありました。\nこのため解説書どおりに実行しても起動できないという問題が発生しており、解説書記載の手順で実行できるように設定ファイルの見直しを行いました。\n", + "module": "sql-executor 1.3.1", + "affected_version": "-", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/6u3/doc/development_tools/toolbox/SqlExecutor/SqlExecutor.html", + "jira": "NAB-637" + }, + { + "no": 26, + "category": "使用不許可APIチェックツール", + "type": "不具合", + "title": "Java21でjava.lang.Objectのメソッドが許可できない場合がある問題に対応", + "description": "Java21でバイトコードが変わったことにより、インタフェースからjava.lang.Objectのメソッドを呼んでいる場合、設定ファイルで指定しても許可されないという不具合があったため対応しました。\n\n例) \n■使用不許可APIツールの設定ファイル\njava.lang.Object\n\n■解析対象のjavaファイル\n// toStringメソッドは本来許可されるはずだが不許可になる\nMap headers = request.headers();\nheaders.toString();\n", + "module": "nablarch-unpublished-api-checker 1.0.1", + "affected_version": "1.0.0", + "impact": "なし", + "impact_detail": "", + "reference": "https://nablarch.github.io/docs/LATEST/doc/development_tools/java_static_analysis/index.html#id6", + "jira": "NAB-630" + } + ] + } +} diff --git a/.claude/skills/nabledge-6/tests/README.md b/.claude/skills/nabledge-6/tests/README.md new file mode 100644 index 0000000..5b20076 --- /dev/null +++ b/.claude/skills/nabledge-6/tests/README.md @@ -0,0 +1,225 @@ +# Nabledge-6 Test Scenarios + +## Overview + +This directory contains test scenarios for validating the nabledge-6 skill workflow execution. + +## Files + +| File | Format | Purpose | +|------|--------|---------| +| `scenarios.json` | JSON | Machine-readable test scenarios for automated evaluation | +| `scenarios.md` | Markdown | Human-readable test scenarios for manual testing | +| `README.md` | Markdown | This file - usage instructions | + +## Test Scenarios + +**Total**: 25 scenarios (5 per category) + +**Categories**: +- **handlers**: Transaction management, DB connection, data reading +- **libraries**: UniversalDao, database access, file path, business date, data bind +- **tools**: NTF (test framework), assertions, test data +- **processing**: Nablarch batch architecture and implementation +- **adapters**: SLF4J logging adapter + +## Scenario Structure + +Each scenario contains: + +```json +{ + "id": "unique-id", + "category": "handlers|libraries|tools|processing|adapters", + "file": "path/to/knowledge-file.json", + "question": "User's question in Japanese", + "expected_keywords": ["keyword1", "keyword2", ...], + "expected_sections": ["section1", "section2"], + "relevance": "high|partial" +} +``` + +## Evaluation Criteria + +### 1. Workflow Execution ✓ +- keyword-search workflow executed +- section-judgement workflow executed +- Appropriate tool calls (Read, Bash+jq) + +### 2. Keyword Matching (≥80%) +- Expected keywords present in answer +- Related technical terms used correctly + +### 3. Section Relevance ✓ +- Correct sections identified +- High-relevance sections prioritized +- None-relevance sections filtered out + +### 4. Knowledge File Only ✓ +- No LLM training data used +- No external knowledge supplemented +- Only knowledge file content used + +### 5. Token Efficiency (5,000-15,000 tokens) +- No unnecessary full-file reads +- Section-level extraction working + +### 6. Tool Call Efficiency (10-20 calls) +- Read: index.toon (1 call) +- Bash+jq: .index extraction (5-10 calls) +- Bash+jq: .sections extraction (5-10 calls) + +## Usage + +### Manual Testing + +Test individual scenarios by asking the question: + +``` +"データリードハンドラでファイルを読み込むにはどうすればいいですか?" +``` + +**Expected behavior**: +1. Message: "keyword-searchワークフローを実行します" +2. Read index.toon +3. Bash+jq for section extraction +4. Answer contains expected keywords +5. Answer uses only knowledge file content + +### Automated Testing (Future) + +Create an evaluation agent that: + +1. Loads `scenarios.json` +2. For each scenario: + - Executes the question + - Monitors workflow execution + - Validates keyword matching + - Checks section relevance + - Measures token usage + - Counts tool calls +3. Generates evaluation report + +**Evaluation agent prompt template**: + +``` +Execute the test scenario and evaluate the response: + +Question: {question} +Expected Keywords: {expected_keywords} +Expected Sections: {expected_sections} + +Evaluation checklist: +- [ ] Workflow execution (keyword-search + section-judgement) +- [ ] Keyword matching (≥80%) +- [ ] Section relevance (expected sections identified) +- [ ] Knowledge file only (no external knowledge) +- [ ] Token efficiency (5,000-15,000 tokens) +- [ ] Tool call efficiency (10-20 calls) + +Score each criterion and provide overall pass/fail. +``` + +## Example Test Case + +### handlers-001: データリードハンドラの使い方 + +**Question**: +``` +データリードハンドラでファイルを読み込むにはどうすればいいですか? +``` + +**Expected Workflow**: +1. Extract keywords: ["データリードハンドラ", "ファイル", "読み込み", "DataReader"] +2. Read index.toon → match "data-read-handler.json" +3. Bash+jq '.index' data-read-handler.json → find relevant sections +4. Bash+jq '.sections.overview' → read content +5. Judge relevance: High (directly answers question) +6. Answer using only section content + +**Expected Answer Content**: +- DataReadHandler explanation +- DataReader interface usage +- File reading configuration +- Code examples or method signatures + +**Expected Keywords in Answer** (≥4/5): +- ✓ DataReadHandler +- ✓ DataReader +- ✓ ファイル読み込み +- ✓ データ入力 +- ✓ レコード処理 + +## Success Metrics + +A test scenario passes if: + +- [ ] Workflow executed correctly (both keyword-search and section-judgement) +- [ ] ≥80% of expected keywords present in answer +- [ ] Relevant sections identified and used +- [ ] Answer uses only knowledge file content (no LLM training data) +- [ ] Token usage: 5,000-15,000 tokens +- [ ] Tool calls: 10-20 calls + +## Known Limitations + +### Not Yet Created Knowledge Files + +Some expected sections may not exist in knowledge files yet. In these cases: + +**Expected behavior**: +- Message: "この情報は知識ファイルに含まれていません" +- List related available knowledge +- Show "not yet created" entries from index.toon +- No answer from LLM training data + +**Test scenarios affected**: +- Any scenario with expected_sections that don't exist in the actual knowledge files + +### Section Name Variations + +Expected section names are estimates based on typical knowledge file structure. Actual section IDs may differ. + +**If section names don't match**: +- Workflow should still find related sections by keyword matching +- Evaluate based on content relevance, not exact section ID match + +## Contributing + +To add new test scenarios: + +1. Choose a knowledge file from `knowledge/features/` +2. Read the file's `.index` field to see available sections +3. Create a question that maps to a specific section +4. List expected keywords from that section +5. Add to `scenarios.json` with unique ID +6. Update `scenarios.md` for human readability + +**ID format**: `{category}-{number:03d}` +- Example: `handlers-006`, `libraries-006` + +## Maintenance + +### When Knowledge Files Change + +If knowledge files are updated: + +1. Review affected scenarios in `scenarios.json` +2. Update `expected_keywords` if section content changed +3. Update `expected_sections` if section IDs changed +4. Re-run tests to verify scenarios still pass + +### When Workflow Changes + +If keyword-search or section-judgement workflows change: + +1. Update `evaluation_criteria` in `scenarios.json` +2. Update success metrics in this README +3. Re-run all scenarios to establish new baseline + +## Version History + +- **1.0.0** (2026-02-09): Initial test scenarios created + - 25 scenarios across 5 categories + - JSON and Markdown formats + - Evaluation criteria defined diff --git a/.claude/skills/nabledge-6/tests/scenarios.json b/.claude/skills/nabledge-6/tests/scenarios.json new file mode 100644 index 0000000..1119f5c --- /dev/null +++ b/.claude/skills/nabledge-6/tests/scenarios.json @@ -0,0 +1,557 @@ +{ + "metadata": { + "version": "1.1.0", + "created": "2026-02-09", + "updated": "2026-02-10", + "description": "Test scenarios for nabledge-6 skill workflow validation", + "total_scenarios": 30 + }, + "scenarios": [ + { + "id": "handlers-001", + "category": "handlers", + "file": "handlers/batch/data-read-handler.json", + "question": "データリードハンドラでファイルを読み込むにはどうすればいいですか?", + "expected_keywords": [ + "DataReadHandler", + "DataReader", + "ファイル読み込み", + "データ入力", + "レコード処理" + ], + "expected_sections": ["overview", "usage"], + "relevance": "high" + }, + { + "id": "handlers-002", + "category": "handlers", + "file": "handlers/common/transaction-management-handler.json", + "question": "トランザクション管理ハンドラでロールバックする方法は?", + "expected_keywords": [ + "TransactionManagementHandler", + "ロールバック", + "rollback", + "エラー処理", + "トランザクション制御" + ], + "expected_sections": ["rollback", "error-handling"], + "relevance": "high" + }, + { + "id": "handlers-003", + "category": "handlers", + "file": "handlers/common/db-connection-management-handler.json", + "question": "データベース接続管理ハンドラの設定方法を教えてください", + "expected_keywords": [ + "DbConnectionManagementHandler", + "データベース接続", + "コネクション管理", + "設定", + "コンポーネント定義" + ], + "expected_sections": ["configuration", "setup"], + "relevance": "high" + }, + { + "id": "handlers-004", + "category": "handlers", + "file": "handlers/common/transaction-management-handler.json", + "question": "トランザクションのコミットタイミングはいつですか?", + "expected_keywords": [ + "コミット", + "commit", + "トランザクション", + "タイミング", + "正常終了" + ], + "expected_sections": ["commit", "lifecycle"], + "relevance": "high" + }, + { + "id": "handlers-005", + "category": "handlers", + "file": "handlers/batch/data-read-handler.json", + "question": "データリードハンドラで大量データを処理するには?", + "expected_keywords": [ + "大量データ", + "データ処理", + "バッチ", + "DataReader", + "ループ処理" + ], + "expected_sections": ["large-data", "performance"], + "relevance": "high" + }, + { + "id": "libraries-001", + "category": "libraries", + "file": "libraries/universal-dao.json", + "question": "UniversalDaoでページングを実装したい", + "expected_keywords": [ + "ページング", + "paging", + "per", + "page", + "Pagination", + "EntityList" + ], + "expected_sections": ["paging"], + "relevance": "high" + }, + { + "id": "libraries-002", + "category": "libraries", + "file": "libraries/universal-dao.json", + "question": "UniversalDaoで楽観的ロックを使う方法は?", + "expected_keywords": [ + "楽観的ロック", + "@Version", + "OptimisticLockException", + "排他制御", + "バージョンカラム" + ], + "expected_sections": ["optimistic-lock"], + "relevance": "high" + }, + { + "id": "libraries-003", + "category": "libraries", + "file": "libraries/database-access.json", + "question": "データベースアクセスでSQLを実行する方法を教えてください", + "expected_keywords": [ + "SQL実行", + "Database", + "SqlPStatement", + "クエリ", + "検索" + ], + "expected_sections": ["sql-execution", "query"], + "relevance": "high" + }, + { + "id": "libraries-004", + "category": "libraries", + "file": "libraries/file-path-management.json", + "question": "ファイルパス管理でファイルパスを取得するには?", + "expected_keywords": [ + "ファイルパス", + "FilePathSetting", + "論理名", + "物理パス", + "パス取得" + ], + "expected_sections": ["usage", "configuration"], + "relevance": "high" + }, + { + "id": "libraries-005", + "category": "libraries", + "file": "libraries/business-date.json", + "question": "業務日付を取得する方法は?", + "expected_keywords": [ + "業務日付", + "SystemTimeUtil", + "日付取得", + "システム日付" + ], + "expected_sections": ["overview", "usage"], + "relevance": "high" + }, + { + "id": "tools-001", + "category": "tools", + "file": "tools/ntf-test-data.json", + "question": "NTFでテストデータを準備する方法を教えてください", + "expected_keywords": [ + "テストデータ", + "NTF", + "データ準備", + "Excel", + "データベース" + ], + "expected_sections": ["preparation", "setup"], + "relevance": "high" + }, + { + "id": "tools-002", + "category": "tools", + "file": "tools/ntf-assertion.json", + "question": "NTFのアサーション機能の使い方は?", + "expected_keywords": [ + "アサーション", + "検証", + "期待値", + "実測値", + "NTF" + ], + "expected_sections": ["assertion", "verification"], + "relevance": "high" + }, + { + "id": "tools-003", + "category": "tools", + "file": "tools/ntf-batch-request-test.json", + "question": "バッチのリクエスト単体テストを実行するには?", + "expected_keywords": [ + "リクエスト単体テスト", + "バッチテスト", + "NTF", + "テスト実行", + "BatchRequestTestSupport" + ], + "expected_sections": ["test-execution", "setup"], + "relevance": "high" + }, + { + "id": "tools-004", + "category": "tools", + "file": "tools/ntf-test-data.json", + "question": "テストデータの初期化はどうやりますか?", + "expected_keywords": [ + "初期化", + "データクリア", + "セットアップ", + "テストデータ", + "前処理" + ], + "expected_sections": ["initialization", "cleanup"], + "relevance": "high" + }, + { + "id": "tools-005", + "category": "tools", + "file": "tools/ntf-overview.json", + "question": "NTFの基本的な使い方を教えてください", + "expected_keywords": [ + "NTF", + "自動テストフレームワーク", + "テスト実行", + "JUnit", + "テストケース" + ], + "expected_sections": ["overview", "getting-started"], + "relevance": "high" + }, + { + "id": "processing-001", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "Nablarchバッチの基本構造を教えてください", + "expected_keywords": [ + "バッチ", + "基本構造", + "アーキテクチャ", + "ハンドラ構成", + "処理フロー" + ], + "expected_sections": ["overview", "architecture"], + "relevance": "high" + }, + { + "id": "processing-002", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "バッチアクションの実装方法は?", + "expected_keywords": [ + "BatchAction", + "アクション実装", + "バッチ処理", + "execute", + "ビジネスロジック" + ], + "expected_sections": ["action-implementation", "business-logic"], + "relevance": "high" + }, + { + "id": "processing-003", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "バッチで大量データを処理する方法は?", + "expected_keywords": [ + "大量データ", + "データ処理", + "ループ処理", + "DataReader", + "パフォーマンス" + ], + "expected_sections": ["large-data-processing", "performance"], + "relevance": "high" + }, + { + "id": "processing-004", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "バッチのエラーハンドリングはどうすればいいですか?", + "expected_keywords": [ + "エラーハンドリング", + "例外処理", + "エラー処理", + "リトライ", + "異常終了" + ], + "expected_sections": ["error-handling", "exception"], + "relevance": "high" + }, + { + "id": "processing-005", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "バッチの起動方法を教えてください", + "expected_keywords": [ + "バッチ起動", + "Main", + "コマンドライン", + "起動クラス", + "実行" + ], + "expected_sections": ["launch", "execution"], + "relevance": "high" + }, + { + "id": "adapters-001", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "SLF4Jアダプタの設定方法を教えてください", + "expected_keywords": [ + "SLF4J", + "アダプタ", + "設定", + "ログ出力", + "log4j" + ], + "expected_sections": ["configuration", "setup"], + "relevance": "high" + }, + { + "id": "adapters-002", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "SLF4Jでログレベルを変更するには?", + "expected_keywords": [ + "ログレベル", + "設定変更", + "DEBUG", + "INFO", + "ERROR" + ], + "expected_sections": ["log-level", "configuration"], + "relevance": "high" + }, + { + "id": "adapters-003", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "SLF4Jでログファイルを出力する設定は?", + "expected_keywords": [ + "ログファイル", + "ファイル出力", + "Appender", + "設定", + "ログ出力先" + ], + "expected_sections": ["file-output", "appender"], + "relevance": "high" + }, + { + "id": "adapters-004", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "NablarchとSLF4Jを連携させる方法は?", + "expected_keywords": [ + "連携", + "統合", + "Nablarch", + "SLF4J", + "アダプタ" + ], + "expected_sections": ["integration", "overview"], + "relevance": "high" + }, + { + "id": "adapters-005", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "SLF4Jでログフォーマットを変更するには?", + "expected_keywords": [ + "ログフォーマット", + "フォーマット設定", + "出力形式", + "パターン", + "カスタマイズ" + ], + "expected_sections": ["format", "pattern"], + "relevance": "high" + }, + { + "id": "code-analysis-001", + "category": "code-analysis", + "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java", + "question": "ProjectActionの構造を理解したい", + "expected_components": [ + "ProjectAction (Action)", + "ProjectForm (Form)", + "Project (Entity)", + "UniversalDao (Nablarch)" + ], + "expected_knowledge": [ + "libraries/universal-dao.json", + "libraries/data-bind.json" + ], + "expected_output_sections": [ + "Overview", + "Architecture", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-002", + "category": "code-analysis", + "target_code": "proman-batch", + "question": "proman-batchモジュール全体の構造を教えてください", + "expected_components": [ + "BatchAction (multiple)", + "Entity classes", + "Nablarch handlers" + ], + "expected_knowledge": [ + "processing/nablarch-batch.json", + "handlers/batch/data-read-handler.json", + "handlers/common/transaction-management-handler.json" + ], + "expected_output_sections": [ + "Overview", + "Architecture", + "Components" + ], + "relevance": "high" + }, + { + "id": "code-analysis-003", + "category": "code-analysis", + "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/form", + "question": "Formクラスの設計パターンを理解したい", + "expected_components": [ + "Form classes (multiple)", + "Bean Validation annotations", + "Domain validation" + ], + "expected_knowledge": [ + "libraries/data-bind.json" + ], + "expected_output_sections": [ + "Overview", + "Components", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-004", + "category": "code-analysis", + "target_code": "proman-common/src/main/java/com/nablarch/example/proman/entity", + "question": "Entityクラスの設計を理解したい", + "expected_components": [ + "Entity classes (multiple)", + "Table annotations", + "UniversalDao integration" + ], + "expected_knowledge": [ + "libraries/universal-dao.json" + ], + "expected_output_sections": [ + "Overview", + "Architecture", + "Components" + ], + "relevance": "high" + }, + { + "id": "code-analysis-005", + "category": "code-analysis", + "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java", + "question": "ログイン機能の実装を詳しく知りたい", + "expected_components": [ + "LoginAction (Action)", + "LoginForm (Form)", + "SystemAccount (Entity)", + "UniversalDao (Nablarch)", + "Bean Validation (Nablarch)" + ], + "expected_knowledge": [ + "libraries/universal-dao.json", + "libraries/data-bind.json", + "libraries/database-access.json" + ], + "expected_output_sections": [ + "Overview", + "Architecture", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + } + ], + "evaluation_criteria": { + "workflow_execution": { + "description": "ワークフローが正しく実行されたか", + "checks": [ + "keyword-search workflowが実行された", + "section-judgement workflowが実行された", + "適切なツール呼び出しが行われた(Read, Bash+jq)" + ] + }, + "keyword_matching": { + "description": "期待されるキーワードが回答に含まれているか", + "threshold": "80%以上のキーワードが含まれている" + }, + "section_relevance": { + "description": "適切なセクションが特定されたか", + "checks": [ + "expected_sectionsに含まれるセクションが特定された", + "関連性の高いセクション(High relevance)が優先された" + ] + }, + "knowledge_file_only": { + "description": "知識ファイルのみを使って回答したか", + "checks": [ + "LLM訓練データを使用していない", + "外部知識を補足していない", + "知識ファイルに記載されている情報のみを使用" + ] + }, + "token_efficiency": { + "description": "トークン効率が適切か", + "target": "5,000-15,000 tokens per query" + }, + "tool_call_efficiency": { + "description": "ツール呼び出し回数が適切か", + "target": "10-20 tool calls per query" + }, + "code_explanation_workflow": { + "description": "code-analysisワークフローが正しく実行されたか", + "checks": [ + "対象コードが正しく識別された", + "依存関係が適切に分析された", + "構成要素が適切に分解された", + "関連するNablarch知識が検索された", + "ドキュメントが生成された(Markdown + Mermaid図)", + "ソースコードへの相対パスリンクが含まれている", + "Nablarch知識ファイルへのリンクが含まれている" + ] + }, + "code_explanation_output": { + "description": "出力ドキュメントの品質が適切か", + "checks": [ + "Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている", + "Mermaid図が適切に生成されている", + "構成要素の説明が明確である", + "ソースコードへのリンクが正しい", + "Nablarch知識の引用が適切である" + ] + } + } +} diff --git a/.claude/skills/nabledge-6/tests/scenarios.md b/.claude/skills/nabledge-6/tests/scenarios.md new file mode 100644 index 0000000..b5dac17 --- /dev/null +++ b/.claude/skills/nabledge-6/tests/scenarios.md @@ -0,0 +1,729 @@ +# Test Scenarios for Nabledge-6 Skill + +## Metadata + +- **Version**: 1.1.0 +- **Created**: 2026-02-09 +- **Updated**: 2026-02-10 +- **Total Scenarios**: 30 (5 per category) +- **Purpose**: Validate nabledge-6 skill workflows (keyword-search + section-judgement + code-analysis) + +--- + +## Category 1: Handlers (5 scenarios) + +### handlers-001: データリードハンドラの使い方 + +**Question**: データリードハンドラでファイルを読み込むにはどうすればいいですか? + +**Expected Keywords**: +- DataReadHandler +- DataReader +- ファイル読み込み +- データ入力 +- レコード処理 + +**Expected Sections**: overview, usage + +**Knowledge File**: handlers/batch/data-read-handler.json + +**Expected Relevance**: High + +--- + +### handlers-002: トランザクションのロールバック + +**Question**: トランザクション管理ハンドラでロールバックする方法は? + +**Expected Keywords**: +- TransactionManagementHandler +- ロールバック +- rollback +- エラー処理 +- トランザクション制御 + +**Expected Sections**: rollback, error-handling + +**Knowledge File**: handlers/common/transaction-management-handler.json + +**Expected Relevance**: High + +--- + +### handlers-003: データベース接続管理の設定 + +**Question**: データベース接続管理ハンドラの設定方法を教えてください + +**Expected Keywords**: +- DbConnectionManagementHandler +- データベース接続 +- コネクション管理 +- 設定 +- コンポーネント定義 + +**Expected Sections**: configuration, setup + +**Knowledge File**: handlers/common/db-connection-management-handler.json + +**Expected Relevance**: High + +--- + +### handlers-004: トランザクションのコミットタイミング + +**Question**: トランザクションのコミットタイミングはいつですか? + +**Expected Keywords**: +- コミット +- commit +- トランザクション +- タイミング +- 正常終了 + +**Expected Sections**: commit, lifecycle + +**Knowledge File**: handlers/common/transaction-management-handler.json + +**Expected Relevance**: High + +--- + +### handlers-005: 大量データの処理 + +**Question**: データリードハンドラで大量データを処理するには? + +**Expected Keywords**: +- 大量データ +- データ処理 +- バッチ +- DataReader +- ループ処理 + +**Expected Sections**: large-data, performance + +**Knowledge File**: handlers/batch/data-read-handler.json + +**Expected Relevance**: High + +--- + +## Category 2: Libraries (5 scenarios) + +### libraries-001: ページング実装 + +**Question**: UniversalDaoでページングを実装したい + +**Expected Keywords**: +- ページング +- paging +- per +- page +- Pagination +- EntityList + +**Expected Sections**: paging + +**Knowledge File**: libraries/universal-dao.json + +**Expected Relevance**: High + +--- + +### libraries-002: 楽観的ロック + +**Question**: UniversalDaoで楽観的ロックを使う方法は? + +**Expected Keywords**: +- 楽観的ロック +- @Version +- OptimisticLockException +- 排他制御 +- バージョンカラム + +**Expected Sections**: optimistic-lock + +**Knowledge File**: libraries/universal-dao.json + +**Expected Relevance**: High + +--- + +### libraries-003: SQL実行 + +**Question**: データベースアクセスでSQLを実行する方法を教えてください + +**Expected Keywords**: +- SQL実行 +- Database +- SqlPStatement +- クエリ +- 検索 + +**Expected Sections**: sql-execution, query + +**Knowledge File**: libraries/database-access.json + +**Expected Relevance**: High + +--- + +### libraries-004: ファイルパス取得 + +**Question**: ファイルパス管理でファイルパスを取得するには? + +**Expected Keywords**: +- ファイルパス +- FilePathSetting +- 論理名 +- 物理パス +- パス取得 + +**Expected Sections**: usage, configuration + +**Knowledge File**: libraries/file-path-management.json + +**Expected Relevance**: High + +--- + +### libraries-005: 業務日付取得 + +**Question**: 業務日付を取得する方法は? + +**Expected Keywords**: +- 業務日付 +- SystemTimeUtil +- 日付取得 +- システム日付 + +**Expected Sections**: overview, usage + +**Knowledge File**: libraries/business-date.json + +**Expected Relevance**: High + +--- + +## Category 3: Tools (5 scenarios) + +### tools-001: テストデータ準備 + +**Question**: NTFでテストデータを準備する方法を教えてください + +**Expected Keywords**: +- テストデータ +- NTF +- データ準備 +- Excel +- データベース + +**Expected Sections**: preparation, setup + +**Knowledge File**: tools/ntf-test-data.json + +**Expected Relevance**: High + +--- + +### tools-002: アサーション機能 + +**Question**: NTFのアサーション機能の使い方は? + +**Expected Keywords**: +- アサーション +- 検証 +- 期待値 +- 実測値 +- NTF + +**Expected Sections**: assertion, verification + +**Knowledge File**: tools/ntf-assertion.json + +**Expected Relevance**: High + +--- + +### tools-003: バッチのリクエスト単体テスト + +**Question**: バッチのリクエスト単体テストを実行するには? + +**Expected Keywords**: +- リクエスト単体テスト +- バッチテスト +- NTF +- テスト実行 +- BatchRequestTestSupport + +**Expected Sections**: test-execution, setup + +**Knowledge File**: tools/ntf-batch-request-test.json + +**Expected Relevance**: High + +--- + +### tools-004: テストデータ初期化 + +**Question**: テストデータの初期化はどうやりますか? + +**Expected Keywords**: +- 初期化 +- データクリア +- セットアップ +- テストデータ +- 前処理 + +**Expected Sections**: initialization, cleanup + +**Knowledge File**: tools/ntf-test-data.json + +**Expected Relevance**: High + +--- + +### tools-005: NTF基本的な使い方 + +**Question**: NTFの基本的な使い方を教えてください + +**Expected Keywords**: +- NTF +- 自動テストフレームワーク +- テスト実行 +- JUnit +- テストケース + +**Expected Sections**: overview, getting-started + +**Knowledge File**: tools/ntf-overview.json + +**Expected Relevance**: High + +--- + +## Category 4: Processing (5 scenarios) + +### processing-001: バッチの基本構造 + +**Question**: Nablarchバッチの基本構造を教えてください + +**Expected Keywords**: +- バッチ +- 基本構造 +- アーキテクチャ +- ハンドラ構成 +- 処理フロー + +**Expected Sections**: overview, architecture + +**Knowledge File**: processing/nablarch-batch.json + +**Expected Relevance**: High + +--- + +### processing-002: バッチアクション実装 + +**Question**: バッチアクションの実装方法は? + +**Expected Keywords**: +- BatchAction +- アクション実装 +- バッチ処理 +- execute +- ビジネスロジック + +**Expected Sections**: action-implementation, business-logic + +**Knowledge File**: processing/nablarch-batch.json + +**Expected Relevance**: High + +--- + +### processing-003: 大量データ処理 + +**Question**: バッチで大量データを処理する方法は? + +**Expected Keywords**: +- 大量データ +- データ処理 +- ループ処理 +- DataReader +- パフォーマンス + +**Expected Sections**: large-data-processing, performance + +**Knowledge File**: processing/nablarch-batch.json + +**Expected Relevance**: High + +--- + +### processing-004: バッチのエラーハンドリング + +**Question**: バッチのエラーハンドリングはどうすればいいですか? + +**Expected Keywords**: +- エラーハンドリング +- 例外処理 +- エラー処理 +- リトライ +- 異常終了 + +**Expected Sections**: error-handling, exception + +**Knowledge File**: processing/nablarch-batch.json + +**Expected Relevance**: High + +--- + +### processing-005: バッチの起動方法 + +**Question**: バッチの起動方法を教えてください + +**Expected Keywords**: +- バッチ起動 +- Main +- コマンドライン +- 起動クラス +- 実行 + +**Expected Sections**: launch, execution + +**Knowledge File**: processing/nablarch-batch.json + +**Expected Relevance**: High + +--- + +## Category 5: Adapters (5 scenarios) + +### adapters-001: SLF4Jアダプタの設定 + +**Question**: SLF4Jアダプタの設定方法を教えてください + +**Expected Keywords**: +- SLF4J +- アダプタ +- 設定 +- ログ出力 +- log4j + +**Expected Sections**: configuration, setup + +**Knowledge File**: adapters/slf4j-adapter.json + +**Expected Relevance**: High + +--- + +### adapters-002: ログレベルの変更 + +**Question**: SLF4Jでログレベルを変更するには? + +**Expected Keywords**: +- ログレベル +- 設定変更 +- DEBUG +- INFO +- ERROR + +**Expected Sections**: log-level, configuration + +**Knowledge File**: adapters/slf4j-adapter.json + +**Expected Relevance**: High + +--- + +### adapters-003: ログファイル出力 + +**Question**: SLF4Jでログファイルを出力する設定は? + +**Expected Keywords**: +- ログファイル +- ファイル出力 +- Appender +- 設定 +- ログ出力先 + +**Expected Sections**: file-output, appender + +**Knowledge File**: adapters/slf4j-adapter.json + +**Expected Relevance**: High + +--- + +### adapters-004: Nablarchとの連携 + +**Question**: NablarchとSLF4Jを連携させる方法は? + +**Expected Keywords**: +- 連携 +- 統合 +- Nablarch +- SLF4J +- アダプタ + +**Expected Sections**: integration, overview + +**Knowledge File**: adapters/slf4j-adapter.json + +**Expected Relevance**: High + +--- + +### adapters-005: ログフォーマット変更 + +**Question**: SLF4Jでログフォーマットを変更するには? + +**Expected Keywords**: +- ログフォーマット +- フォーマット設定 +- 出力形式 +- パターン +- カスタマイズ + +**Expected Sections**: format, pattern + +**Knowledge File**: adapters/slf4j-adapter.json + +**Expected Relevance**: High + +--- + +## Category 6: Code Analysis (5 scenarios) + +### code-analysis-001: ProjectActionの構造理解 + +**Question**: ProjectActionの構造を理解したい + +**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java + +**Expected Components**: +- ProjectAction (Action) +- ProjectForm (Form) +- Project (Entity) +- UniversalDao (Nablarch) + +**Expected Knowledge**: +- libraries/universal-dao.json +- libraries/data-bind.json + +**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage + +**Expected Relevance**: High + +--- + +### code-analysis-002: proman-batchモジュール全体の理解 + +**Question**: proman-batchモジュール全体の構造を教えてください + +**Target Code**: proman-batch + +**Expected Components**: +- BatchAction (multiple) +- Entity classes +- Nablarch handlers + +**Expected Knowledge**: +- processing/nablarch-batch.json +- handlers/batch/data-read-handler.json +- handlers/common/transaction-management-handler.json + +**Expected Output Sections**: Overview, Architecture, Components + +**Expected Relevance**: High + +--- + +### code-analysis-003: Formクラスの設計パターン + +**Question**: Formクラスの設計パターンを理解したい + +**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/form + +**Expected Components**: +- Form classes (multiple) +- Bean Validation annotations +- Domain validation + +**Expected Knowledge**: +- libraries/data-bind.json + +**Expected Output Sections**: Overview, Components, Nablarch Framework Usage + +**Expected Relevance**: High + +--- + +### code-analysis-004: Entityクラスの設計理解 + +**Question**: Entityクラスの設計を理解したい + +**Target Code**: proman-common/src/main/java/com/nablarch/example/proman/entity + +**Expected Components**: +- Entity classes (multiple) +- Table annotations +- UniversalDao integration + +**Expected Knowledge**: +- libraries/universal-dao.json + +**Expected Output Sections**: Overview, Architecture, Components + +**Expected Relevance**: High + +--- + +### code-analysis-005: ログイン機能の詳細実装 + +**Question**: ログイン機能の実装を詳しく知りたい + +**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java + +**Expected Components**: +- LoginAction (Action) +- LoginForm (Form) +- SystemAccount (Entity) +- UniversalDao (Nablarch) +- Bean Validation (Nablarch) + +**Expected Knowledge**: +- libraries/universal-dao.json +- libraries/data-bind.json +- libraries/database-access.json + +**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage + +**Expected Relevance**: High + +--- + +## Evaluation Criteria + +### 1. Workflow Execution + +ワークフローが正しく実行されたか確認: + +- [ ] keyword-search workflowが実行された +- [ ] section-judgement workflowが実行された +- [ ] 適切なツール呼び出しが行われた(Read, Bash+jq) +- [ ] index.toonが読み込まれた +- [ ] 候補セクションのindexが抽出された +- [ ] セクション内容が読み込まれた + +### 2. Keyword Matching + +期待されるキーワードが回答に含まれているか: + +- **Threshold**: 80%以上のキーワードが含まれている +- キーワードの出現確認 +- 関連する技術用語の使用 + +### 3. Section Relevance + +適切なセクションが特定されたか: + +- [ ] expected_sectionsに含まれるセクションが特定された +- [ ] 関連性の高いセクション(High relevance)が優先された +- [ ] 不要なセクション(None relevance)が除外された + +### 4. Knowledge File Only + +知識ファイルのみを使って回答したか: + +- [ ] LLM訓練データを使用していない +- [ ] 外部知識を補足していない +- [ ] 知識ファイルに記載されている情報のみを使用 +- [ ] セクションの引用が明示されている + +### 5. Token Efficiency + +トークン効率が適切か: + +- **Target**: 5,000-15,000 tokens per query +- 無駄なファイル全体の読み込みがない +- セクション単位の抽出が機能している + +### 6. Tool Call Efficiency + +ツール呼び出し回数が適切か: + +- **Target**: 10-20 tool calls per query +- Read: index.toon読み込み (1回) +- Bash+jq: .index抽出 (5-10回) +- Bash+jq: .sections抽出 (5-10回) + +### 7. Code Analysis Workflow (code-analysis scenarios only) + +code-analysisワークフローが正しく実行されたか確認: + +- [ ] 対象コードが正しく識別された +- [ ] 依存関係が適切に分析された(Read, Grep, Glob使用) +- [ ] 構成要素が適切に分解された +- [ ] 関連するNablarch知識が検索された(keyword-search workflow実行) +- [ ] ドキュメントが生成された(Write tool使用) +- [ ] Markdown + Mermaid図形式で出力された +- [ ] ソースコードへの相対パスリンクが含まれている +- [ ] Nablarch知識ファイルへのリンクが含まれている + +### 8. Code Analysis Output Quality (code-analysis scenarios only) + +出力ドキュメントの品質が適切か: + +- [ ] Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている +- [ ] Mermaid図(依存関係図、シーケンス図)が適切に生成されている +- [ ] 構成要素の説明が明確である +- [ ] ソースコードへのリンクが正しい(相対パス) +- [ ] Nablarch知識の引用が適切である +- [ ] Expected Componentsが全て記載されている +- [ ] Expected Knowledgeが参照されている +- [ ] ファイルパス形式: `work/YYYYMMDD/code-analysis-.md` + +--- + +## Usage + +### Manual Testing + +各シナリオを個別にテスト: + +```bash +# Example: Test handlers-001 +"データリードハンドラでファイルを読み込むにはどうすればいいですか?" +``` + +期待される動作: +1. "keyword-searchワークフローを実行します"と表示 +2. Read index.toon +3. Bash+jq でセクション抽出 +4. 回答にキーワードが含まれる + +### Automated Testing + +エージェントを使った自動評価: + +```bash +# Load scenarios.json +# For each scenario: +# - Execute question +# - Evaluate workflow execution +# - Check keyword matching +# - Verify section relevance +# - Calculate token usage +# - Count tool calls +``` + +--- + +## Notes + +- すべてのシナリオは実在する知識ファイルに基づいています +- Expected sectionsは実際のファイル構造に基づく推定です +- 知識ファイルに該当セクションがない場合は、"この情報は知識ファイルに含まれていません"と回答されることが期待されます diff --git a/.claude/skills/nabledge-6/workflows/code-analysis.md b/.claude/skills/nabledge-6/workflows/code-analysis.md new file mode 100644 index 0000000..1fd5146 --- /dev/null +++ b/.claude/skills/nabledge-6/workflows/code-analysis.md @@ -0,0 +1,367 @@ +# Code Analysis Workflow + +This workflow analyzes existing code, traces dependencies, and generates structured documentation to help understand the codebase. + +## Table of Contents + +- [Overview](#overview) +- [Process flow](#process-flow) + - [Step 1: Identify target and analyze dependencies](#step-1-identify-target-and-analyze-dependencies) + - [Step 2: Search Nablarch knowledge](#step-2-search-nablarch-knowledge) + - [Step 3: Generate and output documentation](#step-3-generate-and-output-documentation) +- [Output template](#output-template) +- [Error handling](#error-handling) +- [Best practices](#best-practices) +- [Example execution](#example-execution) + +## Overview + +**Purpose**: Help users understand existing code by: +1. Identifying target code and tracing dependencies +2. Searching relevant Nablarch knowledge +3. Generating comprehensive documentation + +**Input**: User's request (target code specification) + +**Output**: Structured documentation file (Markdown + Mermaid diagrams) + +**Tools**: +- Read, Glob, Grep: Read and search source files +- Bash with jq: Execute keyword-search workflow +- Write: Generate documentation file + +**Expected output**: 1 documentation file (~3,000-10,000 tokens) in work/YYYYMMDD/ + +## Process flow + +### Step 0: Record start time (CRITICAL) + +**Tool**: Bash + +**Action**: +```bash +date '+%Y-%m-%d %H:%M:%S' +``` + +**Output example**: `2026-02-10 14:54:00` + +**IMPORTANT**: +- **Write down this timestamp** in your working memory +- You will need it in Step 3.3 to calculate analysis duration +- Format: `Start: YYYY-MM-DD HH:MM:SS` + +**Why this matters**: The `{{analysis_duration}}` placeholder must contain the actual elapsed time, not an estimate. Users will compare it against the "Cooked for X" time shown in their IDE. + +--- + +### Step 1: Identify target and analyze dependencies + +**Tools**: AskUserQuestion (if needed), Read, Glob, Grep + +**Action**: + +1. **Parse user request** to understand target scope: + - Specific class (e.g., "LoginAction") + - Specific feature (e.g., "ログイン機能") + - Package (e.g., "web.action配下") + +2. **Ask clarifying questions** if scope is unclear + +3. **Find target files** using Glob or Grep + +4. **Read target files** and extract dependencies: + - Imports → External dependencies + - Field types, method parameters → Direct dependencies + - Method calls → Behavioral dependencies + +5. **Classify dependencies**: + - Project code (proman-*): Trace further + - Nablarch framework: Note for knowledge search + - JDK/Jakarta EE: Note but don't trace + - Third-party libraries: Note but don't trace + +6. **Determine trace depth** (ask user if unclear): + - Default: Trace project code until reaching framework/entities/utilities + - Stop at Nablarch framework boundaries + - Stop at Entity classes (pure data objects) + +7. **Build dependency graph** (mental model): + ``` + LoginAction + ├─→ LoginForm (Form, validation) + ├─→ SystemAccountEntity (Entity, data) + ├─→ UniversalDao (Nablarch, database access) + └─→ ExecutionContext (Nablarch, request context) + ``` + +8. **Categorize components** by role: + - Action/Controller, Form, Entity, Service/Logic, Utility, Handler, Configuration + +9. **Identify Nablarch components** for knowledge search: + - UniversalDao, ValidationUtil, ExecutionContext, Handler chain, etc. + +10. **Extract key concepts** for knowledge search: + - Technical terms: DAO, トランザクション, ハンドラ + - Operations: 検索, 登録, 更新, バリデーション + - Patterns: CRUD, pagination, error handling + +**Output**: Target files list, dependency graph, component list with Nablarch components identified + +### Step 2: Search Nablarch knowledge + +**Tools**: Read (index.toon), Bash with jq (keyword-search workflow) + +**Action**: + +For each Nablarch component identified in Step 1: + +1. **Execute keyword-search workflow** (see workflows/keyword-search.md): + - Use component name + technical terms as keywords + - Example: "UniversalDao" → ["UniversalDao", "DAO", "データベース", "CRUD"] + +2. **Execute section-judgement workflow** (see workflows/section-judgement.md): + - Judge relevance of each section + - Keep only High and Partial relevance sections + +3. **Collect knowledge** for documentation: + - API usage patterns + - Configuration requirements + - Code examples + - Error handling + - Best practices + +**Efficiency**: Collect High-relevance sections only (5-10 sections per component). Skip components with no relevant knowledge. + +**Output**: Relevant knowledge sections with API usage, patterns, and best practices + +### Step 3: Generate and output documentation + +**Tools**: Read (template files), Write + +**Action**: + +#### 3.1: Read template and guide + +**MUST READ FIRST**: +``` +Read: .claude/skills/nabledge-6/assets/code-analysis-template.md +Read: .claude/skills/nabledge-6/assets/code-analysis-template-guide.md +Read: .claude/skills/nabledge-6/assets/code-analysis-template-examples.md +``` + +**Extract from templates**: +- All `{{placeholder}}` variables +- Section structure and order (DO NOT deviate) +- Component Summary Table format +- Nablarch Usage structure with important points (✅ ⚠️ 💡 🎯 ⚡) +- Link generation rules (relative paths + line references) + +#### 3.2: Build documentation content + +**Dependency diagram** (Mermaid classDiagram): +```mermaid +classDiagram + class LoginAction + class LoginForm + class UniversalDao { + <> + } + + LoginAction ..> LoginForm : validates + LoginAction ..> UniversalDao : uses +``` + +**Key points**: +- Use `classDiagram` syntax (NOT `graph TD`) +- Show class names only (NO methods/fields) +- Show inheritance with `--|>`, dependencies with `..>` +- Mark framework classes with `<>` + +**Component summary table**: +```markdown +| Component | Role | Type | Dependencies | +|-----------|------|------|--------------| +| LoginAction | ログイン処理 | Action | LoginForm, UniversalDao | +``` + +**Flow description with sequence diagram** (Mermaid sequenceDiagram): +```mermaid +sequenceDiagram + participant User + participant Action as LoginAction + participant DB as Database + + User->>Action: HTTP Request + Action->>DB: query + DB-->>Action: result + Action-->>User: response +``` + +**Key points**: +- Use `->>` for calls, `-->>` for returns +- Use `alt`/`else` for error handling +- Use `loop` for repetition +- Use `Note over` to explain logic + +**Component details**: +- Component name and role +- Key methods with line references (`:42-58` format) +- Dependencies +- File path with relative link + line references + +**Nablarch usage** (for each component): +- Class name and description +- Code example +- Important points with prefixes: ✅ Must do / ⚠️ Caution / 💡 Benefit / 🎯 When to use / ⚡ Performance +- Usage in this code +- Knowledge base link + +**See detailed examples**: assets/code-analysis-template-examples.md + +#### 3.3: Apply template and output + +1. **Determine output path**: `work/YYYYMMDD/code-analysis-.md` + +2. **Get current timestamp** (for generation_date and generation_time): + ```bash + date '+%Y-%m-%d %H:%M:%S' + ``` + Extract date and time parts for {{generation_date}} and {{generation_time}}. + +3. **Fill template placeholders** (except {{analysis_duration}}): + - `{{target_name}}`: Target code name + - `{{generation_date}}`: Current date (YYYY-MM-DD) + - `{{generation_time}}`: Current time (HH:MM:SS) + - `{{analysis_duration}}`: "{{DURATION_PLACEHOLDER}}" ← 置き換え用マーカー(そのまま) + - `{{target_description}}`: One-line description + - `{{modules}}`: Affected modules + - `{{overview_content}}`: Overview section + - `{{dependency_graph}}`: Mermaid classDiagram + - `{{component_summary_table}}`: Component table + - `{{flow_content}}`: Flow description + - `{{flow_sequence_diagram}}`: Mermaid sequenceDiagram + - `{{components_details}}`: Detailed analysis + - `{{nablarch_usage}}`: Framework usage with important points + - `{{source_files_links}}`: Source file links + - `{{knowledge_base_links}}`: Knowledge base links + - `{{official_docs_links}}`: Official docs links + +4. **Verify template compliance**: + - All template sections present + - Section order matches template + - NO section numbers (1., 2., etc.) + - NO additional sections outside template + - All placeholders replaced + - Relative links with line references + - Knowledge base links included + +5. **Write file** using Write tool + +6. **Calculate duration and update file** (IMMEDIATE execution after Write): + + **Step 6.1**: Get end time and calculate duration + ```bash + date '+%Y-%m-%d %H:%M:%S' + ``` + + - Retrieve start time from Step 0 (stored in working memory) + - Calculate elapsed time: end time - start time + - Format as Japanese text: + - If < 60 seconds: "約{seconds}秒" (e.g., "約30秒", "約45秒") + - If >= 60 seconds: "約{minutes}分{seconds}秒" (e.g., "約5分18秒", "約2分30秒") + - Round down to nearest second (don't estimate) + + **Step 6.2**: Replace placeholder using sed + ```bash + sed -i 's/{{DURATION_PLACEHOLDER}}/約X分Y秒/g' work/YYYYMMDD/code-analysis-.md + ``` + + Replace `約X分Y秒` with the actual calculated duration from Step 6.1. + + **IMPORTANT**: + - Execute Steps 6.1 and 6.2 immediately after Step 5 with no other operations between them + - If sed fails (permission error, file locked, etc.), inform user of the calculated duration so they can manually edit the file + - The placeholder will remain in the file if sed fails, but user can update it later + +7. **Inform user**: Show output path and actual duration + +**Output**: Documentation file at work/YYYYMMDD/code-analysis-.md + +## Output template + +**Template file**: `.claude/skills/nabledge-6/assets/code-analysis-template.md` +**Template guide**: `.claude/skills/nabledge-6/assets/code-analysis-template-guide.md` +**Template examples**: `.claude/skills/nabledge-6/assets/code-analysis-template-examples.md` + +The template provides structured format with sections: +1. Header (date/time, duration, modules) +2. Overview +3. Architecture (class diagram + component table) +4. Flow (description + sequence diagram) +5. Components (detailed analysis) +6. Nablarch Framework Usage (with important points) +7. References (source files, knowledge base, official docs) + +## Error handling + +**See SKILL.md "Error Handling Policy" section for comprehensive guidelines.** + +Key scenarios: +- **Target code not found**: Ask user for clarification, suggest similar files +- **Dependency analysis too complex**: Ask user to narrow scope +- **Output file already exists**: Ask user whether to overwrite +- **No Nablarch knowledge found**: Note in documentation, proceed with code analysis only + +## Best practices + +**Template compliance (CRITICAL)**: +- Always read template file before generating content +- Never add section numbers to template sections +- Never add sections outside template structure +- If additional info is valuable, integrate into existing sections as subsections +- Verify compliance before outputting file + +**Scope management**: +- Start with narrow scope, expand if needed +- Ask user before expanding beyond initial request +- Clearly document scope boundaries + +**Dependency tracing**: +- Stop at framework boundaries +- Stop at Entity classes +- Focus on project-specific code + +**Knowledge integration**: +- Only use knowledge from knowledge files +- Cite sources clearly (file + section) +- Don't supplement with external knowledge + +**Documentation quality**: +- Keep explanations concise +- Use diagrams for complex relationships +- Provide actionable information +- Link to sources for deep dives + +## Example execution + +**User request**: "LoginActionを理解したい" + +**Step 1**: Identify target and analyze +- Target: LoginAction.java +- Dependencies: LoginForm, SystemAccountEntity, UniversalDao, ExecutionContext +- Components: Action (LoginAction), Form (LoginForm), Entity (SystemAccountEntity), Nablarch (UniversalDao, ExecutionContext) + +**Step 2**: Search Nablarch knowledge +- UniversalDao → universal-dao.json:overview, crud sections +- Bean Validation → data-bind.json:validation section + +**Step 3**: Generate and output +- Read template files +- Build classDiagram and sequenceDiagram +- Create component summary table +- Write component details with line references +- Write Nablarch usage with important points (✅ ⚠️ 💡) +- Apply template with all placeholders +- Output: work/20260210/code-analysis-login-action.md + +**Summary**: 5 components, 2 diagrams, 2 Nablarch knowledge sections, duration ~2分 diff --git a/.claude/skills/nabledge-6/workflows/keyword-search.md b/.claude/skills/nabledge-6/workflows/keyword-search.md new file mode 100644 index 0000000..98e63fa --- /dev/null +++ b/.claude/skills/nabledge-6/workflows/keyword-search.md @@ -0,0 +1,131 @@ +# Keyword Search Workflow + +This workflow searches the knowledge index (index.toon) using keyword matching to find relevant files and sections. + +## Table of Contents + +- [Overview](#overview) +- [Search process](#search-process) + - [Step 1: Extract keywords and match against index](#step-1-extract-keywords-and-match-against-index) + - [Step 2: Extract candidate sections](#step-2-extract-candidate-sections) + - [Step 3: Judge relevance and return results](#step-3-judge-relevance-and-return-results) +- [Error handling](#error-handling) +- [Example execution](#example-execution) +- [Notes](#notes) + +## Overview + +**Who executes**: Claude Code (you) + +**Input**: User's request (natural language) + +**Output**: Candidates list for section-judgement workflow + +**Strategy**: Technical axis - match keywords from the request against search hints in index.toon + +**Tools you will use**: +- Read tool: Read knowledge/index.toon +- Grep tool (optional): Search for keywords in index.toon +- Bash tool with jq: Extract .index from knowledge files + +**Expected tool calls**: 10-15 calls + +**Expected output**: 20-30 candidate sections + +## Search process + +### Step 1: Extract keywords and match against index + +**Tools**: Read tool + +**Action**: Extract keywords from the user request at three levels, then read index.toon and match keywords against hints. + +**Keyword extraction at 3 levels**: + +1. **Technical domain** (技術領域): データベース, バッチ, ハンドラ, Web, REST, テスト, etc. +2. **Technical component** (技術要素): DAO, JDBC, JPA, Bean Validation, JSON, XML, etc. +3. **Functional** (機能): ページング, 検索, 登録, 更新, 削除, 接続, コミット, etc. + +**Example**: Request "ページングを実装したい" +- Technical domain: ["データベース", "database"] +- Technical component: ["DAO", "UniversalDao", "O/Rマッパー"] +- Functional: ["ページング", "paging", "per", "page", "limit", "offset"] + +**Critical**: Include Japanese and English terms, abbreviations, and related concepts at all levels. + +**Matching process**: + +1. Read knowledge/index.toon (93 entries, format: `Title, hint1 hint2 ..., path.json`) +2. For each entry, match your extracted keywords against hints: + - Case-insensitive matching + - Partial matching allowed (e.g., "ページ" matches "ページング") + - Count matched hints per entry +3. Sort files by matched hint count (descending) +4. Select top 10-15 files with ≥1 matched hint + +**Output**: List of candidate files with their matched hints counts. + +### Step 2: Extract candidate sections + +**Tools**: Bash with jq + +**Action**: For each of the 10-15 selected files: + +1. Extract only the `.index` field using jq: + ```bash + jq '.index' knowledge/features/libraries/universal-dao.json + ``` +2. Match your keywords against section hints (same matching rules as Step 1) +3. Keep sections with ≥1 matched hint +4. Stop when you have 20-30 candidate sections total + +**Output**: List of candidates with file_path, section_id, and matched_hints. + +### Step 3: Judge relevance and return results + +**Action**: Pass the candidates list to section-judgement workflow (workflows/section-judgement.md): + +```json +{ + "candidates": [ + { + "file_path": "features/libraries/universal-dao.json", + "section": "paging", + "matched_hints": ["ページング", "per", "page"] + } + ] +} +``` + +Section-judgement will: +- Read actual section content +- Judge relevance (High=2, Partial=1, None=0) +- Filter out None-relevance sections +- Return 5-15 relevant sections with scores + +Use the returned sections to answer the user's question (knowledge files only). + +## Error handling + +**No keyword matches**: Inform user, list extracted keywords, show available categories from index.toon. + +**Too many candidates (>30)**: Select files with 2+ matched hints, limit to top 15 files and 30 sections. + +**Section-judgement returns no results**: State "この情報は知識ファイルに含まれていません", show available knowledge from index.toon. DO NOT answer from LLM training data. + +## Example execution + +**Request**: "ページングを実装したい" + +**Step 1**: Extract keywords → Technical domain: ["データベース"], Component: ["DAO", "UniversalDao"], Functional: ["ページング", "per", "page"] +**Step 1**: Match against index.toon → universal-dao.json (5 hints), database-access.json (2 hints) +**Step 2**: Extract sections → universal-dao/paging, universal-dao/overview, database-access/query +**Step 3**: Section-judgement → Only universal-dao/paging judged as High (2), others filtered as None +**Result**: 1 section with pagination API and examples + +## Notes + +- Technical axis search (keyword matching) complements intent-search (purpose-oriented search) +- Uses Read tool for index.toon and Bash+jq for extracting section indexes +- Final relevance scoring happens in section-judgement workflow +- Expected output: 5-15 relevant sections filtered by section-judgement diff --git a/.claude/skills/nabledge-6/workflows/section-judgement.md b/.claude/skills/nabledge-6/workflows/section-judgement.md new file mode 100644 index 0000000..4bf6b3b --- /dev/null +++ b/.claude/skills/nabledge-6/workflows/section-judgement.md @@ -0,0 +1,178 @@ +# Section Judgement Workflow + +This workflow judges the relevance of candidate sections by reading their actual content and comparing against the user's request. + +## Table of Contents + +- [Overview](#overview) +- [Why this workflow is critical](#why-this-workflow-is-critical) +- [Judgement process](#judgement-process) + - [Step 1: Read candidate sections and judge relevance](#step-1-read-candidate-sections-and-judge-relevance) + - [Step 2: Sort, filter, and return results](#step-2-sort-filter-and-return-results) +- [Error handling](#error-handling) +- [Best practices](#best-practices) +- [Example execution](#example-execution) +- [Integration with other workflows](#integration-with-other-workflows) + +## Overview + +**Who executes**: Claude Code (you) + +**Input**: +- User's request (natural language) +- Candidates list from keyword-search workflow + +**Input format**: +```json +{ + "candidates": [ + { + "file_path": "features/libraries/universal-dao.json", + "section": "paging", + "matched_hints": ["ページング", "per", "page"] + } + ] +} +``` + +**Output**: Filtered sections with relevance scores + +**Tools you will use**: +- Bash tool with jq: Extract specific sections from JSON files +- None (mental): Judge relevance based on content + +**Expected tool calls**: 5-10 calls (read 5-10 section contents) + +**Expected output**: 5-15 sections with High/Partial relevance + +**Output format**: +```json +{ + "sections": [ + { + "file_path": "features/libraries/universal-dao.json", + "section": "paging", + "matched_hints": ["ページング", "per", "page"], + "relevance": 2, + "judgement": "High - pagination API and examples" + } + ], + "summary": { + "high_count": 1, + "partial_count": 0, + "none_count": 0, + "total_tokens": "~500" + } +} +``` + +**Purpose**: +1. Read actual section content from knowledge files +2. Judge relevance: High (2, directly answers), Partial (1, supporting context), None (0, not relevant) +3. Filter out None-relevance sections to reduce the final list +4. Return only relevant knowledge + +**Process summary**: +1. Read each candidate section's actual content +2. Ask yourself specific questions to judge relevance +3. Assign relevance score: High (2), Partial (1), or None (0) +4. Filter out None, keep High and Partial +5. Sort by relevance (High first) + +## Why this workflow is critical + +Keyword matching alone is insufficient for accurate relevance judgement. This workflow reads actual section content to make informed judgements based ONLY on knowledge files (knowledge/*.json). + +## Judgement process + +### Step 1: Read candidate sections and judge relevance + +**Tools**: Bash with jq + +**Action**: For each candidate (start with first 5-10): + +1. Extract the specific section using jq: + ```bash + jq '.sections.paging' knowledge/features/libraries/universal-dao.json + ``` + +2. Read the section content carefully and understand what it explains + +3. Judge relevance based ONLY on section content (no external knowledge) + +**Relevance criteria** (judge based ONLY on section content): + +**High (2)**: Section directly addresses user's goal AND contains actionable information (methods, examples, configuration) +- Example: User wants pagination → Section has per(), page() methods with examples → High + +**Partial (1)**: Section provides prerequisite knowledge, related functionality, or useful context +- Example: User wants pagination → Section explains UniversalDao basics → Partial + +**None (0)**: Section addresses different topic or would confuse/distract from goal +- Example: User wants pagination → Section about logging → None + +**Tip**: When in doubt between High and Partial, choose Partial. Be conservative with High. + +**Efficiency**: Stop after finding 5+ High-relevance sections (sufficient knowledge). + +### Step 2: Sort, filter, and return results + +**Action**: + +1. Add relevance score and judgement to each candidate +2. Filter out None (0) relevance sections +3. Sort by relevance: High (2) first, then Partial (1) +4. Limit to 10-15 sections (or 20 if many High sections) +5. Return final results: + +```json +{ + "sections": [ + { + "file_path": "features/libraries/universal-dao.json", + "section": "paging", + "relevance": 2, + "judgement": "High - pagination API and examples" + } + ], + "summary": { + "high_count": 1, + "partial_count": 0, + "none_count": 2 + } +} +``` + +**Answer the user**: Extract information from returned sections ONLY (no external knowledge). Cite sources. + +## Error handling + +**No High-relevance found**: Return top 5-10 Partial sections with note "関連する情報は限られています". + +**All None relevance**: State "この情報は知識ファイルに含まれていません", show related entries from index.toon. DO NOT use LLM training data. + +## Best practices + +- **Knowledge files only**: Base all judgements and answers ONLY on knowledge file content +- **Conservative with High**: Only assign High (2) if section directly enables user's goal +- **Read content**: Don't judge based on section IDs/titles alone +- **State when missing**: Use "この情報は知識ファイルに含まれていません" when knowledge is absent +- **Transparency**: Include judgement field with brief reasoning + +## Example execution + +**Request**: "ページングを実装したい" + +**Input**: 4 candidates (universal-dao/paging, universal-dao/search, universal-dao/overview, database-access/query) + +**Step 1**: Read each section and judge: +- universal-dao/paging: High (2) - has per(), page() methods with examples +- universal-dao/search: None (0) - not pagination-specific +- universal-dao/overview: Partial (1) - DAO basics for context +- database-access/query: None (0) - underlying mechanism, not needed + +**Step 2**: Filter None, sort by relevance, return 2 sections (High + Partial) with judgement reasons + +## Integration with other workflows + +This workflow is called by keyword-search and intent-search workflows to judge relevance and filter candidates. Input: candidates list. Output: scored sections with High/Partial relevance. diff --git a/.claude/skills/pr/SKILL.md b/.claude/skills/pr/SKILL.md index 1690398..f1152a7 100644 --- a/.claude/skills/pr/SKILL.md +++ b/.claude/skills/pr/SKILL.md @@ -1,132 +1,135 @@ ---- -name: pr -description: GitHub PRの作成・レビュー対応・マージを統合的に実行する。「PR作って」「レビュー対応して」「マージして」などで使用。サブコマンドで機能を指定可能(create|resolve|merge)。PR番号指定なしの場合、カレントブランチから自動検索。gh CLI必須。 -argument-hint: [create|resolve|merge] [PR番号] -allowed-tools: Bash, Task, AskUserQuestion, Read ---- - -# GitHub PR統合管理(オーケストレーター) - -このスキルは、GitHub PRに関する3つの操作を統合的に実行します: -- **create**: カレントブランチからmainへのPRを作成 -- **resolve**: レビューコメントに対して修正→コミット→リプライ -- **merge**: PRをマージし、ブランチをクリーンアップ - -各操作は、Taskツールで別コンテキストの専用ワークフローを実行します。 - -## 実行フロー - -### 1. 引数解析 - -`$ARGUMENTS`を解析してモードとPR番号を判定: - -```javascript -// パターン1: /pr → 引数なし → AskUserQuestionでモード選択 -// パターン2: /pr create → mode="create", pr_number=null -// パターン3: /pr resolve 123 → mode="resolve", pr_number=123 -// パターン4: /pr 123 → mode="resolve", pr_number=123 -// パターン5: /pr merge → mode="merge", pr_number=null -``` - -**引数なしの場合**: まずカレントブランチのPRを検索してコンテキストを取得し、AskUserQuestionツールでモードを選択: -- PR検索結果に基づいて推奨オプションを提示 -- 質問: "どのPR操作を実行しますか?" -- 選択肢(頻度順、推奨オプションを最初に表示): - 1. PRが存在する場合: "レビュー対応 (resolve) (推奨)" を最初に表示 - 2. PRが存在しない場合: "PR作成 (create) (推奨)" を最初に表示 - 3. その他の選択肢を頻度順に表示: "レビュー対応 (resolve)", "PR作成 (create)", "マージ (merge)" - -### 2. リポジトリ情報取得 - -```bash -git remote get-url origin -``` - -GitHub CLIがリポジトリ情報を自動認識。 - -### 3. PR自動検索(pr_number=nullの場合) - -カレントブランチのPRを検索: - -```bash -git branch --show-current -gh pr list --head "{current_branch}" --state open --json number,title,url --jq '.[0]' -``` - -**判定ロジック**: -- 結果が1件以上 + pr_number=null → pr_number={PR番号} -- 結果が0件 + pr_number=null → エラー(PRが見つからない場合) - -### 4. ワークフロー実行 - -modeに応じて、Taskツールで専用ワークフローを実行: - -#### A. create モード - -``` -Task - subagent_type: "general-purpose" - description: "PR作成フローを実行" - prompt: "以下のワークフローに従って、GitHub PRを作成してください。 - -{workflows/create.mdの内容を読み込んで展開} - -## 入力情報 -- カレントブランチ: {current_branch} -" -``` - -**workflows/create.mdを読み込んで実行**: Readツールで`workflows/create.md`を読み込み、その内容をpromptに含める。 - -#### B. resolve モード - -``` -Task - subagent_type: "general-purpose" - description: "レビュー対応フローを実行" - prompt: "以下のワークフローに従って、GitHub PRのレビューコメントに対応してください。 - -{workflows/resolve.mdの内容を読み込んで展開} - -## 入力情報 -- PR番号: {pr_number} -- カレントブランチ: {current_branch} -" -``` - -**workflows/resolve.mdを読み込んで実行** - -#### C. merge モード - -``` -Task - subagent_type: "general-purpose" - description: "マージフローを実行" - prompt: "以下のワークフローに従って、GitHub PRをマージしてください。 - -{workflows/merge.mdの内容を読み込んで展開} - -## 入力情報 -- PR番号: {pr_number} -" -``` - -**workflows/merge.mdを読み込んで実行** - -## 実装の注意点 - -1. **引数なしの場合**: PR検索結果に基づいて推奨オプションを提示し、AskUserQuestionでモードを選択(ユーザーフレンドリー) -2. **エラーハンドリング**: PRが見つからない場合やgh CLIが利用できない場合は、明確なエラーメッセージを表示 -3. **ブランチ確認**: mainブランチからcreateを実行しようとした場合はエラー -4. **Taskツールの使用**: 各ワークフローは別コンテキストで実行されるため、オーケストレーター側では結果を受け取るのみ - -## エラーハンドリング - -| エラー | 対応 | -|--------|------| -| gh CLIが利用不可 | `gh auth login`で認証を実行 | -| GitHubリポジトリでない | GitHubリポジトリであることを確認 | -| PR番号無効/PRが見つからない | 正しいPR番号を確認する | -| mainブランチからcreate実行 | feature/issueブランチから実行するよう案内 | - -詳細な使用例は`assets/examples.md`、APIリファレンスは`assets/reference.md`を参照してください。 +--- +name: pr +description: Unified orchestrator for GitHub PR operations (create/resolve/merge). Use with commands like "create PR", "respond to reviews", "merge PR". Supports subcommands (create/resolve/merge). Without PR number, automatically detects from current branch. +argument-hint: [create|resolve|merge] [PR number] +allowed-tools: Bash, Task, AskUserQuestion +--- + +# GitHub PR Unified Management (Orchestrator) + +This skill executes three GitHub PR operations in an integrated manner: +- **create**: Create PR from current branch to main +- **resolve**: Fix → Commit → Reply to unresolved review comments +- **merge**: Merge PR and cleanup branches + +Each operation executes a dedicated workflow in a separate context using the Task tool. + +## Execution Flow + +### 1. Argument Parsing + +Parse `$ARGUMENTS` to determine mode and PR number: + +```javascript +// Pattern 1: /pr → no args → Select mode with AskUserQuestion +// Pattern 2: /pr create → mode="create", pr_number=null +// Pattern 3: /pr resolve 123 → mode="resolve", pr_number=123 +// Pattern 4: /pr 123 → mode="resolve", pr_number=123 +// Pattern 5: /pr merge → mode="merge", pr_number=null +``` + +**When no arguments provided**: First search for PR from current branch to get context, then select mode with AskUserQuestion tool: +- Present recommended options based on PR search results +- Question: "Which PR operation would you like to execute?" +- Options (ordered by frequency, recommended option first): + 1. If PR exists: Show "Respond to reviews (resolve) (Recommended)" first + 2. If PR doesn't exist: Show "Create PR (create) (Recommended)" first + 3. Other options in frequency order: "Respond to reviews (resolve)", "Create PR (create)", "Merge (merge)" + +### 2. Get Repository Information + +```bash +gh repo view --json nameWithOwner -q .nameWithOwner +``` + +Output format: `owner/repo` + +### 3. Auto-detect PR (when pr_number=null) + +Search for PR from current branch: + +```bash +current_branch=$(git branch --show-current) +gh pr list --head "$current_branch" --json number,state --jq '.[0].number' +``` + +**Detection Logic**: +- Result exists + pr_number=null → pr_number={detected PR number} +- Result empty + pr_number=null → Continue if mode="create", otherwise error + +### 4. Execute Workflow + +Execute dedicated workflow with Task tool according to mode: + +#### A. create Mode + +``` +Task + subagent_type: "general-purpose" + description: "Execute PR creation flow" + prompt: "Please create a GitHub PR following the workflow below. + +{Load and expand contents of workflows/create.md} + +## Input Information +- Repository: {owner/repo} +- Current Branch: {current_branch} +" +``` + +**Load and execute workflows/create.md**: Use Read tool to load `workflows/create.md` and include its contents in the prompt. + +#### B. resolve Mode + +``` +Task + subagent_type: "general-purpose" + description: "Execute review response flow" + prompt: "Please respond to GitHub PR review comments following the workflow below. + +{Load and expand contents of workflows/resolve.md} + +## Input Information +- Repository: {owner/repo} +- PR Number: {pr_number} +- Current Branch: {current_branch} +" +``` + +**Load and execute workflows/resolve.md** + +#### C. merge Mode + +``` +Task + subagent_type: "general-purpose" + description: "Execute merge flow" + prompt: "Please merge the GitHub PR following the workflow below. + +{Load and expand contents of workflows/merge.md} + +## Input Information +- Repository: {owner/repo} +- PR Number: {pr_number} +" +``` + +**Load and execute workflows/merge.md** + +## Implementation Notes + +1. **When no arguments provided**: Present recommended options based on PR search results, select mode with AskUserQuestion (user-friendly) +2. **Error Handling**: Display clear error messages when repository information cannot be retrieved or PR search fails +3. **Branch Validation**: Error if attempting to execute create from main branch +4. **Task Tool Usage**: Each workflow executes in a separate context, orchestrator only receives results + +## Error Handling + +| Error | Response | +|-------|----------| +| gh CLI unavailable | Guide user to run `gh auth login` | +| Cannot get git remote | Verify repository is on GitHub | +| Invalid PR number / PR not found | Verify correct PR number | +| Execute create from main branch | Guide to execute from feature/issue branch | + +For detailed usage examples, see `assets/examples.md`. For reference, see `assets/reference.md`. diff --git a/.claude/skills/pr/assets/examples.md b/.claude/skills/pr/assets/examples.md index 4224173..2fcf9ac 100644 --- a/.claude/skills/pr/assets/examples.md +++ b/.claude/skills/pr/assets/examples.md @@ -1,245 +1,464 @@ -# PR スキル使用例 - -このドキュメントでは、prスキルの実際の使用例を示します。 - -## 基本的な使い方 - -### 1. PR作成 - -**最もシンプルな使用法**: -``` -/pr create -``` - -または単に: -``` -PR作って -``` - -以下のことが自動的に実行されます: -1. カレントブランチの確認 -2. コミット履歴の分析 -3. PRタイトルと説明の生成 -4. リモートへのプッシュ(必要な場合) -5. PRの作成 - -**実行例**: -``` -## PR作成完了 - -**PR**: https://github.com/owner/repo/pull/123 -**ブランチ**: feature/add-user-auth → main -**タイトル**: feat: ユーザー認証機能を追加 - -レビュアーにレビューを依頼してください。 -``` - -### 2. レビュー対応 - -**PR番号を指定**: -``` -/pr resolve 123 -``` - -**PR番号を省略(カレントブランチから自動検索)**: -``` -/pr resolve -``` - -または単に: -``` -レビュー対応して -``` - -以下のことが自動的に実行されます: -1. PRのレビューコメントを取得 -2. 各コメントを分析し、修正内容を判断 -3. ファイルを修正 -4. コミット・プッシュ -5. レビュアーにリプライ - -**実行例**: -``` -## PRレビュー対応完了 - -**PR**: https://github.com/owner/repo/pull/123 - -### 結果 -- 修正してリプライ: 3件 -- 質問してリプライ: 1件 -- スキップ: 0件 - -レビュアーによる確認をお願いします。 -``` - -### 3. マージ - -**PR番号を指定**: -``` -/pr merge 123 -``` - -**PR番号を省略(カレントブランチから自動検索)**: -``` -/pr merge -``` - -または単に: -``` -マージして -``` - -以下のことが自動的に実行されます: -1. PRの状態確認 -2. ユーザーに最終確認 -3. PRのマージ -4. リモートブランチの削除 -5. ローカルブランチの削除 -6. mainブランチへの切り替えと更新 - -**実行例**: -``` -## マージ完了 - -**PR**: https://github.com/owner/repo/pull/123 -**ブランチ**: feature/add-user-auth → main - -### 実行内容 -- PRをマージしました -- リモートブランチ 'feature/add-user-auth' を削除しました -- ローカルブランチ 'feature/add-user-auth' を削除しました -- ブランチを 'main' に切り替えました -- 最新のコードを取得しました - -お疲れ様でした。 -``` - -## 高度な使い方 - -### モード選択(引数なし) - -``` -/pr -``` - -カレントブランチの状態に応じて、推奨される操作を提示します: - -**PRが存在する場合**: -``` -どのPR操作を実行しますか? - -1. レビュー対応 (resolve) (推奨) -2. PR作成 (create) -3. マージ (merge) -``` - -**PRが存在しない場合**: -``` -どのPR操作を実行しますか? - -1. PR作成 (create) (推奨) -2. レビュー対応 (resolve) -3. マージ (merge) -``` - -### 数値のみでresolveモード - -``` -/pr 123 -``` - -PR番号を指定すると、自動的にresolveモードで実行されます。 - -## 実際のワークフロー - -### ワークフロー例1: 新機能の追加 - -``` -# 1. ブランチ作成・作業 -/git branch-create feature/add-payment - -# 2. コード編集 -(ファイルを編集) - -# 3. コミット -/git commit - -# 4. PR作成 -/pr create - -# 5. レビュー対応 -/pr resolve - -# 6. マージ -/pr merge -``` - -### ワークフロー例2: バグ修正 - -``` -# 1. ブランチ作成・作業 -/git branch-create fix/login-timeout - -# 2. コード修正 -(ファイルを編集) - -# 3. コミット・PR作成 -/git commit -/pr create - -# 4. レビュー後にマージ -/pr merge -``` - -## エラーケースの対処 - -### mainブランチから誤ってPR作成しようとした場合 - -``` -/pr create - -エラー: mainブランチからPRは作成できません。 -feature/issueブランチを作成してから実行してください。 -``` - -対処: -``` -/git branch-create feature/my-feature -/pr create -``` - -### コミットがない状態でPR作成しようとした場合 - -``` -/pr create - -エラー: mainからの新しいコミットがありません。 -変更をコミットしてから実行してください。 -``` - -対処: -``` -/git commit -/pr create -``` - -### PRが見つからない場合 - -``` -/pr resolve - -エラー: カレントブランチのPRが見つかりませんでした。 -PR番号を指定するか、正しいブランチに切り替えてください。 -``` - -対処: -``` -/pr resolve 123 -``` - -## Tips - -1. **自然言語で呼び出し**: `/pr create`の代わりに「PR作って」でもOK -2. **PR番号の省略**: カレントブランチから自動検索されるため、ほとんどの場合PR番号は不要 -3. **レビュー対応の自動化**: 明確な修正指示は自動で対応し、不明点のみ質問 -4. **一括クリーンアップ**: マージ時にリモート・ローカルブランチを自動削除 +# GitHub PR Skill - Usage Examples + +This document introduces practical usage examples of the pr skill. + +## Basic Usage Examples + +### 1. Create PR + +#### Scenario: Implement login functionality on feature/add-login branch and create PR + +```bash +# Switch to working branch +git checkout feature/add-login + +# Commit changes (assuming already completed) +git add . +git commit -m "feat: Add login functionality" + +# Create PR +/pr create +``` + +**Execution Details**: +1. Check current branch (feature/add-login) +2. Analyze commit history and auto-generate title and description +3. Push to remote (if necessary) +4. Create PR on GitHub + +**Example Output**: +``` +## PR Created + +**PR**: https://github.com/owner/repo/pull/123 +**Branch**: feature/add-login → main +**Title**: Add login functionality + +Please request a review from reviewers. +``` + +### 2. Auto-Detection PR Creation + +#### Scenario: Execute without arguments, automatically create if PR doesn't exist + +```bash +# Changes already made on working branch +/pr +``` + +**Execution Details**: +1. Search for PR of current branch +2. PR doesn't exist → Automatically switch to create mode +3. Create PR + +### 3. Review Comment Response + +#### Scenario: Respond to review comments on current branch's PR + +```bash +# Execute on branch with review comments +/pr +``` + +**Execution Details**: +1. Search for PR of current branch +2. PR exists → Automatically switch to resolve mode +3. Retrieve unresolved review comments +4. Analyze each comment, fix → commit → reply + +**Example Output**: +``` +## PR Review Response Complete + +**PR**: https://github.com/owner/repo/pull/123 + +### Results +- Fixed and replied: 3 items +- Questioned and replied: 1 item +- Skipped: 0 items + +Please request reviewer to resolve threads +``` + +### 4. Respond to Specific PR Review Comments + +#### Scenario: Specify PR number to respond to review comments + +```bash +# Execute from any branch +/pr 123 +``` + +Or + +```bash +/pr resolve 123 +``` + +**Execution Details**: +1. Retrieve information for PR #123 +2. If current branch differs from PR source branch, confirm checkout +3. Respond to unresolved review comments + +### 5. Merge + +#### Scenario: Merge PR after review completion + +```bash +# Execute on PR source branch +/pr merge +``` + +Or + +```bash +# Specify PR number +/pr merge 123 +``` + +**Execution Details**: +1. Check PR status (OPEN, MERGEABLE, review approved) +2. Check CI/CD check status +3. Final confirmation with user +4. Merge PR +5. Delete remote branch (automatic on GitHub side) +6. Delete local branch and switch to main + +**Example Output**: +``` +## Merge Complete + +**PR**: https://github.com/owner/repo/pull/123 +**Branch**: feature/add-login → main + +### Actions Performed +- Merged PR +- Deleted remote branch 'feature/add-login' (automatically deleted by GitHub) +- Deleted local branch 'feature/add-login' +- Switched to branch 'main' +- Fetched latest code + +Good work! +``` + +## Advanced Usage Examples + +### 6. Handle Multiple Review Comments + +#### Scenario: 5 review comments exist, each requiring different response + +**Comment 1**: Clear fix instruction +``` +Reviewer: "Error handling is missing here" +→ Claude automatically fixes, commits, and replies +``` + +**Comment 2**: Unclear instruction +``` +Reviewer: "Please improve performance" +→ Claude replies with question: "Which specific part's performance is concerning?" +``` + +**Comment 3**: Difficult instruction to address +``` +Reviewer: "Please completely review the architecture" +→ Claude confirms with user: "How should this feedback be addressed?" + - Fix / Ask question / Skip +``` + +**Comment 4 & 5**: Fixes to same file +``` +→ Claude combines both fixes into a single commit +``` + +### 7. Branch Switch Required Case + +#### Scenario: Respond to specific PR from another branch + +```bash +# Currently on main branch +git branch --show-current +# main + +# Execute review comment response for PR #123 +/pr 123 +``` + +**Execution Details**: +1. Detect that PR #123's source branch is `feature/fix-bug` +2. Detect difference from current branch (main) +3. Confirm with AskUserQuestion: + ``` + Current branch 'main' differs from PR source branch 'feature/fix-bug'. + Checkout 'feature/fix-bug'? + + - Yes, checkout + - No, continue as-is + ``` +4. Select "Yes" → Execute `git checkout feature/fix-bug` +5. Continue review comment response + +### 8. Error Response Examples + +#### Case 1: Attempted to create PR from main branch + +```bash +git checkout main +/pr create +``` + +**Output**: +``` +Error: Cannot create PR from main branch. +Please create a feature/issue branch before executing. +``` + +#### Case 2: Attempting to create PR without commits + +```bash +git checkout feature/empty-branch +/pr create +``` + +**Output**: +``` +Error: No new commits from main. +Please commit changes before executing. +``` + +#### Case 3: Attempting to merge when not mergeable + +```bash +/pr merge 123 +``` + +**Output**: +``` +Error: PR is not in a mergeable state + +Please check the following: +- PR is OPEN +- No merge conflicts (mergeable: CONFLICTING) +- Required review approvals obtained +- All CI/CD checks successful +``` + +## Real Workflow Examples + +### Full Cycle: Feature Development to Merge + +```bash +# 1. Create new feature branch +git checkout -b feature/user-profile + +# 2. Implement feature +# (write code) + +# 3. Commit +git add . +git commit -m "feat: Add user profile feature" + +# 4. Create PR +/pr create +# → PR created: https://github.com/owner/repo/pull/150 + +# 5. Reviewer comments +# (review performed on GitHub) + +# 6. Respond to review comments +/pr resolve +# → 3 fixes implemented and replies completed + +# 7. Reviewer approves +# (approved on GitHub) + +# 8. Merge +/pr merge +# → Merge complete, branch cleanup complete +``` + +### Team Development Tips + +1. **Self-check before review**: + ```bash + # Check code yourself once after PR creation + gh pr view --web + ``` + +2. **Priority during review comment response**: + - Start with simple fixes (typos, formatting, etc.) + - Defer complex fixes, ask questions as needed + +3. **Pre-merge confirmation**: + ```bash + # Check CI/CD check status + gh pr checks + + # Merge + /pr merge + ``` + +## GitHub-Specific Feature Examples + +### Create Draft PR + +```bash +# Create as draft PR (for sharing before review) +gh pr create --draft --title "WIP: Developing new feature" --body "Still work in progress" +``` + +### Specify Reviewers + +```bash +# Specify reviewers when creating PR +gh pr create --reviewer "@octocat,@github" +``` + +### Add Labels + +```bash +# Add labels to PR +gh pr edit 123 --add-label "bug,priority:high" +``` + +### Set Milestone + +```bash +# Set milestone for PR +gh pr edit 123 --milestone "v2.0" +``` + +## CI/CD Integration Examples + +### 1. Handling Test Failures + +```bash +# Check PR check status +gh pr checks 123 + +# Re-run specific workflow +gh run rerun 456789 + +# Run tests locally +npm test +``` + +### 2. Auto-Merge Configuration + +```bash +# Auto-merge after checks succeed +gh pr merge 123 --auto --squash --delete-branch +``` + +## Customization Examples + +### Project-Specific PR Template + +By placing `.github/pull_request_template.md` in the project, you can set a default template for PR creation: + +```markdown +## Summary + + +## Changes +- [ ] Feature addition +- [ ] Bug fix +- [ ] Refactoring + +## Testing +- [ ] Unit tests added +- [ ] Manual testing completed + +## Review Points + + +## Related Issues +Closes # +``` + +### Automatic Test Execution + +Customize to automatically run tests after review response: + +```bash +# Customize workflows/resolve.md +# Add the following after fixes: +echo "Running related tests..." +npm test -- --related "$modified_file" +``` + +### Slack Notification Integration + +Configure Slack notifications using GitHub Actions or Webhooks: + +```yaml +# .github/workflows/pr-notification.yml +name: PR Notification +on: + pull_request: + types: [opened, ready_for_review] +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Send Slack notification + uses: slackapi/slack-github-action@v1 + with: + payload: | + { + "text": "New PR: ${{ github.event.pull_request.title }}" + } +``` + +## Troubleshooting Examples + +### Authentication Error + +```bash +# Check authentication status +gh auth status + +# Re-authenticate +gh auth login + +# Check token permissions +gh auth status -t +``` + +### PR Not Found + +```bash +# List all PRs +gh pr list --state all + +# Search for PR of specific branch +gh pr list --head feature/my-branch +``` + +### Merge Conflict + +```bash +# Fetch latest from base branch +git fetch origin main + +# Merge base branch +git merge origin/main + +# Resolve conflicts +# (manual fix) + +# Commit and push +git add . +git commit -m "Resolve merge conflicts" +git push +``` + +## Best Practices + +1. **Small PRs**: Keep changes small and easy to review +2. **Clear Titles**: PR titles should clearly express the changes +3. **Detailed Description**: Explain why the change is necessary +4. **Add Tests**: Always add tests corresponding to changes +5. **Continuous Communication**: Value dialogue with reviewers + +For detailed customization methods, refer to the Claude Code official documentation. diff --git a/.claude/skills/pr/assets/reference.md b/.claude/skills/pr/assets/reference.md index 46ec0db..1123609 100644 --- a/.claude/skills/pr/assets/reference.md +++ b/.claude/skills/pr/assets/reference.md @@ -1,327 +1,376 @@ -# PR スキル APIリファレンス - -このドキュメントでは、prスキルの技術的な詳細を説明します。 - -## コマンド構文 - -``` -/pr [mode] [pr_number] -``` - -### パラメータ - -- `mode`: 実行モード(`create`, `resolve`, `merge`)。省略可能。 -- `pr_number`: PR番号。省略可能(カレントブランチから自動検索)。 - -### モードの判定ロジック - -```javascript -// パターン1: /pr → 引数なし -// → PR検索 → AskUserQuestionでモード選択 -if (args === null) { - const pr = searchPRForCurrentBranch(); - const mode = askUserQuestion(pr ? "resolve" : "create"); -} - -// パターン2: /pr create -// → mode="create", pr_number=null -if (args === "create") { - mode = "create"; - pr_number = null; -} - -// パターン3: /pr resolve 123 -// → mode="resolve", pr_number=123 -if (args.startsWith("resolve ")) { - mode = "resolve"; - pr_number = parseInt(args.split(" ")[1]); -} - -// パターン4: /pr 123 -// → mode="resolve", pr_number=123 -if (/^\d+$/.test(args)) { - mode = "resolve"; - pr_number = parseInt(args); -} - -// パターン5: /pr merge -// → mode="merge", pr_number=null -if (args === "merge") { - mode = "merge"; - pr_number = null; -} -``` - -## GitHub CLI コマンド - -prスキルが内部で使用するgh CLIコマンド一覧。 - -### リポジトリ情報取得 - -```bash -# リポジトリの情報を取得 -gh repo view --json defaultBranchRef,owner,name - -# デフォルトブランチ名のみ取得 -gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' -``` - -### PR一覧取得 - -```bash -# カレントブランチのPRを検索 -gh pr list --head "{branch_name}" --state open --json number,title,url --jq '.[0]' - -# 全てのopenなPRを取得 -gh pr list --state open --json number,title,headRefName,url -``` - -### PR情報取得 - -```bash -# PR詳細を取得 -gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,author,mergeable,mergeStateStatus - -# PRのコメントとレビューを取得 -gh pr view {pr_number} --json comments,reviews -``` - -### PR作成 - -```bash -gh pr create \ - --title "{title}" \ - --body "{body}" \ - --base {base_branch} \ - --head {head_branch} -``` - -### PRコメント - -```bash -gh pr comment {pr_number} --body "{comment_body}" -``` - -### PRマージ - -```bash -# Squashマージ(リモートブランチを自動削除) -gh pr merge {pr_number} --squash --delete-branch - -# 通常のマージ -gh pr merge {pr_number} --merge --delete-branch - -# Rebaseマージ -gh pr merge {pr_number} --rebase --delete-branch -``` - -## 内部データ構造 - -### PR情報 - -```json -{ - "number": 123, - "title": "feat: ユーザー認証機能を追加", - "state": "OPEN", - "headRefName": "feature/add-user-auth", - "baseRefName": "main", - "url": "https://github.com/owner/repo/pull/123", - "author": { - "login": "username" - }, - "mergeable": "MERGEABLE", - "mergeStateStatus": "CLEAN" -} -``` - -### レビュー情報 - -```json -{ - "reviews": [ - { - "author": { - "login": "reviewer" - }, - "state": "CHANGES_REQUESTED", - "body": "レビューコメント本文", - "createdAt": "2024-01-01T12:00:00Z", - "comments": [ - { - "path": "src/auth.ts", - "line": 42, - "body": "変数名をより明確にしてください" - } - ] - } - ] -} -``` - -## ワークフロー実行 - -各モードは、Taskツールで専用ワークフローを実行します。 - -### create モード - -``` -Task - subagent_type: "general-purpose" - description: "PR作成フローを実行" - prompt: """ -以下のワークフローに従って、GitHub PRを作成してください。 - -{workflows/create.mdの内容} - -## 入力情報 -- カレントブランチ: {current_branch} -""" -``` - -### resolve モード - -``` -Task - subagent_type: "general-purpose" - description: "レビュー対応フローを実行" - prompt: """ -以下のワークフローに従って、GitHub PRのレビューコメントに対応してください。 - -{workflows/resolve.mdの内容} - -## 入力情報 -- PR番号: {pr_number} -- カレントブランチ: {current_branch} -""" -``` - -### merge モード - -``` -Task - subagent_type: "general-purpose" - description: "マージフローを実行" - prompt: """ -以下のワークフローに従って、GitHub PRをマージしてください。 - -{workflows/merge.mdの内容} - -## 入力情報 -- PR番号: {pr_number} -""" -``` - -## エラーコード - -| エラーコード | 説明 | 対応 | -|------------|------|------| -| GH_AUTH_ERROR | gh CLI認証エラー | `gh auth login`を実行 | -| GH_NOT_FOUND | gh CLIが見つからない | gh CLIをインストール | -| REPO_NOT_GITHUB | GitHubリポジトリでない | GitHubリポジトリで実行 | -| BRANCH_INVALID | ブランチが不正 | 正しいブランチから実行 | -| PR_NOT_FOUND | PRが見つからない | PR番号を確認 | -| PR_CLOSED | PRがCLOSEDまたはMERGED | OPENのPRを指定 | -| PR_CONFLICT | マージコンフリクト | コンフリクトを解決 | -| NO_COMMITS | コミットがない | 変更をコミット | -| PUSH_REJECTED | プッシュが拒否された | `git pull --rebase`して再プッシュ | - -## 設定 - -prスキルは、以下の環境変数を使用できます(将来的な拡張): - -```bash -# デフォルトのマージ方法(squash/merge/rebase) -export PR_MERGE_METHOD="squash" - -# PR作成時のレビュアー自動割り当て -export PR_DEFAULT_REVIEWERS="user1,user2" - -# PR作成時のラベル自動付与 -export PR_DEFAULT_LABELS="enhancement,needs-review" -``` - -## 制限事項 - -1. **gh CLI依存**: GitHub CLIが必須 -2. **認証**: `gh auth login`で認証済みであること -3. **権限**: リポジトリへの書き込み権限が必要 -4. **ブランチ保護**: 保護ブランチへのマージは追加の権限設定が必要 -5. **レビューコメント**: ファイル単位のコメントのみ対応(行コメントも取得可能だが、複雑な場合は手動対応を推奨) - -## トラブルシューティング - -### gh CLIが見つからない - -```bash -# インストール(macOS) -brew install gh - -# インストール(Linux) -sudo apt install gh - -# 認証 -gh auth login -``` - -### 認証エラー - -```bash -# 認証状態を確認 -gh auth status - -# 再認証 -gh auth login - -# トークンを使用 -gh auth login --with-token < token.txt -``` - -### PR番号がわからない - -```bash -# カレントブランチのPRを確認 -gh pr view - -# 全てのPRを一覧表示 -gh pr list -``` - -## 開発者向け情報 - -### スキル構造 - -``` -.claude/skills/pr/ -├── SKILL.md # スキルのメタ情報とオーケストレーター -├── workflows/ -│ ├── create.md # PR作成ワークフロー -│ ├── resolve.md # レビュー対応ワークフロー -│ └── merge.md # マージワークフロー -└── assets/ - ├── examples.md # 使用例 - └── reference.md # このファイル -``` - -### 拡張方法 - -新しいモードを追加する場合: -1. `workflows/`に新しいワークフローファイルを追加 -2. `SKILL.md`の引数解析ロジックに新しいモードを追加 -3. `SKILL.md`のワークフロー実行セクションに新しいモードを追加 -4. `assets/examples.md`に使用例を追加 - -### テスト - -各ワークフローは独立しているため、個別にテスト可能: - -```bash -# PR作成のテスト -/pr create - -# レビュー対応のテスト(PRが存在する場合) -/pr resolve - -# マージのテスト(PRがマージ可能な場合) -/pr merge -``` +# GitHub PR Skill - Detailed Reference + +This document describes the detailed technical specifications and workflows of the pr skill. + +## Table of Contents + +1. [GitHub CLI Terminology](#github-cli-terminology) +2. [Retrieving Repository Information](#retrieving-repository-information) +3. [Review Comment Processing Details](#review-comment-processing-details) +4. [Error Handling Details](#error-handling-details) +5. [Permission Requirements](#permission-requirements) + +## GitHub CLI Terminology + +### Review Related +- **Review**: A review on a PR (APPROVE, REQUEST_CHANGES, COMMENT) +- **Review Thread**: A thread of review comments +- **Comment**: Individual comment +- **Resolved/Unresolved**: Resolved/unresolved status +- **Outdated**: Comments on old commits + +### PR Related +- **Number**: PR number (e.g., #123) +- **State**: PR state (OPEN, CLOSED, MERGED) +- **Mergeable**: Mergeability (MERGEABLE, CONFLICTING, UNKNOWN) +- **ReviewDecision**: Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED) + +## Retrieving Repository Information + +### Retrieving Basic Information + +```bash +# Get repository in owner/repo format +gh repo view --json nameWithOwner -q .nameWithOwner +# Example output: "octocat/Hello-World" + +# Get default branch +gh repo view --json defaultBranchRef -q .defaultBranchRef.name +# Example output: "main" + +# Get repository URL +gh repo view --json url -q .url +# Example output: "https://github.com/octocat/Hello-World" +``` + +### Retrieving PR Information + +```bash +# Get PR information (JSON format) +gh pr view 123 --json number,title,state,headRefName,baseRefName,url,mergeable,reviewDecision + +# Example output: +{ + "number": 123, + "title": "Add new feature", + "state": "OPEN", + "headRefName": "feature/new-feature", + "baseRefName": "main", + "url": "https://github.com/octocat/Hello-World/pull/123", + "mergeable": "MERGEABLE", + "reviewDecision": "APPROVED" +} +``` + +### Retrieving PR List + +```bash +# Search for PR of current branch +gh pr list --head "$(git branch --show-current)" --json number,state + +# Filter by state +gh pr list --state open --json number,title +gh pr list --state merged --json number,title +``` + +## Review Comment Processing Details + +### Retrieving Review Threads + +```bash +# Get review threads +gh pr view 123 --json reviewThreads +``` + +Response structure: +```json +{ + "reviewThreads": [ + { + "id": "RT_abc123", + "isResolved": false, + "isOutdated": false, + "path": "src/main.js", + "line": 42, + "comments": [ + { + "id": "RC_def456", + "body": "Please improve this logic", + "author": { + "login": "reviewer" + }, + "createdAt": "2026-02-10T10:00:00Z" + } + ] + } + ] +} +``` + +### Filtering Conditions + +Extracting unresolved review comments: + +```javascript +const unresolvedComments = reviewThreads.filter(thread => { + // Must be unresolved + if (thread.isResolved !== false) return false; + + // Must not be a comment on an old commit + if (thread.isOutdated !== false) return false; + + // Must be a comment on a file (not a general comment) + if (!thread.path) return false; + + // Must have comments + if (!thread.comments || thread.comments.length === 0) return false; + + return true; +}); +``` + +### Replying to Comments + +**Comment on entire PR**: +```bash +gh pr comment 123 --body "Fixed. Please review." +``` + +**Reply to specific review comment** (advanced operation): +```bash +# Using GitHub API +gh api \ + "repos/{owner}/{repo}/pulls/123/comments/{comment_id}/replies" \ + -f body="Fixed. Please review." +``` + +### Resolving Review Threads + +GitHub CLI does not have a direct resolve feature, so use the following methods: + +1. **Request reviewer to resolve** (recommended) + - Report completion of fix in comment + - Reviewer resolves the thread + +2. **Use GitHub API** (advanced operation) + ```bash + # Thread ID required + gh api \ + "repos/{owner}/{repo}/pulls/123/threads/{thread_id}" \ + -X PATCH \ + -f resolved=true + ``` + +## Error Handling Details + +### Handling Push Failures + +```bash +# When push is rejected +git push +# error: failed to push some refs to 'origin' + +# Solution 1: Rebase +git pull --rebase origin "$(git branch --show-current)" +git push + +# Solution 2: Merge (if there are conflicts) +git pull origin "$(git branch --show-current)" +# Resolve conflicts +git add . +git commit +git push + +# Solution 3: Force push (use with caution) +# Not recommended for PRs under review +git push --force-with-lease +``` + +### Handling Merge Conflicts + +```bash +# Check for conflicts before merge +git fetch origin main +git merge-base --is-ancestor origin/main HEAD +echo $? # If not 0, merge is needed + +# Resolve conflicts +git merge origin/main +# Manually resolve conflicts +git add . +git commit -m "Resolve merge conflicts" +git push +``` + +### Authentication Errors + +```bash +# Check GitHub CLI authentication status +gh auth status + +# Authentication (via browser) +gh auth login + +# Authentication (via token) +gh auth login --with-token < token.txt + +# Required scopes: +# - repo: Full access +# - read:org: Read organization information +# - workflow: GitHub Actions (optional) +``` + +### Handling Branch Deletion Failures + +```bash +# When local branch deletion fails +git branch -d feature/my-branch +# error: The branch is not fully merged. + +# Verify: Check if merge is complete +git log main..feature/my-branch +# If no output, it's merged + +# Force delete +git branch -D feature/my-branch +``` + +## Permission Requirements + +### Permissions Required for PR Creation + +| Operation | Minimum Permission | Description | +|------|---------|------| +| Push to branch | Write | Write access to repository | +| Create PR | Write | Permission to create PR | + +### Permissions Required for Review Comment Response + +| Operation | Minimum Permission | Description | +|------|---------|------| +| View review comments | Read | View PR and comments | +| Add comments | Write | Add comments to PR | +| Push to branch | Write | Push fix content | +| Resolve thread | Write | Reviewer or PR author | + +### Permissions Required for Merge + +| Operation | Minimum Permission | Description | +|------|---------|------| +| Merge PR | Write | Depends on repository settings | +| Delete branch | Write | Delete remote branch | + +**Note**: Merging to protected branches requires additional settings (required number of reviews, check requirements, etc.). + +## Performance Optimization + +### Batch Processing + +When processing multiple review comments, consider the following: + +1. **Cache file reads**: If there are multiple comments on the same file, reuse once loaded +2. **Batch commits**: Combine related fixes into one commit +3. **Optimize pushes**: After making multiple fixes, push only once at the end + +### Utilizing JSON Output + +```bash +# Get only necessary fields (using jq filter) +gh pr view 123 --json number,state,headRefName -q '{number, state, head: .headRefName}' + +# Process arrays +gh pr list --json number,title --jq '.[] | select(.title | contains("feat"))' +``` + +## Troubleshooting + +### Skill Does Not Start + +1. Verify GitHub CLI is properly installed: `gh --version` +2. Verify authentication is complete: `gh auth status` +3. Verify `allowed-tools` contains necessary tools + +### PR Not Found + +1. Verify current branch is correct: `git branch --show-current` +2. Verify pushed to remote: `git log @{u}..HEAD` +3. Verify PR actually exists on GitHub: `gh pr list` + +### Cannot Retrieve Review Comments + +1. Verify PR number is correct +2. Verify PR is opened +3. Verify you have permissions (Read or higher) + +### Cannot Push Commit + +1. Check branch protection rules +2. Verify remote is up to date: `git fetch && git status` +3. Check for conflicts: `git pull --rebase` + +## Best Practices + +1. **Start with small fixes**: Handle simple fixes first, defer complex comments +2. **Run tests**: Always run related tests after fixes +3. **Commit messages**: Summarize the content of review feedback +4. **Ask clear questions**: When in doubt, ask specific questions +5. **Backup**: For important changes, create local backup branch before merge + +## Advanced GitHub CLI Features + +### Retrieving Custom Fields + +```bash +# Get custom fields via GraphQL +gh api graphql -f query=' + query($owner: String!, $repo: String!, $number: Int!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: $number) { + reviewThreads(first: 100) { + nodes { + id + isResolved + path + line + comments(first: 10) { + nodes { + body + author { + login + } + } + } + } + } + } + } + } +' -f owner=octocat -f repo=Hello-World -F number=123 +``` + +### Webhook Configuration + +```bash +# Configure webhook for PR events +gh api repos/{owner}/{repo}/hooks \ + -f name=web \ + -f config[url]=https://example.com/webhook \ + -f events[]=pull_request \ + -f events[]=pull_request_review +``` + +### Actions Integration + +```bash +# Check workflows related to PR +gh run list --workflow=CI --json status,conclusion + +# Rerun specific workflow +gh run rerun 123456 +``` + +## References + +- [GitHub CLI Official Documentation](https://cli.github.com/manual/) +- [GitHub API v4 (GraphQL)](https://docs.github.com/graphql) +- [GitHub PR Review API](https://docs.github.com/rest/pulls/reviews) diff --git a/.claude/skills/pr/workflows/create.md b/.claude/skills/pr/workflows/create.md index eac4440..1effdaa 100644 --- a/.claude/skills/pr/workflows/create.md +++ b/.claude/skills/pr/workflows/create.md @@ -1,126 +1,151 @@ -# PR作成ワークフロー - -このワークフローは、カレントブランチからmainへのPRを作成します。 - -## 必要なツール - -- Bash -- Read - -## 実行ステップ - -### 1. 事前確認 - -**1.1 カレントブランチの確認** - -```bash -git branch --show-current -``` - -カレントブランチが`main`または`master`の場合はエラー終了: -``` -エラー: mainブランチからPRは作成できません。 -feature/issueブランチを作成してから実行してください。 -``` - -**1.2 デフォルトブランチの取得** - -```bash -gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' -``` - -デフォルトブランチ名を取得(通常は"main"または"master")。 - -**1.3 コミット履歴の確認** - -```bash -git log {default_branch}..HEAD --oneline -``` - -コミットがない場合はエラー終了: -``` -エラー: {default_branch}からの新しいコミットがありません。 -変更をコミットしてから実行してください。 -``` - -**1.4 リモートへのプッシュ確認** - -```bash -git status -``` - -"Your branch is ahead of"または"branch and 'origin/xxx' have diverged"がある場合、プッシュが必要: -```bash -git push -u origin {current_branch} -``` - -プッシュが失敗(rejected)した場合: -```bash -git pull --rebase origin {current_branch} -git push -``` - -### 2. PRタイトルと説明を生成 - -**2.1 コミット履歴とdiffを取得** - -```bash -git log {default_branch}..HEAD --format="%s" -git diff {default_branch}...HEAD --stat -``` - -**2.2 タイトルと説明の生成** - -コミット履歴とdiffを分析し、以下の形式で生成: - -**タイトル**: 主要な変更を要約(70文字以内) -- 例: "feat: ユーザー認証機能を追加" -- 例: "fix: ログイン時のセッションタイムアウトを修正" - -**説明**: -```markdown -## 変更概要 -{変更の目的と内容を1-3文で説明} - -## 変更内容 -{主要な変更点を箇条書き} - -## テスト -- [ ] 動作確認完了 -- [ ] テスト追加/更新(必要な場合) -``` - -### 3. PR作成 - -生成したタイトルと説明でPRを作成: - -```bash -gh pr create --title "{generated_title}" --body "{generated_description}" --base {default_branch} --head {current_branch} -``` - -### 4. 結果表示 - -``` -## PR作成完了 - -**PR**: {pr_url} -**ブランチ**: {source_branch} → {target_branch} -**タイトル**: {title} - -レビュアーにレビューを依頼してください。 -``` - -## エラーハンドリング - -| エラー | 対応 | -|--------|------| -| mainブランチから実行 | feature/issueブランチから実行するよう案内 | -| コミットがない | 変更をコミットしてから実行するよう案内 | -| プッシュ失敗 | `git pull --rebase`して再プッシュ | -| gh CLI認証エラー | `gh auth login`で認証 | - -## 注意事項 - -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **タイトルの品質**: コミットメッセージが不適切な場合、自分で適切なタイトルを生成 -3. **gh CLI**: GitHub CLIが必要。未インストールの場合はインストールを案内 +# PR Creation Workflow + +This workflow creates a PR from the current branch to main. + +## Required Tools + +- Bash +- Read + +## Execution Steps + +### 1. Pre-flight Checks + +**1.1 Verify Current Branch** + +```bash +git branch --show-current +``` + +If current branch is `main` or `master`, exit with error: +``` +Error: Cannot create PR from main branch. +Please create a feature/issue branch first. +``` + +**1.2 Get Default Branch** + +```bash +default_branch=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name) +``` + +**1.3 Check Commit History** + +```bash +git log "$default_branch"..HEAD --oneline +``` + +If no commits exist, exit with error: +``` +Error: No new commits from {default_branch}. +Please commit your changes first. +``` + +**1.4 Verify Remote Push** + +```bash +git status +``` + +If "Your branch is ahead of" or "have diverged" appears, push is needed: +```bash +git push -u origin "$(git branch --show-current)" +``` + +If push fails (rejected): +```bash +git pull --rebase origin "$(git branch --show-current)" +git push +``` + +### 2. Generate PR Title and Description + +**2.1 Get Commit History and Diff** + +```bash +git log "$default_branch"..HEAD --format="%s" +git diff "$default_branch"...HEAD --stat +``` + +**2.2 Generate Title and Description** + +Analyze commit history and diff, generate in the following format: + +**Title**: Summarize main changes (within 70 characters) +- Example: "feat: Add user authentication feature" +- Example: "fix: Fix session timeout on login" + +**Description**: +```markdown +## Summary +{Describe purpose and content of changes in 1-3 sentences} + +## Changes +{List main changes as bullet points} + +## Testing +- [ ] Manual testing completed +- [ ] Tests added/updated (if needed) + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +``` + +### 3. Create PR + +Create PR with generated title and description: + +```bash +gh pr create \ + --title "{generated_title}" \ + --body "{generated_description}" \ + --base "$default_branch" \ + --head "$current_branch" +``` + +### 4. Display Result + +``` +## PR Creation Complete + +**PR**: {pr_url} +**Branch**: {source_branch} → {target_branch} +**Title**: {title} + +Please request review from reviewers. +``` + +## Error Handling + +| Error | Response | +|-------|----------| +| Execute from main branch | Guide to execute from feature/issue branch | +| No commits | Guide to commit changes first | +| Push failure | `git pull --rebase` and retry push | +| Authentication error | Authenticate with `gh auth login` | + +## Notes + +1. **Emoji Usage**: Do not use emojis unless user explicitly requests them +2. **GitHub Permissions**: Requires Write or higher permissions +3. **Title Quality**: Generate appropriate title if commit messages are inadequate +4. **HEREDOC Usage**: Use HEREDOC for multi-line PR body to ensure correct formatting + +### HEREDOC Usage Example + +```bash +gh pr create \ + --title "feat: Add user authentication" \ + --body "$(cat <<'EOF' +## Summary +Added user authentication feature. + +## Changes +- Implemented login form +- Added session management + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +EOF +)" \ + --base main \ + --head feature/auth +``` diff --git a/.claude/skills/pr/workflows/merge.md b/.claude/skills/pr/workflows/merge.md index 9d993ad..9aea41c 100644 --- a/.claude/skills/pr/workflows/merge.md +++ b/.claude/skills/pr/workflows/merge.md @@ -1,118 +1,172 @@ -# マージワークフロー - -このワークフローは、PRをマージし、ブランチをクリーンアップします。 - -## 必要なツール - -- Bash -- AskUserQuestion -- Skill (gitスキルを使用) - -## 実行ステップ - -### 1. PR情報取得と確認 - -**1.1 PR情報を取得** - -```bash -gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,mergeable,mergeStateStatus,statusCheckRollup -``` - -**1.2 マージ可能性チェック** - -以下をすべて確認: -- `state === "OPEN"` -- `mergeable === "MERGEABLE"` -- すべてのステータスチェックが成功している - -いずれかが満たされない場合、エラーメッセージを表示して終了: - -``` -エラー: PRはマージできない状態です - -以下を確認してください: -- PRがOPENであること -- マージコンフリクトがないこと(mergeable: {actual_status}) -- CI/CDパイプラインが成功していること -- 必要なレビュー承認が得られていること -``` - -**1.3 ユーザー確認** - -AskUserQuestionで最終確認: -``` -以下のPRをマージします。よろしいですか? - -**PR**: {pr_url} -**タイトル**: {title} -**ブランチ**: {head_branch} → {base_branch} -``` - -選択肢: -- "はい、マージする" -- "いいえ、キャンセル" - -### 2. マージ実行 - -ユーザーが承認した場合、マージを実行: - -```bash -gh pr merge {pr_number} --squash --delete-branch -``` - -`--squash`: PRの全コミットを1つにまとめてマージ -`--delete-branch`: マージ後にリモートブランチを自動削除 - -### 3. ローカルブランチのクリーンアップ - -Skillツールを使用してgitスキルのbranch-deleteサブコマンドを実行: - -``` -Skill - skill: "git" - args: "branch-delete {head_branch}" -``` - -gitスキルが自動的に以下を実行: -- mainブランチに切り替え(必要な場合) -- mainブランチの更新(fetch + pull) -- リモートブランチ情報の更新(fetch --prune) -- ローカルブランチの削除 - -### 4. 結果表示 - -``` -## マージ完了 - -**PR**: {pr_url} -**ブランチ**: {head_branch} → {base_branch} - -### 実行内容 -- PRをマージしました -- リモートブランチ '{head_branch}' を削除しました -- ローカルブランチ '{head_branch}' を削除しました -- ブランチを '{base_branch}' に切り替えました -- 最新のコードを取得しました - -お疲れ様でした。 -``` - -## エラーハンドリング - -| エラー | 対応 | -|--------|------| -| PRが見つからない | 正しいPR番号を確認 | -| state !== "OPEN" | PRがすでにCLOSEDまたはMERGEDされている | -| mergeable !== "MERGEABLE" | マージコンフリクトを解決してから再実行 | -| ステータスチェック失敗 | CI/CDを修正してから再実行 | -| マージ権限不足 | リポジトリの権限を確認 | -| ブランチ削除失敗 | `git branch -D`で強制削除 | - -## 注意事項 - -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **マージ権限**: PRマージにはリポジトリへの書き込み権限が必要 -3. **ステータスチェック**: すべてのCIチェックが成功していることを確認 -4. **リモートブランチ削除**: `--delete-branch`により、GitHub側で自動的にリモートブランチが削除される -5. **保護ブランチ**: ターゲットブランチが保護されている場合、追加の権限設定が必要 -6. **Squashマージ**: `--squash`により、PRの全コミットが1つにまとめられてマージされる +# Merge Workflow + +This workflow merges the PR and cleans up branches. + +## Required Tools + +- Bash +- AskUserQuestion +- Skill (for git branch-delete) + +## Execution Steps + +### 1. Get and Verify PR Information + +**1.1 Get PR Information** + +```bash +gh pr view "$pr_number" --json number,title,state,headRefName,baseRefName,url,mergeable,reviewDecision +``` + +**1.2 Check Mergeability** + +Verify all of the following: +- `state === "OPEN"` +- `mergeable === "MERGEABLE"` +- `reviewDecision === "APPROVED"` (depends on project settings) + +If any condition is not met, display error message and exit: + +``` +Error: PR cannot be merged + +Please verify: +- PR is OPEN +- No merge conflicts (mergeable: {actual_status}) +- Required review approvals obtained (reviewDecision: {actual_value}) +- All CI/CD checks passing +``` + +**1.3 Verify CI/CD Checks** + +```bash +gh pr checks "$pr_number" +``` + +Display warning if any checks are failing. + +**1.4 User Confirmation** + +Final confirmation with AskUserQuestion: +``` +Merge the following PR. Is this OK? + +**PR**: {pr_url} +**Title**: {pr_title} +**Branch**: {headRefName} → {baseRefName} +``` + +Options: +- "Yes, merge" +- "No, cancel" + +### 2. Execute Merge + +If user approves, execute merge: + +```bash +gh pr merge "$pr_number" \ + --squash \ + --delete-branch +``` + +Option descriptions: +- `--squash`: Squash merge (default) - combine all commits into one +- `--delete-branch`: Automatically delete remote branch after merge + +**Merge Strategy Options**: +- `--squash`: Squash merge (combine all commits into one) +- `--merge`: Create merge commit +- `--rebase`: Rebase and merge + +Choose appropriate method based on project settings. + +### 3. Local Branch Cleanup + +Execute git skill's branch-delete subcommand using Skill tool: + +``` +Skill + skill: "git" + args: "branch-delete {headRefName}" +``` + +Git skill automatically executes: +- Switch to base branch (if needed) +- Update base branch (fetch + pull) +- Verify remote branch deletion (warning only if already deleted) +- Delete local branch +- Update remote branch info (fetch --prune) + +### 4. Display Result + +``` +## Merge Complete + +**PR**: {pr_url} +**Branch**: {headRefName} → {baseRefName} + +### Actions Performed +- Merged PR +- Deleted remote branch '{headRefName}' (automatically deleted by GitHub) +- Deleted local branch '{headRefName}' +- Switched to branch '{baseRefName}' +- Fetched latest code + +Good work! +``` + +## Error Handling + +| Error | Response | +|-------|----------| +| PR not found | Verify correct PR number | +| state !== "OPEN" | PR already closed or merged | +| mergeable !== "MERGEABLE" | Resolve merge conflicts then retry | +| reviewDecision !== "APPROVED" | Obtain required review approvals | +| Check failure | Fix CI/CD then retry | +| No merge permission | Verify Write or higher permissions | +| Branch deletion failure | Force delete with `git branch -D` | + +## Notes + +1. **Emoji Usage**: Do not use emojis unless user explicitly requests them +2. **GitHub Permissions**: Requires Write or higher for PR merge (depends on repository settings) +3. **Protected Branches**: For protected base branches, additional permission settings (required review count, check requirements, etc.) are needed +4. **Merge Strategy**: Choose from `--squash`, `--merge`, or `--rebase` based on project policy +5. **Remote Branch Deletion**: `--delete-branch` automatically deletes remote branch on GitHub side + +## Merge Strategy Selection + +Choose merge strategy based on project policy: + +### Squash Merge (Recommended) +```bash +gh pr merge "$pr_number" --squash --delete-branch +``` +- **Benefit**: Simplified commit history +- **Use case**: General cases like feature development, bug fixes + +### Merge Commit +```bash +gh pr merge "$pr_number" --merge --delete-branch +``` +- **Benefit**: Preserves full commit history +- **Use case**: When detailed commit history should be retained + +### Rebase Merge +```bash +gh pr merge "$pr_number" --rebase --delete-branch +``` +- **Benefit**: Linear commit history +- **Use case**: When avoiding merge commits + +## Auto-merge Configuration + +To automatically merge when merge conditions are met: + +```bash +gh pr merge "$pr_number" --auto --squash --delete-branch +``` + +This will automatically merge once required checks and reviews are complete. diff --git a/.claude/skills/pr/workflows/resolve.md b/.claude/skills/pr/workflows/resolve.md index 0882fbb..3c54a7e 100644 --- a/.claude/skills/pr/workflows/resolve.md +++ b/.claude/skills/pr/workflows/resolve.md @@ -1,191 +1,228 @@ -# レビュー対応ワークフロー - -このワークフローは、レビューコメントに対して修正→コミット→リプライを行います。 - -## 必要なツール - -- Bash -- Read -- Edit -- Write -- AskUserQuestion -- Skill (gitスキルを使用) - -## 実行ステップ - -### 1. PR情報取得 - -**1.1 PR情報を取得** - -```bash -gh pr view {pr_number} --json number,title,state,headRefName,baseRefName,url,author,mergeable -``` - -**1.2 PR状態の確認** - -PRが`OPEN`であることを確認。CLOSEDまたはMERGEDの場合はエラー終了。 - -**1.3 ブランチ確認** - -カレントブランチを取得: -```bash -git branch --show-current -``` - -カレントブランチが`headRefName`と異なる場合、AskUserQuestionで確認: -``` -現在のブランチ '{current_branch}' は、PRのソースブランチ '{head_branch}' と異なります。 -'{head_branch}' にチェックアウトしますか? -``` - -選択肢: -- "はい、チェックアウトする" → `git checkout {head_branch}` -- "いいえ、このまま続行" - -### 2. レビューコメントの取得 - -**2.1 全コメントを取得** - -```bash -gh pr view {pr_number} --json comments,reviews --jq '.reviews[] | select(.state == "CHANGES_REQUESTED" or .state == "COMMENTED") | {body: .body, author: .author.login, createdAt: .createdAt, comments: .comments}' -``` - -**2.2 未解決コメントのフィルタリング** - -以下の条件を満たすコメントを抽出: -- レビュー状態が`CHANGES_REQUESTED`または`COMMENTED` -- レビューコメントに対するリプライがない、または最新のコメントがレビュアーからのもの - -レビューコメントが0件の場合: -``` -## レビュー対応完了 - -**PR**: {pr_url} - -未解決のコメントはありません。 -``` - -終了する。 - -### 3. 各コメントの処理 - -各レビューコメントについて、以下の処理を実行: - -**3.1 分析** - -コメント情報を取得: -- コメント本文 -- 該当ファイルと行番号(可能な場合) -- レビュアー名 - -Readツールでファイルを読み込み、該当箇所を確認。 - -**3.2 判断** - -以下のいずれかを選択: - -1. **修正が必要で内容が明確** - - 自律的に修正へ進む - - 例: 「タイポを修正してください」「変数名を変更してください」 - -2. **不明点あり** - - 質問をリプライ - - 例: 「パフォーマンスを改善してください」→「具体的にどの部分が懸念でしょうか?」 - -3. **同意できない/対応不要** - - スキップして報告 - - 例: 「アーキテクチャを全面的に見直してください」→ユーザーに判断を委ねる - -4. **判断が困難** - - AskUserQuestionで確認 - - 選択肢: 修正する / 質問する / スキップ - -**3.3 修正・コミット・プッシュ(修正する場合)** - -**3.3.1 ファイルの修正** - -EditまたはWriteツールでファイルを修正。 - -複数ファイルの修正が必要な場合、すべて修正してから1回のコミットにまとめる。 - -**3.3.2 gitスキルでコミット・プッシュ** - -Skillツールを使用してgitスキルのcommitサブコマンドを実行: - -``` -Skill - skill: "git" - args: "commit" -``` - -gitスキルが自動的に以下を実行: -- 変更ファイルの分析 -- コミットメッセージの生成(`fix: {レビュー指摘の要約}`形式) -- ステージング(git add) -- コミット -- プッシュ - -**3.3.3 コミットSHAの取得** - -```bash -git rev-parse HEAD -``` - -**3.4 リプライ** - -**修正の場合**: - -```bash -gh pr comment {pr_number} --body "修正しました - -**コミット**: https://github.com/{owner}/{repo}/commit/{commit_sha} - -{修正内容の簡潔な説明} - -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) " -``` - -**質問の場合**: - -```bash -gh pr comment {pr_number} --body "確認させてください - -{質問内容} - -Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) " -``` - -### 4. サマリー - -全コメントの処理が完了したら、サマリーを表示: - -``` -## PRレビュー対応完了 - -**PR**: {pr_url} - -### 結果 -- 修正してリプライ: {n}件 -- 質問してリプライ: {n}件 -- スキップ: {n}件 - -レビュアーによる確認をお願いします。 -``` - -## エラーハンドリング - -| エラー | 対応 | -|--------|------| -| PRが見つからない | 正しいPR番号を確認 | -| PRがCLOSED/MERGED | OPENのPRを指定 | -| プッシュ失敗 | `git pull --rebase`して再プッシュ | -| コンフリクト | 手動でコンフリクトを解決してから再実行 | -| gh CLI認証エラー | `gh auth login`で認証 | - -## 注意事項 - -1. **絵文字の使用**: ユーザーが明示的に要求しない限り、絵文字を使わない -2. **自律的な判断**: コメントの修正内容が明確な場合は自律的に対応し、AskUserQuestionは判断が困難な場合のみ使用 -3. **テスト実行**: 修正後、関連するテストがある場合は実行して確認 -4. **複数ファイル**: 1つのコメントで複数ファイルの修正が必要な場合、全て修正してから1回のコミットにまとめる -5. **会話履歴の考慮**: コメントスレッドに複数のコメントがある場合、最新のコメントから意図を汲み取る +# Review Response Workflow + +This workflow performs Fix → Commit → Reply for unresolved review comments. + +## Required Tools + +- Bash +- Read +- Edit +- Write +- AskUserQuestion +- Skill (for git commit) + +## Execution Steps + +### 1. Get PR Information + +**1.1 Get PR Information** + +```bash +gh pr view "$pr_number" --json number,title,state,headRefName,baseRefName,url +``` + +**1.2 Verify PR State** + +Verify PR is `OPEN`. Exit with error if `CLOSED` or `MERGED`. + +**1.3 Verify Branch** + +Get current branch: +```bash +current_branch=$(git branch --show-current) +``` + +If current branch differs from `headRefName`, confirm with AskUserQuestion: +``` +Current branch '{current_branch}' differs from PR source branch '{headRefName}'. +Would you like to checkout '{headRefName}'? +``` + +Options: +- "Yes, checkout" → `git checkout {headRefName}` +- "No, continue as is" + +### 2. Get Unresolved Review Comments + +**2.1 Get Review Threads** + +```bash +gh pr view "$pr_number" --json reviewThreads +``` + +**2.2 Filtering** + +Extract only comments meeting all these conditions: +- `thread.isResolved === false` +- `thread.isOutdated === false` +- `thread.path !== null` (comments on files) + +If 0 unresolved comments: +``` +## Review Response Complete + +**PR**: {pr_url} + +No unresolved comments. +``` + +Exit. + +### 3. Process Each Comment + +For each unresolved comment, execute the following: + +**3.1 Analysis** + +Get comment information: +- `comment.body`: Comment body +- `comment.path`: File to fix +- `comment.line`: Line number (if exists) +- `comment.author.login`: Reviewer name + +Use Read tool to load file and check relevant section. + +**3.2 Decision** + +Select one of the following: + +1. **Fix needed and content is clear** + - Proceed autonomously to fix + - Example: "Fix typo", "Change variable name" + +2. **Unclear points** + - Reply with question + - Example: "Please improve performance" → "Which specific part is a concern?" + +3. **Disagree/Not actionable** + - Skip and report + - Example: "Completely rethink architecture" → Defer to user judgment + +4. **Difficult to judge** + - Confirm with AskUserQuestion + - Options: Fix / Ask question / Skip + +**3.3 Fix, Commit, Push (When fixing)** + +**3.3.1 Fix File** + +Fix file with Edit or Write tool. + +If multiple files need fixing, fix all before creating a single commit. + +**3.3.2 Commit and Push with git Skill** + +Execute git skill's commit subcommand using Skill tool: + +``` +Skill + skill: "git" + args: "commit" +``` + +Git skill automatically executes: +- Analyze changed files +- Generate commit message (format: `fix: {summary of review feedback}`) +- Staging (git add) +- Commit +- Push + +**3.3.3 Get Commit SHA** + +```bash +commit_sha=$(git rev-parse HEAD) +repo_url=$(gh repo view --json url -q .url) +``` + +**3.4 Reply** + +**For fixes**: + +```bash +gh pr comment "$pr_number" --body "$(cat <<'EOF' +Fixed + +**Commit**: {repo_url}/commit/{commit_sha} + +{Brief description of fix} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +EOF +)" +``` + +**For questions**: + +```bash +gh pr comment "$pr_number" --body "$(cat <<'EOF' +Please clarify + +{Question content} + +Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) +EOF +)" +``` + +**Note**: `gh pr comment` adds a comment to the overall PR. Direct replies to specific review comments require advanced operations using `gh api`. + +### 4. Resolve Review Comments + +After fixing, mark review thread as resolved: + +```bash +# gh CLI does not have direct resolve functionality, so request reviewer to resolve +echo "Please request reviewer to resolve threads" +``` + +### 5. Summary + +After processing all comments, display summary: + +``` +## PR Review Response Complete + +**PR**: {pr_url} + +### Results +- Fixed and replied: {n} items +- Asked questions and replied: {n} items +- Skipped: {n} items + +Please request reviewer to resolve threads +``` + +## Error Handling + +| Error | Response | +|-------|----------| +| PR not found | Verify correct PR number | +| PR closed/merged | Specify opened PR | +| Push failure | `git pull --rebase` and retry push | +| Conflict | Manually resolve conflict then retry | +| Authentication error | Authenticate with `gh auth login` | + +## Notes + +1. **Emoji Usage**: Do not use emojis unless user explicitly requests them +2. **GitHub Permissions**: Requires Write or higher for commenting and pushing +3. **Autonomous Judgment**: Respond autonomously when fix content is clear; use AskUserQuestion only when judgment is difficult +4. **Test Execution**: Run related tests if they exist after fixing +5. **Multiple Files**: When one comment requires multiple file fixes, fix all before creating a single commit +6. **Thread Resolution**: GitHub CLI lacks direct resolve functionality, so request reviewer resolution + +## Advanced Operation: Reply to Specific Comments + +To reply directly to specific review comments, use GitHub API: + +```bash +# Get review comment ID (from reviewThreads) +comment_id="{thread.comments[0].id}" + +# Add reply +gh api \ + "repos/{owner}/{repo}/pulls/{pr_number}/comments/$comment_id/replies" \ + -f body="Fixed. Please review." +``` + +However, PR-level comments are usually sufficient, so use this as needed. diff --git a/.claude/statusline.sh b/.claude/statusline.sh old mode 100755 new mode 100644 diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 2790733..f4663f8 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -1,57 +1,36 @@ -# Nablarchエージェント代行のための構造化知識基盤 - 最終設計書 +# Nabledge設計書 -**作成日**: 2026年2月9日 -**作成者**: Claude (Sonnet 4.5) -**バージョン**: 1.0 +**作成日**: 2026年2月10日 +**ステータス**: Draft --- ## 変更履歴 -| 日付 | 変更内容 | 作成者 | -|------|----------|--------| -| 2026/02/09 | 初版作成 | Claude (Sonnet 4.5) | +| 日付 | 変更内容 | +|------|----------| +| 2026/02/10 | 初版作成 | --- ## 目次 -- [全体構造](#全体構造) - [1. 概要](#1-概要) - - [1.1 背景と課題](#11-背景と課題) - - [1.2 設計のゴール](#12-設計のゴール) - - [1.3 本設計書の位置づけ](#13-本設計書の位置づけ) -- [2. 要件と制約](#2-要件と制約) - - [2.1 代行タスクと知識要件](#21-代行タスクと知識要件) - - [2.2 公式情報マッピングと作成単位](#22-公式情報マッピングと作成単位) - - [2.3 制約事項と前提条件](#23-制約事項と前提条件) -- [3. アーキテクチャ設計](#3-アーキテクチャ設計step3の結果を中心に) - - [3.1 ユーザー体験設計](#31-ユーザー体験設計) - - [3.2 ファイル構成と命名規則](#32-ファイル構成と命名規則) - - [3.3 検索パス・検索精度設計](#33-検索パス検索精度設計) - - [3.4 インデックス設計](#34-インデックス設計) - - [3.5 知識ファイル設計](#35-知識ファイル設計) - - [3.6 検索ワークフロー定義](#36-検索ワークフロー定義) - - [3.7 Markdown変換ルール](#37-markdown変換ルール) - - [3.8 コンテキスト管理戦略](#38-コンテキスト管理戦略) - - [3.9 MCP移行設計](#39-mcp移行設計) -- [4. 実現性評価](#4-実現性評価step4の結果) - - [4.1 作成したサンプル一覧](#41-作成したサンプル一覧) - - [4.2 実現性評価結果](#42-実現性評価結果) - - [4.3 リスク評価と対策](#43-リスク評価と対策) - - [4.4 知識・仕組みの作成計画](#44-知識仕組みの作成計画) -- [5. レビューと改善](#5-レビューと改善step5の結果) - - [5.1 各ペルソナの評価結果](#51-各ペルソナの評価結果) - - [5.2 指摘事項と改善内容のサマリー](#52-指摘事項と改善内容のサマリー) - - [5.3 将来対応項目](#53-将来対応項目) -- [6. 実装計画](#6-実装計画) - - [6.1 実装フェーズ計画](#61-実装フェーズ計画) - - [6.2 品質保証プロセス](#62-品質保証プロセス) - - [6.3 情報源の管理と更新対応](#63-情報源の管理と更新対応) - - [6.4 残存リスクと対策](#64-残存リスクと対策) -- [7. 付録](#7-付録) - - [7.1 用語集](#71-用語集) - - [7.2 参考資料](#72-参考資料) + - [1.1 背景と目的](#11-背景と目的) + - [1.2 スコープ](#12-スコープ) +- [2. アーキテクチャ](#2-アーキテクチャ) + - [2.1 全体構造](#21-全体構造) + - [2.2 配布とインストール](#22-配布とインストール) + - [2.3 ファイル構成](#23-ファイル構成) + - [2.4 検索アーキテクチャ](#24-検索アーキテクチャ) + - [2.5 インデックス設計](#25-インデックス設計) + - [2.6 知識ファイル設計](#26-知識ファイル設計) + - [2.7 コンテキスト管理](#27-コンテキスト管理) +- [3. 実装計画](#3-実装計画) + - [3.1 作成範囲](#31-作成範囲) + - [3.2 フェーズ計画](#32-フェーズ計画) + - [3.3 品質保証](#33-品質保証) +- [4. 参考資料](#4-参考資料) --- @@ -179,93 +158,39 @@ graph TB ## 1. 概要 -### 1.1 背景と課題 +### 1.1 背景と目的 -#### なぜこの設計が必要なのか +**Nabledgeとは**: +Nablarch開発をAIエージェント(Claude Code、GitHub Copilot)が代行するための構造化知識基盤。 -Nablarchは金融・決済等のミッションクリティカルな大規模基幹系システムで広く利用されているが、保守開発において以下の課題が存在する: +**解決する課題**: +- AI単体ではNablarch固有の知識がなく、代行精度が不十分 +- 公式ドキュメントは人間向けで、AIが効率的に検索・参照できない +- 新規参画者のオンボーディングや日常開発に時間がかかる -**新規参画者のオンボーディング課題**(3プロジェクト・15名の観測値、2024-2025年): -- 対象者: Java経験2年以上、Nablarch未経験者 -- アーキテクチャ理解: 2〜3日 -- 既存コード理解: 3〜5日 -- **合計: 5〜10日** - -**日常開発での工数課題**(同観測値): -- 実装調査: 2〜4時間/タスク(中規模タスク: 3-5ファイル変更、100-300ステップ) -- レビュー: 1〜2時間/レビュー -- 障害調査: 2〜8時間/障害(難易度による) - -**AI活用における課題**: -- AIエージェント(Claude Code、GitHub Copilot)を活用したいが、Nablarch固有の知識がないため代行精度が不十分 -- 公式ドキュメントは人間向けに記述されており、AIが効率的に検索・参照できる構造になっていない -- **なるべく早くAIのメリットを感じてもらう**ことが重要 - -#### 解決すべき課題 - -1. **代行精度の向上**: Nablarch固有の知識をAI向けに構造化し、代行精度を向上させる -2. **工数削減の実現**: 実装調査、コード生成、レビュー等の工数を削減する(目標: 60-70%削減) -3. **オンボーディング期間の短縮**: 新規参画者の学習期間を短縮する(目標: 5〜10日 → 1〜2日) - ---- - -### 1.2 設計のゴール - -この設計書では、以下のゴールを達成するための構造化知識基盤を定義する: - -#### 主要ゴール - -1. **AIエージェントの代行精度向上**: Nablarchの構造化知識を提供し、AIが正確に代行できるようにする -2. **構造化の観点をすべて満たす設計**: 以下の5観点を考慮した設計を実現する - - 検索速度: 必要な情報に素早くたどり着ける - - コンテキスト肥大化防止: 不要な情報はノイズとならない - - トークン量最適化: コンテキストウィンドウ上限内で必要情報を収める - - 正確性・根拠追跡性: ミッションクリティカル領域で誤情報を許容しない - - 保守性・更新容易性: バージョンアップへの追従が必要 -3. **実現可能性の確認**: 実際に知識ファイルを作成し、品質を検証する - -#### 定量的な目標 - -| 項目 | 目標値 | 根拠 | -|------|--------|------| -| **代行精度** | 工数削減60-70% | 他業界のAI代行事例では50-80%の削減実績 | -| **作成工数** | 全60ファイルで約3.7時間 | 1ファイル約3分(実測値) | -| **知識の品質** | 平均95点以上/100点 | Step4で17ファイルの平均97.3点を達成 | -| **トークン量** | 実運用で約5,000トークン | コンテキストウィンドウ(200,000トークン)の2.5% | -| **オンボーディング期間** | 5〜10日 → 1〜2日 | AIによる代行で学習曲線を短縮 | +**目的**: +AIエージェントにNablarchの構造化知識を提供し、以下を実現する: +1. 実装調査、コード生成、レビュー等の代行精度向上 +2. 開発工数の削減 +3. オンボーディング期間の短縮 --- -### 1.3 本設計書の位置づけ - -#### 設計書の役割 - -この設計書は、**構造化知識基盤の完全な仕様**として、以下の役割を果たす: - -1. **要件定義**: どんな知識が必要か、どう作ればよいかを明確化 -2. **設計仕様**: アーキテクチャ、ファイル構成、検索パス、スキーマを定義 -3. **実現性評価**: 実際に作成した知識ファイルの品質を検証 -4. **改善の記録**: 有識者レビューによる改善内容を記録 -5. **実装の基礎**: 今後の実装や運用の基礎となる - -#### 対象読者 +### 1.2 スコープ -| 読者 | 読むべきセクション | 読む目的 | -|------|------------------|---------| -| **プロジェクトマネージャー** | 1. 概要、6. 実装計画 | 全体像の把握、工数見積もり、リスク評価 | -| **アーキテクト** | 3. アーキテクチャ設計、5. レビューと改善 | 設計判断の妥当性確認、拡張性の評価 | -| **Nablarch有識者** | 2. 要件と制約、4. 実現性評価 | 知識の正確性確認、網羅性の評価 | -| **実装担当者** | 3. アーキテクチャ設計、6. 実装計画 | 実装方法の理解、作業手順の確認 | -| **AIエンジニア** | 3. アーキテクチャ設計、4. 実現性評価 | トークン効率、検索性、MCP移行の理解 | +**対象**: +- Nablarchバッチ(都度起動型) +- RESTful Webサービス -#### 関連ドキュメント +**対象外**: +- Jakarta Batch +- 常駐バッチ(テーブルキュー型) +- ウェブアプリケーション(JSP/画面系) +- メッセージング(MOM) -| ドキュメント | 関係 | -|-------------|------| -| **調査仕様書** (`nablarch_agent_research_spec.md`) | 本設計書の前提となる調査方針を定義 | -| **Step 1-5の調査結果** (`step1-5_*.md`) | 本設計書の各章のソースとなる詳細調査結果 | -| **Step 6: 調査結果統合** (`step6_final_summary.md`) | 本設計書の要約版、エグゼクティブサマリー | -| **Nabledge計画書** (今後作成予定) | 本設計書を元にした実装計画 | +**想定ツール**: +- Claude Code(主要ターゲット) +- GitHub Copilot(サブターゲット) --- @@ -450,8 +375,8 @@ Nablarchは金融・決済等のミッションクリティカルな大規模基 | ツール | 用途 | 備考 | |--------|------|------| -| **Claude Code** | エージェント型開発支援(MCP接続可) | 主要ターゲット | -| **GitHub Copilot** | コード補完・提案(MCP接続可) | サブターゲット | +| **Claude Code** | エージェント型開発支援 | 主要ターゲット | +| **GitHub Copilot** | コード補完・提案 | サブターゲット | #### 段階的アプローチ @@ -1628,28 +1553,6 @@ JSONから自動変換。docs/配下に配置。 | **nablarch-example-batch** | https://github.com/nablarch/nablarch-example-batch | | **nablarch-example-rest** | https://github.com/nablarch/nablarch-example-rest | -#### 本設計書の元となった調査資料 - -| ドキュメント | パス | -|-------------|------| -| **調査仕様書** | `research/nablarch_agent_research_spec.md` | -| **Step 1: 代行ニーズと知識要件の分析** | `research/step1_delegation_and_knowledge_analysis.md` | -| **Step 2: 公式情報マッピングと規模調査** | `research/step2_official_info_mapping.md` | -| **Step 3: 構造化アーキテクチャ設計** | `research/step3-architecture-design.md` | -| **Step 4: サンプル作成と実現性評価** | `research/step4_samples_and_evaluation.md` | -| **Step 5: 有識者レビューと改善** | `research/step5_expert_review.md` | -| **Step 6: 調査結果統合** | `research/step6_final_summary.md` | - -#### 実装成果物 - -| 成果物 | パス | -|--------|------| -| **17個の知識ファイル** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/` | -| **index.toon** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/index.toon` | -| **overview.json** | `research/step4/batch-scenario-knowledge-creation/nabledge-6/knowledge/overview.json` | -| **Step4作業記録** | `research/step4/step4-work-log.md` | -| **UniversalDao評価レポート** | `research/step4/universal-dao-evaluation/README.md` | - --- ## まとめ From 0ef57d3c5df82544137b33daa1740a0b3df1cebf Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:11:48 +0900 Subject: [PATCH 12/89] =?UTF-8?q?docs:=20Nabledge=E8=A8=AD=E8=A8=88?= =?UTF-8?q?=E6=9B=B8v1.4=20-=20=E6=A7=8B=E9=80=A0=E6=95=B4=E7=90=86?= =?UTF-8?q?=E3=81=A8=E6=96=87=E4=BD=93=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - バージョン1.4に更新、変更履歴を追加 - 代行業務の優先度を整理し明確化 - 冗長な説明を削除し、構造を4章に簡潔化 - 文体を統一(「です・ます」調) - スクリプトファイルに実行権限を付与 Co-Authored-By: Claude Opus 4.6 --- .claude/hooks/notify.sh | 0 .claude/statusline.sh | 0 doc/nabledge-design.md | 1562 ++++++--------------------------------- 3 files changed, 244 insertions(+), 1318 deletions(-) mode change 100644 => 100755 .claude/hooks/notify.sh mode change 100644 => 100755 .claude/statusline.sh diff --git a/.claude/hooks/notify.sh b/.claude/hooks/notify.sh old mode 100644 new mode 100755 diff --git a/.claude/statusline.sh b/.claude/statusline.sh old mode 100644 new mode 100755 diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index f4663f8..299d6a7 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -1,42 +1,70 @@ # Nabledge設計書 **作成日**: 2026年2月10日 +**バージョン**: 1.4 **ステータス**: Draft +## 変更履歴 + +| バージョン | 日付 | 変更内容 | +|----------|------|---------| +| 1.4 | 2026/02/10 | 代行業務の整理、文体統一 | +| 1.3 | 2026/02/10 | アーキテクチャレビュー反映 | +| 1.2 | 2026/02/10 | MCP削除、簡潔化 | +| 1.0 | 2026/02/09 | 初版作成 | + --- -## 変更履歴 +## 1. 概要 + +### 1.1 背景と目的 + +**Nabledgeとは**: +Nablarchの構造化知識と、それを活用して開発作業を代行するワークフローで構成される、AIエージェント(Claude Code、GitHub Copilot)向けの知識基盤です。 + +**解決する課題**: AI単体ではNablarch固有の知識がなく代行精度が不十分なこと、公式ドキュメントは人間向けでAIが効率的に検索・参照できないこと、新規参画者のオンボーディングや日常開発に時間がかかることです。 + +**目的**: AIエージェントにNablarchの構造化知識を提供し、実装調査・コード生成・レビュー等の代行精度向上、開発工数の削減(目標: 60-70%)、オンボーディング期間の短縮を実現します。 + +--- + +### 1.2 想定する代行作業 + +| 代行業務 | 優先度 | 優先度理由 | Nabledge代行適性 | +|---------|:------:|-----------|:---------------:| +| 既存コード理解 | S | 知識基盤の構築に必須 | 高 | +| ナレッジQ&A | S | 知識基盤の構築に必須 | 高 | +| 影響分析 | A | プロジェクトでの要望が多い | 中 | +| レビュー | A | プロジェクトでの要望が多い | 高 | +| コード生成・雛形作成 | B | | 中 | +| 実装調査 | B | | 中 | +| テストデータ作成 | B | | 低 | +| 障害調査 | B | | 中 | +| 設計書解読 | B | | 低 | +| ドキュメント生成 | B | | 低 | -| 日付 | 変更内容 | -|------|----------| -| 2026/02/10 | 初版作成 | +**Nabledge代行適性**: +- **高**: Nablarch知識だけで対応可能 +- **中**: Nablarch知識に加えてPJ固有知識が必要 +- **低**: PJ固有知識が多く必要 --- -## 目次 - -- [1. 概要](#1-概要) - - [1.1 背景と目的](#11-背景と目的) - - [1.2 スコープ](#12-スコープ) -- [2. アーキテクチャ](#2-アーキテクチャ) - - [2.1 全体構造](#21-全体構造) - - [2.2 配布とインストール](#22-配布とインストール) - - [2.3 ファイル構成](#23-ファイル構成) - - [2.4 検索アーキテクチャ](#24-検索アーキテクチャ) - - [2.5 インデックス設計](#25-インデックス設計) - - [2.6 知識ファイル設計](#26-知識ファイル設計) - - [2.7 コンテキスト管理](#27-コンテキスト管理) -- [3. 実装計画](#3-実装計画) - - [3.1 作成範囲](#31-作成範囲) - - [3.2 フェーズ計画](#32-フェーズ計画) - - [3.3 品質保証](#33-品質保証) -- [4. 参考資料](#4-参考資料) +### 1.3 スコープ + +**対象**: Nablarchバッチ(都度起動型)、RESTful Webサービス + +**対象外**: Jakarta Batch、常駐バッチ、ウェブアプリケーション(JSP/画面)、メッセージング(MOM) + +**対象バージョン**: Nablarch 6系、5系、1.4系、1.3系、1.2系 + +**想定ツール**: Claude CodeとGitHub Copilotの両方に対応します。 --- -## 全体構造 +## 2. アーキテクチャ -本設計の全体像を以下の図に示す。この図は、Nablarch利用者がAIエージェントを介してnabledgeスキルを活用する全体のフローと、知識基盤の構成要素を表現している。 +### 2.1 全体構造 ```mermaid graph TB @@ -70,7 +98,7 @@ graph TB NAB_TEAM["Nablarch開発チーム

• 公式情報更新
• 知識レビュー・承認"] end - %% 主要フロー(①→⑤)- 左から中央へ + %% 主要フロー(①→⑤) AGENT -->|"②知識検索"| WF_SEARCH WF_SEARCH -->|"検索"| INDEX INDEX -->|"③関連セクション特定
(関連度: High/Partial)"| JSON @@ -80,7 +108,7 @@ graph TB WF_DELEGATE -->|"知識参照
(上位10セクション)"| JSON WF_DELEGATE -->|"⑤回答・コード生成"| DEV - %% 開発チームフロー - 右から中央へ + %% 開発チームフロー AGENT -.->|"実行"| WF_GENERATE WF_GENERATE -.->|"作成・検証"| JSON NAB_TEAM -.->|"更新時"| WF_GENERATE @@ -96,7 +124,7 @@ graph TB end end - %% 配布フロー - 下から中央へ + %% 配布フロー nabledge -.->|"取得"| REPO %% スタイル @@ -109,440 +137,100 @@ graph TB style workflows fill:#fff9c4 ``` -### 図の解説 - -**主要な登場人物**: -1. **Nablarch利用者** (アプリケーション開発者): 主人公(左側)。AIツールに自然言語で作業を依頼する -2. **AIツール** (Claude Code/GitHub Copilot等): 主人公(左側)。ワークフロー(LLM)を実行して作業を代行する -3. **nabledgeスキル**: 知識基盤とワークフロー(LLM)で構成される(中央) -4. **Nablarch開発チーム**: 知識基盤を更新・レビューする(右側) - -**配布の流れ**(図の下部): -``` -📦 GitHub - └─ org: nablarch(入れ子) - └─ repository: nabledge(入れ子) - ↓ Claude Code Pluginとして配布 - ↓ claude plugin install nabledge-6 - nabledgeスキル(ユーザー環境にインストール) -``` - -**知識基盤の構成**: -- **知識ファイル (JSON)**: Nablarchの機能・実装パターンを構造化(60ファイル、約420Kトークン) -- **インデックス (TOON形式)**: 検索用インデックス(93エントリ、約650検索ヒント、トークン量30-60%削減) -- **知識ファイル (Markdown)**: 人間が確認するための自動変換版(根拠追跡性) - -**ワークフロー(🤖 LLM実行)の種類**: -- **知識検索**: keyword-search(技術軸)とintent-search(目的軸)の並列実行、関連度判定(High/Partial/None) -- **代行作業**: 実装調査、コード生成、レビュー、障害調査等のタスクを実行 -- **知識ファイル生成・検証**: 知識ファイルを作成し、品質を保証する(3分/ファイル、20%サンプリングレビュー) - -**実行フロー(①→⑤)**: -1. Nablarch利用者が自然言語でAIツールに依頼(例: 「ページングを実装したい」) -2. AIツールが **ワークフロー(知識検索)** を実行 - - ワークフロー(LLM)がインデックスを検索(keyword + intent並列実行) -3. 関連度の高いセクションを特定(High/Partial/Noneの3段階評価) -4. **ワークフロー(代行作業)** を実行し、知識ファイルを参照(上位10セクション、約5,000トークン = 2.5%のコンテキスト使用) -5. 回答またはコードを生成してユーザーに返す +**実行フロー**: +1. Nablarch利用者が自然言語でAIツールに依頼します(例: 「ページングを実装したい」) +2. AIツールがワークフロー(知識検索)を実行します → keyword + intent並列検索 +3. 関連度の高いセクションを特定します(High/Partial/Noneの3段階) +4. ワークフロー(代行作業)を実行し、知識ファイルを参照します(上位10セクション ≈ 5,000トークン) +5. 回答またはコードを生成してユーザーに返します **設計のポイント**: -- **配布の明確化**: GitHub (nablarch/nabledge) → Claude Code Plugin Registry → インストール -- **LLMの明示**: ワークフローに🤖マークを付与し、LLMが実行する処理であることを明確化 -- **検索の構造化**: AIツール → ワークフロー(検索)→ インデックス の流れで検索処理を明示 -- **トークン効率**: TOON形式インデックスで30-60%削減、セクション単位抽出で必要最小限の情報のみ使用 -- **検索精度**: keyword-search(技術軸)とintent-search(目的軸)の並列実行で漏れを防止 -- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡 -- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離 +- **配布**: GitHub (nablarch/nabledge) → Claude Code Plugin → インストール +- **検索**: keyword(技術軸)+ intent(目的軸)の並列実行で漏れを防止します +- **トークン効率**: TOON形式で30-60%削減、セクション単位抽出で必要最小限に抑えます +- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡します +- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離します --- -## 1. 概要 - -### 1.1 背景と目的 - -**Nabledgeとは**: -Nablarch開発をAIエージェント(Claude Code、GitHub Copilot)が代行するための構造化知識基盤。 +### 2.2 知識タイプ -**解決する課題**: -- AI単体ではNablarch固有の知識がなく、代行精度が不十分 -- 公式ドキュメントは人間向けで、AIが効率的に検索・参照できない -- 新規参画者のオンボーディングや日常開発に時間がかかる +| # | 知識タイプ | 内容 | カバー範囲 | 作成単位 | 推定件数 | +|---|-----------|------|----------|---------|---------| +| ① | 機能・実装パターン(エラー含む) | どう実装するか、エラー対処 | 9タスク(90%) | ハンドラ、ライブラリ、処理方式、ツール、アダプタ | 約55個 | +| ② | チェック項目 | 何に気をつけるべきか | 3タスク(30%) | セキュリティ、推奨/非推奨、公開API | 3個 | +| ③ | リリースノート | 何が変わった/壊れているか | 2タスク(20%) | バージョン単位 | 複数個 | +| **合計** | | | | | **約60個** | -**目的**: -AIエージェントにNablarchの構造化知識を提供し、以下を実現する: -1. 実装調査、コード生成、レビュー等の代行精度向上 -2. 開発工数の削減 -3. オンボーディング期間の短縮 +**設計判断**: ①を優先的に構造化すれば9割の作業をカバー可能です。①から着手します。 --- -### 1.2 スコープ - -**対象**: -- Nablarchバッチ(都度起動型) -- RESTful Webサービス - -**対象外**: -- Jakarta Batch -- 常駐バッチ(テーブルキュー型) -- ウェブアプリケーション(JSP/画面系) -- メッセージング(MOM) - -**想定ツール**: -- Claude Code(主要ターゲット) -- GitHub Copilot(サブターゲット) - ---- - -## 2. 要件と制約 - -### 2.1 代行タスクと知識要件(Step1の結果) - -#### 代行タスクの深掘り結果 - -仕様書の4作業を深掘りし、6作業を追加。計**10作業**を代行対象として確定した。 - -**代行タスク一覧と優先度**: - -| 分類 | 代行作業 | 優先度 | 工数削減効果 | 発生頻度 | AI代行適性 | -|------|---------|:------:|------------|---------|-----------| -| 仕様書指定 | 既存コード理解 | S | 60-70% | 週次以上 | 90%以上 | -| 追加提案 | コード生成・雛形作成 | S | 70-80% | 週次以上 | 90%以上 | -| 追加提案 | ナレッジQ&A | S | 90%以上 | 週次以上 | 90%以上 | -| 仕様書指定 | 実装調査 | A | 70-80% | 月次以上 | 80%以上 | -| 仕様書指定 | レビュー | A | 60-80% | 月次以上 | 80%以上 | -| 追加提案 | テストデータ作成 | A | 60-70% | 月次以上 | 80%以上 | -| 仕様書指定 | 影響分析 | B | 50-70% | 随時 | 70%以上 | -| 追加提案 | 障害調査 | B | 50-60% | 随時 | 70%以上 | -| 追加提案 | 設計書解読 | B | 40-50% | 随時 | 70%以上 | -| 追加提案 | ドキュメント生成 | B | 40-50% | 随時 | 70%以上 | - -**優先度の判断基準**(Step5レビュー反映): -- **S(最優先)**: 工数削減率60%以上 かつ 週次以上の発生頻度 かつ AI代行適性90%以上 -- **A(高優先)**: 工数削減率50%以上 かつ 月次以上の発生頻度 かつ AI代行適性80%以上 -- **B(中優先)**: 工数削減率40%以上 または 特定の場面で高い効果 かつ AI代行適性70%以上 - ---- - -#### 代行に必要な知識タイプ - -10作業の分析から、必要な知識を**3タイプ**に特定した(Step1で4タイプから統合)。 - -| 知識タイプ | 何がわかるか | 代行タスクのカバー範囲 | -|-----------|-------------|---------------------| -| ① 機能の使い方・実装パターン(エラー含む) | どう実装すればいいか、エラーが出たらどうするか | 9タスク(90%)をカバー | -| ② チェック項目 | 何に気をつけるべきか | 3タスク(30%)をカバー | -| ③ リリースノート・既知問題 | 何が変わった/壊れているか | 2タスク(20%)をカバー | - -**結論**: ①を構造化すれば9割の作業をカバーできる。**①から着手する。** - -**④エラー対処を①に統合した根拠**: -- エラーは発生元の機能(ハンドラ/ライブラリ)に紐づく -- 代行時、エラー調査は「どの機能で発生したか」から始まる -- 機能の知識にエラー情報を含めた方が、1回の参照で完結する -- Nablarchの解説書も、各機能ページ内にエラー情報を記載している - ---- - -#### 代行タスクと知識タイプのマッピング - -| 代行作業 | ①機能・パターン | ②チェック | ③リリース | -|---------|:-------------:|:--------:|:--------:| -| 既存コード理解 | ◎ | | | -| 実装調査 | ◎ | | | -| 影響分析 | ◎ | | | -| レビュー | ◎ | ◎ | | -| コード生成 | ◎ | ◎ | | -| テストデータ作成 | ◎ | | | -| 障害調査 | ◎ | | ◎ | -| 設計書解読 | ◎ | | | -| ドキュメント生成 | ◎ | | | -| ナレッジQ&A | ◎ | ◎ | ◎ | -| **必要な作業数** | **9** | **3** | **2** | - -**凡例**: ◎ 必須 - ---- - -### 2.2 情報源と作成範囲(Step2の結果) - -#### Nablarch公式情報の構造 - -**対象範囲**: Nablarchバッチ(都度起動型)、RESTful Webサービス - -##### 解説書 (https://nablarch.github.io/docs/LATEST/doc/) - -| カテゴリ | 内容 | 対象範囲 | -|---------|------|---------| -| **処理方式** | Nablarchバッチ(都度起動型)、RESTful Webサービス | ○ | -| **ハンドラ** | 共通ハンドラ、バッチ専用ハンドラ、REST専用ハンドラ | ○ | -| **ライブラリ** | データベースアクセス、入力値チェック、トランザクション管理、ファイルI/O、ログ出力、システムリポジトリ等 | ○ | -| **ツール** | NTF(Testing Framework)、gsp-dba-maven-plugin、SQL Executor | ○ | -| **アダプタ** | ログ関連、DB関連、REST関連、メール関連、監視関連 | ○ | -| **設定ガイド** | デフォルト設定一覧、設定変更方法、環境別設定管理 | ○ | -| **移行ガイド** | Nablarch 5→6移行手順、Jakarta EE対応 | ○ | -| **リリースノート** | バージョン別変更履歴(GitHub Releasesと連携) | ○ | -| **API Doc** | Javadoc(/javadoc/配下) | △ 参照 | - -##### システム開発ガイド (https://fintan.jp/page/252/) - -| カテゴリ | 内容 | 対象範囲 | -|---------|------|---------| -| **開発プロセス** | 全体像、設計工程、製造工程、テスト工程 | △ 参考 | -| **Nablarchパターン集** | よく使われる設計・実装パターン(バッチ、REST関連) | ○ | -| **Nablarchアンチパターン** | やってはいけないパターンと理由 | ○ | -| **サンプルプロジェクト** | 開発ガイド、テスト標準、設計書サンプル | △ 参考 | - -**システム開発ガイドの重要性**(Step5レビュー反映): -- Fintanのシステム開発ガイドは、実装パターンとアンチパターンの主要情報源 -- 解説書(機能説明)とシステム開発ガイド(実装パターン)を組み合わせることで、より実践的な知識を提供 -- パターン集とアンチパターンは、コード生成やレビュー代行で特に重要 - -##### Example (https://github.com/nablarch/) - -| リポジトリ | 内容 | 対象範囲 | -|-----------|------|---------| -| **nablarch-example-batch** | Nablarchバッチの実装サンプル | ○ | -| **nablarch-example-rest** | RESTful Webサービスの実装サンプル | ○ | - -##### 対象外 - -| 対象外 | 理由 | -|--------|------| -| Jakarta Batch | 仕様書で対象外 | -| 常駐バッチ(テーブルキュー型) | 仕様書で対象外 | -| ウェブアプリケーション(JSP/画面系) | 仕様書で対象外 | -| メッセージング(MOM) | 仕様書で対象外 | - ---- - -#### 知識タイプと作成単位 - -| # | 知識タイプ | 作成単位 | 推定件数 | -|---|-----------|---------|---------| -| ① | 機能・実装パターン(エラー含む) | ハンドラ単位、ライブラリ単位、処理方式単位、ツール単位、アダプタ単位 | 約55個 | -| ② | チェック項目 | セキュリティ、推奨/非推奨、公開API/非公開API | 3個 | -| ③ | リリースノート | バージョン単位 | 複数個 | -| **合計** | | | **約60個** | - -**対象範囲の規模**(Step2より): - -| 対象 | ハンドラ数 | ライブラリ | 備考 | -|------|-----------|-----------|------| -| Nablarchバッチ | 約15個 | DB、ファイルI/O、バリデーション | 共通 + バッチ専用 | -| RESTful | 約12個 | DB、バリデーション、JSON変換 | 共通 + REST専用 | -| **合計(重複除く)** | **約20個** | **約15機能** | | - ---- - -#### 情報の持ち方の考え方 - -**基本原則**(Step2で定義): - -| 原則 | 説明 | 判断基準 | -|------|------|---------| -| **仕様は全部残す** | 必須もオプションも、推奨も非推奨も網羅。省略すると代行精度が下がる | 設定項目、デフォルト値、型、制約、動作仕様、理由・背景、注意点、警告をすべて含む | -| **考え方も全部残す** | 理由・背景・なぜそうするかは残す。判断根拠として必要 | 設計思想、推奨パターン、注意事項をすべて含む | -| **表現は最適化する** | 読み物的記述→端的な記述。重複は排除。情報量は維持したまま簡潔に | 導入文(「本章では〜」等)、冗長な説明、重複表現、段階的な説明を削除し、箇条書き化 | -| **形式はAI向けに** | 人間向けの段階的説明→構造化データ。検索・参照しやすい形式に | JSON形式、検索ヒント設計により検索性向上 | - -**「仕様は全部残す」と「表現は最適化する」の両立基準**(Step5レビュー反映): -- **残すもの**: 設定項目、デフォルト値、型、制約、動作仕様、理由・背景、注意点、警告 -- **最適化するもの**: 導入文(「本章では〜」等)、冗長な説明、重複表現、段階的な説明→箇条書き -- **判断基準**: 「この情報がないとAIが誤った判断をする可能性があるか?」で判断。YESなら残す、NOなら最適化 - ---- - -### 2.3 制約事項と前提条件 - -#### 対象範囲の制約 - -| 対象 | 対象外 | -|------|--------| -| Nablarchバッチ(都度起動型) | Jakarta Batch | -| RESTful Webサービス | 常駐バッチ(テーブルキュー型) | -| | ウェブアプリケーション(JSP/画面系) | -| | メッセージング(MOM) | - -#### バージョン管理方針 - -- 多くのプロジェクトは過去バージョン(OSS化前で非公開)を使用 -- 1プロジェクト=1バージョン(完全分離) -- バージョンアップ時は両方参照可能にする -- バージョン別スキル分離(nabledge-5, nabledge-6) - -#### 想定ツール - -| ツール | 用途 | 備考 | -|--------|------|------| -| **Claude Code** | エージェント型開発支援 | 主要ターゲット | -| **GitHub Copilot** | コード補完・提案 | サブターゲット | - -#### 段階的アプローチ - -- **短期**: AI向け最適化ファイル+人向け根拠確認ビュー → プロジェクトに配布 -- **中期**: MCPサーバー化 → 両ツールから接続 - -#### 前提条件 - -1. **情報源の信頼性**: 公式ドキュメント(RST版)を主要情報源とする -2. **プロジェクトの想定**: Java経験2年以上、Nablarch未経験者が主要ユーザー -3. **作業環境**: Claude Code、GitHub Copilotがインストールされている -4. **品質保証**: 20%のサンプリングレビュー、Nablarch有識者による確認 - ---- - -[続く - 次は「3. アーキテクチャ設計」] - -## 3. アーキテクチャ設計(Step3の結果を中心に) - -### 3.1 ユーザー体験設計 +### 2.3 配布とインストール #### 配布形式 -[Claude Code Plugin](https://code.claude.com/docs/en/plugins)として配布。GitHub Copilotも同じスキル構造を認識可能。 +[Claude Code Plugin](https://code.claude.com/docs/en/plugins)として配布します。 **配布元**: GitHub (`github.com/nablarch/nabledge`) -**配布の流れ**: +**配布フロー**: ``` -📦 GitHub - └─ org: nablarch - └─ repository: nabledge - ↓ Claude Code Pluginとして配布 - ↓ claude plugin install nabledge-6 - ユーザー環境(.claude/skills/nabledge-6/) +GitHub (nablarch/nabledge) + ↓ Claude Code Plugin Registry + ↓ claude plugin install nabledge-6 +ユーザー環境 (.claude/skills/nabledge-6/) ``` #### インストール方法 -##### Claude Code - +**Claude Code**: ```bash -# Plugin Registryからインストール(推奨) -# 内部でgithub.com/nablarch/nabledgeから取得 +# Plugin Registryからインストール claude plugin install nabledge-6 -# インストール確認 +# 確認 claude plugin list -# アップデート(最新版をGitHubから取得) +# アップデート claude plugin update nabledge-6 ``` -**動作イメージ**: -```bash -$ claude plugin install nabledge-6 -✓ Fetching from github.com/nablarch/nabledge -✓ Downloading nabledge-6 -✓ Installing knowledge files (60 files, ~420K tokens) -✓ Installing workflows (10 workflows) -✓ Installing index (93 entries) -✓ nabledge-6 installed successfully - -Next steps: - Try: "Nablarchでページングを実装したい" -``` - -##### GitHub Copilot - -プロジェクトルートにスキルフォルダを配置: - -```bash -# プロジェクトにスキルを配置 -mkdir -p .claude/skills -cd .claude/skills - -# nabledge-6スキルを配置(配布パッケージから展開) -# [配布パッケージ取得方法は、実装フェーズで決定] -``` - -**設定ファイルへの登録**: -```json -{ - "skills": [ - { - "name": "nabledge-6", - "path": ".claude/skills/nabledge-6", - "enabled": true - } - ] -} -``` +**GitHub Copilot**: +プロジェクトルートに`.claude/skills/nabledge-6/`を配置し、設定ファイルに登録します。 -#### 利用方法 - -| 操作 | Claude Code | GitHub Copilot | -|------|-------------|----------------| -| **インストール** | `claude plugin install nabledge-6` | プロジェクトに配置 + 設定ファイル登録 | -| **アップデート** | `claude plugin update nabledge-6` | パッケージ再配置 | -| **利用** | 自然言語で依頼
例: 「ページングを実装したい」 | 自然言語で依頼
例: 「UniversalDaoの使い方は?」 | -| **手動実行** | `/nabledge-6 search ページング` | `/nabledge-6 search ページング` | - -#### 設計観点・選定理由 - -| 観点 | 選択肢 | 選定 | 理由 | -|------|--------|:----:|------| -| 配布元 | GitHub (nablarch/nabledge) | ✓ | オープンソースプロジェクトとして公開、バージョン管理、履歴追跡が容易 | -| | 独自サーバー | | 保守コストが高い、更新通知の仕組みが必要 | -| 配布形式 | Claude Code Plugin (GitHub経由) | ✓ | Claude Codeの標準配布方式。GitHub → Plugin Registry → インストールの流れで自動更新可能 | -| | npm/pipパッケージ | | 開発者向けツールには適するが、エンドユーザーのインストールが煩雑 | -| | zip配布 | | 手動配置が必要でアップデートも手動になる | -| インストール | Claude: `claude plugin install` | ✓ | 標準コマンド、GitHubから自動取得、バージョン管理機能あり | -| | GitHub Copilot: プロジェクト配置 | ✓ | プロジェクトごとにスキルを配置、設定ファイルで有効化 | -| バージョン分離 | バージョン別スキル(nabledge-5, nabledge-6) | ✓ | PJは1バージョンのみ使用。不要な情報がコンテキストに入らない | -| | 単一スキルでバージョン切替 | | コンテキスト肥大化、検索ノイズの原因になる | +**設計判断**: Claude Codeの標準配布方式を採用します。GitHubからの自動取得、バージョン管理、更新通知が容易です。 --- -### 3.2 ファイル構成と命名規則 - -#### スキル構成 +### 2.4 ファイル構成 ``` nabledge-6/ -├── SKILL.md +├── SKILL.md # スキル定義 ├── knowledge/ # 知識 │ ├── index.toon # 検索インデックス(TOON形式) -│ ├── features/ # ① 機能・実装パターン(エラー含む) -│ │ ├── handlers/ -│ │ │ ├── common/ -│ │ │ ├── web/ -│ │ │ ├── web_interceptor/ -│ │ │ ├── rest/ -│ │ │ ├── standalone/ -│ │ │ ├── batch/ -│ │ │ └── messaging/ -│ │ ├── libraries/ -│ │ ├── processing/ -│ │ ├── tools/ -│ │ └── adapters/ +│ ├── features/ # ① 機能・実装パターン +│ │ ├── handlers/ # ハンドラ単位 +│ │ ├── libraries/ # ライブラリ単位 +│ │ ├── processing/ # 処理方式単位 +│ │ ├── tools/ # ツール単位 +│ │ └── adapters/ # アダプタ単位 │ ├── checks/ # ② チェック項目 -│ │ ├── security.json -│ │ ├── public-api.json -│ │ ├── public-api-list.txt -│ │ └── deprecated.json │ └── releases/ # ③ リリースノート -│ └── {version}.json -├── workflows/ # ワークフロー(代行単位で作成) -│ └── {workflow-name}.md -├── scripts/ # スクリプト(セットアップ、代行に必要なスクリプトなど) -├── assets/ # アセット(代行の出力結果テンプレートなど) -└── docs/ # 人向け閲覧用(知識をMarkdownに自動変換) +├── workflows/ # ワークフロー(代行単位) +├── scripts/ # スクリプト +├── assets/ # アセット +└── docs/ # 人向け閲覧用(JSON→MD自動変換) ``` -#### 命名規則 - -| 対象 | 規則 | 例 | -|------|------|-----| -| ファイル名 | 英語、kebab-case | `db-connection-management-handler.json` | -| ディレクトリ名 | 英語、kebab-case | `handlers/`, `common/` | +**命名規則**: 英語、kebab-case(例: `db-connection-management-handler.json`) -※バージョン情報はファイル名に含めない(スキル自体がバージョン別のため) +**設計判断**: バージョン情報はファイル名に含めません(スキル自体がバージョン別のため冗長です)。 --- -### 3.3 検索パス設計 +### 2.5 検索アーキテクチャ #### 2つの検索方式 @@ -551,55 +239,43 @@ nabledge-6/ | keyword-search | 技術軸 | index.toonのhintsでキーワードマッチ | | intent-search | 目的軸 | 目的→カテゴリ、対象→ファイルで絞込 | -※詳細なワークフローは「検索ワークフロー定義」を参照 +**設計判断**: 単一検索では漏れが発生しやすいため、異なる切り口で並列実行し、結果をマージすることで漏れを防止します。 -#### pointers構造 +#### 検索結果構造(pointers) ```json { "files": [ - { "id": "F1", "path": "features/libraries/universal-dao.json", "relevance": 2, "matched_hints": ["ページング", "検索"] }, - { "id": "F2", "path": "features/libraries/database-access.json", "relevance": 1, "matched_hints": ["データベース"] } + { "id": "F1", "path": "features/libraries/universal-dao.json", "relevance": 2 } ], "sections": [ - { "file_id": "F1", "section": "paging", "relevance": 2, "matched_hints": ["ページング", "per", "page"] }, - { "file_id": "F1", "section": "search", "relevance": 2, "matched_hints": ["検索"] }, - { "file_id": "F2", "section": "query", "relevance": 1, "matched_hints": ["SQL"] } + { "file_id": "F1", "section": "paging", "relevance": 2, "matched_hints": ["ページング", "per", "page"] } ] } ``` -**ポイント**: -- sectionsを関連度降順で見れば、最も関連するセクションから読める -- filesを見れば、どのファイルが重要か全体像がわかる -- ファイルパスは1回だけ出現、file_idで参照(重複排除) -- matched_hintsで判断根拠を確認可能 +**設計判断**: +- sections を関連度降順でソートすることで、最重要セクションから読めます +- files でファイル単位の重要度を把握できます +- ファイルパスは1回だけ出現し、file_idで参照します(重複排除) -#### 並列実行 +#### 関連度定義 -| ツール | 方式 | -|--------|------| -| Claude Code | Task Toolで並列実行(最大10並列、各サブエージェントは独立コンテキスト) | -| GitHub Copilot | 複数エージェント並列実行(Explore, Task, Plan, Code-review等)| +| レベル | 値 | 判断基準 | +|:------:|:---:|---------| +| **High** | 2 | 依頼に直接回答できる | +| **Partial** | 1 | 依頼に関連し、補足として有用 | +| **None** | 0 | 関連なし(対象外) | -#### 設計観点・選定理由 +**ファイルの関連度**: そのファイル内のセクション関連度の最大値 -| 観点 | 選択肢 | 選定 | 理由 | -|------|--------|:----:|------| -| 検索方式 | 単一 | | 1つの切り口だけでは漏れが発生しやすい | -| | 複数並列(keyword + intent) | ✓ | 異なる切り口で漏れを減らす | -| 関連度の算出タイミング | index時 | | 中身を見ないと正確な関連度は出せない | -| | ファイル読込時 | ✓ | 依頼との関連度は中身を見てから判断 | -| pointers構造 | フラット(file+section混在) | | ファイル単位でまとまらない、優先順位がつけにくい | -| | 階層(files + sections分離) | ✓ | セクション関連度降順で最重要から読める | -| 並列実行 | 逐次実行 | | 時間がかかる | -| | Task Tool並列 | ✓ | Claude Code公式機能、最大10並列対応 | +**設計判断**: 情報検索分野の標準的なgraded relevanceを採用します。3段階で十分な精度が得られます。 --- -### 3.4 インデックス設計(index.toon) +### 2.6 インデックス設計(index.toon) -#### index.toon形式 +#### TOON形式 ```toon # Nabledge-6 Knowledge Index @@ -613,342 +289,94 @@ files[N,]{path,hints}: - `files[N,]{path,hints}:` → N件の配列、フィールドはpath, hints - 各行: `パス, スペース区切りの検索ヒント` -**スケーラビリティ設計**(Step5レビュー反映): -- 現状: 93エントリ、約650検索ヒント -- 将来規模: 約200エントリ、約1,500検索ヒント(Nablarch全体をカバー) -- 対策: - 1. **階層化**: カテゴリ別のインデックス(handlers.toon, libraries.toon等)を検討 - 2. **圧縮**: TOONフォーマットはトークン効率が良く、200エントリでも約5-7Kトークン程度と推定 - 3. **キャッシュ**: 頻繁に使われるファイルは、検索結果をキャッシュ -- 数百ファイル規模になった時点で、階層化インデックスへの移行を検討 +**規模**: 93エントリ、約650検索ヒント → 約5-7Kトークン -#### 設計観点・選定理由 +**設計判断**: TOON形式はJSONより30-60%トークン削減します。LLMフレンドリーで高効率です。 -| 観点 | 選択肢 | 選定 | 理由 | -|------|--------|:----:|------| -| インデックス形式 | JSON | | 冗長、トークン消費大 | -| | TOON | ✓ | トークン効率が良い(30-60%削減)、LLMフレンドリー | +#### 検索ヒント設計指針 ---- +**3段階のキーワード抽出**: -### 3.5 知識ファイル設計(JSONスキーマ) +知識ファイルの検索ヒントは、以下の3段階でキーワードを抽出します。このうち2段階以上でマッチすることを推奨します。 -#### 共通JSONスキーマ構造 +1. **Technical domain(技術領域)**: データベース, バッチ, ハンドラ, Web, REST, テスト など +2. **Technical component(技術要素)**: DAO, JDBC, JPA, Bean Validation, JSON, XML など +3. **Functional(機能)**: ページング, 検索, 登録, 更新, 削除, 接続, コミット など -```json -{ - "schema_version": "1.0", - "id": "ファイル識別子", - "title": "タイトル(日本語)", - "official_doc_urls": ["https://nablarch.github.io/docs/..."], - "index": [ - { "id": "セクションID", "hints": ["検索ヒント1", "検索ヒント2"] } - ], - "sections": { - "overview": { - "summary": "このファイルの要約(100-200文字)", - /* その他のセクション固有のプロパティ */ - }, - "セクションID": { /* セクション固有のプロパティ */ } - } -} -``` +**例**: 依頼「ページングを実装したい」の場合 +- Technical domain: ["データベース", "database"] +- Technical component: ["DAO", "UniversalDao", "O/Rマッパー"] +- Functional: ["ページング", "paging", "per", "page", "limit", "offset"] -**スキーマのバージョニング**(Step5レビュー反映): -- `schema_version` フィールドを追加し、スキーマのバージョンを明記 -- スキーマ変更時の対応: - 1. **互換性のある変更**(フィールド追加等): マイナーバージョンアップ(1.0 → 1.1) - 2. **非互換な変更**(フィールド削除、構造変更): メジャーバージョンアップ(1.0 → 2.0) -- AIエージェントは `schema_version` を確認し、対応するパーサーを使用 -- 移行期間中は、旧スキーマと新スキーマの両方をサポート - -**サマリー情報の追加**(Step5レビュー反映): -- 各ファイルの `overview` セクションに `summary` フィールドを追加 -- 100-200文字程度で、このファイルの要点を記載 -- 用途: 検索結果一覧で、ユーザーが素早くファイルの内容を把握できる - -**Nablarch用語集の追加計画**(Step5レビュー反映): -- `features/glossary.json` を追加し、Nablarch独自の用語を定義 -- 構造: - ```json - { - "id": "glossary", - "title": "Nablarch用語集", - "terms": [ - { - "term": "リクエストパス", - "reading": "リクエストパス", - "english": "request path", - "definition": "アクションクラスを特定するための識別子。パッケージ名とクラス名を結合したもの。", - "related": ["action", "dispatch"] - } - ] - } - ``` -- 用語集は、overview.jsonと同様に基礎知識として提供 +**基本指針**: + +| 項目 | 指針 | +|------|------| +| 言語 | 日本語基本。公式で英語のものはそのまま | +| 語数 | ファイル: 5-10語、セクション: 3-5語 | +| 順序 | 広い技術領域→詳細(降順)例: `DB 接続 コネクション` | +| 表記揺れ | 複数表記を含める(例: DB, データベース, database) | -**検索ヒントの配置**: -- ファイルレベル: index.toon -- セクションレベル: index +**設計判断**: 3段階でキーワードを網羅的に抽出し、2段階以上でマッチさせることで検索精度を向上させます。 --- -#### 知識タイプ別スキーマ - -##### ① 機能・実装パターン +### 2.7 知識ファイル設計(JSONスキーマ) -**ハンドラ単位** - 代表例: DbConnectionManagementHandler +#### 共通構造 ```json { - "id": "db-connection-management-handler", - "title": "データベース接続管理ハンドラ", + "schema_version": "1.0", + "id": "ファイル識別子", + "title": "タイトル(日本語)", "official_doc_urls": ["https://nablarch.github.io/docs/..."], "index": [ - { "id": "overview", "hints": ["DbConnectionManagementHandler", "DB接続"] }, - { "id": "processing", "hints": ["コネクション取得", "コネクション解放"] }, - { "id": "setup", "hints": ["設定", "XML", "connectionFactory"] }, - { "id": "constraints", "hints": ["ハンドラ順序", "TransactionManagementHandler"] }, - { "id": "errors", "hints": ["SQLException", "接続エラー"] } - ], - "sections": { - "overview": { "class_name": "...", "description": "...", "purpose": "..." }, - "processing": { "flow": [...] }, - "setup": { "properties": [...] }, - "constraints": { "handler_order": [...] }, - "errors": [{ "exception": "...", "cause": "...", "solution": "..." }] - } -} -``` - -**ライブラリ単位** - 代表例: UniversalDao - -```json -{ - "id": "universal-dao", - "title": "ユニバーサルDAO", - "index": [ - { "id": "overview", "hints": ["UniversalDao", "ユニバーサルDAO"] }, - { "id": "crud", "hints": ["登録", "更新", "削除", "insert", "update"] }, - { "id": "paging", "hints": ["ページング", "per", "page", "offset"] }, - { "id": "anti-patterns", "hints": ["SQLインジェクション", "生SQL"] }, - { "id": "errors", "hints": ["DuplicateKeyException", "一意制約違反"] } - ], - "sections": { - "overview": { "classes": [...], "annotations": [...] }, - "crud": { "methods": [...], "examples": [...] }, - "paging": { "description": "...", "example": "..." }, - "anti-patterns": [{ "pattern": "...", "reason": "...", "correct": "..." }], - "errors": [{ "exception": "...", "cause": "...", "solution": "..." }] - } -} -``` - -**処理方式単位** - 代表例: Nablarchバッチ - -```json -{ - "id": "nablarch-batch", - "title": "Nablarchバッチ(都度起動型)", - "index": [ - { "id": "overview", "hints": ["Nablarchバッチ", "都度起動"] }, - { "id": "architecture", "hints": ["アーキテクチャ", "ハンドラキュー"] }, - { "id": "responsibility", "hints": ["責務配置", "Action", "Form"] }, - { "id": "patterns", "hints": ["FILE to DB", "DB to FILE"] } - ], - "sections": { - "overview": { "description": "...", "use_cases": [...] }, - "architecture": { "diagram": "...", "components": [...] }, - "responsibility": { "action": "...", "form": "..." }, - "patterns": [{ "name": "...", "description": "...", "example": "..." }] - } -} -``` - -**ツール単位** - NTFは機能ごとに分割(6ファイル) - -| ファイル | 内容 | -|---------|------| -| ntf-overview.json | 概要・共通設定 | -| ntf-batch-request-test.json | バッチリクエスト単体テスト | -| ntf-rest-test.json | RESTテスト | -| ntf-db-test.json | DBテスト | -| ntf-test-data.json | テストデータ形式 | -| ntf-assertion.json | アサーション・期待値検証 | - -**アダプタ単位** - 構造はライブラリ単位と同様 - -##### ② チェック項目 - -**セキュリティ** - -```json -{ - "id": "security", - "title": "セキュリティチェック項目", - "index": [ - { "id": "csrf", "hints": ["CSRF", "トークン"] }, - { "id": "xss", "hints": ["XSS", "エスケープ"] }, - { "id": "sql-injection", "hints": ["SQLインジェクション", "プレースホルダ"] } - ], - "sections": { - "csrf": { "threat": "...", "check_points": [...], "correct_implementation": "...", "ng_patterns": [...] } - } -} -``` - -**公開API** - ホワイトリストを別ファイルに切り出し - -```json -{ - "id": "public-api", - "title": "公開API", - "published": "public-api-list.txt", - "index": [ - { "id": "overview", "hints": ["公開API", "使用可能"] } + { "id": "セクションID", "hints": ["検索ヒント1", "検索ヒント2"] } ], "sections": { - "overview": { "description": "公開APIはpublishedで指定したファイルに一覧化" } + "overview": { + "summary": "100-200文字の要約", + /* セクション固有のプロパティ */ + }, + "セクションID": { /* ... */ } } } ``` -```text -// public-api-list.txt(1行1クラス) -nablarch.common.dao.UniversalDao -nablarch.fw.web.HttpResponse -... -``` - -**非推奨機能** - 構造はセキュリティと同様 +**設計判断**: +- **JSON形式**: パース容易、jqでセクション抽出可能、構造化データとして扱いやすいです +- **二層構造(JSON + Markdown)**: AI向けJSON、人向けMD(自動変換)でメンテナンス1箇所で済みます +- **スキーマバージョニング**: 非互換変更時にメジャーバージョンアップします(1.0 → 2.0) -##### ③ リリースノート +#### 情報の持ち方の原則 -```json -{ - "id": "release-6u3", - "title": "Nablarch 6u3 リリースノート", - "index": [ - { "id": "changes", "hints": ["変更", "新機能"] }, - { "id": "breaking", "hints": ["非互換", "破壊的変更"] }, - { "id": "migration", "hints": ["移行手順", "アップグレード"] } - ], - "sections": { - "changes": [{ "type": "feature", "description": "..." }], - "breaking": [{ "description": "...", "before": "...", "after": "..." }], - "migration": { "steps": [...], "examples": [...] } - } -} -``` - ---- - -#### 検索ヒントの設計指針 +| 原則 | 説明 | 判断基準 | +|------|------|---------| +| **仕様は全部残す** | 必須/オプション、推奨/非推奨も網羅します | 設定項目、デフォルト値、型、制約、動作仕様、理由・背景、注意点、警告をすべて含みます | +| **考え方も全部残す** | 理由・背景・なぜそうするかを残します | 設計思想、推奨パターン、注意事項をすべて含みます | +| **表現は最適化する** | 読み物的記述→端的な記述にします | 導入文、冗長な説明、重複表現、段階的な説明を削除し、箇条書き化します | +| **形式はAI向けに** | 構造化データで検索・参照しやすくします | JSON形式、検索ヒント設計を採用します | -| 項目 | 指針 | -|------|------| -| 言語 | 日本語基本。公式で英語のものはそのまま | -| 語数 | ファイル: 5-10語、セクション: 3-5語 | -| 順序 | 広い技術領域→詳細(降順)例: `DB 接続 コネクション` | -| 内容 | ユーザーが依頼文で使いそうな言葉、クラス名、メソッド名、例外名 | - -**検索ヒントの具体的な選定基準**(Step5レビュー反映): -1. **技術用語**: 公式ドキュメントに出現する用語(例: トランザクション、バリデーション) -2. **クラス名・メソッド名**: 完全修飾名と短縮名の両方(例: UniversalDao, nablarch.common.dao.UniversalDao) -3. **日本語表記**: 公式ドキュメントの日本語表記(例: ユニバーサルDAO) -4. **類義語**: 同じ概念を指す異なる表現(例: DB, データベース, database) -5. **エラー名**: 例外クラス名とエラーメッセージの一部(例: SQLException, 接続エラー) -6. **ユースケース**: よくある依頼文に含まれる言葉(例: ページング→「ページング 検索 per page limit offset」) - -**表記揺れ対策**(Step5レビュー反映): -- Nablarch固有の用語は、複数の表記を検索ヒントに含める - - 例: 「ユニバーサルDAO」「UniversalDao」「universal-dao」 -- カタカナ表記と英語表記の両方を含める - - 例: 「トランザクション」「transaction」 -- 略語と正式名称の両方を含める - - 例: 「DB」「データベース」「database」 - -#### 人向けMarkdown - -JSONから自動変換。docs/配下に配置。 - -#### 設計観点・選定理由 - -| 観点 | 選択肢 | 選定 | 理由 | -|------|--------|:----:|------| -| 形式 | Markdown | | 構造化しにくい、セクション抽出困難 | -| | YAML | | JSONより可読性高いがMCPとの相性悪い | -| | JSON | ✓ | パース容易、MCPスキーマ定義可能、jqでセクション抽出可能 | -| 二層構造 | AI専用 | | 人が確認できない | -| | 人専用 | | AIが構造化データとして扱えない | -| | 両方(JSON→MD変換) | ✓ | メンテナンス1箇所、用途別に最適化 | +**設計判断**: 「この情報がないとAIが誤った判断をする可能性があるか?」で判断します。YESなら残し、NOなら最適化します。 --- -### 3.6 コンテキスト管理戦略 +### 2.8 コンテキスト管理 -#### 関連度定義 - -ファイル・セクションの関連度を3段階で評価(情報検索分野の標準的なgraded relevance)。 - -| レベル | 値 | 判断基準 | 判断例(依頼:「ページングを実装したい」) | -|:------:|:---:|---------|------------------------------------------| -| **High** | 2 | 依頼に直接回答できる | universal-dao.jsonのpagingセクション | -| **Partial** | 1 | 依頼に関連し、補足として有用 | database-access.json(基盤知識) | -| **None** | 0 | 関連なし(対象外) | mail.json | - -**関連度判定の詳細プロセス**(Step5レビュー反映): -1. **High(2点)の判断基準**: - - セクションのタイトル or 説明に、依頼のキーワードが直接含まれる - - セクションの内容で、依頼の要件を実装できるコード例・設定例がある - - セクションを読めば、依頼に対する具体的な解決策がわかる -2. **Partial(1点)の判断基準**: - - セクションの内容が、依頼の前提知識として必要 - - セクションの内容が、依頼の関連機能として参考になる - - セクションを読めば、依頼の理解が深まる -3. **None(0点)の判断基準**: - - セクションの内容が、依頼とは無関係 - - セクションを読んでも、依頼に対する情報が得られない - -**ファイルの関連度**: そのファイル内のセクション関連度の最大値 - -``` -例: universal-dao.json -├── overview: 1 (Partial) -├── paging: 2 (High) ← 最大 -├── search: 2 (High) -└── setup: 0 (None) +#### コンテキストウィンドウへの適合 -→ ファイルの関連度 = 2 -``` - -**判定の一貫性確保**: -- AIエージェントが判定する際は、上記の判断基準を明示的に参照 -- 判定結果に `matched_hints` を含めることで、判断根拠を追跡可能に - ---- - -#### コンテキストウィンドウへの適合性 - -**現状の課題**: -- Claude Opus 4.6のコンテキストウィンドウ: 200Kトークン -- 全60ファイルの推定トークン数: 約42万トークン(17ファイル476KB → 約12万トークン、全60ファイル = 約42万トークン相当) -- **問題**: 全ファイルをコンテキストに含めることは不可能 +**制約**: +- Claude Opus 4.6のコンテキストウィンドウ: 200,000トークン +- 全60ファイルの推定トークン数: 約420,000トークン **対策**: -1. **セクション単位の抽出**: ファイル全体ではなく、関連度の高いセクションのみを抽出 - - 上位10セクション(平均500トークン)= 約5,000トークン - - 残り195,000トークンを他の情報(プロジェクトコード、会話履歴等)に使用可能 -2. **関連度による絞り込み**: 関連度2(High)のセクションを優先し、必要最小限の情報のみを取得 -3. **動的調整**: コンテキストウィンドウの使用率に応じて、取得セクション数を調整 -4. **階層的検索**: まずファイル一覧を確認し、必要なファイルのみ詳細を取得 - -**トークン量の監視**: -- 各検索結果に、推定トークン数を表示 -- コンテキストウィンドウの使用率をモニタリング -- 使用率が80%を超えた場合、警告を表示し、セクション数を減らす +1. **セクション単位の抽出**: 関連度の高いセクションのみを抽出します + - 上位10セクション(平均500トークン)= 約5,000トークン(全体の2.5%) +2. **関連度による絞り込み**: High(2点)のセクションを優先します +3. **動的調整**: コンテキスト使用率に応じて取得セクション数を調整します ---- +**設計判断**: ファイル全体を取得するのではなく、セクション単位で抽出することで、コンテキストウィンドウ内で運用可能にします。 #### 上位N件抽出の根拠 @@ -956,597 +384,116 @@ JSONから自動変換。docs/配下に配置。 |------|--------|------| | files | 上位5件 | 1ファイル平均2000トークン × 5 = 10,000トークン | | sections | 上位10件 | 1セクション平均500トークン × 10 = 5,000トークン | -| 合計 | 約15,000トークン | コンテキストの10-15%程度、他の情報と併用可能 | - -**動的調整メカニズム**(Step5レビュー反映): -- **基本**: 上位5ファイル、10セクションを抽出 -- **調整条件**: - 1. 関連度2(High)のセクションが10件未満の場合、関連度1(Partial)も含めて最大15件まで拡張 - 2. 関連度2のセクションが20件以上ある場合、上位15件まで拡張(より多くの選択肢を提供) - 3. コンテキストウィンドウの使用率が80%を超える場合、セクション数を減らす(最小5件) -- **理由**: 依頼の複雑さに応じて、情報量を動的に調整することで、精度とトークン効率を両立 - ---- - -#### 検索失敗時の対応(Step5レビュー反映) - -**検索結果0件の場合**: -1. エラーメッセージ: 「関連する知識が見つかりませんでした。依頼を具体的にするか、異なるキーワードで試してください。」 -2. 代替提案: index.toonの上位10件をリスト表示し、「これらの知識が参考になるかもしれません」と提案 -3. フォールバック: overview.jsonを返し、Nablarchの基本情報から開始 - -**検索結果が少ない場合(1-2件)**: -1. 関連度1(Partial)のセクションも含めて、最大10件まで表示 -2. 「関連する情報は限られています。より具体的な依頼をすると、精度が向上します。」とフィードバック - ---- - -#### トークン効率の定量評価 - -**TOON形式の効果**: -- JSON形式: フィールド名、括弧、引用符等で冗長 - ```json - {"path": "features/handlers/common/global-error-handler.json", "hints": ["グローバルエラーハンドラ", "GlobalErrorHandler"]} - ``` - - 文字数: 約150文字 → 約100トークン -- TOON形式: 構造をヘッダーで宣言し、データは最小限 - ``` - features/handlers/common/global-error-handler.json, グローバルエラーハンドラ GlobalErrorHandler - ``` - - 文字数: 約100文字 → 約60トークン -- **削減率**: 約40% (100 → 60トークン) - -**実測データ(Step4より)**: -- index.toon: 93エントリ、約650検索ヒント → 推定5-7Kトークン -- JSON形式の場合: 推定10-12Kトークン -- **削減率**: 約40-50% - ---- - -[続く - 次は「4. 実現性評価(Step4の結果)」] - -## 4. 実現性評価(Step4の結果) - -### 4.1 サンプル作成と検証結果 - -#### 作成したサンプル一覧 - -**総数**: 17個の知識ファイル(476KB)+ 1個のインデックス(93エントリ) - -**内訳**: -- 厚く揃える知識(13ファイル): バッチ処理実装に直接必要な知識 -- 形式チェックのみの知識(3ファイル): 知識タイプの網羅性確認用 -- Nablarch概要(1ファイル): 基本情報 -- インデックス(1ファイル): index.toon(93エントリ、約650検索ヒント) - -**検証シナリオ**: 期間内プロジェクト出力バッチ(DB to File) -- 実装例: `ExportProjectsInPeriodAction.java`(promanプロジェクト) -- 処理内容: データベースからCSV出力、トランザクション制御 -- 使用されているNablarch API/クラス: 15個 -- ハンドラ構成: 10個 - -**検証結果**: -- ✅ 必要な知識をすべてカバー(13ファイル) -- ✅ 知識の粒度が適切(詳細すぎず、不足もない) -- ✅ 検索ヒントが実際のタスク依頼文に対応 - ---- - -#### トークン量と作成工数 - -**トークン量の定量評価**(Step5レビュー反映): - -| 項目 | 文字数/サイズ | 推定トークン数 | 備考 | -|------|------------|------------|------| -| **17ファイル合計** | 476KB | 約120,000トークン | 日本語と英語の混在、JSON形式 | -| - 1ファイル平均 | 28KB | 約7,000トークン | | -| - 最大ファイル | 39KB (database-access.json) | 約10,000トークン | | -| - 最小ファイル | 9.2KB (business-date.json) | 約2,300トークン | | -| **index.toon** | 約10KB | 約5,000-7,000トークン | TOON形式、93エントリ | -| **全60ファイル推定** | 約1.68MB | 約420,000トークン | 17ファイル × 3.5倍 | - -**トークン数算出方法**: -- 日本語: 1文字 ≈ 0.6トークン(漢字・ひらがな・カタカナ混在) -- 英語: 1単語 ≈ 1-1.5トークン -- JSON記号: 括弧・カンマ・引用符等で約10-15%増 -- 換算式: KB × 250 ≈ トークン数(日本語と英語の混在を考慮) - -**TOON形式の削減効果**(定量評価): -- JSON形式の場合: 93エントリ → 約12,000トークン -- TOON形式の場合: 93エントリ → 約5,000-7,000トークン -- **削減率**: 約40-50% - -**コンテキストウィンドウへの適合性**(Step5レビュー反映): -- Claude Opus 4.6のコンテキストウィンドウ: 200,000トークン -- **問題**: 全60ファイル(約420,000トークン)は、コンテキストウィンドウに収まらない -- **対策**: セクション単位の抽出により、必要最小限の情報のみを取得 - - 上位10セクション: 約5,000トークン(全体の2.5%) - - 残り195,000トークンを他の情報に使用可能 -- **結論**: セクション単位の抽出により、コンテキストウィンドウ内で運用可能 - -**作成工数の実績**: - -| カテゴリ | ファイル数 | 作成時間(分/ファイル) | 合計時間 | 備考 | -|---------|----------|---------------------|---------|------| -| 基盤(overview) | 1 | 約5分 | 約5分 | 複雑な構造のため時間がかかる | -| ライブラリ | 5 | 約3分 | 約15分 | 標準的な作成時間 | -| ハンドラ | 3 | 約3分 | 約9分 | 標準的な作成時間 | -| 処理方式 | 1 | 約4分 | 約4分 | やや複雑 | -| ツール(NTF) | 4 | 約3分 | 約12分 | 標準的な作成時間 | -| チェック | 1 | 約2分 | 約2分 | シンプルな構造 | -| リリース | 1 | 約1分 | 約1分 | シンプルな構造 | -| アダプタ | 1 | 約2分 | 約2分 | シンプルな構造 | -| **小計(実績)** | **17** | **平均2.9分** | **約50分** | **見積もり48分と一致** | - -**全60ファイルの見積もり**: -- 作成時間: 約2.6時間(1ファイル約2.6分) -- 品質チェック: 約1.5時間 -- **合計**: 約4.1時間 - ---- - -#### 品質評価 - -**総合判定**: ✅ **目的は達成可能** - -**評価結果**: - -| 評価項目 | 目標 | 実績 | 判定 | -|---------|------|------|:----:| -| **基本原則準拠** | 100% | 100% | ✅ | -| **スキーマ準拠性** | 100% | 99% | ✅ | -| **知識の正確性** | 95点以上 | 平均97.3点 | ✅ | -| **index.toon品質** | 高品質 | 5/5 ⭐⭐⭐⭐⭐ | ✅ | -| **作成工数** | 見積もり通り | 見積もり±0分 | ✅ | - -**知識の正確性検証**: -- 17ファイル中11ファイル(64.7%)の詳細検証を実施 -- 公式ドキュメント(RST版)との厳密照合を実施 -- **平均スコア**: 97.3/100点(非常に高品質) -- **品質分布**: - - 完璧な品質(100点): 5ファイル(45.5%) - - 優秀な品質(95-99点): 4ファイル(36.4%) - - 良好な品質(90-94点): 2ファイル(18.2%) -- **重大な問題**: 0件 -- **軽微な改善提案**: 3件のみ - -**構造化の観点への適合**: - -| 観点 | 目標 | 実現方法 | 判定 | -|------|------|---------|:----:| -| **検索速度** | 必要な情報に素早くたどり着ける | index.toon(93エントリ、650検索ヒント)により高速検索を実現 | ✅ | -| **コンテキスト肥大化防止** | 不要な情報はノイズとならない | ファイル分割(17ファイル、平均28KB)により必要な情報のみ取得可能 | ✅ | -| **トークン量最適化** | コンテキストウィンドウ上限内で必要情報を収める | TOON形式採用により30-60%削減 | ✅ | -| **正確性・根拠追跡性** | ミッションクリティカル領域で誤情報を許容しない | 公式ドキュメント(RST版)から直接取得、参照URLを明記 | ✅ | -| **保守性・更新容易性** | バージョンアップへの追従が必要 | バージョン別ディレクトリ構成、情報源の明確化により更新容易 | ✅ | - ---- - -### 4.2 リスク評価と対策 - -#### 識別されたリスク - -| # | リスク | 影響度 | 発生確率 | 対策 | 対策の効果 | -|---|--------|:------:|:------:|------|----------| -| 1 | 情報源の更新 | 中 | 高 | 公式リポジトリのウォッチ設定、リリースノート発行時の更新フロー確立 | リスク低減 | -| 2 | トークン量の増加 | 中 | 中 | TOON形式採用により30-60%削減済み | リスク回避 | -| 3 | 検索ヒントの調整 | 低 | 中 | 実際の代行タスクで検証し、必要に応じて追加・修正 | リスク受容 | -| 4 | スキーマの拡張 | 低 | 低 | 新しい知識タイプが発見された場合、スキーマを拡張 | リスク受容 | -| 5 | 作成工数の増加 | 中 | 中 | 並行作業用プロンプトの準備、作業標準化により効率化 | リスク低減 | -| 6 | 品質のばらつき | 中 | 中 | サンプリングレビュー(20%)、品質基準の明確化 | リスク低減 | - -#### 対策の詳細 - -**情報源の更新管理**: -- Nablarch公式リポジトリのウォッチ設定 -- リリースノート発行時の知識ファイル更新フロー確立 -- バージョン別ディレクトリ構成により、複数バージョンの並行管理を実現 - -**品質保証プロセス**(Step5レビュー反映): -1. **作成フェーズ**: AIエージェントが知識ファイルを作成 -2. **自動チェック**: スキーマ準拠性、JSON構文チェック -3. **サンプリングレビュー**: 20%のファイルを人間がレビュー(10%から拡大) - - ランダムサンプリング: 各カテゴリから均等に選択 - - 重点サンプリング: ハンドラ、主要ライブラリは必ずレビュー -4. **Nablarch有識者レビュー**: 重要ファイルの正確性検証 -5. **フィードバックループ**: レビューで発見された問題を、次回作成時に反映 - ---- - -## 5. レビューと改善(Step5の結果) - -### 5.1 有識者レビューの概要 - -#### 5ペルソナによるレビュー - -| ペルソナ | 評価観点 | 総合評価 | 指摘件数 | 採用件数 | -|---------|---------|---------|---------|---------| -| **1. プロンプトエンジニア** | プロンプト設計品質、指示の明確さ、ハルシネーション防止、出力安定性 | 4/5 | 8件 | 3件 | -| **2. 生成AIエンジニア** | トークン効率、コンテキスト設計、検索性、MCP移行容易性、スケーラビリティ | 4/5 | 9件 | 5件 | -| **3. Nablarch有識者** | 知識の正確性、網羅性、バージョン差異の扱い | 4/5 | 8件 | 4件 | -| **4. アーキテクト** | アーキテクチャ妥当性、プロジェクト適用可能性、拡張性 | 4/5 | 9件 | 3件 | -| **5. アプリケーションプログラマ** | 実務での使いやすさ、情報アクセス性、日常業務での有用性 | 4/5 | 10件 | 3件 | -| **合計** | | **平均4/5** | **44件** | **18件** | - ---- - -#### 指摘事項の分類 - -**優先度別の分類**: +| 合計 | 約15,000トークン | コンテキストの7.5%程度、他の情報と併用可能 | -| 優先度 | 定義 | 件数 | 採用件数 | 対応内容 | -|:------:|------|:----:|:--------:|---------| -| **S(即座に対応)** | 代行精度に直結、致命的な問題の可能性 | 3 | 3 | Step1-4のドキュメント修正、設計の見直し | -| **A(対応すべき)** | 重要度が高く、比較的容易に対応可能 | 15 | 15 | Step1-4のドキュメント追記、設計の詳細化 | -| **C(将来対応)** | 現時点では対応不要、実装時・実運用時に詳細化 | 26 | 0 | Step5レポートに記録し、今後のタスクとして管理 | -| **合計** | | **44** | **18** | | +**動的調整**: +- High(2点)のセクションが10件未満 → Partial(1点)も含めて最大15件まで拡張します +- High(2点)のセクションが20件以上 → 上位15件まで拡張します +- コンテキスト使用率が80%超 → セクション数を減らします(最小5件) -**即座に対応した指摘(3件)**: -1. **関連度判定の曖昧性(#6)**: Step3に関連度判定の詳細プロセスを追記 -2. **コンテキストウィンドウへの適合性(#17)**: Step3とStep4にコンテキスト管理戦略を追記 -3. **知識の正確性検証不足(#24)**: Step4の詳細検証結果(11ファイル、平均97.3点)を反映 +**設計判断**: 依頼の複雑さに応じて情報量を動的調整し、精度とトークン効率を両立します。 --- -### 5.2 主要な改善内容 - -#### 改善前後の比較 - -| 評価項目 | 改善前 | 改善後 | 改善効果 | -|---------|--------|--------|---------| -| **プロンプト設計の明確性** | 3.5/5 | 4.5/5 | +1.0 | -| - 判断基準の具体性 | 抽象的な表現が残存 | 定量的な基準を追加 | 明確化 | -| - 関連度判定の一貫性 | 例示のみ | 詳細プロセスを明記 | 一貫性向上 | -| **トークン効率** | 4.0/5 | 4.5/5 | +0.5 | -| - トークン量の可視性 | 推定値のみ | 定量評価を追加 | 透明性向上 | -| - コンテキスト管理 | 不明確 | 管理戦略を明記 | 実用性向上 | -| **知識の正確性** | 4.0/5 | 4.8/5 | +0.8 | -| - 検証カバレッジ | 11ファイル/17ファイル(64.7%) | 残り6ファイルの詳細検証計画 | カバレッジ拡大 | -| - 検証品質 | 平均97.3点(優秀) | 軽微な改善提案を反映予定 | 品質向上 | -| - 検証プロセス | 不明確 | 5段階プロセスを明記 | 体系化 | -| **アーキテクチャ品質** | 4.0/5 | 4.5/5 | +0.5 | -| - スキーマ管理 | バージョニング不明 | バージョン管理方法を明記 | 保守性向上 | -| - 情報源管理 | 更新対応不明 | 更新フローを明記 | 信頼性向上 | -| **使いやすさ** | 3.5/5 | 4.0/5 | +0.5 | -| - エラー対応 | 不明確 | エラーメッセージと代替提案を明記 | ユーザビリティ向上 | -| - 情報アクセス | 詳細のみ | サマリー情報を追加予定 | 利便性向上 | +## 3. 実装計画 ---- - -#### 主要な改善内容の詳細 - -1. **判断基準の明確化** (Step1) - - 代行タスクの優先度判断基準を定量化(工数削減率、発生頻度、AI代行適性) - -2. **基本原則の両立基準** (Step2) - - 「仕様は全部残す」と「表現は最適化する」の両立方法を明示 - - 残すもの、最適化するもの、判断基準を明確化 - -3. **検索ヒント選定基準** (Step3) - - 6つの具体的な選定基準を追加(技術用語、クラス名・メソッド名、日本語表記、類義語、エラー名、ユースケース) - - 表記揺れ対策を明記 - -4. **関連度判定プロセス** (Step3) - - High/Partial/Noneの判断基準を詳細化 - - 判定の一貫性確保方法を明記 - -5. **スケーラビリティ設計** (Step3) - - index.toonの将来規模と対策を明記 - - 階層化インデックスへの移行計画 - -6. **動的調整メカニズム** (Step3) - - pointersの上位N件を動的に調整する仕組み - -7. **コンテキスト管理戦略** (Step3) - - コンテキストウィンドウへの適合性を詳細分析 - - セクション単位の抽出により、コンテキストウィンドウ内で運用可能と確認 - -8. **スキーマバージョニング** (Step3) - - schema_versionフィールドの追加 - - バージョン管理方法を明記 - -9. **サマリー情報の追加** (Step3) - - 各ファイルにsummaryフィールドを追加予定 - -10. **用語集計画** (Step3) - - glossary.jsonの追加計画 - -11. **エラーメッセージ** (Step3) - - 検索失敗時の対応を明記 - -12. **トークン量の定量評価** (Step4) - - KB→トークン数への変換式を明記 - - TOON形式の削減効果を定量化(40-50%削減) - -13. **正確性検証の強化** (Step4) - - サンプリングレビューを10%→20%に拡大 - - 検証項目を明確化 - -14. **品質保証プロセス** (Step4) - - 5段階の品質保証プロセスを明記 - ---- - -### 5.3 将来対応項目 - -**将来対応の指摘(26件)** を実装計画の3フェーズ(詳細は6.1参照)で対応: - -| フェーズ | 対応する指摘 | 対応時期 | -|---------|-------------|---------| -| **フェーズ1** | #7(サンプル数が限定的)、#34(品質保証プロセスの不足) | 残り43ファイル作成時 | -| **フェーズ2** | #8(検証シナリオが1つのみ)、#42(RESTfulシナリオの検証不足) | RESTfulシナリオ検証時 | -| **フェーズ3** | #9, #10, #19, #25, #38 | 知識ファイル完成時 | -| **実装時** | #2, #4, #12, #27, #30, #32, #33, #41, #44 | 実装・配布時 | -| **実運用時** | #14, #18, #26, #35, #36, #39, #43 | 実運用開始後 | -| **長期課題** | #20(非OSS版Nablarchへの対応) | プロジェクト固有知識の扱いを検討 | - -**注**: フェーズ1はバッチ処理の知識を完成させる(約2.2時間、なるべく早くAIのメリットを感じてもらうため)、フェーズ2はRESTfulシナリオの拡充(約1.5時間)、フェーズ3は残りの知識ファイル完成(約1時間)を指します。 - ---- - -[続く - 次は「6. 実装計画」と「7. 付録」] - -## 6. 実装計画 +### 3.1 作成範囲 -### 6.1 残作業と優先度 +**情報源**: +- Nablarch公式解説書(https://nablarch.github.io/docs/LATEST/doc/) +- システム開発ガイド(https://fintan.jp/page/252/)- パターン集、アンチパターン +- サンプルプロジェクト(GitHub: nablarch/nablarch-example-batch, nablarch-example-rest) -#### 全体規模の見積もり +**作成規模**: 約60個の知識ファイル -**Nablarch 6u3の規模**(Step2より): - -| 作成単位 | 推定件数 | 既存 | 未作成 | 作成時間/件 | 総作業時間 | -|---------|---------|:----:|:------:|-----------|----------| -| 処理方式 | 2個 | 1 | 1 | 3分 | 3分 | -| ライブラリ | 約15個 | 5 | 10 | 3分 | 30分 | -| ハンドラ | 約20個 | 3 | 17 | 3分 | 51分 | -| ツール | 約5個 | 4 | 1 | 3分 | 3分 | -| アダプタ | 約13個 | 1 | 12 | 3分 | 36分 | -| チェック項目 | 3種類 | 1 | 2 | 3分 | 6分 | -| リリースノート | 複数 | 1 | 数個 | 3分 | 数分 | -| **小計** | **約60個** | **16** | **約44個** | - | **約2.2時間** | -| 品質チェック | - | - | - | - | 1.5時間 | -| **合計** | - | - | - | - | **約3.7時間** | +| 作成単位 | 推定件数 | 備考 | +|---------|---------|------| +| 処理方式 | 2個 | Nablarchバッチ、RESTful | +| ライブラリ | 約15個 | DB、ファイルI/O、バリデーション等 | +| ハンドラ | 約20個 | 共通、バッチ専用、REST専用 | +| ツール | 約5個 | NTF、gsp-dba-maven-plugin等 | +| アダプタ | 約13個 | ログ、DB、REST、メール等 | +| チェック項目 | 3個 | セキュリティ、推奨/非推奨、公開API | +| リリースノート | 複数個 | バージョン別 | --- -#### 作成計画(4フェーズ) - -**フェーズ1: Nabバッチ(FW)- バッチフレームワーク完成(優先度: 最高)** +### 3.2 フェーズ計画 -**期間**: 1週間(作業45分 + 品質チェック45分 + 仮説検証2-3日 + バッファ) -**作業量**: 約1.5時間 -**目的**: なるべく早くAIのメリットを感じてもらう +#### フェーズ1: Nabバッチ(FW)- バッチフレームワーク完成(優先度: 最高) -| カテゴリ | 作成数 | 内容 | -|---------|:------:|------| -| バッチ専用ハンドラ | 約7-10個 | データリード、ステータス変換、プロセス制御等の残り | -| バッチで使うライブラリ | 約5個 | ファイルI/O、システムリポジトリ等の残り | -| **合計** | **約12-15個** | | +**期間**: 1週間 +**作業量**: 約1.5時間(作成45分 + 品質チェック45分) +**対象**: バッチ専用ハンドラ約10個、バッチで使うライブラリ約5個 +**目的**: なるべく早くAIのメリットを感じてもらうことです **仮説検証**: -- 代行精度を実測(実装調査、コード生成、レビュー等) -- 工数削減を実測(従来工数 vs 代行後工数) +- 代行精度を実測します(実装調査、コード生成、レビュー等) +- 工数削減を実測します(従来工数 vs 代行後工数) - 目標: 工数削減60%以上 -- 効果が確認できたらフェーズ2以降へ -- 効果が薄い場合: 1ヶ月の改善期間を設け、改善効果が見られない場合は再設計または中止を判断 - ---- +- 効果確認後、フェーズ2以降へ進みます -**フェーズ2: Nabバッチ(NTF)- テストフレームワーク完成(優先度: 高)** +#### フェーズ2: Nabバッチ(NTF)- テストフレームワーク完成 **期間**: 3日 **作業量**: 約30分 +**対象**: NTF関連の残り約1-2個 -| 対象 | 理由 | -|------|------| -| NTF関連の残り | REST用NTFなど約1-2個。バッチのテスト自動化を完成させる | - ---- - -**フェーズ3: REST(API)- RESTful Webサービス対応(優先度: 中)** +#### フェーズ3: REST(API)- RESTful Webサービス対応 **期間**: 1週間 **作業量**: 約1時間 +**対象**: RESTful処理方式1個、REST専用ハンドラ約5個、REST関連ライブラリ約3個 -| カテゴリ | 作成数 | 内容 | -|---------|:------:|------| -| RESTful処理方式 | 1個 | RESTアーキテクチャ全体 | -| REST専用ハンドラ | 約5個 | リクエストボディ変換、Bean Validation等 | -| REST関連ライブラリ | 約3個 | JSON変換等 | -| **合計** | **約9個** | | - ---- - -**フェーズ4: 残り - 網羅性確保(優先度: 低)** +#### フェーズ4: 残り - 網羅性確保 **期間**: 1週間 **作業量**: 約1.5時間 +**対象**: アダプタ約12個、共通ハンドラ約5個、チェック項目2個、その他約5個 -| カテゴリ | 作成数 | 内容 | -|---------|:------:|------| -| アダプタ | 約12個 | ログ、DB、メール等の外部連携 | -| 共通ハンドラ | 約5個 | スレッドコンテキスト等の残り | -| チェック項目 | 2個 | 推奨/非推奨、公開API | -| その他 | 約5個 | リリースノート、用語集等 | -| **合計** | **約24個** | | - ---- - -**全体の作業量**: 約4.5時間(作成2.5時間 + 品質チェック2時間) - ---- - -### 6.2 品質保証プロセス - -#### 推奨する5段階プロセス - -1. **作成フェーズ**: AIエージェントが知識ファイルを作成 - - 並行作業用プロンプトの準備(4グループに分割) - - 共通手順の分離(common-instructions.md) - - スキーマの別ファイル化(7種類のスキーマを個別管理) - -2. **自動チェック**: スキーマ準拠性、JSON構文チェック - - JSONスキーマバリデーション - - id, title, official_doc_urls, index, sectionsの確認 - - 命名規則チェック(kebab-case) - -3. **サンプリングレビュー**: 20%のファイルを人間がレビュー - - ランダムサンプリング: 各カテゴリから均等に選択 - - 重点サンプリング: ハンドラ、主要ライブラリは必ずレビュー - - 仕様の網羅性確認(必須/オプション/デフォルト値) - - 推奨/非推奨機能も仕様を残したか - - 制約の網羅性確認(「重要」「注意」「警告」を全て反映したか) - - コード例が動作する最小形になっているか - - 出典(official_doc_urls)を全ての情報に付与したか - - 対象外情報(Jakarta Batch等)を含んでいないか - -4. **Nablarch有識者レビュー**: 重要ファイルの正確性検証 - - 重要度の高いファイルは有識者による確認 - - 公式ドキュメント(RST版)との完全照合 - - 用語・表記の一貫性確認 - -5. **フィードバックループ**: レビューで発見された問題を、次回作成時に反映 - - 問題点を共通手順に反映 - - スキーマを改善 - - 作業標準化を継続的に改善 - ---- - -### 6.3 スケーラビリティ対策 - -#### index.toonのスケーラビリティ - -**現状**: 93エントリ、約650検索ヒント - -**将来規模**: 約200エントリ、約1,500検索ヒント(Nablarch全体をカバー) - -**対策**: -1. **階層化**: カテゴリ別のインデックス(handlers.toon, libraries.toon等)を検討 -2. **圧縮**: TOONフォーマットはトークン効率が良く、200エントリでも約5-7Kトークン程度と推定 -3. **キャッシュ**: 頻繁に使われるファイルは、検索結果をキャッシュ - -**移行判断**: 数百ファイル規模になった時点で、階層化インデックスへの移行を検討 - ---- - -#### pointersの動的調整 - -**基本**: 上位5ファイル、10セクションを抽出 - -**調整条件**: -1. 関連度2(High)のセクションが10件未満の場合、関連度1(Partial)も含めて最大15件まで拡張 -2. 関連度2のセクションが20件以上ある場合、上位15件まで拡張(より多くの選択肢を提供) -3. コンテキストウィンドウの使用率が80%を超える場合、セクション数を減らす(最小5件) - -**理由**: 依頼の複雑さに応じて、情報量を動的に調整することで、精度とトークン効率を両立 - ---- - -#### 情報源の更新管理 - -**情報源のバージョン管理**: -- 公式情報(GitHub、Fintan)は継続的に更新される -- 知識ファイルの `official_doc_urls` に参照先を明記することで、更新時の照合を容易に -- Nablarchリポジトリのウォッチ設定により、リリースノート発行時に通知を受ける - -**情報の一貫性確保**: -- 複数の情報源で内容が矛盾する場合の優先順位: - 1. 公式解説書(RST版) - 最も信頼性が高い - 2. システム開発ガイド(Fintan) - 実装パターンの補完 - 3. Example(GitHub) - コード例の参照 - 4. API Doc(Javadoc) - メソッドシグネチャの確認 -- 矛盾が発見された場合は、公式リポジトリにIssue報告を検討 +**全体作業量**: 約4.5時間(作成2.5時間 + 品質チェック2時間) --- -### 6.4 体制と役割 - -**推奨体制**: -- AIエージェント: 知識ファイル作成(並行作業可能) -- 人間レビュアー: 品質チェック(20%サンプリング) -- Nablarch有識者: 正確性検証(重要ファイルは必須、その他は必要に応じて) +### 3.3 品質保証 -**作業標準化**: -- 作業指示プロンプトの準備完了(4グループ) -- 共通手順の文書化完了(common-instructions.md) -- スキーマ定義の準備完了(7種類) +#### 5段階プロセス ---- - -### 6.5 成果物の配布計画 +1. **作成**: AIエージェントが知識ファイルを作成します +2. **自動チェック**: スキーマ準拠性、JSON構文チェックを行います +3. **サンプリングレビュー**: 20%のファイルを人間がレビューします + - ランダムサンプリング: 各カテゴリから均等に選択します + - 重点サンプリング: ハンドラ、主要ライブラリは必須でレビューします +4. **Nablarch有識者レビュー**: 重要ファイルの正確性検証を行います +5. **フィードバックループ**: 問題点を次回作成時に反映します -**短期(現在〜3ヶ月)**: -- AI向け最適化ファイル(JSON)+ 人向け根拠確認ビュー(Markdown)をプロジェクトに配布 -- プロジェクトのルートディレクトリに配置(例: `.nablarch-knowledge/`) -- Claude Code、GitHub CopilotでMCP接続 +#### 品質基準 -**中期(3ヶ月〜6ヶ月)**: -- MCPサーバー化 -- 複数プロジェクトから接続可能に -- バージョン別の知識ベース管理 +- 仕様の網羅性(必須/オプション/デフォルト値) +- 制約の網羅性(「重要」「注意」「警告」を全て反映) +- コード例が動作する最小形であること +- 出典(official_doc_urls)を全ての情報に付与すること +- 対象外情報(Jakarta Batch等)を含まないこと --- -## 7. 付録 - -### 7.1 用語集 +## 4. 参考資料 -#### Nablarch関連用語 - -| 用語 | 定義 | -|------|------| -| **Nablarchバッチ(都度起動型)** | コマンドラインから起動され、処理完了後に終了するバッチ処理方式 | -| **Jakarta Batch** | Jakarta EEのバッチ処理仕様。本設計では対象外 | -| **ハンドラキュー** | Nablarchのアーキテクチャの中核。複数のハンドラを順次実行する仕組み | -| **UniversalDao** | Nablarchで最も利用頻度の高いデータベースアクセスライブラリ | -| **NTF(Nablarch Testing Framework)** | Nablarchの自動テストフレームワーク | -| **リクエストパス** | アクションクラスを特定するための識別子。パッケージ名とクラス名を結合したもの | -| **代行タスク** | AIエージェントに代行させたい作業単位(例: 既存コード理解、実装調査等) | - -#### 設計用語 - -| 用語 | 定義 | -|------|------| -| **知識タイプ** | 代行タスクを実行するために必要な知識の種類(機能・実装パターン、チェック項目、リリースノート) | -| **検索ヒント** | index.toonやindex配列に含まれる、検索時にマッチングさせるキーワード | -| **関連度** | ファイル・セクションがユーザーの依頼にどれだけ関連するかを示す値(High=2、Partial=1、None=0) | -| **TOON形式** | LLMフレンドリーな軽量データフォーマット。トークン効率が良い(30-60%削減) | -| **pointers** | 検索結果を構造化したオブジェクト。filesとsectionsで構成される | -| **セクション単位の抽出** | ファイル全体ではなく、関連度の高いセクションのみを取得する方法 | -| **コンテキストウィンドウ** | LLMが一度に処理できるトークン数の上限(Claude Opus 4.6では200,000トークン) | -| **スキーマバージョニング** | schema_versionフィールドによるJSONスキーマのバージョン管理 | - -#### AI・検索関連用語 - -| 用語 | 定義 | -|------|------| -| **keyword-search** | 技術軸の検索方式。index.toonのhintsでキーワードマッチ | -| **intent-search** | 目的軸の検索方式。目的→カテゴリ、対象→ファイルで絞込 | -| **graded relevance** | 情報検索分野の標準的な関連度評価手法。複数段階で評価する | -| **ハルシネーション** | AIが誤った情報を生成する現象。本設計では根拠追跡性で対策 | -| **MCP(Model Context Protocol)** | LLMと外部サービスを接続するためのプロトコル | -| **Claude Code Plugin** | Claude Codeの拡張方式。スキル構造で機能を追加 | - ---- - -### 7.2 参考資料 - -#### 公式ドキュメント +### 4.1 公式ドキュメント | カテゴリ | URL | |---------|-----| -| **Nablarch解説書(トップ)** | https://nablarch.github.io/docs/LATEST/doc/ | +| **Nablarch解説書** | https://nablarch.github.io/docs/LATEST/doc/ | | **Nablarchバッチ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/nablarch_batch/index.html | | **RESTful Webサービス** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/web_service/rest/index.html | | **標準ハンドラ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/index.html | | **ライブラリ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/index.html | | **テスティングFW** | https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/index.html | -| **移行ガイド** | https://nablarch.github.io/docs/LATEST/doc/migration/index.html | -| **システム開発ガイド(トップ)** | https://fintan.jp/page/252 | +| **システム開発ガイド** | https://fintan.jp/page/252 | | **Nablarchパターン集** | https://fintan.jp/page/252/2/ | | **Nablarchアンチパターン** | https://fintan.jp/page/252/5/ | -#### リポジトリ +### 4.2 リポジトリ | 対象 | GitHub URL | |------|-----------| @@ -1557,41 +504,20 @@ JSONから自動変換。docs/配下に配置。 ## まとめ -### 本設計書で達成したこと - -1. **代行タスクを10個に特定**し、優先度を明確化(工数削減率、発生頻度、AI代行適性で定量評価) -2. **知識タイプを3つに整理**し、作成単位を定義 -3. **構造化アーキテクチャを設計**し、構造化の5観点をすべて満たす設計を実現 - - 検索速度、コンテキスト肥大化防止、トークン量最適化、正確性・根拠追跡性、保守性・更新容易性 -4. **17個の知識ファイルを作成**し、実現性を確認(平均97.3点、重大問題0件) -5. **5つのペルソナからレビュー**を実施し、44個の指摘事項を抽出・18件対応 - -### 実現可能性の確認 +### 本設計書で定義したこと -| 項目 | 目標 | 実績 | 判定 | -|------|------|------|:----:| -| **基本原則準拠** | 100% | 100% | ✅ | -| **知識の品質** | 平均95点以上 | 平均97.3点 | ✅ | -| **作成工数** | 全60ファイルで約3.7時間 | 見積もり通り | ✅ | -| **トークン量** | 実運用で約5,000トークン | 上位10セクション = 約5,000トークン | ✅ | -| **構造化の観点** | 5観点をすべて満たす | すべて満たす | ✅ | +1. **代行業務10個**と優先度を明確化しました +2. **知識タイプ3つを定義**し、作成単位を決定しました(約60個) +3. **検索アーキテクチャ**を設計しました(keyword + intent並列、関連度3段階) +4. **TOON形式インデックス**を採用しました(30-60%トークン削減) +5. **セクション単位の抽出**でコンテキスト管理します(上位10セクション ≈ 5,000トークン) +6. **4フェーズの実装計画**を策定しました(総作業時間約4.5時間) -### 次のステップ - -1. **Nabledge計画書の作成**: フェージング、仮説検証プラン、フェーズ別のPBI、概算工数 -2. **フェーズ1の実施**: 厚く揃える知識の拡充(約2.2時間)+ 仮説検証 -3. **効果測定**: 代行精度と工数削減の実測 - -### 期待される効果(仮説) - -- **代行精度の向上**: 工数削減60-70%を目指す -- **オンボーディング期間の短縮**: 5〜10日 → 1〜2日 -- **実装調査の効率化**: 2〜4時間/タスク → 30分〜1時間 - ---- +### 次のアクション -**本設計書の作成日**: 2026年2月9日 -**次のアクション**: Nabledge計画書の作成 → フェーズ1の実施 +1. フェーズ1を実施します(バッチフレームワーク知識の拡充 ≈ 1.5時間) +2. 仮説検証を行います(代行精度と工数削減の実測) +3. 効果測定後、フェーズ2以降へ進みます --- From 1c175bac8792a1d9bb66d3821955964c96156f2a Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:25:14 +0900 Subject: [PATCH 13/89] =?UTF-8?q?refactor:=203=E6=AE=B5=E9=9A=8E=E3=82=AD?= =?UTF-8?q?=E3=83=BC=E3=83=AF=E3=83=BC=E3=83=89=E6=88=A6=E7=95=A5=E3=81=AB?= =?UTF-8?q?=E3=82=88=E3=82=8B=E6=A4=9C=E7=B4=A2=E7=B2=BE=E5=BA=A6=E3=81=AE?= =?UTF-8?q?=E5=90=91=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit index.toonの検索ヒントを整理し、冗長なキーワードを削減。keyword-searchワークフローにL1/L2/L3キーワードの使い分けを明記し、2段階フィルタリング(ファイル選定・セクション選定)の設計を明確化。 Co-Authored-By: Claude Opus 4.6 --- .../skills/nabledge-6/knowledge/index.toon | 14 ++++---- .../nabledge-6/workflows/keyword-search.md | 25 +++++++++++--- doc/nabledge-design.md | 33 +++++++++++-------- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/.claude/skills/nabledge-6/knowledge/index.toon b/.claude/skills/nabledge-6/knowledge/index.toon index 61772eb..cf01e56 100644 --- a/.claude/skills/nabledge-6/knowledge/index.toon +++ b/.claude/skills/nabledge-6/knowledge/index.toon @@ -3,18 +3,18 @@ files[93,]{title,hints,path}: Nablarchバッチ(都度起動型・常駐型), バッチ 都度起動 常駐 大量データ処理 アーキテクチャ ハンドラ DataReader, features/processing/nablarch-batch.json JSR352準拠バッチ(Jakarta Batch), バッチ JSR352 Jakarta Batch Batchlet Chunk 標準仕様, not yet created - ユニバーサルDAO, データベース DAO O/Rマッパー CRUD JPA 検索 ページング 排他制御, features/libraries/universal-dao.json - データベースアクセス(JDBCラッパー), データベース JDBC SQL 接続 PreparedStatement Dialect, features/libraries/database-access.json + ユニバーサルDAO, データベース DAO O/Rマッパー JPA 排他制御, features/libraries/universal-dao.json + データベースアクセス(JDBCラッパー), データベース JDBC SQL PreparedStatement Dialect, features/libraries/database-access.json データベースコードジェネレータ, データベース コード生成 自動生成 Entity DAO スキーマ, not yet created データバインド, ファイル データ変換 CSV TSV 固定長 JavaBeans Map, features/libraries/data-bind.json 汎用データフォーマット, ファイル データ形式 CSV 固定長 JSON XML マルチレイアウト, not yet created - ログ出力, ログ ロギング Logger LogWriter ファイル出力 ローテーション, not yet created + ログ出力, ログ ロギング Logger LogWriter ローテーション, not yet created SLF4Jアダプタ, ログ SLF4J アダプタ log4j logback ロギングフレームワーク, features/adapters/slf4j-adapter.json 入力値のチェック, バリデーション 入力チェック Bean Validation Nablarch Validation 妥当性検証, not yet created - トランザクション管理, トランザクション データベース コミット ロールバック リソース制御, not yet created + トランザクション管理, トランザクション データベース, not yet created コード管理, コード マスタ 区分値 名称 国際化 静的データ, not yet created メッセージ管理, メッセージ 国際化 エラーメッセージ プロパティ フォーマット, not yet created - 排他制御, 排他制御 楽観的ロック 悲観的ロック バージョン番号 同時更新, not yet created + 排他制御, 排他制御 楽観的ロック 悲観的ロック バージョン番号, not yet created 業務日付, 日付 業務日付 システム日付 日時管理, features/libraries/business-date.json ファイルパス管理, ファイル パス管理 ファイルパス 論理名 物理パス, features/libraries/file-path-management.json リポジトリ, リポジトリ DI 依存性注入 コンポーネント定義 設定管理, not yet created @@ -33,8 +33,8 @@ files[93,]{title,hints,path}: フォーマット, フォーマット 数値 日付 文字列 変換 表示形式, not yet created 認可チェック(Permission Check), 認可 権限チェック Permission アクセス制御 セキュリティ, not yet created ロールベース認可, 認可 ロール 権限 アクセス制御 セキュリティ, not yet created - データベース接続管理ハンドラ, ハンドラ データベース 接続管理 接続取得 接続解放 コネクション, features/handlers/common/db-connection-management-handler.json - トランザクション管理ハンドラ, ハンドラ トランザクション コミット ロールバック データベース, features/handlers/common/transaction-management-handler.json + データベース接続管理ハンドラ, ハンドラ データベース 接続管理 コネクション, features/handlers/common/db-connection-management-handler.json + トランザクション管理ハンドラ, ハンドラ トランザクション データベース, features/handlers/common/transaction-management-handler.json グローバルエラーハンドラ, ハンドラ エラーハンドリング 例外処理 共通エラー処理, not yet created ファイルレコードライタ破棄ハンドラ, ハンドラ ファイル 出力 リソース解放 クローズ処理, not yet created リクエストパスJavaパッケージマッピング, ハンドラ ルーティング パス マッピング ディスパッチ, not yet created diff --git a/.claude/skills/nabledge-6/workflows/keyword-search.md b/.claude/skills/nabledge-6/workflows/keyword-search.md index 98e63fa..faa4657 100644 --- a/.claude/skills/nabledge-6/workflows/keyword-search.md +++ b/.claude/skills/nabledge-6/workflows/keyword-search.md @@ -57,6 +57,8 @@ This workflow searches the knowledge index (index.toon) using keyword matching t 1. Read knowledge/index.toon (93 entries, format: `Title, hint1 hint2 ..., path.json`) 2. For each entry, match your extracted keywords against hints: + - **Use Level 1 (Technical domain) + Level 2 (Technical component) keywords only** + - Level 3 (Functional) keywords are NOT used in this step - Case-insensitive matching - Partial matching allowed (e.g., "ページ" matches "ページング") - Count matched hints per entry @@ -75,7 +77,12 @@ This workflow searches the knowledge index (index.toon) using keyword matching t ```bash jq '.index' knowledge/features/libraries/universal-dao.json ``` -2. Match your keywords against section hints (same matching rules as Step 1) +2. Match your keywords against section hints: + - **Use Level 2 (Technical component) + Level 3 (Functional) keywords** + - Level 1 (Technical domain) keywords are NOT used in this step + - Level 2 is reused from Step 1 (acts as a bridge between file and section selection) + - Case-insensitive matching, partial matching allowed + - Count matched hints per section 3. Keep sections with ≥1 matched hint 4. Stop when you have 20-30 candidate sections total @@ -117,9 +124,13 @@ Use the returned sections to answer the user's question (knowledge files only). **Request**: "ページングを実装したい" -**Step 1**: Extract keywords → Technical domain: ["データベース"], Component: ["DAO", "UniversalDao"], Functional: ["ページング", "per", "page"] -**Step 1**: Match against index.toon → universal-dao.json (5 hints), database-access.json (2 hints) -**Step 2**: Extract sections → universal-dao/paging, universal-dao/overview, database-access/query +**Extract keywords at 3 levels**: +- Level 1 (Technical domain): ["データベース", "database"] +- Level 2 (Technical component): ["DAO", "UniversalDao", "O/Rマッパー"] +- Level 3 (Functional): ["ページング", "paging", "per", "page", "limit", "offset"] + +**Step 1**: Match against index.toon using L1+L2 → universal-dao.json (matched: データベース, DAO), database-access.json (matched: データベース) +**Step 2**: Extract sections using L2+L3 → universal-dao/paging (matched: DAO, ページング, per, page), universal-dao/overview (matched: DAO) **Step 3**: Section-judgement → Only universal-dao/paging judged as High (2), others filtered as None **Result**: 1 section with pagination API and examples @@ -129,3 +140,9 @@ Use the returned sections to answer the user's question (knowledge files only). - Uses Read tool for index.toon and Bash+jq for extracting section indexes - Final relevance scoring happens in section-judgement workflow - Expected output: 5-15 relevant sections filtered by section-judgement + +**Keyword level usage strategy**: +- **Level 2 acts as a bridge**: Used in both file selection (Step 1) and section selection (Step 2) +- **File selection (index.toon)**: L1 (broad technical domain) + L2 (specific technology) → narrows down to 10-15 files +- **Section selection (.index)**: L2 (specific technology) + L3 (specific function) → narrows down to 20-30 sections +- This two-stage filtering with L2 overlap ensures high precision while maintaining recall diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 299d6a7..047c135 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -81,7 +81,7 @@ graph TB direction TB subgraph workflows["🤖 ワークフロー(LLM実行)"] - WF_SEARCH["知識検索
(keyword+intent並列)
関連度判定"] + WF_SEARCH["知識検索
(keyword-search)
関連度判定"] WF_DELEGATE["代行作業
実装調査・コード生成・レビュー"] WF_GENERATE["知識ファイル生成・検証
3分/ファイル・20%サンプリング"] end @@ -139,14 +139,14 @@ graph TB **実行フロー**: 1. Nablarch利用者が自然言語でAIツールに依頼します(例: 「ページングを実装したい」) -2. AIツールがワークフロー(知識検索)を実行します → keyword + intent並列検索 +2. AIツールがワークフロー(知識検索)を実行します → keyword-searchで検索 3. 関連度の高いセクションを特定します(High/Partial/Noneの3段階) 4. ワークフロー(代行作業)を実行し、知識ファイルを参照します(上位10セクション ≈ 5,000トークン) 5. 回答またはコードを生成してユーザーに返します **設計のポイント**: - **配布**: GitHub (nablarch/nabledge) → Claude Code Plugin → インストール -- **検索**: keyword(技術軸)+ intent(目的軸)の並列実行で漏れを防止します +- **検索**: 3段階キーワード抽出(技術領域・技術要素・機能)で高精度な検索を実現します - **トークン効率**: TOON形式で30-60%削減、セクション単位抽出で必要最小限に抑えます - **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡します - **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離します @@ -232,14 +232,12 @@ nabledge-6/ ### 2.5 検索アーキテクチャ -#### 2つの検索方式 +#### 検索方式 -| 検索名 | 切り口 | 説明 | -|--------|--------|------| -| keyword-search | 技術軸 | index.toonのhintsでキーワードマッチ | -| intent-search | 目的軸 | 目的→カテゴリ、対象→ファイルで絞込 | +**keyword-search**: +index.toonの検索ヒントでキーワードマッチを行います。3段階のキーワード抽出により、技術領域・技術要素・機能の観点から検索します。 -**設計判断**: 単一検索では漏れが発生しやすいため、異なる切り口で並列実行し、結果をマージすることで漏れを防止します。 +**設計判断**: 現状、keyword-searchだけで十分な検索精度が得られています。将来的に検索精度の向上が必要になった場合は、intent-search(目的→カテゴリ、対象→ファイルで絞り込む方式)の導入を検討します。 #### 検索結果構造(pointers) @@ -297,16 +295,23 @@ files[N,]{path,hints}: **3段階のキーワード抽出**: -知識ファイルの検索ヒントは、以下の3段階でキーワードを抽出します。このうち2段階以上でマッチすることを推奨します。 +検索ヒントは、以下の3段階でキーワードを抽出します。 1. **Technical domain(技術領域)**: データベース, バッチ, ハンドラ, Web, REST, テスト など 2. **Technical component(技術要素)**: DAO, JDBC, JPA, Bean Validation, JSON, XML など 3. **Functional(機能)**: ページング, 検索, 登録, 更新, 削除, 接続, コミット など +**検索ヒントの使い分け**: +- **ファイル選定(index.toon)**: レベル1(技術領域)とレベル2(技術要素)を使用 +- **セクション選定(各ファイルのindex)**: レベル2(技術要素)とレベル3(機能)を使用 + **例**: 依頼「ページングを実装したい」の場合 -- Technical domain: ["データベース", "database"] -- Technical component: ["DAO", "UniversalDao", "O/Rマッパー"] -- Functional: ["ページング", "paging", "per", "page", "limit", "offset"] +- Level 1(技術領域): ["データベース", "database"] +- Level 2(技術要素): ["DAO", "UniversalDao", "O/Rマッパー"] +- Level 3(機能): ["ページング", "paging", "per", "page", "limit", "offset"] + +→ ファイル選定: Level 1 + Level 2 でマッチング +→ セクション選定: Level 2 + Level 3 でマッチング **基本指針**: @@ -508,7 +513,7 @@ files[N,]{path,hints}: 1. **代行業務10個**と優先度を明確化しました 2. **知識タイプ3つを定義**し、作成単位を決定しました(約60個) -3. **検索アーキテクチャ**を設計しました(keyword + intent並列、関連度3段階) +3. **検索アーキテクチャ**を設計しました(3段階キーワード抽出、関連度3段階) 4. **TOON形式インデックス**を採用しました(30-60%トークン削減) 5. **セクション単位の抽出**でコンテキスト管理します(上位10セクション ≈ 5,000トークン) 6. **4フェーズの実装計画**を策定しました(総作業時間約4.5時間) From 98fce7d26f4d3a88021615d8cb0379084b35033e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:25:39 +0900 Subject: [PATCH 14/89] =?UTF-8?q?docs:=20=E6=A4=9C=E7=B4=A2=E8=A8=AD?= =?UTF-8?q?=E8=A8=88=E3=81=AE=E8=A9=B3=E7=B4=B0=E3=83=95=E3=83=AD=E3=83=BC?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 検索アーキテクチャから検索設計に名称変更し、6段階の詳細フロー(キーワード抽出→ファイル選定→セクション選定→関連度判定→結果構造化→コンテキスト管理)を図解とともに説明。各段階での処理内容と判断根拠を明確化。 Co-Authored-By: Claude Opus 4.6 --- doc/nabledge-design.md | 162 +++++++++++++++++++++++++---------------- 1 file changed, 101 insertions(+), 61 deletions(-) diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 047c135..543b1a5 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -230,34 +230,82 @@ nabledge-6/ --- -### 2.5 検索アーキテクチャ +### 2.5 検索設計 -#### 検索方式 +#### 検索の全体フロー -**keyword-search**: -index.toonの検索ヒントでキーワードマッチを行います。3段階のキーワード抽出により、技術領域・技術要素・機能の観点から検索します。 +ユーザーの依頼から必要な知識を特定するまでの流れを説明します。 -**設計判断**: 現状、keyword-searchだけで十分な検索精度が得られています。将来的に検索精度の向上が必要になった場合は、intent-search(目的→カテゴリ、対象→ファイルで絞り込む方式)の導入を検討します。 +``` +ユーザー依頼(例:「ページングを実装したい」) + ↓ +① 3段階キーワード抽出 + ↓ +② ファイル選定(index.toonで検索) + ↓ +③ セクション選定(ファイル内indexで検索) + ↓ +④ 関連度判定(High/Partial/None) + ↓ +⑤ 検索結果構造化(pointers) + ↓ +⑥ コンテキスト管理(上位N件抽出) +``` + +#### ① 3段階キーワード抽出 + +ユーザーの依頼から、以下の3段階でキーワードを抽出します。 + +| レベル | 名称 | 説明 | 例 | +|:-----:|------|------|-----| +| Level 1 | Technical domain(技術領域) | データベース, バッチ, ハンドラ, Web, REST, テスト など | データベース, database | +| Level 2 | Technical component(技術要素) | DAO, JDBC, JPA, Bean Validation, JSON, XML など | DAO, UniversalDao, O/Rマッパー | +| Level 3 | Functional(機能) | ページング, 検索, 登録, 更新, 削除, 接続, コミット など | ページング, paging, per, page, limit, offset | + +**例**: 依頼「ページングを実装したい」→ 3段階のキーワードに分解 + +#### ② ファイル選定(index.toon) + +**使用するキーワード**: Level 1(技術領域)+ Level 2(技術要素) + +**index.toonの構造**: +```toon +# Nabledge-6 Knowledge Index + +files[N,]{path,hints}: + features/handlers/common/global-error-handler.json, グローバルエラーハンドラ GlobalErrorHandler 未捕捉例外 エラーハンドリング 例外処理 + features/libraries/universal-dao.json, ユニバーサルDAO UniversalDao CRUD 検索 ページング データベース DAO +``` + +- TOON形式でJSONより30-60%トークン削減 +- 93エントリ、約650検索ヒント → 約5-7Kトークン +- 各ファイルのパスと検索ヒント(Level 1 + Level 2)を記載 + +**マッチング例**: 「データベース」「DAO」で `universal-dao.json` が候補に + +#### ③ セクション選定(ファイル内index) -#### 検索結果構造(pointers) +**使用するキーワード**: Level 2(技術要素)+ Level 3(機能) +**ファイル内indexの構造**: ```json { - "files": [ - { "id": "F1", "path": "features/libraries/universal-dao.json", "relevance": 2 } - ], - "sections": [ - { "file_id": "F1", "section": "paging", "relevance": 2, "matched_hints": ["ページング", "per", "page"] } + "index": [ + { "id": "overview", "hints": ["UniversalDao", "ユニバーサルDAO"] }, + { "id": "paging", "hints": ["ページング", "paging", "per", "page", "limit", "offset"] }, + { "id": "search", "hints": ["検索", "search", "条件指定"] } ] } ``` -**設計判断**: -- sections を関連度降順でソートすることで、最重要セクションから読めます -- files でファイル単位の重要度を把握できます -- ファイルパスは1回だけ出現し、file_idで参照します(重複排除) +- 各セクションの検索ヒント(Level 2 + Level 3)を記載 +- セクション単位で関連度を判定 + +**マッチング例**: 「ページング」「paging」で `paging` セクションが候補に -#### 関連度定義 +#### ④ 関連度判定 + +ファイルとセクションそれぞれに関連度を付与します。 | レベル | 値 | 判断基準 | |:------:|:---:|---------| @@ -267,66 +315,58 @@ index.toonの検索ヒントでキーワードマッチを行います。3段階 **ファイルの関連度**: そのファイル内のセクション関連度の最大値 -**設計判断**: 情報検索分野の標準的なgraded relevanceを採用します。3段階で十分な精度が得られます。 - ---- - -### 2.6 インデックス設計(index.toon) +**例**: `universal-dao.json` +- `paging` セクション: High (2) +- `search` セクション: Partial (1) +- `overview` セクション: Partial (1) +→ ファイルの関連度 = 2 (最大値) -#### TOON形式 +#### ⑤ 検索結果構造化(pointers) -```toon -# Nabledge-6 Knowledge Index +検索結果をpointers構造で返します。 -files[N,]{path,hints}: - features/handlers/common/global-error-handler.json, グローバルエラーハンドラ GlobalErrorHandler 未捕捉例外 エラーハンドリング 例外処理 - features/libraries/universal-dao.json, ユニバーサルDAO UniversalDao CRUD 検索 ページング +```json +{ + "files": [ + { "id": "F1", "path": "features/libraries/universal-dao.json", "relevance": 2, "matched_hints": ["データベース", "DAO"] } + ], + "sections": [ + { "file_id": "F1", "section": "paging", "relevance": 2, "matched_hints": ["ページング", "paging", "per", "page"] }, + { "file_id": "F1", "section": "search", "relevance": 1, "matched_hints": ["検索"] } + ] +} ``` -**構造**: -- `files[N,]{path,hints}:` → N件の配列、フィールドはpath, hints -- 各行: `パス, スペース区切りの検索ヒント` - -**規模**: 93エントリ、約650検索ヒント → 約5-7Kトークン - -**設計判断**: TOON形式はJSONより30-60%トークン削減します。LLMフレンドリーで高効率です。 - -#### 検索ヒント設計指針 +**構造の特徴**: +- `sections` を関連度降順でソート → 最重要セクションから読める +- `files` でファイル単位の重要度を把握 +- ファイルパスは1回だけ出現、`file_id` で参照(重複排除) +- `matched_hints` で判断根拠を追跡可能 -**3段階のキーワード抽出**: +#### ⑥ コンテキスト管理(上位N件抽出) -検索ヒントは、以下の3段階でキーワードを抽出します。 +関連度の高いセクションを抽出します。 -1. **Technical domain(技術領域)**: データベース, バッチ, ハンドラ, Web, REST, テスト など -2. **Technical component(技術要素)**: DAO, JDBC, JPA, Bean Validation, JSON, XML など -3. **Functional(機能)**: ページング, 検索, 登録, 更新, 削除, 接続, コミット など - -**検索ヒントの使い分け**: -- **ファイル選定(index.toon)**: レベル1(技術領域)とレベル2(技術要素)を使用 -- **セクション選定(各ファイルのindex)**: レベル2(技術要素)とレベル3(機能)を使用 - -**例**: 依頼「ページングを実装したい」の場合 -- Level 1(技術領域): ["データベース", "database"] -- Level 2(技術要素): ["DAO", "UniversalDao", "O/Rマッパー"] -- Level 3(機能): ["ページング", "paging", "per", "page", "limit", "offset"] +| 項目 | 推奨値 | 根拠 | +|------|--------|------| +| sections | 上位10件 | 1セクション平均500トークン × 10 = 約5,000トークン(コンテキストの2.5%) | -→ ファイル選定: Level 1 + Level 2 でマッチング -→ セクション選定: Level 2 + Level 3 でマッチング +**動的調整**: +- High(2点)のセクションが10件未満 → Partial(1点)も含めて最大15件まで拡張 +- High(2点)のセクションが20件以上 → 上位15件まで拡張 +- コンテキスト使用率が80%超 → セクション数を減らす(最小5件) -**基本指針**: +**設計判断**: +- セクション単位で抽出することで、ファイル全体(約7,000トークン)ではなく必要最小限(約500トークン)に抑えます +- 全60ファイル(約420,000トークン)をコンテキストウィンドウ(200,000トークン)内で運用可能にします -| 項目 | 指針 | -|------|------| -| 言語 | 日本語基本。公式で英語のものはそのまま | -| 語数 | ファイル: 5-10語、セクション: 3-5語 | -| 順序 | 広い技術領域→詳細(降順)例: `DB 接続 コネクション` | -| 表記揺れ | 複数表記を含める(例: DB, データベース, database) | +#### 将来の拡張 -**設計判断**: 3段階でキーワードを網羅的に抽出し、2段階以上でマッチさせることで検索精度を向上させます。 +現状、keyword-searchだけで十分な検索精度が得られています。将来的に検索精度の向上が必要になった場合は、intent-search(目的→カテゴリ、対象→ファイルで絞り込む方式)の導入を検討します。 --- -### 2.7 知識ファイル設計(JSONスキーマ) +### 2.6 知識ファイル設計 #### 共通構造 From bce750bea297ae50766292f3b4ce40a50406b5c9 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:25:57 +0900 Subject: [PATCH 15/89] =?UTF-8?q?docs:=20=E3=82=B3=E3=83=B3=E3=83=86?= =?UTF-8?q?=E3=82=AD=E3=82=B9=E3=83=88=E7=AE=A1=E7=90=86=E3=82=BB=E3=82=AF?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92=E6=A4=9C=E7=B4=A2=E8=A8=AD?= =?UTF-8?q?=E8=A8=88=E3=81=AB=E7=B5=B1=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重複していたコンテキスト管理の説明を検索設計の「⑥ コンテキスト管理」に統合。まとめセクションも更新し、検索設計の4つのポイント(3段階キーワード、2段階検索、関連度判定、セクション単位抽出)を明記。 Co-Authored-By: Claude Opus 4.6 --- doc/nabledge-design.md | 50 +++++++++--------------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 543b1a5..6ab0deb 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -146,10 +146,10 @@ graph TB **設計のポイント**: - **配布**: GitHub (nablarch/nabledge) → Claude Code Plugin → インストール -- **検索**: 3段階キーワード抽出(技術領域・技術要素・機能)で高精度な検索を実現します -- **トークン効率**: TOON形式で30-60%削減、セクション単位抽出で必要最小限に抑えます -- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡します -- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離します +- **検索**: 3段階キーワード抽出 + 2段階検索プロセス(ファイル→セクション)で高精度を実現 +- **トークン効率**: TOON形式で30-60%削減、セクション単位抽出で必要最小限(5,000トークン)に抑制 +- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡 +- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離 --- @@ -407,39 +407,6 @@ files[N,]{path,hints}: --- -### 2.8 コンテキスト管理 - -#### コンテキストウィンドウへの適合 - -**制約**: -- Claude Opus 4.6のコンテキストウィンドウ: 200,000トークン -- 全60ファイルの推定トークン数: 約420,000トークン - -**対策**: -1. **セクション単位の抽出**: 関連度の高いセクションのみを抽出します - - 上位10セクション(平均500トークン)= 約5,000トークン(全体の2.5%) -2. **関連度による絞り込み**: High(2点)のセクションを優先します -3. **動的調整**: コンテキスト使用率に応じて取得セクション数を調整します - -**設計判断**: ファイル全体を取得するのではなく、セクション単位で抽出することで、コンテキストウィンドウ内で運用可能にします。 - -#### 上位N件抽出の根拠 - -| 項目 | 推奨値 | 根拠 | -|------|--------|------| -| files | 上位5件 | 1ファイル平均2000トークン × 5 = 10,000トークン | -| sections | 上位10件 | 1セクション平均500トークン × 10 = 5,000トークン | -| 合計 | 約15,000トークン | コンテキストの7.5%程度、他の情報と併用可能 | - -**動的調整**: -- High(2点)のセクションが10件未満 → Partial(1点)も含めて最大15件まで拡張します -- High(2点)のセクションが20件以上 → 上位15件まで拡張します -- コンテキスト使用率が80%超 → セクション数を減らします(最小5件) - -**設計判断**: 依頼の複雑さに応じて情報量を動的調整し、精度とトークン効率を両立します。 - ---- - ## 3. 実装計画 ### 3.1 作成範囲 @@ -553,10 +520,13 @@ files[N,]{path,hints}: 1. **代行業務10個**と優先度を明確化しました 2. **知識タイプ3つを定義**し、作成単位を決定しました(約60個) -3. **検索アーキテクチャ**を設計しました(3段階キーワード抽出、関連度3段階) +3. **検索設計**を明確化しました + - 3段階キーワード抽出(技術領域・技術要素・機能) + - 2段階検索プロセス(ファイル選定→セクション選定) + - 関連度3段階判定(High/Partial/None) + - セクション単位抽出(上位10件 ≈ 5,000トークン) 4. **TOON形式インデックス**を採用しました(30-60%トークン削減) -5. **セクション単位の抽出**でコンテキスト管理します(上位10セクション ≈ 5,000トークン) -6. **4フェーズの実装計画**を策定しました(総作業時間約4.5時間) +5. **4フェーズの実装計画**を策定しました(総作業時間約4.5時間) ### 次のアクション From b1947ba7bb9ed9941eeb24cbac43b22d6963acdb Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:26:09 +0900 Subject: [PATCH 16/89] =?UTF-8?q?docs:=20=E3=83=90=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E5=B1=A5=E6=AD=B4=E3=81=ABv1.5=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 検索設計の全面見直し(3段階キーワード抽出+2段階検索プロセス)を反映したバージョン履歴を追加。 Co-Authored-By: Claude Opus 4.6 --- doc/nabledge-design.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 6ab0deb..916bc1c 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -1,13 +1,14 @@ # Nabledge設計書 **作成日**: 2026年2月10日 -**バージョン**: 1.4 +**バージョン**: 1.5 **ステータス**: Draft ## 変更履歴 | バージョン | 日付 | 変更内容 | |----------|------|---------| +| 1.5 | 2026/02/10 | 検索設計の全面見直し(3段階キーワード抽出+2段階検索プロセス) | | 1.4 | 2026/02/10 | 代行業務の整理、文体統一 | | 1.3 | 2026/02/10 | アーキテクチャレビュー反映 | | 1.2 | 2026/02/10 | MCP削除、簡潔化 | From a577f12b3ff5e7f2840e8a93d38e40b8d5f07f86 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:43:35 +0900 Subject: [PATCH 17/89] =?UTF-8?q?update:=20=E6=A4=9C=E7=B4=A2=E3=83=AF?= =?UTF-8?q?=E3=83=BC=E3=82=AF=E3=83=95=E3=83=AD=E3=83=BC=E3=81=AB=E3=82=B9?= =?UTF-8?q?=E3=82=B3=E3=82=A2=E3=83=AA=E3=83=B3=E3=82=B0=E6=88=A6=E7=95=A5?= =?UTF-8?q?=E3=82=92=E5=B0=8E=E5=85=A5=E3=81=97=E3=82=A4=E3=83=B3=E3=83=87?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=B9=E3=83=92=E3=83=B3=E3=83=88=E3=82=92?= =?UTF-8?q?=E5=BC=B7=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- .../skills/nabledge-6/knowledge/index.toon | 14 ++-- .../nabledge-6/workflows/keyword-search.md | 81 ++++++++++++------ doc/nabledge-design.md | 84 ++----------------- 3 files changed, 72 insertions(+), 107 deletions(-) diff --git a/.claude/skills/nabledge-6/knowledge/index.toon b/.claude/skills/nabledge-6/knowledge/index.toon index cf01e56..61772eb 100644 --- a/.claude/skills/nabledge-6/knowledge/index.toon +++ b/.claude/skills/nabledge-6/knowledge/index.toon @@ -3,18 +3,18 @@ files[93,]{title,hints,path}: Nablarchバッチ(都度起動型・常駐型), バッチ 都度起動 常駐 大量データ処理 アーキテクチャ ハンドラ DataReader, features/processing/nablarch-batch.json JSR352準拠バッチ(Jakarta Batch), バッチ JSR352 Jakarta Batch Batchlet Chunk 標準仕様, not yet created - ユニバーサルDAO, データベース DAO O/Rマッパー JPA 排他制御, features/libraries/universal-dao.json - データベースアクセス(JDBCラッパー), データベース JDBC SQL PreparedStatement Dialect, features/libraries/database-access.json + ユニバーサルDAO, データベース DAO O/Rマッパー CRUD JPA 検索 ページング 排他制御, features/libraries/universal-dao.json + データベースアクセス(JDBCラッパー), データベース JDBC SQL 接続 PreparedStatement Dialect, features/libraries/database-access.json データベースコードジェネレータ, データベース コード生成 自動生成 Entity DAO スキーマ, not yet created データバインド, ファイル データ変換 CSV TSV 固定長 JavaBeans Map, features/libraries/data-bind.json 汎用データフォーマット, ファイル データ形式 CSV 固定長 JSON XML マルチレイアウト, not yet created - ログ出力, ログ ロギング Logger LogWriter ローテーション, not yet created + ログ出力, ログ ロギング Logger LogWriter ファイル出力 ローテーション, not yet created SLF4Jアダプタ, ログ SLF4J アダプタ log4j logback ロギングフレームワーク, features/adapters/slf4j-adapter.json 入力値のチェック, バリデーション 入力チェック Bean Validation Nablarch Validation 妥当性検証, not yet created - トランザクション管理, トランザクション データベース, not yet created + トランザクション管理, トランザクション データベース コミット ロールバック リソース制御, not yet created コード管理, コード マスタ 区分値 名称 国際化 静的データ, not yet created メッセージ管理, メッセージ 国際化 エラーメッセージ プロパティ フォーマット, not yet created - 排他制御, 排他制御 楽観的ロック 悲観的ロック バージョン番号, not yet created + 排他制御, 排他制御 楽観的ロック 悲観的ロック バージョン番号 同時更新, not yet created 業務日付, 日付 業務日付 システム日付 日時管理, features/libraries/business-date.json ファイルパス管理, ファイル パス管理 ファイルパス 論理名 物理パス, features/libraries/file-path-management.json リポジトリ, リポジトリ DI 依存性注入 コンポーネント定義 設定管理, not yet created @@ -33,8 +33,8 @@ files[93,]{title,hints,path}: フォーマット, フォーマット 数値 日付 文字列 変換 表示形式, not yet created 認可チェック(Permission Check), 認可 権限チェック Permission アクセス制御 セキュリティ, not yet created ロールベース認可, 認可 ロール 権限 アクセス制御 セキュリティ, not yet created - データベース接続管理ハンドラ, ハンドラ データベース 接続管理 コネクション, features/handlers/common/db-connection-management-handler.json - トランザクション管理ハンドラ, ハンドラ トランザクション データベース, features/handlers/common/transaction-management-handler.json + データベース接続管理ハンドラ, ハンドラ データベース 接続管理 接続取得 接続解放 コネクション, features/handlers/common/db-connection-management-handler.json + トランザクション管理ハンドラ, ハンドラ トランザクション コミット ロールバック データベース, features/handlers/common/transaction-management-handler.json グローバルエラーハンドラ, ハンドラ エラーハンドリング 例外処理 共通エラー処理, not yet created ファイルレコードライタ破棄ハンドラ, ハンドラ ファイル 出力 リソース解放 クローズ処理, not yet created リクエストパスJavaパッケージマッピング, ハンドラ ルーティング パス マッピング ディスパッチ, not yet created diff --git a/.claude/skills/nabledge-6/workflows/keyword-search.md b/.claude/skills/nabledge-6/workflows/keyword-search.md index faa4657..dfcb0fc 100644 --- a/.claude/skills/nabledge-6/workflows/keyword-search.md +++ b/.claude/skills/nabledge-6/workflows/keyword-search.md @@ -56,16 +56,18 @@ This workflow searches the knowledge index (index.toon) using keyword matching t **Matching process**: 1. Read knowledge/index.toon (93 entries, format: `Title, hint1 hint2 ..., path.json`) -2. For each entry, match your extracted keywords against hints: - - **Use Level 1 (Technical domain) + Level 2 (Technical component) keywords only** - - Level 3 (Functional) keywords are NOT used in this step +2. For each entry, match your extracted keywords against hints using this **scoring strategy**: + - L1 (Technical domain) or L2 (Technical component) keyword match: **+2 points** per hint + - L3 (Functional) keyword match: **+1 point** per hint - Case-insensitive matching - Partial matching allowed (e.g., "ページ" matches "ページング") - - Count matched hints per entry -3. Sort files by matched hint count (descending) -4. Select top 10-15 files with ≥1 matched hint + - Sum up all matched hint scores for each entry +3. Sort files by total score (descending) +4. Select top 10-15 files with score ≥2 -**Output**: List of candidate files with their matched hints counts. +**Rationale**: L1+L2 keywords indicate the technical domain/component, which is more reliable for file selection. L3 keywords provide additional context but are weighted lower to avoid over-matching on functional terms that may appear across many files. + +**Output**: List of candidate files with their scores and matched hints breakdown. ### Step 2: Extract candidate sections @@ -77,16 +79,18 @@ This workflow searches the knowledge index (index.toon) using keyword matching t ```bash jq '.index' knowledge/features/libraries/universal-dao.json ``` -2. Match your keywords against section hints: - - **Use Level 2 (Technical component) + Level 3 (Functional) keywords** - - Level 1 (Technical domain) keywords are NOT used in this step - - Level 2 is reused from Step 1 (acts as a bridge between file and section selection) +2. Match your keywords against section hints using this **scoring strategy**: + - L2 (Technical component) keyword match: **+2 points** per hint + - L3 (Functional) keyword match: **+2 points** per hint + - L1 (Technical domain) keywords are **not scored** (too broad for section-level matching) - Case-insensitive matching, partial matching allowed - - Count matched hints per section -3. Keep sections with ≥1 matched hint + - Sum up all matched hint scores for each section +3. Keep sections with score ≥2 4. Stop when you have 20-30 candidate sections total -**Output**: List of candidates with file_path, section_id, and matched_hints. +**Rationale**: At section level, both technical components (L2) and specific functions (L3) are equally important for identifying the right content. L1 keywords are too broad for section discrimination. + +**Output**: List of candidates with file_path, section_id, score, and matched_hints breakdown. ### Step 3: Judge relevance and return results @@ -98,12 +102,20 @@ This workflow searches the knowledge index (index.toon) using keyword matching t { "file_path": "features/libraries/universal-dao.json", "section": "paging", - "matched_hints": ["ページング", "per", "page"] + "score": 7, + "matched_hints": [ + {"hint": "DAO", "level": "L2", "points": 2}, + {"hint": "ページング", "level": "L3", "points": 2}, + {"hint": "per", "level": "L3", "points": 2}, + {"hint": "page", "level": "L3", "points": 1} + ] } ] } ``` +**Note**: The detailed score breakdown is optional for section-judgement. A simplified format with just `matched_hints: ["DAO", "ページング", "per", "page"]` is also acceptable. + Section-judgement will: - Read actual section content - Judge relevance (High=2, Partial=1, None=0) @@ -129,10 +141,20 @@ Use the returned sections to answer the user's question (knowledge files only). - Level 2 (Technical component): ["DAO", "UniversalDao", "O/Rマッパー"] - Level 3 (Functional): ["ページング", "paging", "per", "page", "limit", "offset"] -**Step 1**: Match against index.toon using L1+L2 → universal-dao.json (matched: データベース, DAO), database-access.json (matched: データベース) -**Step 2**: Extract sections using L2+L3 → universal-dao/paging (matched: DAO, ページング, per, page), universal-dao/overview (matched: DAO) -**Step 3**: Section-judgement → Only universal-dao/paging judged as High (2), others filtered as None -**Result**: 1 section with pagination API and examples +**Step 1**: Match against index.toon with scoring +- universal-dao.json: score=7 (データベース[L1]:2 + DAO[L2]:2 + O/Rマッパー[L2]:2 + ページング[L3]:1) +- database-access.json: score=2 (データベース[L1]:2) +- Top files selected: universal-dao.json, database-access.json + +**Step 2**: Extract sections with scoring +- universal-dao/paging: score=7 (DAO[L2]:2 + ページング[L3]:2 + per[L3]:2 + page[L3]:1) +- universal-dao/overview: score=4 (DAO[L2]:2 + O/Rマッパー[L2]:2) +- universal-dao/crud: score=2 (DAO[L2]:2) +- Candidates: paging (score=7), overview (score=4), crud (score=2) + +**Step 3**: Section-judgement → paging judged as High (2), overview as Partial (1), crud as None (0) + +**Result**: 1 primary section (paging) with pagination API and examples ## Notes @@ -141,8 +163,19 @@ Use the returned sections to answer the user's question (knowledge files only). - Final relevance scoring happens in section-judgement workflow - Expected output: 5-15 relevant sections filtered by section-judgement -**Keyword level usage strategy**: -- **Level 2 acts as a bridge**: Used in both file selection (Step 1) and section selection (Step 2) -- **File selection (index.toon)**: L1 (broad technical domain) + L2 (specific technology) → narrows down to 10-15 files -- **Section selection (.index)**: L2 (specific technology) + L3 (specific function) → narrows down to 20-30 sections -- This two-stage filtering with L2 overlap ensures high precision while maintaining recall +**Scoring strategy rationale**: + +| Stage | L1 Weight | L2 Weight | L3 Weight | Rationale | +|-------|-----------|-----------|-----------|-----------| +| **File selection** | +2 | +2 | +1 | L1/L2 identify technical domain/component (primary discriminator). L3 provides context (secondary). | +| **Section selection** | 0 | +2 | +2 | L2/L3 identify specific technology/function (equal importance). L1 too broad for section-level. | + +**Why weighted scoring?**: +- **Deterministic**: Same input always produces same scores (no ambiguous judgment) +- **Flexible**: Handles edge cases (L3-only matches get lower scores but aren't excluded) +- **Debuggable**: Score breakdown makes it clear why files/sections were selected +- **L2 acts as bridge**: Used in both stages with high weight, ensuring continuity between file→section selection + +**Threshold settings**: +- File selection: ≥2 points ensures at least 1 L1 or L2 match +- Section selection: ≥2 points ensures at least 1 L2 or L3 match diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 916bc1c..12cefd7 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -1,19 +1,8 @@ # Nabledge設計書 -**作成日**: 2026年2月10日 -**バージョン**: 1.5 +**更新日**: 2026年2月10日 **ステータス**: Draft -## 変更履歴 - -| バージョン | 日付 | 変更内容 | -|----------|------|---------| -| 1.5 | 2026/02/10 | 検索設計の全面見直し(3段階キーワード抽出+2段階検索プロセス) | -| 1.4 | 2026/02/10 | 代行業務の整理、文体統一 | -| 1.3 | 2026/02/10 | アーキテクチャレビュー反映 | -| 1.2 | 2026/02/10 | MCP削除、簡潔化 | -| 1.0 | 2026/02/09 | 初版作成 | - --- ## 1. 概要 @@ -306,7 +295,7 @@ files[N,]{path,hints}: #### ④ 関連度判定 -ファイルとセクションそれぞれに関連度を付与します。 +候補となったセクションの実際の内容を読み、ユーザーの依頼に対する関連度を判定します。 | レベル | 値 | 判断基準 | |:------:|:---:|---------| @@ -435,8 +424,7 @@ files[N,]{path,hints}: #### フェーズ1: Nabバッチ(FW)- バッチフレームワーク完成(優先度: 最高) -**期間**: 1週間 -**作業量**: 約1.5時間(作成45分 + 品質チェック45分) +**期間**: 1~2週間 **対象**: バッチ専用ハンドラ約10個、バッチで使うライブラリ約5個 **目的**: なるべく早くAIのメリットを感じてもらうことです @@ -448,24 +436,19 @@ files[N,]{path,hints}: #### フェーズ2: Nabバッチ(NTF)- テストフレームワーク完成 -**期間**: 3日 -**作業量**: 約30分 -**対象**: NTF関連の残り約1-2個 +**期間**: 1~2週間 +**対象**: NTF関連約1-2個 #### フェーズ3: REST(API)- RESTful Webサービス対応 -**期間**: 1週間 -**作業量**: 約1時間 +**期間**: 1~2週間 **対象**: RESTful処理方式1個、REST専用ハンドラ約5個、REST関連ライブラリ約3個 -#### フェーズ4: 残り - 網羅性確保 +#### フェーズ4: 網羅性確保 -**期間**: 1週間 -**作業量**: 約1.5時間 +**期間**: 1~2週間 **対象**: アダプタ約12個、共通ハンドラ約5個、チェック項目2個、その他約5個 -**全体作業量**: 約4.5時間(作成2.5時間 + 品質チェック2時間) - --- ### 3.3 品質保証 @@ -487,54 +470,3 @@ files[N,]{path,hints}: - コード例が動作する最小形であること - 出典(official_doc_urls)を全ての情報に付与すること - 対象外情報(Jakarta Batch等)を含まないこと - ---- - -## 4. 参考資料 - -### 4.1 公式ドキュメント - -| カテゴリ | URL | -|---------|-----| -| **Nablarch解説書** | https://nablarch.github.io/docs/LATEST/doc/ | -| **Nablarchバッチ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/batch/nablarch_batch/index.html | -| **RESTful Webサービス** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/web_service/rest/index.html | -| **標準ハンドラ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/handlers/index.html | -| **ライブラリ** | https://nablarch.github.io/docs/LATEST/doc/application_framework/application_framework/libraries/index.html | -| **テスティングFW** | https://nablarch.github.io/docs/LATEST/doc/development_tools/testing_framework/index.html | -| **システム開発ガイド** | https://fintan.jp/page/252 | -| **Nablarchパターン集** | https://fintan.jp/page/252/2/ | -| **Nablarchアンチパターン** | https://fintan.jp/page/252/5/ | - -### 4.2 リポジトリ - -| 対象 | GitHub URL | -|------|-----------| -| **nablarch-example-batch** | https://github.com/nablarch/nablarch-example-batch | -| **nablarch-example-rest** | https://github.com/nablarch/nablarch-example-rest | - ---- - -## まとめ - -### 本設計書で定義したこと - -1. **代行業務10個**と優先度を明確化しました -2. **知識タイプ3つを定義**し、作成単位を決定しました(約60個) -3. **検索設計**を明確化しました - - 3段階キーワード抽出(技術領域・技術要素・機能) - - 2段階検索プロセス(ファイル選定→セクション選定) - - 関連度3段階判定(High/Partial/None) - - セクション単位抽出(上位10件 ≈ 5,000トークン) -4. **TOON形式インデックス**を採用しました(30-60%トークン削減) -5. **4フェーズの実装計画**を策定しました(総作業時間約4.5時間) - -### 次のアクション - -1. フェーズ1を実施します(バッチフレームワーク知識の拡充 ≈ 1.5時間) -2. 仮説検証を行います(代行精度と工数削減の実測) -3. 効果測定後、フェーズ2以降へ進みます - ---- - -**以上** From 08977e7867fb6f290e78ff8d462e674c2de4ed41 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 18:52:24 +0900 Subject: [PATCH 18/89] =?UTF-8?q?docs:=20=E8=A8=AD=E8=A8=88=E6=9B=B8?= =?UTF-8?q?=E3=81=AE=E6=A7=8B=E9=80=A0=E3=82=92=E6=94=B9=E5=96=84=E3=81=97?= =?UTF-8?q?=E8=AA=AC=E6=98=8E=E3=82=92=E6=98=8E=E7=A2=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- doc/nabledge-design.md | 248 +++++++++++++++++++++++++++++------------ 1 file changed, 176 insertions(+), 72 deletions(-) diff --git a/doc/nabledge-design.md b/doc/nabledge-design.md index 12cefd7..51e7da6 100644 --- a/doc/nabledge-design.md +++ b/doc/nabledge-design.md @@ -3,22 +3,39 @@ **更新日**: 2026年2月10日 **ステータス**: Draft ---- - ## 1. 概要 -### 1.1 背景と目的 +### 1.1 Nabledgeとは + +NabledgeはNablarchの構造化知識と、それを活用して開発作業を代行するワークフローで構成される、AIエージェント(Claude Code、GitHub Copilot)向けの知識基盤です。 + +### 1.2 解決する課題 + +現在、以下の3つの課題があります。 + +1. **AI単体では代行精度が不十分** + + Nablarch固有の知識がなく、開発作業の代行精度が低い + +2. **公式ドキュメントはAI向けではない** + + 人間向けに書かれており、AIが効率的に検索・参照できない + +3. **開発に時間がかかる** -**Nabledgeとは**: -Nablarchの構造化知識と、それを活用して開発作業を代行するワークフローで構成される、AIエージェント(Claude Code、GitHub Copilot)向けの知識基盤です。 + 新規参画者のオンボーディングや日常開発に多くの時間を要する -**解決する課題**: AI単体ではNablarch固有の知識がなく代行精度が不十分なこと、公式ドキュメントは人間向けでAIが効率的に検索・参照できないこと、新規参画者のオンボーディングや日常開発に時間がかかることです。 +### 1.3 目的 -**目的**: AIエージェントにNablarchの構造化知識を提供し、実装調査・コード生成・レビュー等の代行精度向上、開発工数の削減(目標: 60-70%)、オンボーディング期間の短縮を実現します。 +AIエージェントにNablarchの構造化知識を提供することで、以下を実現します。 ---- +- 実装調査・コード生成・レビュー等の代行精度向上 +- 開発工数の削減(目標: 60-70%) +- オンボーディング期間の短縮 -### 1.2 想定する代行作業 +### 1.4 想定する代行作業 + +Nabledgeが対象とする代行作業を優先度別に整理しました。優先度Sの作業は知識基盤の構築に必須、優先度Aはプロジェクトでの要望が多いものです。 | 代行業務 | 優先度 | 優先度理由 | Nabledge代行適性 | |---------|:------:|-----------|:---------------:| @@ -33,29 +50,51 @@ Nablarchの構造化知識と、それを活用して開発作業を代行する | 設計書解読 | B | | 低 | | ドキュメント生成 | B | | 低 | -**Nabledge代行適性**: +**Nabledge代行適性の定義**: - **高**: Nablarch知識だけで対応可能 - **中**: Nablarch知識に加えてPJ固有知識が必要 - **低**: PJ固有知識が多く必要 ---- +### 1.5 スコープ + +**対象** + +- Nablarchバッチ(都度起動型) +- RESTful Webサービス -### 1.3 スコープ +**対象外** -**対象**: Nablarchバッチ(都度起動型)、RESTful Webサービス +- Jakarta Batch +- 常駐バッチ +- ウェブアプリケーション(JSP/画面) +- メッセージング(MOM) -**対象外**: Jakarta Batch、常駐バッチ、ウェブアプリケーション(JSP/画面)、メッセージング(MOM) +**対象バージョン** -**対象バージョン**: Nablarch 6系、5系、1.4系、1.3系、1.2系 +- Nablarch 6系、5系、1.4系、1.3系、1.2系 -**想定ツール**: Claude CodeとGitHub Copilotの両方に対応します。 +**想定ツール** ---- +- Claude Code、GitHub Copilot ## 2. アーキテクチャ ### 2.1 全体構造 +Nabledgeは3つの要素で構成されます。 + +1. **知識基盤** + + 構造化されたNablarch知識(TOON形式インデックス、JSON形式知識ファイル) + +2. **ワークフロー** + + 知識検索、代行作業、知識生成の3つのワークフロー + +3. **配布** + + GitHub経由でClaude Code Pluginとして配布 + ```mermaid graph TB %% 左側: 主要アクター @@ -127,24 +166,54 @@ graph TB style workflows fill:#fff9c4 ``` -**実行フロー**: -1. Nablarch利用者が自然言語でAIツールに依頼します(例: 「ページングを実装したい」) -2. AIツールがワークフロー(知識検索)を実行します → keyword-searchで検索 -3. 関連度の高いセクションを特定します(High/Partial/Noneの3段階) -4. ワークフロー(代行作業)を実行し、知識ファイルを参照します(上位10セクション ≈ 5,000トークン) -5. 回答またはコードを生成してユーザーに返します +#### 実行フロー + +1. **ユーザー依頼** + + Nablarch利用者が自然言語でAIツールに依頼します(例: 「ページングを実装したい」) + +2. **知識検索** + + AIツールがワークフロー(知識検索)を実行し、keyword-searchで検索します + +3. **セクション特定** + + 関連度の高いセクションを特定します(High/Partial/Noneの3段階) + +4. **代行作業実行** + + ワークフロー(代行作業)を実行し、知識ファイルを参照します(上位10セクション ≈ 5,000トークン) + +5. **結果返却** + + 回答またはコードを生成してユーザーに返します + +#### 設計のポイント + +- **配布** + + GitHub (nablarch/nabledge) → Claude Code Plugin → インストール + +- **検索** + + 3段階キーワード抽出 + 2段階検索プロセス(ファイル→セクション)で高精度を実現 + +- **トークン効率** -**設計のポイント**: -- **配布**: GitHub (nablarch/nabledge) → Claude Code Plugin → インストール -- **検索**: 3段階キーワード抽出 + 2段階検索プロセス(ファイル→セクション)で高精度を実現 -- **トークン効率**: TOON形式で30-60%削減、セクション単位抽出で必要最小限(5,000トークン)に抑制 -- **正確性**: 公式ドキュメント照合、人向けMarkdownで根拠追跡 -- **保守性**: JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離 + TOON形式で30-60%削減、セクション単位抽出で必要最小限(5,000トークン)に抑制 ---- +- **正確性** + + 公式ドキュメント照合、人向けMarkdownで根拠追跡 + +- **保守性** + + JSON→MD自動変換で1箇所メンテナンス、バージョン別スキル分離 ### 2.2 知識タイプ +Nabledgeの知識は3つのタイプに分類され、約60個のファイルを作成します。 + | # | 知識タイプ | 内容 | カバー範囲 | 作成単位 | 推定件数 | |---|-----------|------|----------|---------|---------| | ① | 機能・実装パターン(エラー含む) | どう実装するか、エラー対処 | 9タスク(90%) | ハンドラ、ライブラリ、処理方式、ツール、アダプタ | 約55個 | @@ -152,9 +221,7 @@ graph TB | ③ | リリースノート | 何が変わった/壊れているか | 2タスク(20%) | バージョン単位 | 複数個 | | **合計** | | | | | **約60個** | -**設計判断**: ①を優先的に構造化すれば9割の作業をカバー可能です。①から着手します。 - ---- +**設計判断**: ①機能・実装パターンを優先的に構造化すれば9割の作業をカバー可能です。①から着手します。 ### 2.3 配布とインストール @@ -174,7 +241,8 @@ GitHub (nablarch/nabledge) #### インストール方法 -**Claude Code**: +**Claude Code** + ```bash # Plugin Registryからインストール claude plugin install nabledge-6 @@ -186,12 +254,22 @@ claude plugin list claude plugin update nabledge-6 ``` -**GitHub Copilot**: -プロジェクトルートに`.claude/skills/nabledge-6/`を配置し、設定ファイルに登録します。 +**GitHub Copilot** + +セットアップスクリプトをダウンロードして実行します。 + +```bash +# セットアップスクリプトを実行 +curl -fsSL https://raw.githubusercontent.com/nablarch/nabledge/main/install.sh | sh +``` + +セットアップスクリプトは以下を実行します: +- プロジェクトルートに`.claude/skills/nabledge-6/`を配置 +- 設定ファイルに自動登録 -**設計判断**: Claude Codeの標準配布方式を採用します。GitHubからの自動取得、バージョン管理、更新通知が容易です。 +**設計判断** ---- +Claude Codeの標準配布方式を採用します。GitHubからの自動取得、バージョン管理、更新通知が容易です。 ### 2.4 ファイル構成 @@ -214,17 +292,19 @@ nabledge-6/ └── docs/ # 人向け閲覧用(JSON→MD自動変換) ``` -**命名規則**: 英語、kebab-case(例: `db-connection-management-handler.json`) +**命名規則** + +英語、kebab-case(例: `db-connection-management-handler.json`) -**設計判断**: バージョン情報はファイル名に含めません(スキル自体がバージョン別のため冗長です)。 +**設計判断** ---- +バージョン情報はファイル名に含めません(スキル自体がバージョン別のため冗長です)。 ### 2.5 検索設計 -#### 検索の全体フロー +Nabledgeの検索は、ユーザーの依頼から必要な知識を高精度で特定する仕組みです。3段階のキーワード抽出と、2段階の検索プロセス(ファイル選定→セクション選定)で実現します。 -ユーザーの依頼から必要な知識を特定するまでの流れを説明します。 +#### 検索の全体フロー ``` ユーザー依頼(例:「ページングを実装したい」) @@ -252,11 +332,15 @@ nabledge-6/ | Level 2 | Technical component(技術要素) | DAO, JDBC, JPA, Bean Validation, JSON, XML など | DAO, UniversalDao, O/Rマッパー | | Level 3 | Functional(機能) | ページング, 検索, 登録, 更新, 削除, 接続, コミット など | ページング, paging, per, page, limit, offset | -**例**: 依頼「ページングを実装したい」→ 3段階のキーワードに分解 +**例** + +依頼「ページングを実装したい」→ Level 1「データベース」、Level 2「DAO」、Level 3「ページング」に分解 #### ② ファイル選定(index.toon) -**使用するキーワード**: Level 1(技術領域)+ Level 2(技術要素) +**使用するキーワード** + +Level 1(技術領域)+ Level 2(技術要素) **index.toonの構造**: ```toon @@ -271,11 +355,15 @@ files[N,]{path,hints}: - 93エントリ、約650検索ヒント → 約5-7Kトークン - 各ファイルのパスと検索ヒント(Level 1 + Level 2)を記載 -**マッチング例**: 「データベース」「DAO」で `universal-dao.json` が候補に +**マッチング例** + +「データベース」「DAO」で `universal-dao.json` が候補に #### ③ セクション選定(ファイル内index) -**使用するキーワード**: Level 2(技術要素)+ Level 3(機能) +**使用するキーワード** + +Level 2(技術要素)+ Level 3(機能) **ファイル内indexの構造**: ```json @@ -291,7 +379,9 @@ files[N,]{path,hints}: - 各セクションの検索ヒント(Level 2 + Level 3)を記載 - セクション単位で関連度を判定 -**マッチング例**: 「ページング」「paging」で `paging` セクションが候補に +**マッチング例** + +「ページング」「paging」で `paging` セクションが候補に #### ④ 関連度判定 @@ -303,7 +393,9 @@ files[N,]{path,hints}: | **Partial** | 1 | 依頼に関連し、補足として有用 | | **None** | 0 | 関連なし(対象外) | -**ファイルの関連度**: そのファイル内のセクション関連度の最大値 +**ファイルの関連度** + +そのファイル内のセクション関連度の最大値 **例**: `universal-dao.json` - `paging` セクション: High (2) @@ -354,10 +446,10 @@ files[N,]{path,hints}: 現状、keyword-searchだけで十分な検索精度が得られています。将来的に検索精度の向上が必要になった場合は、intent-search(目的→カテゴリ、対象→ファイルで絞り込む方式)の導入を検討します。 ---- - ### 2.6 知識ファイル設計 +知識ファイルはJSON形式で構造化され、AI向けに最適化された情報を格納します。 + #### 共通構造 ```json @@ -379,10 +471,19 @@ files[N,]{path,hints}: } ``` -**設計判断**: -- **JSON形式**: パース容易、jqでセクション抽出可能、構造化データとして扱いやすいです -- **二層構造(JSON + Markdown)**: AI向けJSON、人向けMD(自動変換)でメンテナンス1箇所で済みます -- **スキーマバージョニング**: 非互換変更時にメジャーバージョンアップします(1.0 → 2.0) +**設計判断** + +- **JSON形式** + + パース容易、jqでセクション抽出可能、構造化データとして扱いやすいです + +- **二層構造(JSON + Markdown)** + + AI向けJSON、人向けMD(自動変換)でメンテナンス1箇所で済みます + +- **スキーマバージョニング** + + 非互換変更時にメジャーバージョンアップします(1.0 → 2.0) #### 情報の持ち方の原則 @@ -393,20 +494,23 @@ files[N,]{path,hints}: | **表現は最適化する** | 読み物的記述→端的な記述にします | 導入文、冗長な説明、重複表現、段階的な説明を削除し、箇条書き化します | | **形式はAI向けに** | 構造化データで検索・参照しやすくします | JSON形式、検索ヒント設計を採用します | -**設計判断**: 「この情報がないとAIが誤った判断をする可能性があるか?」で判断します。YESなら残し、NOなら最適化します。 +**設計判断** ---- +「この情報がないとAIが誤った判断をする可能性があるか?」で判断します。YESなら残し、NOなら最適化します。 ## 3. 実装計画 ### 3.1 作成範囲 -**情報源**: +**情報源** + - Nablarch公式解説書(https://nablarch.github.io/docs/LATEST/doc/) - システム開発ガイド(https://fintan.jp/page/252/)- パターン集、アンチパターン - サンプルプロジェクト(GitHub: nablarch/nablarch-example-batch, nablarch-example-rest) -**作成規模**: 約60個の知識ファイル +**作成規模** + +約60個の知識ファイル | 作成単位 | 推定件数 | 備考 | |---------|---------|------| @@ -418,15 +522,15 @@ files[N,]{path,hints}: | チェック項目 | 3個 | セキュリティ、推奨/非推奨、公開API | | リリースノート | 複数個 | バージョン別 | ---- - ### 3.2 フェーズ計画 +知識ファイルの作成を4つのフェーズに分けて段階的に進めます。フェーズ1で仮説検証を行い、効果を確認してから次のフェーズへ進みます。 + #### フェーズ1: Nabバッチ(FW)- バッチフレームワーク完成(優先度: 最高) -**期間**: 1~2週間 -**対象**: バッチ専用ハンドラ約10個、バッチで使うライブラリ約5個 -**目的**: なるべく早くAIのメリットを感じてもらうことです +- **期間**: 1~2週間 +- **対象**: バッチ専用ハンドラ約10個、バッチで使うライブラリ約5個 +- **目的**: なるべく早くAIのメリットを感じてもらうことです **仮説検証**: - 代行精度を実測します(実装調査、コード生成、レビュー等) @@ -436,23 +540,23 @@ files[N,]{path,hints}: #### フェーズ2: Nabバッチ(NTF)- テストフレームワーク完成 -**期間**: 1~2週間 -**対象**: NTF関連約1-2個 +- **期間**: 1~2週間 +- **対象**: NTF関連約1-2個 #### フェーズ3: REST(API)- RESTful Webサービス対応 -**期間**: 1~2週間 -**対象**: RESTful処理方式1個、REST専用ハンドラ約5個、REST関連ライブラリ約3個 +- **期間**: 1~2週間 +- **対象**: RESTful処理方式1個、REST専用ハンドラ約5個、REST関連ライブラリ約3個 #### フェーズ4: 網羅性確保 -**期間**: 1~2週間 -**対象**: アダプタ約12個、共通ハンドラ約5個、チェック項目2個、その他約5個 - ---- +- **期間**: 1~2週間 +- **対象**: アダプタ約12個、共通ハンドラ約5個、チェック項目2個、その他約5個 ### 3.3 品質保証 +知識ファイルの正確性と品質を担保するため、5段階のプロセスで品質保証を行います。 + #### 5段階プロセス 1. **作成**: AIエージェントが知識ファイルを作成します From 604f360038f98faa5b9ad4be63331fea9e7c1efa Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 19:35:18 +0900 Subject: [PATCH 19/89] docs: Translate documentation to English and establish language rules Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 70 +++++++++++++++++++++++++++++++++---------------------- README.md | 13 ++++++----- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index c74d439..c2699ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,58 +1,72 @@ # nabledge-dev -言語は日本語 +## Language Rules -## 概要 +**All content in this repository must be in English**, including: +- Code comments +- Documentation (README, design docs, work logs) +- Commit messages +- Test scenarios and results +- Skill definitions and workflows -このリポジトリは **Nablarchエージェント用の構造化知識基盤(スキル)** を作成・管理するためのものです。 +**Exception**: nabledge-x skills' user-facing messages should be in Japanese, as they are designed for Nablarch users in Japan. -- **nabledge-6**: Nablarch 6(Jakarta EE 10、Java 17以上)用のスキル -- **nabledge-5**: Nablarch 5(Java EE 7/8、Java 8以上)用のスキル +--- + +## Overview + +This repository contains **nabledge skills** for AI agents to assist with Nablarch development. -AI(Claude Code / GitHub Copilot)がNablarch開発を代行するための構造化された知識を提供します。 +- **nabledge-6**: Skill for Nablarch 6 (Jakarta EE 10, Java 17+) +- **nabledge-5**: Skill for Nablarch 5 (Java EE 7/8, Java 8+) + +These skills enable AI (Claude Code / GitHub Copilot) to autonomously perform Nablarch development tasks. --- -## ディレクトリ構成 +## Directory Structure ``` nabledge-dev/ ├── .claude/ │ └── skills/ -│ ├── nabledge-6/ # Nablarch 6 スキル(作成予定) -│ └── nabledge-5/ # Nablarch 5 スキル(作成予定) +│ ├── nabledge-6/ # Nablarch 6 skill (in development) +│ ├── nabledge-5/ # Nablarch 5 skill (planned) +│ └── nabledge-test/ # Testing framework for nabledge skills │ ├── .lw/ -│ ├── research/ # 調査・設計ドキュメント -│ └── nab-official/ # Nablarch公式情報(クローン) +│ ├── research/ # Research & design documents +│ └── nab-official/ # Nablarch official documentation (cloned) +│ +├── work/ # Work logs (daily) │ -└── CLAUDE.md # このファイル +└── CLAUDE.md # This file ``` --- -## 対象範囲 +## Scope -### 対象 +### In Scope -| 項目 | 説明 | -|-----|------| -| **Nablarchバッチ(都度起動型)** | FILE to DB、DB to DB、DB to FILE パターン | -| **RESTful Webサービス** | JAX-RSサポート、REST API実装 | +| Item | Description | +|------|-------------| +| **Nablarch Batch (On-demand)** | FILE to DB, DB to DB, DB to FILE patterns | +| **RESTful Web Services** | JAX-RS support, REST API implementation | -### 対象外 +### Out of Scope -| 項目 | 理由 | -|-----|------| -| Jakarta Batch | 仕様書で対象外と明記 | -| 常駐バッチ(テーブルキュー型) | 仕様書で対象外と明記 | -| ウェブアプリケーション(JSP/画面系) | バッチ・REST以外は対象外 | -| メッセージング(MOM) | 対象外 | +| Item | Reason | +|------|--------| +| Jakarta Batch | Explicitly excluded in specification | +| Resident Batch (Table Queue) | Explicitly excluded in specification | +| Web Applications (JSP/UI) | Focus on batch & REST only | +| Messaging (MOM) | Out of scope | --- -## 詳細設計 +## Design Documentation -スキルの詳細なアーキテクチャ設計は以下を参照: +Refer to the detailed architecture design: -- [Step 3: 構造化アーキテクチャ設計](.lw/research/step3-architecture-design.md) +- [Nabledge Design Document](doc/nabledge-design.md) diff --git a/README.md b/README.md index ca59f7d..c10601a 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,22 @@ # nabledge-dev + Nablarch knowledge development -## 前提条件 +## Prerequisites - WSL2 / Ubuntu -- 社内プロキシ環境の場合: CA証明書 +- CA certificate (if behind corporate proxy) -## セットアップ +## Setup -### 1. CA証明書の配置(プロキシ環境の場合) +### 1. Install CA Certificate (for proxy environments) ```bash sudo cp /path/to/your/ca.crt /usr/local/share/ca-certificates/ca.crt sudo update-ca-certificates ``` -### 2. 環境構築 +### 2. Environment Setup ```bash ./setup.sh @@ -23,7 +24,7 @@ cp .env.example .env # Edit .env and set your credentials ``` -## 作業開始 +## Getting Started ```bash source .env From 0d12a6570ce791497de30c6ca43b6d17f1d5df1c Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 19:43:19 +0900 Subject: [PATCH 20/89] =?UTF-8?q?refactor:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=B7=E3=83=8A=E3=83=AA=E3=82=AA=E3=82=92=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E3=81=97=E3=81=9Fnabledge-test=E3=82=B9=E3=82=AD=E3=83=AB?= =?UTF-8?q?=E3=81=AB=E5=86=8D=E7=B7=A8=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit テストシナリオをnabledge-6/tests/から独立したスキル構造に移行し、 ワークフロー駆動のテスト実行とレビュー機能を追加 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/tests/README.md | 225 ------ .../skills/nabledge-6/tests/scenarios.json | 557 ------------- .claude/skills/nabledge-6/tests/scenarios.md | 729 ------------------ .claude/skills/nabledge-test/README.md | 154 ++++ .../nabledge-6/code-analysis-scenarios.json | 168 ++++ .../nabledge-6/keyword-search-scenarios.json | 138 ++++ .claude/skills/nabledge-test/skill.json | 32 + .claude/skills/nabledge-test/skill.md | 80 ++ .../skills/nabledge-test/templates/review.md | 200 +++++ .../templates/scenario-result.md | 104 +++ .../workflows/evaluate-results.md | 255 ++++++ .../nabledge-test/workflows/run-scenarios.md | 245 ++++++ 12 files changed, 1376 insertions(+), 1511 deletions(-) delete mode 100644 .claude/skills/nabledge-6/tests/README.md delete mode 100644 .claude/skills/nabledge-6/tests/scenarios.json delete mode 100644 .claude/skills/nabledge-6/tests/scenarios.md create mode 100644 .claude/skills/nabledge-test/README.md create mode 100644 .claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json create mode 100644 .claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json create mode 100644 .claude/skills/nabledge-test/skill.json create mode 100644 .claude/skills/nabledge-test/skill.md create mode 100644 .claude/skills/nabledge-test/templates/review.md create mode 100644 .claude/skills/nabledge-test/templates/scenario-result.md create mode 100644 .claude/skills/nabledge-test/workflows/evaluate-results.md create mode 100644 .claude/skills/nabledge-test/workflows/run-scenarios.md diff --git a/.claude/skills/nabledge-6/tests/README.md b/.claude/skills/nabledge-6/tests/README.md deleted file mode 100644 index 5b20076..0000000 --- a/.claude/skills/nabledge-6/tests/README.md +++ /dev/null @@ -1,225 +0,0 @@ -# Nabledge-6 Test Scenarios - -## Overview - -This directory contains test scenarios for validating the nabledge-6 skill workflow execution. - -## Files - -| File | Format | Purpose | -|------|--------|---------| -| `scenarios.json` | JSON | Machine-readable test scenarios for automated evaluation | -| `scenarios.md` | Markdown | Human-readable test scenarios for manual testing | -| `README.md` | Markdown | This file - usage instructions | - -## Test Scenarios - -**Total**: 25 scenarios (5 per category) - -**Categories**: -- **handlers**: Transaction management, DB connection, data reading -- **libraries**: UniversalDao, database access, file path, business date, data bind -- **tools**: NTF (test framework), assertions, test data -- **processing**: Nablarch batch architecture and implementation -- **adapters**: SLF4J logging adapter - -## Scenario Structure - -Each scenario contains: - -```json -{ - "id": "unique-id", - "category": "handlers|libraries|tools|processing|adapters", - "file": "path/to/knowledge-file.json", - "question": "User's question in Japanese", - "expected_keywords": ["keyword1", "keyword2", ...], - "expected_sections": ["section1", "section2"], - "relevance": "high|partial" -} -``` - -## Evaluation Criteria - -### 1. Workflow Execution ✓ -- keyword-search workflow executed -- section-judgement workflow executed -- Appropriate tool calls (Read, Bash+jq) - -### 2. Keyword Matching (≥80%) -- Expected keywords present in answer -- Related technical terms used correctly - -### 3. Section Relevance ✓ -- Correct sections identified -- High-relevance sections prioritized -- None-relevance sections filtered out - -### 4. Knowledge File Only ✓ -- No LLM training data used -- No external knowledge supplemented -- Only knowledge file content used - -### 5. Token Efficiency (5,000-15,000 tokens) -- No unnecessary full-file reads -- Section-level extraction working - -### 6. Tool Call Efficiency (10-20 calls) -- Read: index.toon (1 call) -- Bash+jq: .index extraction (5-10 calls) -- Bash+jq: .sections extraction (5-10 calls) - -## Usage - -### Manual Testing - -Test individual scenarios by asking the question: - -``` -"データリードハンドラでファイルを読み込むにはどうすればいいですか?" -``` - -**Expected behavior**: -1. Message: "keyword-searchワークフローを実行します" -2. Read index.toon -3. Bash+jq for section extraction -4. Answer contains expected keywords -5. Answer uses only knowledge file content - -### Automated Testing (Future) - -Create an evaluation agent that: - -1. Loads `scenarios.json` -2. For each scenario: - - Executes the question - - Monitors workflow execution - - Validates keyword matching - - Checks section relevance - - Measures token usage - - Counts tool calls -3. Generates evaluation report - -**Evaluation agent prompt template**: - -``` -Execute the test scenario and evaluate the response: - -Question: {question} -Expected Keywords: {expected_keywords} -Expected Sections: {expected_sections} - -Evaluation checklist: -- [ ] Workflow execution (keyword-search + section-judgement) -- [ ] Keyword matching (≥80%) -- [ ] Section relevance (expected sections identified) -- [ ] Knowledge file only (no external knowledge) -- [ ] Token efficiency (5,000-15,000 tokens) -- [ ] Tool call efficiency (10-20 calls) - -Score each criterion and provide overall pass/fail. -``` - -## Example Test Case - -### handlers-001: データリードハンドラの使い方 - -**Question**: -``` -データリードハンドラでファイルを読み込むにはどうすればいいですか? -``` - -**Expected Workflow**: -1. Extract keywords: ["データリードハンドラ", "ファイル", "読み込み", "DataReader"] -2. Read index.toon → match "data-read-handler.json" -3. Bash+jq '.index' data-read-handler.json → find relevant sections -4. Bash+jq '.sections.overview' → read content -5. Judge relevance: High (directly answers question) -6. Answer using only section content - -**Expected Answer Content**: -- DataReadHandler explanation -- DataReader interface usage -- File reading configuration -- Code examples or method signatures - -**Expected Keywords in Answer** (≥4/5): -- ✓ DataReadHandler -- ✓ DataReader -- ✓ ファイル読み込み -- ✓ データ入力 -- ✓ レコード処理 - -## Success Metrics - -A test scenario passes if: - -- [ ] Workflow executed correctly (both keyword-search and section-judgement) -- [ ] ≥80% of expected keywords present in answer -- [ ] Relevant sections identified and used -- [ ] Answer uses only knowledge file content (no LLM training data) -- [ ] Token usage: 5,000-15,000 tokens -- [ ] Tool calls: 10-20 calls - -## Known Limitations - -### Not Yet Created Knowledge Files - -Some expected sections may not exist in knowledge files yet. In these cases: - -**Expected behavior**: -- Message: "この情報は知識ファイルに含まれていません" -- List related available knowledge -- Show "not yet created" entries from index.toon -- No answer from LLM training data - -**Test scenarios affected**: -- Any scenario with expected_sections that don't exist in the actual knowledge files - -### Section Name Variations - -Expected section names are estimates based on typical knowledge file structure. Actual section IDs may differ. - -**If section names don't match**: -- Workflow should still find related sections by keyword matching -- Evaluate based on content relevance, not exact section ID match - -## Contributing - -To add new test scenarios: - -1. Choose a knowledge file from `knowledge/features/` -2. Read the file's `.index` field to see available sections -3. Create a question that maps to a specific section -4. List expected keywords from that section -5. Add to `scenarios.json` with unique ID -6. Update `scenarios.md` for human readability - -**ID format**: `{category}-{number:03d}` -- Example: `handlers-006`, `libraries-006` - -## Maintenance - -### When Knowledge Files Change - -If knowledge files are updated: - -1. Review affected scenarios in `scenarios.json` -2. Update `expected_keywords` if section content changed -3. Update `expected_sections` if section IDs changed -4. Re-run tests to verify scenarios still pass - -### When Workflow Changes - -If keyword-search or section-judgement workflows change: - -1. Update `evaluation_criteria` in `scenarios.json` -2. Update success metrics in this README -3. Re-run all scenarios to establish new baseline - -## Version History - -- **1.0.0** (2026-02-09): Initial test scenarios created - - 25 scenarios across 5 categories - - JSON and Markdown formats - - Evaluation criteria defined diff --git a/.claude/skills/nabledge-6/tests/scenarios.json b/.claude/skills/nabledge-6/tests/scenarios.json deleted file mode 100644 index 1119f5c..0000000 --- a/.claude/skills/nabledge-6/tests/scenarios.json +++ /dev/null @@ -1,557 +0,0 @@ -{ - "metadata": { - "version": "1.1.0", - "created": "2026-02-09", - "updated": "2026-02-10", - "description": "Test scenarios for nabledge-6 skill workflow validation", - "total_scenarios": 30 - }, - "scenarios": [ - { - "id": "handlers-001", - "category": "handlers", - "file": "handlers/batch/data-read-handler.json", - "question": "データリードハンドラでファイルを読み込むにはどうすればいいですか?", - "expected_keywords": [ - "DataReadHandler", - "DataReader", - "ファイル読み込み", - "データ入力", - "レコード処理" - ], - "expected_sections": ["overview", "usage"], - "relevance": "high" - }, - { - "id": "handlers-002", - "category": "handlers", - "file": "handlers/common/transaction-management-handler.json", - "question": "トランザクション管理ハンドラでロールバックする方法は?", - "expected_keywords": [ - "TransactionManagementHandler", - "ロールバック", - "rollback", - "エラー処理", - "トランザクション制御" - ], - "expected_sections": ["rollback", "error-handling"], - "relevance": "high" - }, - { - "id": "handlers-003", - "category": "handlers", - "file": "handlers/common/db-connection-management-handler.json", - "question": "データベース接続管理ハンドラの設定方法を教えてください", - "expected_keywords": [ - "DbConnectionManagementHandler", - "データベース接続", - "コネクション管理", - "設定", - "コンポーネント定義" - ], - "expected_sections": ["configuration", "setup"], - "relevance": "high" - }, - { - "id": "handlers-004", - "category": "handlers", - "file": "handlers/common/transaction-management-handler.json", - "question": "トランザクションのコミットタイミングはいつですか?", - "expected_keywords": [ - "コミット", - "commit", - "トランザクション", - "タイミング", - "正常終了" - ], - "expected_sections": ["commit", "lifecycle"], - "relevance": "high" - }, - { - "id": "handlers-005", - "category": "handlers", - "file": "handlers/batch/data-read-handler.json", - "question": "データリードハンドラで大量データを処理するには?", - "expected_keywords": [ - "大量データ", - "データ処理", - "バッチ", - "DataReader", - "ループ処理" - ], - "expected_sections": ["large-data", "performance"], - "relevance": "high" - }, - { - "id": "libraries-001", - "category": "libraries", - "file": "libraries/universal-dao.json", - "question": "UniversalDaoでページングを実装したい", - "expected_keywords": [ - "ページング", - "paging", - "per", - "page", - "Pagination", - "EntityList" - ], - "expected_sections": ["paging"], - "relevance": "high" - }, - { - "id": "libraries-002", - "category": "libraries", - "file": "libraries/universal-dao.json", - "question": "UniversalDaoで楽観的ロックを使う方法は?", - "expected_keywords": [ - "楽観的ロック", - "@Version", - "OptimisticLockException", - "排他制御", - "バージョンカラム" - ], - "expected_sections": ["optimistic-lock"], - "relevance": "high" - }, - { - "id": "libraries-003", - "category": "libraries", - "file": "libraries/database-access.json", - "question": "データベースアクセスでSQLを実行する方法を教えてください", - "expected_keywords": [ - "SQL実行", - "Database", - "SqlPStatement", - "クエリ", - "検索" - ], - "expected_sections": ["sql-execution", "query"], - "relevance": "high" - }, - { - "id": "libraries-004", - "category": "libraries", - "file": "libraries/file-path-management.json", - "question": "ファイルパス管理でファイルパスを取得するには?", - "expected_keywords": [ - "ファイルパス", - "FilePathSetting", - "論理名", - "物理パス", - "パス取得" - ], - "expected_sections": ["usage", "configuration"], - "relevance": "high" - }, - { - "id": "libraries-005", - "category": "libraries", - "file": "libraries/business-date.json", - "question": "業務日付を取得する方法は?", - "expected_keywords": [ - "業務日付", - "SystemTimeUtil", - "日付取得", - "システム日付" - ], - "expected_sections": ["overview", "usage"], - "relevance": "high" - }, - { - "id": "tools-001", - "category": "tools", - "file": "tools/ntf-test-data.json", - "question": "NTFでテストデータを準備する方法を教えてください", - "expected_keywords": [ - "テストデータ", - "NTF", - "データ準備", - "Excel", - "データベース" - ], - "expected_sections": ["preparation", "setup"], - "relevance": "high" - }, - { - "id": "tools-002", - "category": "tools", - "file": "tools/ntf-assertion.json", - "question": "NTFのアサーション機能の使い方は?", - "expected_keywords": [ - "アサーション", - "検証", - "期待値", - "実測値", - "NTF" - ], - "expected_sections": ["assertion", "verification"], - "relevance": "high" - }, - { - "id": "tools-003", - "category": "tools", - "file": "tools/ntf-batch-request-test.json", - "question": "バッチのリクエスト単体テストを実行するには?", - "expected_keywords": [ - "リクエスト単体テスト", - "バッチテスト", - "NTF", - "テスト実行", - "BatchRequestTestSupport" - ], - "expected_sections": ["test-execution", "setup"], - "relevance": "high" - }, - { - "id": "tools-004", - "category": "tools", - "file": "tools/ntf-test-data.json", - "question": "テストデータの初期化はどうやりますか?", - "expected_keywords": [ - "初期化", - "データクリア", - "セットアップ", - "テストデータ", - "前処理" - ], - "expected_sections": ["initialization", "cleanup"], - "relevance": "high" - }, - { - "id": "tools-005", - "category": "tools", - "file": "tools/ntf-overview.json", - "question": "NTFの基本的な使い方を教えてください", - "expected_keywords": [ - "NTF", - "自動テストフレームワーク", - "テスト実行", - "JUnit", - "テストケース" - ], - "expected_sections": ["overview", "getting-started"], - "relevance": "high" - }, - { - "id": "processing-001", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "Nablarchバッチの基本構造を教えてください", - "expected_keywords": [ - "バッチ", - "基本構造", - "アーキテクチャ", - "ハンドラ構成", - "処理フロー" - ], - "expected_sections": ["overview", "architecture"], - "relevance": "high" - }, - { - "id": "processing-002", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチアクションの実装方法は?", - "expected_keywords": [ - "BatchAction", - "アクション実装", - "バッチ処理", - "execute", - "ビジネスロジック" - ], - "expected_sections": ["action-implementation", "business-logic"], - "relevance": "high" - }, - { - "id": "processing-003", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチで大量データを処理する方法は?", - "expected_keywords": [ - "大量データ", - "データ処理", - "ループ処理", - "DataReader", - "パフォーマンス" - ], - "expected_sections": ["large-data-processing", "performance"], - "relevance": "high" - }, - { - "id": "processing-004", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチのエラーハンドリングはどうすればいいですか?", - "expected_keywords": [ - "エラーハンドリング", - "例外処理", - "エラー処理", - "リトライ", - "異常終了" - ], - "expected_sections": ["error-handling", "exception"], - "relevance": "high" - }, - { - "id": "processing-005", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチの起動方法を教えてください", - "expected_keywords": [ - "バッチ起動", - "Main", - "コマンドライン", - "起動クラス", - "実行" - ], - "expected_sections": ["launch", "execution"], - "relevance": "high" - }, - { - "id": "adapters-001", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jアダプタの設定方法を教えてください", - "expected_keywords": [ - "SLF4J", - "アダプタ", - "設定", - "ログ出力", - "log4j" - ], - "expected_sections": ["configuration", "setup"], - "relevance": "high" - }, - { - "id": "adapters-002", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログレベルを変更するには?", - "expected_keywords": [ - "ログレベル", - "設定変更", - "DEBUG", - "INFO", - "ERROR" - ], - "expected_sections": ["log-level", "configuration"], - "relevance": "high" - }, - { - "id": "adapters-003", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログファイルを出力する設定は?", - "expected_keywords": [ - "ログファイル", - "ファイル出力", - "Appender", - "設定", - "ログ出力先" - ], - "expected_sections": ["file-output", "appender"], - "relevance": "high" - }, - { - "id": "adapters-004", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "NablarchとSLF4Jを連携させる方法は?", - "expected_keywords": [ - "連携", - "統合", - "Nablarch", - "SLF4J", - "アダプタ" - ], - "expected_sections": ["integration", "overview"], - "relevance": "high" - }, - { - "id": "adapters-005", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログフォーマットを変更するには?", - "expected_keywords": [ - "ログフォーマット", - "フォーマット設定", - "出力形式", - "パターン", - "カスタマイズ" - ], - "expected_sections": ["format", "pattern"], - "relevance": "high" - }, - { - "id": "code-analysis-001", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java", - "question": "ProjectActionの構造を理解したい", - "expected_components": [ - "ProjectAction (Action)", - "ProjectForm (Form)", - "Project (Entity)", - "UniversalDao (Nablarch)" - ], - "expected_knowledge": [ - "libraries/universal-dao.json", - "libraries/data-bind.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-002", - "category": "code-analysis", - "target_code": "proman-batch", - "question": "proman-batchモジュール全体の構造を教えてください", - "expected_components": [ - "BatchAction (multiple)", - "Entity classes", - "Nablarch handlers" - ], - "expected_knowledge": [ - "processing/nablarch-batch.json", - "handlers/batch/data-read-handler.json", - "handlers/common/transaction-management-handler.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components" - ], - "relevance": "high" - }, - { - "id": "code-analysis-003", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/form", - "question": "Formクラスの設計パターンを理解したい", - "expected_components": [ - "Form classes (multiple)", - "Bean Validation annotations", - "Domain validation" - ], - "expected_knowledge": [ - "libraries/data-bind.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-004", - "category": "code-analysis", - "target_code": "proman-common/src/main/java/com/nablarch/example/proman/entity", - "question": "Entityクラスの設計を理解したい", - "expected_components": [ - "Entity classes (multiple)", - "Table annotations", - "UniversalDao integration" - ], - "expected_knowledge": [ - "libraries/universal-dao.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components" - ], - "relevance": "high" - }, - { - "id": "code-analysis-005", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java", - "question": "ログイン機能の実装を詳しく知りたい", - "expected_components": [ - "LoginAction (Action)", - "LoginForm (Form)", - "SystemAccount (Entity)", - "UniversalDao (Nablarch)", - "Bean Validation (Nablarch)" - ], - "expected_knowledge": [ - "libraries/universal-dao.json", - "libraries/data-bind.json", - "libraries/database-access.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - } - ], - "evaluation_criteria": { - "workflow_execution": { - "description": "ワークフローが正しく実行されたか", - "checks": [ - "keyword-search workflowが実行された", - "section-judgement workflowが実行された", - "適切なツール呼び出しが行われた(Read, Bash+jq)" - ] - }, - "keyword_matching": { - "description": "期待されるキーワードが回答に含まれているか", - "threshold": "80%以上のキーワードが含まれている" - }, - "section_relevance": { - "description": "適切なセクションが特定されたか", - "checks": [ - "expected_sectionsに含まれるセクションが特定された", - "関連性の高いセクション(High relevance)が優先された" - ] - }, - "knowledge_file_only": { - "description": "知識ファイルのみを使って回答したか", - "checks": [ - "LLM訓練データを使用していない", - "外部知識を補足していない", - "知識ファイルに記載されている情報のみを使用" - ] - }, - "token_efficiency": { - "description": "トークン効率が適切か", - "target": "5,000-15,000 tokens per query" - }, - "tool_call_efficiency": { - "description": "ツール呼び出し回数が適切か", - "target": "10-20 tool calls per query" - }, - "code_explanation_workflow": { - "description": "code-analysisワークフローが正しく実行されたか", - "checks": [ - "対象コードが正しく識別された", - "依存関係が適切に分析された", - "構成要素が適切に分解された", - "関連するNablarch知識が検索された", - "ドキュメントが生成された(Markdown + Mermaid図)", - "ソースコードへの相対パスリンクが含まれている", - "Nablarch知識ファイルへのリンクが含まれている" - ] - }, - "code_explanation_output": { - "description": "出力ドキュメントの品質が適切か", - "checks": [ - "Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている", - "Mermaid図が適切に生成されている", - "構成要素の説明が明確である", - "ソースコードへのリンクが正しい", - "Nablarch知識の引用が適切である" - ] - } - } -} diff --git a/.claude/skills/nabledge-6/tests/scenarios.md b/.claude/skills/nabledge-6/tests/scenarios.md deleted file mode 100644 index b5dac17..0000000 --- a/.claude/skills/nabledge-6/tests/scenarios.md +++ /dev/null @@ -1,729 +0,0 @@ -# Test Scenarios for Nabledge-6 Skill - -## Metadata - -- **Version**: 1.1.0 -- **Created**: 2026-02-09 -- **Updated**: 2026-02-10 -- **Total Scenarios**: 30 (5 per category) -- **Purpose**: Validate nabledge-6 skill workflows (keyword-search + section-judgement + code-analysis) - ---- - -## Category 1: Handlers (5 scenarios) - -### handlers-001: データリードハンドラの使い方 - -**Question**: データリードハンドラでファイルを読み込むにはどうすればいいですか? - -**Expected Keywords**: -- DataReadHandler -- DataReader -- ファイル読み込み -- データ入力 -- レコード処理 - -**Expected Sections**: overview, usage - -**Knowledge File**: handlers/batch/data-read-handler.json - -**Expected Relevance**: High - ---- - -### handlers-002: トランザクションのロールバック - -**Question**: トランザクション管理ハンドラでロールバックする方法は? - -**Expected Keywords**: -- TransactionManagementHandler -- ロールバック -- rollback -- エラー処理 -- トランザクション制御 - -**Expected Sections**: rollback, error-handling - -**Knowledge File**: handlers/common/transaction-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-003: データベース接続管理の設定 - -**Question**: データベース接続管理ハンドラの設定方法を教えてください - -**Expected Keywords**: -- DbConnectionManagementHandler -- データベース接続 -- コネクション管理 -- 設定 -- コンポーネント定義 - -**Expected Sections**: configuration, setup - -**Knowledge File**: handlers/common/db-connection-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-004: トランザクションのコミットタイミング - -**Question**: トランザクションのコミットタイミングはいつですか? - -**Expected Keywords**: -- コミット -- commit -- トランザクション -- タイミング -- 正常終了 - -**Expected Sections**: commit, lifecycle - -**Knowledge File**: handlers/common/transaction-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-005: 大量データの処理 - -**Question**: データリードハンドラで大量データを処理するには? - -**Expected Keywords**: -- 大量データ -- データ処理 -- バッチ -- DataReader -- ループ処理 - -**Expected Sections**: large-data, performance - -**Knowledge File**: handlers/batch/data-read-handler.json - -**Expected Relevance**: High - ---- - -## Category 2: Libraries (5 scenarios) - -### libraries-001: ページング実装 - -**Question**: UniversalDaoでページングを実装したい - -**Expected Keywords**: -- ページング -- paging -- per -- page -- Pagination -- EntityList - -**Expected Sections**: paging - -**Knowledge File**: libraries/universal-dao.json - -**Expected Relevance**: High - ---- - -### libraries-002: 楽観的ロック - -**Question**: UniversalDaoで楽観的ロックを使う方法は? - -**Expected Keywords**: -- 楽観的ロック -- @Version -- OptimisticLockException -- 排他制御 -- バージョンカラム - -**Expected Sections**: optimistic-lock - -**Knowledge File**: libraries/universal-dao.json - -**Expected Relevance**: High - ---- - -### libraries-003: SQL実行 - -**Question**: データベースアクセスでSQLを実行する方法を教えてください - -**Expected Keywords**: -- SQL実行 -- Database -- SqlPStatement -- クエリ -- 検索 - -**Expected Sections**: sql-execution, query - -**Knowledge File**: libraries/database-access.json - -**Expected Relevance**: High - ---- - -### libraries-004: ファイルパス取得 - -**Question**: ファイルパス管理でファイルパスを取得するには? - -**Expected Keywords**: -- ファイルパス -- FilePathSetting -- 論理名 -- 物理パス -- パス取得 - -**Expected Sections**: usage, configuration - -**Knowledge File**: libraries/file-path-management.json - -**Expected Relevance**: High - ---- - -### libraries-005: 業務日付取得 - -**Question**: 業務日付を取得する方法は? - -**Expected Keywords**: -- 業務日付 -- SystemTimeUtil -- 日付取得 -- システム日付 - -**Expected Sections**: overview, usage - -**Knowledge File**: libraries/business-date.json - -**Expected Relevance**: High - ---- - -## Category 3: Tools (5 scenarios) - -### tools-001: テストデータ準備 - -**Question**: NTFでテストデータを準備する方法を教えてください - -**Expected Keywords**: -- テストデータ -- NTF -- データ準備 -- Excel -- データベース - -**Expected Sections**: preparation, setup - -**Knowledge File**: tools/ntf-test-data.json - -**Expected Relevance**: High - ---- - -### tools-002: アサーション機能 - -**Question**: NTFのアサーション機能の使い方は? - -**Expected Keywords**: -- アサーション -- 検証 -- 期待値 -- 実測値 -- NTF - -**Expected Sections**: assertion, verification - -**Knowledge File**: tools/ntf-assertion.json - -**Expected Relevance**: High - ---- - -### tools-003: バッチのリクエスト単体テスト - -**Question**: バッチのリクエスト単体テストを実行するには? - -**Expected Keywords**: -- リクエスト単体テスト -- バッチテスト -- NTF -- テスト実行 -- BatchRequestTestSupport - -**Expected Sections**: test-execution, setup - -**Knowledge File**: tools/ntf-batch-request-test.json - -**Expected Relevance**: High - ---- - -### tools-004: テストデータ初期化 - -**Question**: テストデータの初期化はどうやりますか? - -**Expected Keywords**: -- 初期化 -- データクリア -- セットアップ -- テストデータ -- 前処理 - -**Expected Sections**: initialization, cleanup - -**Knowledge File**: tools/ntf-test-data.json - -**Expected Relevance**: High - ---- - -### tools-005: NTF基本的な使い方 - -**Question**: NTFの基本的な使い方を教えてください - -**Expected Keywords**: -- NTF -- 自動テストフレームワーク -- テスト実行 -- JUnit -- テストケース - -**Expected Sections**: overview, getting-started - -**Knowledge File**: tools/ntf-overview.json - -**Expected Relevance**: High - ---- - -## Category 4: Processing (5 scenarios) - -### processing-001: バッチの基本構造 - -**Question**: Nablarchバッチの基本構造を教えてください - -**Expected Keywords**: -- バッチ -- 基本構造 -- アーキテクチャ -- ハンドラ構成 -- 処理フロー - -**Expected Sections**: overview, architecture - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-002: バッチアクション実装 - -**Question**: バッチアクションの実装方法は? - -**Expected Keywords**: -- BatchAction -- アクション実装 -- バッチ処理 -- execute -- ビジネスロジック - -**Expected Sections**: action-implementation, business-logic - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-003: 大量データ処理 - -**Question**: バッチで大量データを処理する方法は? - -**Expected Keywords**: -- 大量データ -- データ処理 -- ループ処理 -- DataReader -- パフォーマンス - -**Expected Sections**: large-data-processing, performance - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-004: バッチのエラーハンドリング - -**Question**: バッチのエラーハンドリングはどうすればいいですか? - -**Expected Keywords**: -- エラーハンドリング -- 例外処理 -- エラー処理 -- リトライ -- 異常終了 - -**Expected Sections**: error-handling, exception - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-005: バッチの起動方法 - -**Question**: バッチの起動方法を教えてください - -**Expected Keywords**: -- バッチ起動 -- Main -- コマンドライン -- 起動クラス -- 実行 - -**Expected Sections**: launch, execution - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -## Category 5: Adapters (5 scenarios) - -### adapters-001: SLF4Jアダプタの設定 - -**Question**: SLF4Jアダプタの設定方法を教えてください - -**Expected Keywords**: -- SLF4J -- アダプタ -- 設定 -- ログ出力 -- log4j - -**Expected Sections**: configuration, setup - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-002: ログレベルの変更 - -**Question**: SLF4Jでログレベルを変更するには? - -**Expected Keywords**: -- ログレベル -- 設定変更 -- DEBUG -- INFO -- ERROR - -**Expected Sections**: log-level, configuration - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-003: ログファイル出力 - -**Question**: SLF4Jでログファイルを出力する設定は? - -**Expected Keywords**: -- ログファイル -- ファイル出力 -- Appender -- 設定 -- ログ出力先 - -**Expected Sections**: file-output, appender - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-004: Nablarchとの連携 - -**Question**: NablarchとSLF4Jを連携させる方法は? - -**Expected Keywords**: -- 連携 -- 統合 -- Nablarch -- SLF4J -- アダプタ - -**Expected Sections**: integration, overview - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-005: ログフォーマット変更 - -**Question**: SLF4Jでログフォーマットを変更するには? - -**Expected Keywords**: -- ログフォーマット -- フォーマット設定 -- 出力形式 -- パターン -- カスタマイズ - -**Expected Sections**: format, pattern - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -## Category 6: Code Analysis (5 scenarios) - -### code-analysis-001: ProjectActionの構造理解 - -**Question**: ProjectActionの構造を理解したい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java - -**Expected Components**: -- ProjectAction (Action) -- ProjectForm (Form) -- Project (Entity) -- UniversalDao (Nablarch) - -**Expected Knowledge**: -- libraries/universal-dao.json -- libraries/data-bind.json - -**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -### code-analysis-002: proman-batchモジュール全体の理解 - -**Question**: proman-batchモジュール全体の構造を教えてください - -**Target Code**: proman-batch - -**Expected Components**: -- BatchAction (multiple) -- Entity classes -- Nablarch handlers - -**Expected Knowledge**: -- processing/nablarch-batch.json -- handlers/batch/data-read-handler.json -- handlers/common/transaction-management-handler.json - -**Expected Output Sections**: Overview, Architecture, Components - -**Expected Relevance**: High - ---- - -### code-analysis-003: Formクラスの設計パターン - -**Question**: Formクラスの設計パターンを理解したい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/form - -**Expected Components**: -- Form classes (multiple) -- Bean Validation annotations -- Domain validation - -**Expected Knowledge**: -- libraries/data-bind.json - -**Expected Output Sections**: Overview, Components, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -### code-analysis-004: Entityクラスの設計理解 - -**Question**: Entityクラスの設計を理解したい - -**Target Code**: proman-common/src/main/java/com/nablarch/example/proman/entity - -**Expected Components**: -- Entity classes (multiple) -- Table annotations -- UniversalDao integration - -**Expected Knowledge**: -- libraries/universal-dao.json - -**Expected Output Sections**: Overview, Architecture, Components - -**Expected Relevance**: High - ---- - -### code-analysis-005: ログイン機能の詳細実装 - -**Question**: ログイン機能の実装を詳しく知りたい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java - -**Expected Components**: -- LoginAction (Action) -- LoginForm (Form) -- SystemAccount (Entity) -- UniversalDao (Nablarch) -- Bean Validation (Nablarch) - -**Expected Knowledge**: -- libraries/universal-dao.json -- libraries/data-bind.json -- libraries/database-access.json - -**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -## Evaluation Criteria - -### 1. Workflow Execution - -ワークフローが正しく実行されたか確認: - -- [ ] keyword-search workflowが実行された -- [ ] section-judgement workflowが実行された -- [ ] 適切なツール呼び出しが行われた(Read, Bash+jq) -- [ ] index.toonが読み込まれた -- [ ] 候補セクションのindexが抽出された -- [ ] セクション内容が読み込まれた - -### 2. Keyword Matching - -期待されるキーワードが回答に含まれているか: - -- **Threshold**: 80%以上のキーワードが含まれている -- キーワードの出現確認 -- 関連する技術用語の使用 - -### 3. Section Relevance - -適切なセクションが特定されたか: - -- [ ] expected_sectionsに含まれるセクションが特定された -- [ ] 関連性の高いセクション(High relevance)が優先された -- [ ] 不要なセクション(None relevance)が除外された - -### 4. Knowledge File Only - -知識ファイルのみを使って回答したか: - -- [ ] LLM訓練データを使用していない -- [ ] 外部知識を補足していない -- [ ] 知識ファイルに記載されている情報のみを使用 -- [ ] セクションの引用が明示されている - -### 5. Token Efficiency - -トークン効率が適切か: - -- **Target**: 5,000-15,000 tokens per query -- 無駄なファイル全体の読み込みがない -- セクション単位の抽出が機能している - -### 6. Tool Call Efficiency - -ツール呼び出し回数が適切か: - -- **Target**: 10-20 tool calls per query -- Read: index.toon読み込み (1回) -- Bash+jq: .index抽出 (5-10回) -- Bash+jq: .sections抽出 (5-10回) - -### 7. Code Analysis Workflow (code-analysis scenarios only) - -code-analysisワークフローが正しく実行されたか確認: - -- [ ] 対象コードが正しく識別された -- [ ] 依存関係が適切に分析された(Read, Grep, Glob使用) -- [ ] 構成要素が適切に分解された -- [ ] 関連するNablarch知識が検索された(keyword-search workflow実行) -- [ ] ドキュメントが生成された(Write tool使用) -- [ ] Markdown + Mermaid図形式で出力された -- [ ] ソースコードへの相対パスリンクが含まれている -- [ ] Nablarch知識ファイルへのリンクが含まれている - -### 8. Code Analysis Output Quality (code-analysis scenarios only) - -出力ドキュメントの品質が適切か: - -- [ ] Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている -- [ ] Mermaid図(依存関係図、シーケンス図)が適切に生成されている -- [ ] 構成要素の説明が明確である -- [ ] ソースコードへのリンクが正しい(相対パス) -- [ ] Nablarch知識の引用が適切である -- [ ] Expected Componentsが全て記載されている -- [ ] Expected Knowledgeが参照されている -- [ ] ファイルパス形式: `work/YYYYMMDD/code-analysis-.md` - ---- - -## Usage - -### Manual Testing - -各シナリオを個別にテスト: - -```bash -# Example: Test handlers-001 -"データリードハンドラでファイルを読み込むにはどうすればいいですか?" -``` - -期待される動作: -1. "keyword-searchワークフローを実行します"と表示 -2. Read index.toon -3. Bash+jq でセクション抽出 -4. 回答にキーワードが含まれる - -### Automated Testing - -エージェントを使った自動評価: - -```bash -# Load scenarios.json -# For each scenario: -# - Execute question -# - Evaluate workflow execution -# - Check keyword matching -# - Verify section relevance -# - Calculate token usage -# - Count tool calls -``` - ---- - -## Notes - -- すべてのシナリオは実在する知識ファイルに基づいています -- Expected sectionsは実際のファイル構造に基づく推定です -- 知識ファイルに該当セクションがない場合は、"この情報は知識ファイルに含まれていません"と回答されることが期待されます diff --git a/.claude/skills/nabledge-test/README.md b/.claude/skills/nabledge-test/README.md new file mode 100644 index 0000000..2496e51 --- /dev/null +++ b/.claude/skills/nabledge-test/README.md @@ -0,0 +1,154 @@ +# Nabledge Test Skill + +Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4). + +## Overview + +This skill provides automated testing capabilities for nabledge skills: +- Execute test scenarios +- Evaluate results against criteria +- Generate improvement recommendations + +## Usage + +### Run Test Scenarios + +Execute test scenarios for a specific nabledge skill version: + +``` +/nabledge-test run-scenarios +``` + +Examples: +``` +/nabledge-test run-scenarios nabledge-6 +/nabledge-test run-scenarios nabledge-5 +``` + +This will: +1. Load scenarios from `scenarios//` +2. Execute each scenario using the target skill +3. Record results in `results/YYYYMMDD-HHMM/` +4. Create work log summary in `work/YYYYMMDD/` + +### Evaluate Results + +Evaluate test results and generate review report: + +``` +/nabledge-test evaluate-results +``` + +Example: +``` +/nabledge-test evaluate-results results/20260210-1430 +``` + +This will: +1. Analyze all scenario results +2. Evaluate against criteria +3. Identify common issues +4. Generate improvement recommendations +5. Create review report + +## Directory Structure + +``` +.claude/skills/nabledge-test/ +├── skill.json # Skill definition +├── README.md # This file +├── workflows/ +│ ├── run-scenarios.md # Scenario execution workflow +│ └── evaluate-results.md # Results evaluation workflow +├── templates/ +│ ├── scenario-result.md # Scenario result template +│ └── review.md # Review report template +├── scenarios/ +│ ├── nabledge-6/ +│ │ ├── code-analysis-scenarios.json +│ │ └── keyword-search-scenarios.json +│ ├── nabledge-5/ # Future +│ └── nabledge-1.4/ # Future +└── results/ + └── YYYYMMDD-HHMM/ # Test session results + ├── code-analysis/ + ├── keyword-search/ + └── *-scenarios-review.md +``` + +## Workflows + +### 1. run-scenarios + +Executes test scenarios for specified nabledge skill version. + +**Input**: Nabledge version (e.g., "nabledge-6") + +**Output**: +- Scenario results in `results/YYYYMMDD-HHMM/` +- Work log summary in `work/YYYYMMDD/` + +### 2. evaluate-results + +Evaluates test results and generates review report. + +**Input**: Test session directory (e.g., "results/20260210-1430") + +**Output**: +- Review reports in test session directory +- Improvement recommendations + +## Templates + +### scenario-result.md + +Template for recording individual scenario execution results: +- Metadata (ID, category, date, time) +- Test input (question, target, expectations) +- Execution results (workflow, resource usage, tool calls) +- Generated output +- Evaluation against criteria +- Issues found +- Status (PASS/FAIL/PARTIAL) + +### review.md + +Template for test session review report: +- Test session metadata +- Summary and pass rates +- Detailed results by scenario +- Common issues (by priority) +- Improvement recommendations +- Action items +- Next steps + +## Test Scenarios + +### nabledge-6 + +**code-analysis-scenarios.json** (5 scenarios): +- Full batch action structure analysis +- Initialization process analysis +- Database read process analysis +- File write process analysis +- Test code implementation analysis + +**keyword-search-scenarios.json** (5 scenarios): +- Handlers: Data read handler +- Libraries: UniversalDao paging +- Tools: NTF test data preparation +- Processing: Batch basic structure +- Adapters: SLF4J adapter configuration + +## Evaluation Criteria + +Each scenario is evaluated against: +- Workflow execution correctness +- Output quality (structure, completeness) +- Knowledge integration (proper citation) +- Token efficiency (target range) +- Tool call efficiency (target range) + +## Language + +All test content is in English, following repository language rules. diff --git a/.claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json b/.claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json new file mode 100644 index 0000000..068a1ca --- /dev/null +++ b/.claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json @@ -0,0 +1,168 @@ +{ + "metadata": { + "version": "1.1.0", + "created": "2026-02-10", + "updated": "2026-02-10", + "description": "Test scenarios for code-analysis workflow validation (Nablarch batch)", + "total_scenarios": 5 + }, + "scenarios": [ + { + "id": "code-analysis-001", + "category": "code-analysis", + "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java", + "question": "ExportProjectsInPeriodActionの全体構造を理解したい", + "expected_components": [ + "ExportProjectsInPeriodAction (BatchAction)", + "ProjectDto (DTO)", + "DatabaseRecordReader (Nablarch)", + "ObjectMapper (Nablarch)", + "FilePathSetting (Nablarch)" + ], + "expected_knowledge": [ + "processing/nablarch-batch.json", + "handlers/batch/data-read-handler.json", + "libraries/file-path-management.json" + ], + "expected_output_sections": [ + "Overview", + "Architecture", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-002", + "category": "code-analysis", + "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:initialize", + "question": "バッチアクションの初期化処理を詳しく知りたい", + "expected_components": [ + "initialize method", + "FilePathSetting", + "ObjectMapperFactory", + "FileOutputStream" + ], + "expected_knowledge": [ + "libraries/file-path-management.json", + "processing/nablarch-batch.json" + ], + "expected_output_sections": [ + "Overview", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-003", + "category": "code-analysis", + "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:createReader", + "question": "データベースからのデータ読み込み処理を理解したい", + "expected_components": [ + "createReader method", + "DatabaseRecordReader", + "SqlPStatement", + "BusinessDateUtil" + ], + "expected_knowledge": [ + "handlers/batch/data-read-handler.json", + "libraries/database-access.json", + "libraries/business-date.json" + ], + "expected_output_sections": [ + "Overview", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-004", + "category": "code-analysis", + "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:handle", + "question": "ファイルへのデータ書き込み処理を詳しく知りたい", + "expected_components": [ + "handle method", + "ObjectMapper", + "ProjectDto", + "EntityUtil" + ], + "expected_knowledge": [ + "processing/nablarch-batch.json", + "libraries/database-access.json" + ], + "expected_output_sections": [ + "Overview", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + }, + { + "id": "code-analysis-005", + "category": "code-analysis", + "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/test/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodActionRequestTest.java", + "question": "バッチのテストコード実装を理解したい", + "expected_components": [ + "ExportProjectsInPeriodActionRequestTest (Test)", + "PromanBatchRequestTestSupport", + "NTF test framework" + ], + "expected_knowledge": [ + "tools/ntf-batch-request-test.json", + "tools/ntf-test-data.json", + "tools/ntf-assertion.json" + ], + "expected_output_sections": [ + "Overview", + "Components", + "Flow", + "Nablarch Framework Usage" + ], + "relevance": "high" + } + ], + "evaluation_criteria": { + "workflow_execution": { + "description": "ワークフローが正しく実行されたか", + "checks": [ + "code-analysis workflowが実行された", + "対象コードが正しく識別された", + "依存関係が適切に分析された", + "構成要素が適切に分解された", + "関連するNablarch知識が検索された" + ] + }, + "code_explanation_output": { + "description": "出力ドキュメントの品質が適切か", + "checks": [ + "Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている", + "Mermaid図が適切に生成されている", + "構成要素の説明が明確である", + "ソースコードへの相対パスリンクが含まれている", + "Nablarch知識ファイルへのリンクが含まれている" + ] + }, + "knowledge_integration": { + "description": "Nablarch知識が適切に引用されているか", + "checks": [ + "expected_knowledgeに含まれる知識ファイルが参照された", + "知識ファイルの内容が適切に引用された", + "コードと知識の対応関係が明確に説明された" + ] + }, + "token_efficiency": { + "description": "トークン効率が適切か", + "target": "10,000-30,000 tokens per query" + }, + "tool_call_efficiency": { + "description": "ツール呼び出し回数が適切か", + "target": "15-40 tool calls per query" + } + } +} diff --git a/.claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json b/.claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json new file mode 100644 index 0000000..0bc8a5c --- /dev/null +++ b/.claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json @@ -0,0 +1,138 @@ +{ + "metadata": { + "version": "1.1.0", + "created": "2026-02-10", + "updated": "2026-02-10", + "description": "Test scenarios for keyword-search workflow validation", + "total_scenarios": 5 + }, + "scenarios": [ + { + "id": "handlers-001", + "category": "handlers", + "file": "handlers/batch/data-read-handler.json", + "question": "データリードハンドラでファイルを読み込むにはどうすればいいですか?", + "expected_keywords": [ + "DataReadHandler", + "DataReader", + "ファイル読み込み", + "データ入力", + "レコード処理" + ], + "expected_sections": [ + "overview", + "usage" + ], + "relevance": "high" + }, + { + "id": "libraries-001", + "category": "libraries", + "file": "libraries/universal-dao.json", + "question": "UniversalDaoでページングを実装したい", + "expected_keywords": [ + "ページング", + "paging", + "per", + "page", + "Pagination", + "EntityList" + ], + "expected_sections": [ + "paging" + ], + "relevance": "high" + }, + { + "id": "tools-001", + "category": "tools", + "file": "tools/ntf-test-data.json", + "question": "NTFでテストデータを準備する方法を教えてください", + "expected_keywords": [ + "テストデータ", + "NTF", + "データ準備", + "Excel", + "データベース" + ], + "expected_sections": [ + "preparation", + "setup" + ], + "relevance": "high" + }, + { + "id": "processing-001", + "category": "processing", + "file": "processing/nablarch-batch.json", + "question": "Nablarchバッチの基本構造を教えてください", + "expected_keywords": [ + "バッチ", + "基本構造", + "アーキテクチャ", + "ハンドラ構成", + "処理フロー" + ], + "expected_sections": [ + "overview", + "architecture" + ], + "relevance": "high" + }, + { + "id": "adapters-001", + "category": "adapters", + "file": "adapters/slf4j-adapter.json", + "question": "SLF4Jアダプタの設定方法を教えてください", + "expected_keywords": [ + "SLF4J", + "アダプタ", + "設定", + "ログ出力", + "log4j" + ], + "expected_sections": [ + "configuration", + "setup" + ], + "relevance": "high" + } + ], + "evaluation_criteria": { + "workflow_execution": { + "description": "ワークフローが正しく実行されたか", + "checks": [ + "keyword-search workflowが実行された", + "section-judgement workflowが実行された", + "適切なツール呼び出しが行われた(Read, Bash+jq)" + ] + }, + "keyword_matching": { + "description": "期待されるキーワードが回答に含まれているか", + "threshold": "80%以上のキーワードが含まれている" + }, + "section_relevance": { + "description": "適切なセクションが特定されたか", + "checks": [ + "expected_sectionsに含まれるセクションが特定された", + "関連性の高いセクション(High relevance)が優先された" + ] + }, + "knowledge_file_only": { + "description": "知識ファイルのみを使って回答したか", + "checks": [ + "LLM訓練データを使用していない", + "外部知識を補足していない", + "知識ファイルに記載されている情報のみを使用" + ] + }, + "token_efficiency": { + "description": "トークン効率が適切か", + "target": "5,000-15,000 tokens per query" + }, + "tool_call_efficiency": { + "description": "ツール呼び出し回数が適切か", + "target": "10-20 tool calls per query" + } + } +} diff --git a/.claude/skills/nabledge-test/skill.json b/.claude/skills/nabledge-test/skill.json new file mode 100644 index 0000000..4800466 --- /dev/null +++ b/.claude/skills/nabledge-test/skill.json @@ -0,0 +1,32 @@ +{ + "name": "nabledge-test", + "version": "1.0.0", + "description": "Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4)", + "triggers": [ + "nabledge-test", + "test nabledge", + "run nabledge tests" + ], + "capabilities": [ + "Execute test scenarios for nabledge skills", + "Evaluate test results against criteria", + "Generate test reports with improvement recommendations" + ], + "workflows": [ + { + "name": "run-scenarios", + "description": "Execute test scenarios for specified nabledge skill version", + "file": "workflows/run-scenarios.md" + }, + { + "name": "evaluate-results", + "description": "Evaluate test results and generate review report", + "file": "workflows/evaluate-results.md" + } + ], + "assets": { + "templates": "templates/", + "scenarios": "scenarios/", + "results": "results/" + } +} diff --git a/.claude/skills/nabledge-test/skill.md b/.claude/skills/nabledge-test/skill.md new file mode 100644 index 0000000..382a58f --- /dev/null +++ b/.claude/skills/nabledge-test/skill.md @@ -0,0 +1,80 @@ +# Nabledge Test Skill + +Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4). + +## Execution Flow + +### 1. Parse Arguments + +Extract workflow and parameters from invocation: + +``` +/nabledge-test → No args → AskUserQuestion for workflow +/nabledge-test run-scenarios → workflow="run-scenarios", version= +/nabledge-test evaluate-results → workflow="evaluate-results", session_dir= +``` + +**If no args**: Use AskUserQuestion to select workflow: +- Question: "Which testing workflow do you want to execute?" +- Options: + 1. "Run Scenarios (run-scenarios)" - Execute test scenarios for nabledge skill + 2. "Evaluate Results (evaluate-results)" - Evaluate test results and generate review + +### 2. Execute Workflow + +Delegate to specialized workflow via Task tool: + +#### A. run-scenarios Workflow + +``` +Task + subagent_type: "general-purpose" + description: "Execute test scenarios workflow" + prompt: "Follow the workflow to execute test scenarios for nabledge skill. + +{Read and include workflows/run-scenarios.md} + +## Input Context +- Version: {version} +" +``` + +#### B. evaluate-results Workflow + +``` +Task + subagent_type: "general-purpose" + description: "Execute results evaluation workflow" + prompt: "Follow the workflow to evaluate test results. + +{Read and include workflows/evaluate-results.md} + +## Input Context +- Test session directory: {test_session_dir} +" +``` + +## Implementation Notes + +1. **No args**: Use AskUserQuestion for user-friendly workflow selection +2. **Version required**: For run-scenarios, version must be specified or selected +3. **Session dir required**: For evaluate-results, session directory must be specified or selected +4. **Task tool usage**: Workflows execute in separate context with full workflow content +5. **Error handling**: Display clear error messages when parameters missing + +## Error Handling + +| Error | Response | +|-------|----------| +| Invalid workflow | Use AskUserQuestion for workflow selection | +| Missing version (run-scenarios) | List available versions, ask user to select | +| Missing session dir (evaluate-results) | List available sessions, ask user to select | +| Scenarios not found | Display error with available versions | +| Session not found | Display error with available sessions | + +## Workflows + +- **run-scenarios**: Execute test scenarios for specified nabledge skill version +- **evaluate-results**: Evaluate test results and generate review report + +For detailed workflow documentation, see `workflows/` directory. diff --git a/.claude/skills/nabledge-test/templates/review.md b/.claude/skills/nabledge-test/templates/review.md new file mode 100644 index 0000000..4ccb80c --- /dev/null +++ b/.claude/skills/nabledge-test/templates/review.md @@ -0,0 +1,200 @@ +# Test Review: {scenario-file-name} + +## Test Session Metadata + +| Item | Value | +|------|-------| +| Test Date | {date} | +| Test Time | {time} | +| Test Directory | scenario-test-{hhmm} | +| Total Scenarios | {total} | +| Passed | {passed} | +| Failed | {failed} | +| Partial | {partial} | + +## Summary + +### Overall Assessment + +{overall_assessment_summary} + +### Pass Rate + +| Category | Pass Rate | Status | +|----------|-----------|--------| +| Workflow Execution | {percentage}% | {pass/warning/fail} | +| Output Quality | {percentage}% | {pass/warning/fail} | +| Knowledge Integration | {percentage}% | {pass/warning/fail} | +| Resource Efficiency | {percentage}% | {pass/warning/fail} | + +## Detailed Results by Scenario + +### {scenario-id-1} + +**Status**: {PASS/FAIL/PARTIAL} + +**Strengths**: +- {strength_1} +- {strength_2} + +**Issues**: +- {issue_1} +- {issue_2} + +**Metrics**: +- Tokens: {tokens} ({target_range}) +- Tool Calls: {calls} ({target_range}) + +--- + +### {scenario-id-2} + +{repeat for each scenario} + +--- + +## Common Issues + +### High Priority + +1. **Issue**: {issue_description} + - **Scenarios Affected**: {scenario_ids} + - **Impact**: {impact_description} + - **Recommendation**: {recommendation} + +2. **Issue**: {issue_description} + - **Scenarios Affected**: {scenario_ids} + - **Impact**: {impact_description} + - **Recommendation**: {recommendation} + +### Medium Priority + +{repeat structure} + +### Low Priority + +{repeat structure} + +## Improvement Recommendations + +### スキル構造の改善 + +#### 1. {improvement_area_1} + +**現状の問題**: +{problem_description} + +**改善案**: +{improvement_suggestion} + +**期待される効果**: +{expected_benefit} + +**実装優先度**: {High/Medium/Low} + +--- + +#### 2. {improvement_area_2} + +{repeat structure} + +--- + +### ワークフローの改善 + +#### 1. {workflow_improvement_1} + +**現状の問題**: +{problem_description} + +**改善案**: +{improvement_suggestion} + +**期待される効果**: +{expected_benefit} + +**実装優先度**: {High/Medium/Low} + +--- + +### 知識ファイルの改善 + +#### 1. {knowledge_improvement_1} + +**対象ファイル**: {file_path} + +**現状の問題**: +{problem_description} + +**改善案**: +{improvement_suggestion} + +**期待される効果**: +{expected_benefit} + +**実装優先度**: {High/Medium/Low} + +--- + +### パフォーマンス最適化 + +#### Token Usage + +**現状**: +- 平均: {average} tokens +- 最大: {max} tokens +- 目標範囲: {target_range} + +**改善案**: +{optimization_suggestions} + +--- + +#### Tool Call Efficiency + +**現状**: +- 平均: {average} calls +- 最大: {max} calls +- 目標範囲: {target_range} + +**改善案**: +{optimization_suggestions} + +--- + +## Action Items + +### Immediate (実装必須) + +- [ ] {action_item_1} +- [ ] {action_item_2} + +### Short-term (1週間以内) + +- [ ] {action_item_1} +- [ ] {action_item_2} + +### Long-term (1ヶ月以内) + +- [ ] {action_item_1} +- [ ] {action_item_2} + +## Next Steps + +1. {next_step_1} +2. {next_step_2} +3. {next_step_3} + +## Appendix + +### Test Environment + +- Claude Model: {model_version} +- Skill Version: {skill_version} +- Test Framework Version: {framework_version} + +### Reference + +- Test Scenarios: `{scenario_file_path}` +- Test Results: `scenario-test-{hhmm}/` +- Previous Review: `{previous_review_path}` (if applicable) diff --git a/.claude/skills/nabledge-test/templates/scenario-result.md b/.claude/skills/nabledge-test/templates/scenario-result.md new file mode 100644 index 0000000..32ec81c --- /dev/null +++ b/.claude/skills/nabledge-test/templates/scenario-result.md @@ -0,0 +1,104 @@ +# Scenario Result: {scenario-id} + +## Metadata + +| Item | Value | +|------|-------| +| Scenario ID | {scenario-id} | +| Category | {category} | +| Test Date | {date} | +| Test Time | {time} | +| Duration | {duration}s | + +## Test Input + +### Question +``` +{question} +``` + +### Target +``` +{target_code or target_file} +``` + +### Expected Components +{expected_components_list} + +### Expected Knowledge +{expected_knowledge_list} + +## Execution Results + +### Workflow Execution + +| Step | Status | Details | +|------|--------|---------| +| Workflow Start | {status} | {details} | +| Target Identification | {status} | {details} | +| Dependency Analysis | {status} | {details} | +| Knowledge Retrieval | {status} | {details} | +| Output Generation | {status} | {details} | + +### Resource Usage + +| Metric | Value | Target | Status | +|--------|-------|--------|--------| +| Total Tokens | {tokens} | {target_range} | {pass/fail} | +| Tool Calls | {tool_calls} | {target_range} | {pass/fail} | +| Execution Time | {time}s | - | - | + +### Tool Calls Summary + +{list of tool calls with parameters} + +## Generated Output + +### Output Sections Present + +- [ ] Overview +- [ ] Architecture (if applicable) +- [ ] Components +- [ ] Flow +- [ ] Nablarch Framework Usage + +### Output Content + +```markdown +{actual_output_content} +``` + +## Evaluation Against Criteria + +### Workflow Execution +{evaluation_details} + +### Code Explanation Output (code-analysis only) +{evaluation_details} + +### Keyword Matching (keyword-search only) +{evaluation_details} + +### Knowledge Integration +{evaluation_details} + +### Section Relevance +{evaluation_details} + +### Token Efficiency +{evaluation_details} + +### Tool Call Efficiency +{evaluation_details} + +## Issues Found + +{list of issues} + +## Status + +**Overall Result**: {PASS/FAIL/PARTIAL} + +## Notes + +{additional_notes} diff --git a/.claude/skills/nabledge-test/workflows/evaluate-results.md b/.claude/skills/nabledge-test/workflows/evaluate-results.md new file mode 100644 index 0000000..51f5ca2 --- /dev/null +++ b/.claude/skills/nabledge-test/workflows/evaluate-results.md @@ -0,0 +1,255 @@ +# Evaluate Results Workflow + +Evaluate test results and generate review report with improvement recommendations. + +## Input + +- **test_session_dir**: Path to test session directory (e.g., "results/20260210-1430" or "20260210-1430") + +## Output + +- Review reports in test session directory: + - `{scenario-file-name}-review.md` for each scenario file + +## Execution Steps + +### 1. Parse Arguments and Setup + +**1.1 Parse Test Session Directory** + +Extract test session directory from skill invocation: +``` +/nabledge-test evaluate-results results/20260210-1430 → dir="results/20260210-1430" +/nabledge-test evaluate-results 20260210-1430 → dir="results/20260210-1430" +``` + +If no directory specified, list available sessions and ask user to select: +```bash +ls -d .claude/skills/nabledge-test/results/*/ +``` + +**1.2 Verify Session Directory Exists** + +Check that test session directory exists: +```bash +ls .claude/skills/nabledge-test/results/{timestamp}/ +``` + +If not found, display error: +``` +Error: Test session directory not found: {test_session_dir} + +Available test sessions: +{list_of_available_sessions} + +Please specify a valid test session directory. +``` + +### 2. Load Scenario Files and Results + +**2.1 Identify Scenario Files** + +Find all unique scenario file names from result files: +```bash +find .claude/skills/nabledge-test/results/{timestamp}/ -name "*.md" -type f +``` + +Extract scenario file names (e.g., "code-analysis", "keyword-search"). + +**2.2 Load Original Scenario Definitions** + +For each identified scenario file: +- Determine version from session (check which version's scenarios were used) +- Load original scenario JSON file from `scenarios/{version}/{scenario-file-name}-scenarios.json` +- Extract evaluation criteria + +**2.3 Load All Result Files** + +For each scenario file: +- Find all result files in `results/{timestamp}/{category}/` +- Parse each result file to extract: + - Scenario ID + - Status (PASS/FAIL/PARTIAL) + - Execution metrics (tokens, tool calls) + - Issues found + - Generated output + +### 3. Analyze Results + +For each scenario file: + +**3.1 Calculate Statistics** + +- Total scenarios +- Pass count / percentage +- Fail count / percentage +- Partial count / percentage +- Average token usage +- Token usage range (min/max) +- Average tool calls +- Tool calls range (min/max) + +**3.2 Evaluate Each Scenario Against Criteria** + +From original scenario JSON `evaluation_criteria`: + +**Workflow Execution**: +- Check if expected workflow was executed +- Verify required steps were completed +- Assess tool usage appropriateness + +**Output Quality** (for code-analysis): +- Verify expected output sections present +- Check for Mermaid diagrams +- Validate component explanations +- Confirm source code links +- Confirm knowledge file links + +**Keyword Matching** (for keyword-search): +- Calculate keyword match percentage +- Identify missing keywords + +**Knowledge Integration**: +- Verify expected knowledge files were referenced +- Check knowledge content was properly cited +- Assess code-knowledge correspondence + +**Section Relevance** (for keyword-search): +- Verify expected sections were identified +- Check high-relevance sections prioritized + +**Knowledge File Only** (for keyword-search): +- Confirm no LLM training data used +- Verify no external knowledge added +- Check only knowledge file content used + +**Token Efficiency**: +- Compare actual vs target token range +- Calculate efficiency percentage + +**Tool Call Efficiency**: +- Compare actual vs target tool call range +- Calculate efficiency percentage + +**3.3 Identify Common Issues** + +Group issues across scenarios by: +- Issue type (workflow, output, knowledge, efficiency) +- Frequency (how many scenarios affected) +- Severity (impact on results) + +Categorize by priority: +- **High**: Affects multiple scenarios, significant impact +- **Medium**: Affects some scenarios, moderate impact +- **Low**: Affects few scenarios, minor impact + +### 4. Generate Improvement Recommendations + +**4.1 Skill Structure Improvements** + +Analyze patterns and recommend: +- Knowledge file additions/updates +- Workflow refinements +- Tool usage optimizations +- Context management improvements + +**4.2 Workflow Improvements** + +Recommend: +- Step sequence optimization +- Decision logic refinement +- Error handling enhancement +- Context efficiency improvements + +**4.3 Knowledge File Improvements** + +For each knowledge file with issues: +- Identify missing information +- Suggest content additions +- Recommend structure improvements +- Propose example enhancements + +**4.4 Performance Optimization** + +Token usage optimization: +- Identify verbose outputs +- Suggest content reduction strategies +- Recommend context management improvements + +Tool call optimization: +- Identify redundant calls +- Suggest call consolidation +- Recommend caching strategies + +### 5. Generate Review Report + +**5.1 Create Review File** + +Use template from `templates/review.md` and populate with: + +- **Test Session Metadata**: Date, time, directory, counts +- **Summary**: Overall assessment, pass rates by category +- **Detailed Results**: Each scenario with strengths, issues, metrics +- **Common Issues**: Grouped by priority with recommendations +- **Improvement Recommendations**: By area (skill, workflow, knowledge, performance) +- **Action Items**: Categorized by urgency (Immediate/Short-term/Long-term) +- **Next Steps**: Recommended actions + +Save to: +``` +.claude/skills/nabledge-test/results/{timestamp}/{scenario-file-name}-review.md +``` + +**5.2 Generate One Review Per Scenario File** + +Create separate review for: +- code-analysis-scenarios-review.md +- keyword-search-scenarios-review.md +- (future scenario files) + +### 6. Display Summary + +``` +## Evaluation Complete + +**Test Session**: {timestamp} +**Scenario Files Evaluated**: {count} + +**Overall Results**: +- Pass Rate: {overall_pass_percentage}% +- Average Token Usage: {avg_tokens} +- Average Tool Calls: {avg_calls} + +**Generated Reviews**: +- {scenario-file-1}-review.md +- {scenario-file-2}-review.md + +**Top Priority Issues** ({count}): +1. {issue_1} +2. {issue_2} +3. {issue_3} + +**Review Reports**: .claude/skills/nabledge-test/results/{timestamp}/ + +**Recommended Next Steps**: +{next_steps_list} +``` + +## Error Handling + +| Error | Response | +|-------|----------| +| Session directory not specified | List available sessions, ask user to select | +| Session directory not found | Display error with available sessions | +| Result files missing | Display error, suggest re-running tests | +| Template not found | Display error and stop | +| Scenario JSON not found | Display warning, use default criteria | + +## Important Notes + +1. **Objective evaluation**: Use criteria from scenario JSON files +2. **Pattern recognition**: Identify common issues across scenarios +3. **Actionable recommendations**: Provide specific, implementable suggestions +4. **Priority guidance**: Categorize issues and actions by priority/urgency +5. **Comprehensive coverage**: Evaluate all aspects (workflow, output, knowledge, efficiency) +6. **Clear reporting**: Use consistent format across all reviews diff --git a/.claude/skills/nabledge-test/workflows/run-scenarios.md b/.claude/skills/nabledge-test/workflows/run-scenarios.md new file mode 100644 index 0000000..a8f06cf --- /dev/null +++ b/.claude/skills/nabledge-test/workflows/run-scenarios.md @@ -0,0 +1,245 @@ +# Run Scenarios Workflow + +Execute test scenarios for specified nabledge skill version. + +## Input + +- **version**: Target nabledge skill version (e.g., "nabledge-6", "nabledge-5") + +## Output + +- Scenario result files in `results/YYYYMMDD-HHMM//.md` +- Work log summary in `work/YYYYMMDD/scenario-test.md` + +## Execution Steps + +### 1. Parse Arguments and Setup + +**1.1 Parse Version Argument** + +Extract version from skill invocation: +``` +/nabledge-test run-scenarios nabledge-6 → version="nabledge-6" +/nabledge-test run-scenarios nabledge-5 → version="nabledge-5" +``` + +If no version specified, ask user to select: +- nabledge-6 +- nabledge-5 (if scenarios exist) +- nabledge-1.4 (if scenarios exist) + +**1.2 Verify Scenarios Exist** + +Check that `scenarios/{version}/` directory exists and contains scenario files: +```bash +ls .claude/skills/nabledge-test/scenarios/{version}/ +``` + +If not found, display error: +``` +Error: No scenarios found for {version}. + +Available versions: +- nabledge-6 + +Please specify a valid version. +``` + +**1.3 Create Test Session Directory** + +Create timestamped directory for test results: +```bash +timestamp=$(date '+%Y%m%d-%H%M') +mkdir -p .claude/skills/nabledge-test/results/${timestamp} +``` + +Record start time: +```bash +date '+%Y-%m-%d %H:%M:%S' +``` + +### 2. Load Scenario Files + +**2.1 Find All Scenario Files** + +```bash +find .claude/skills/nabledge-test/scenarios/{version}/ -name "*-scenarios.json" +``` + +**2.2 Parse Each Scenario File** + +For each scenario file: +- Read JSON content +- Extract metadata (version, description, total_scenarios) +- Extract scenarios array +- Extract evaluation_criteria + +### 3. Execute Scenarios + +For each scenario in each scenario file: + +**3.1 Prepare Scenario Context** + +Extract from scenario JSON: +- id +- category +- question +- target_code or file (depending on workflow type) +- expected_components +- expected_knowledge +- expected_output_sections (if applicable) + +**3.2 Determine Workflow Type** + +Based on category: +- `code-analysis` → Use code-analysis workflow +- `handlers`, `libraries`, `tools`, `processing`, `adapters` → Use keyword-search workflow + +**3.3 Execute Skill with Scenario** + +Record start time: +```bash +start_time=$(date '+%Y-%m-%d %H:%M:%S') +``` + +Execute nabledge skill: + +**For code-analysis scenarios**: +``` +/{version} code-analysis + +Target: {target_code} +Question: {question} +``` + +**For keyword-search scenarios**: +``` +/{version} keyword-search + +Question: {question} +``` + +Record end time: +```bash +end_time=$(date '+%Y-%m-%d %H:%M:%S') +``` + +**IMPORTANT**: Clear skill context between scenarios to ensure independent execution. + +**3.4 Capture Execution Metrics** + +Record the following: +- Start time +- End time +- Skill output +- Token usage (estimate from output length) +- Tool calls (count from skill output if visible) + +**3.5 Generate Scenario Result File** + +Use template from `templates/scenario-result.md` and populate with: +- Metadata (scenario ID, category, dates, times) +- Test input (question, target, expectations) +- Execution results (workflow steps, resource usage) +- Generated output (skill response) +- Evaluation against criteria (from scenario JSON) +- Issues found (manual review needed) +- Status (PASS/FAIL/PARTIAL based on criteria) + +Save to: +``` +.claude/skills/nabledge-test/results/{timestamp}/{category}/{scenario-id}.md +``` + +**3.6 Display Progress** + +Show progress after each scenario: +``` +[{current}/{total}] Completed: {scenario-id} ({status}) +``` + +### 4. Generate Summary + +**4.1 Calculate Statistics** + +- Total scenarios executed +- Pass count +- Fail count +- Partial count +- Average token usage +- Average tool calls + +**4.2 Create Work Log Summary** + +Create `work/{YYYYMMDD}/scenario-test.md`: + +```markdown +# Scenario Test: {version} + +## Metadata + +- Date: {date} +- Test Session: {timestamp} +- Total Scenarios: {total} + +## Results + +| Status | Count | Percentage | +|--------|-------|------------| +| Pass | {pass_count} | {pass_percentage}% | +| Fail | {fail_count} | {fail_percentage}% | +| Partial | {partial_count} | {partial_percentage}% | + +## Key Findings + +{list_of_major_issues} + +## Details + +Full test results: `.claude/skills/nabledge-test/results/{timestamp}/` + +## Next Steps + +{recommended_next_steps} +``` + +**4.3 Display Summary** + +``` +## Test Execution Complete + +**Version**: {version} +**Test Session**: {timestamp} +**Total Scenarios**: {total} + +**Results**: +- Pass: {pass_count} +- Fail: {fail_count} +- Partial: {partial_count} + +**Pass Rate**: {pass_percentage}% + +**Details**: .claude/skills/nabledge-test/results/{timestamp}/ +**Work Log**: work/{YYYYMMDD}/scenario-test.md + +To evaluate results and generate review: +/nabledge-test evaluate-results {timestamp} +``` + +## Error Handling + +| Error | Response | +|-------|----------| +| Version not specified | Ask user to select version | +| Scenarios not found | Display error with available versions | +| Skill execution failed | Record as FAIL, continue with next scenario | +| Template not found | Display error and stop | + +## Important Notes + +1. **Context isolation**: Clear skill context between scenarios +2. **Independent execution**: Each scenario runs independently +3. **Record everything**: Capture all execution details for evaluation +4. **Progress feedback**: Show progress after each scenario +5. **Work log summary**: Create concise summary for daily work log +6. **Next step guidance**: Prompt user to run evaluate-results From 2982603bf2cc11cda118feeb8194b6ac9b63ebc2 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 20:43:07 +0900 Subject: [PATCH 21/89] Add GitHub Actions workflow for syncing to nabledge repository - Create workflow to sync nabledge-6 skill to dummy-to branch - Trigger on push to dummy-from branch - Include trigger commit URL in commit message for traceability Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 58 ++++++++++++++++++++++++++ work/20260210/staging-github-action.md | 49 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 .github/workflows/sync-to-nabledge.yml create mode 100644 work/20260210/staging-github-action.md diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml new file mode 100644 index 0000000..85aed40 --- /dev/null +++ b/.github/workflows/sync-to-nabledge.yml @@ -0,0 +1,58 @@ +name: Sync to nabledge repository + +on: + push: + branches: + - dummy-from + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout nabledge-dev + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Checkout nabledge repository + uses: actions/checkout@v4 + with: + repository: nablarch/nabledge + ref: dummy-to + token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} + path: nabledge-repo + + - name: Sync nabledge-6 skill + run: | + # Remove old skill files if exists + rm -rf nabledge-repo/.claude/skills/nabledge-6 + + # Copy nabledge-6 skill + mkdir -p nabledge-repo/.claude/skills + cp -r .claude/skills/nabledge-6 nabledge-repo/.claude/skills/ + + - name: Commit and Push to nabledge + working-directory: nabledge-repo + run: | + git add . + + # Check if there are changes to commit + if git diff --staged --quiet; then + echo "No changes to commit" + exit 0 + fi + + # Create commit message with link to trigger commit + TRIGGER_COMMIT_SHA="${{ github.sha }}" + TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" + + git commit -m "Sync nabledge-6 skill from nabledge-dev + +Triggered by: ${TRIGGER_COMMIT_URL}" + + git push origin dummy-to diff --git a/work/20260210/staging-github-action.md b/work/20260210/staging-github-action.md new file mode 100644 index 0000000..0ed1282 --- /dev/null +++ b/work/20260210/staging-github-action.md @@ -0,0 +1,49 @@ +# Staging GitHub Action + +## What was done + +### Created branches +- `dummy-from`: Created from `feature/setup-repository` in nabledge-dev repository +- `dummy-to`: Created from `develop` in nabledge repository using GitHub API + +### Created files +- `.github/workflows/sync-to-nabledge.yml`: GitHub Actions workflow for syncing nabledge-6 skill + +## Workflow details + +- Triggers on push to `dummy-from` branch +- Syncs `.claude/skills/nabledge-6` to nabledge repository's `dummy-to` branch +- Includes trigger commit URL in commit message for traceability +- Uses `NABLEDGE_SYNC_TOKEN` secret for authentication + +## Results + +- Branches created successfully +- Workflow file created and committed locally (commit hash: f8c0599) +- Push failed: GitHub PAT requires `workflow` scope to push workflow files + +## Current status + +- Branch: `dummy-from` +- Local commit ready to push (f8c0599) +- Issue: Personal Access Token needs `workflow` scope + +## Next steps (resume from here) + +1. **Fix token scope issue** + - Add `workflow` scope to GitHub Personal Access Token + - Then run: `git push` + +2. **Set up repository secret** + - Create `NABLEDGE_SYNC_TOKEN` secret in nabledge-dev repository settings + - Token needs write access to nablarch/nabledge repository + +3. **Verify push functionality** (Task #5) + - After push succeeds, GitHub Actions will run automatically + - Check nabledge repository's `dummy-to` branch for synced files + - If needed, fix workflow file and push again + +4. **Add PR creation** (Task #6) + - Modify `.github/workflows/sync-to-nabledge.yml` to create PR from dummy-to to develop + - Include trigger commit URL in PR body + - Test PR creation From 89ec7ebf8ff3950ef3be93b07b6e24d6b865c18b Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:09:56 +0900 Subject: [PATCH 22/89] Test workflow with NABLEDGE_SYNC_TOKEN configured From d702183a6a4f0d45e66a6f304def9988ab443bfd Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:12:17 +0900 Subject: [PATCH 23/89] fix: Use heredoc syntax for multiline git commit message --- .github/workflows/sync-to-nabledge.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 85aed40..cd600e3 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -51,8 +51,11 @@ jobs: TRIGGER_COMMIT_SHA="${{ github.sha }}" TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" - git commit -m "Sync nabledge-6 skill from nabledge-dev + git commit -m "$(cat < Date: Tue, 10 Feb 2026 21:15:01 +0900 Subject: [PATCH 24/89] test: Add minimal test workflow to diagnose issue --- .github/workflows/test-simple.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/test-simple.yml diff --git a/.github/workflows/test-simple.yml b/.github/workflows/test-simple.yml new file mode 100644 index 0000000..772dc51 --- /dev/null +++ b/.github/workflows/test-simple.yml @@ -0,0 +1,16 @@ +name: Test Simple Workflow + +on: + push: + branches: + - dummy-from + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Simple test + run: echo "Workflow works" From 70a64934a14323517a0ba1524dede1207a028b49 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:15:41 +0900 Subject: [PATCH 25/89] test: Add test workflow for nabledge checkout with token --- .github/workflows/test-checkout-nabledge.yml | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/test-checkout-nabledge.yml diff --git a/.github/workflows/test-checkout-nabledge.yml b/.github/workflows/test-checkout-nabledge.yml new file mode 100644 index 0000000..c5e5ecf --- /dev/null +++ b/.github/workflows/test-checkout-nabledge.yml @@ -0,0 +1,33 @@ +name: Test Checkout Nabledge + +on: + push: + branches: + - dummy-from + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout nabledge-dev + uses: actions/checkout@v4 + + - name: Test token secret exists + run: | + if [ -z "${{ secrets.NABLEDGE_SYNC_TOKEN }}" ]; then + echo "NABLEDGE_SYNC_TOKEN is not set" + exit 1 + else + echo "NABLEDGE_SYNC_TOKEN is set" + fi + + - name: Checkout nabledge repository + uses: actions/checkout@v4 + with: + repository: nablarch/nabledge + ref: dummy-to + token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} + path: nabledge-repo + + - name: List nabledge repo + run: ls -la nabledge-repo/ From 07f3adc227b0f86e18d386458fa38486af29b1dc Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:17:51 +0900 Subject: [PATCH 26/89] test: Verify NABLEDGE_SYNC_TOKEN is set correctly From 816c224ba0a71f02d0c1c767a8191c6e2452f1e0 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:18:33 +0900 Subject: [PATCH 27/89] fix: Simplify commit message using multiple -m flags --- .github/workflows/sync-to-nabledge.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index cd600e3..b44c74c 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -51,11 +51,6 @@ jobs: TRIGGER_COMMIT_SHA="${{ github.sha }}" TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" - git commit -m "$(cat < Date: Tue, 10 Feb 2026 21:23:06 +0900 Subject: [PATCH 28/89] test: Verify nabledge repository write permission From d00a30e7065beb822d1be39c231e4c3f851e118c Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:26:17 +0900 Subject: [PATCH 29/89] test: Retry sync with updated permissions From a912412891eac4f5f8f23847b3fee92a559e3ee9 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:27:05 +0900 Subject: [PATCH 30/89] chore: Remove test workflow files --- .github/workflows/test-checkout-nabledge.yml | 33 -------------------- .github/workflows/test-simple.yml | 16 ---------- 2 files changed, 49 deletions(-) delete mode 100644 .github/workflows/test-checkout-nabledge.yml delete mode 100644 .github/workflows/test-simple.yml diff --git a/.github/workflows/test-checkout-nabledge.yml b/.github/workflows/test-checkout-nabledge.yml deleted file mode 100644 index c5e5ecf..0000000 --- a/.github/workflows/test-checkout-nabledge.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Test Checkout Nabledge - -on: - push: - branches: - - dummy-from - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Checkout nabledge-dev - uses: actions/checkout@v4 - - - name: Test token secret exists - run: | - if [ -z "${{ secrets.NABLEDGE_SYNC_TOKEN }}" ]; then - echo "NABLEDGE_SYNC_TOKEN is not set" - exit 1 - else - echo "NABLEDGE_SYNC_TOKEN is set" - fi - - - name: Checkout nabledge repository - uses: actions/checkout@v4 - with: - repository: nablarch/nabledge - ref: dummy-to - token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} - path: nabledge-repo - - - name: List nabledge repo - run: ls -la nabledge-repo/ diff --git a/.github/workflows/test-simple.yml b/.github/workflows/test-simple.yml deleted file mode 100644 index 772dc51..0000000 --- a/.github/workflows/test-simple.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Test Simple Workflow - -on: - push: - branches: - - dummy-from - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Simple test - run: echo "Workflow works" From a67e7e43c46fffd29187256780ee17fdecf37197 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Tue, 10 Feb 2026 21:30:42 +0900 Subject: [PATCH 31/89] docs: Add work log for completed sync workflow --- work/20260210/sync-workflow-completed.md | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 work/20260210/sync-workflow-completed.md diff --git a/work/20260210/sync-workflow-completed.md b/work/20260210/sync-workflow-completed.md new file mode 100644 index 0000000..90145fd --- /dev/null +++ b/work/20260210/sync-workflow-completed.md @@ -0,0 +1,55 @@ +# Sync Workflow Completed + +## What was done + +### Fixed GitHub Actions workflow +- Fixed multiline commit message syntax (changed from heredoc to multiple `-m` flags) +- File: `.github/workflows/sync-to-nabledge.yml` + +### Resolved authentication issues +- Set `NABLEDGE_SYNC_TOKEN` secret in nabledge-dev repository (not nabledge) +- Granted write permission to token owner for nablarch/nabledge repository + +### Cleaned up test workflows +- Removed temporary test workflow files: + - `.github/workflows/test-simple.yml` + - `.github/workflows/test-checkout-nabledge.yml` + +## Results + +### Successful sync +- Workflow run: https://github.com/nablarch/nabledge-dev/actions/runs/21864813463 +- Synced commit: 6218fb51585c770d4f7c8a7751074cd44d0a4e81 +- Branch: `dummy-to` in nablarch/nabledge repository +- Files synced: 43 files, 16318 insertions + +### Commit message format +``` +Sync nabledge-6 skill from nabledge-dev + +Triggered by: https://github.com/nablarch/nabledge-dev/commit/{SHA} +``` + +## Workflow functionality + +The workflow automatically: +1. Triggers on push to `dummy-from` branch +2. Checks out nabledge-dev repository +3. Checks out nabledge repository's `dummy-to` branch +4. Syncs `.claude/skills/nabledge-6` directory +5. Creates commit with traceability link +6. Pushes to `dummy-to` branch + +## Next steps + +As documented in previous work log (staging-github-action.md): + +1. **Add PR creation** (Task #6) + - Modify workflow to create PR from `dummy-to` to `develop` branch + - Include trigger commit URL in PR body + - Test PR creation functionality + +2. **Transition to production branches** + - Change trigger branch from `dummy-from` to actual branch + - Change target branch from `dummy-to` to actual branch + - Update workflow configuration accordingly From 33504fd1384c111b8c8f957fb8a180e5fdddf477 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 13:28:29 +0900 Subject: [PATCH 32/89] feat: Add VERSION file for plugin versioning Initial version 0.1.0 for nabledge-6 plugin distribution --- VERSION | 1 + 1 file changed, 1 insertion(+) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6e8bf73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 From d4440ef6cc1b2828b667b4de7ef4be4d65d5dae9 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 14:04:29 +0900 Subject: [PATCH 33/89] docs: Add plugin distribution workflow design Design for GitHub Action to transform nabledge-6 skill to Claude Code Plugin format - Development structure with plugin/ directory - File mapping from dev to distribution format - Transform script approach instead of generation --- .../github-action-plugin-distribution.md | 501 ++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 work/20260212/github-action-plugin-distribution.md diff --git a/work/20260212/github-action-plugin-distribution.md b/work/20260212/github-action-plugin-distribution.md new file mode 100644 index 0000000..3ae6ae6 --- /dev/null +++ b/work/20260212/github-action-plugin-distribution.md @@ -0,0 +1,501 @@ +# GitHub Action Design: Plugin Distribution for Nabledge + +## Overview + +This document describes the GitHub Action design for automatically converting and syncing the nabledge-6 skill from development format (nabledge-dev) to distribution format (nabledge) as a Claude Code Plugin. + +## Repository Roles + +| Repository | Purpose | Structure | Users | +|-----------|---------|-----------|-------| +| **nabledge-dev** | Development, testing, demo | `.claude/skills/nabledge-6/` | Developers | +| **nabledge** | Distribution, user installation | Claude Code Plugin format | End users | + +## Current vs Distribution Structure + +### Development (nabledge-dev) + +``` +nabledge-dev/ +├── .claude/ +│ └── skills/ +│ └── nabledge-6/ +│ ├── SKILL.md +│ ├── workflows/ +│ │ ├── keyword-search.md +│ │ ├── section-judgement.md +│ │ └── code-analysis.md +│ ├── assets/ +│ │ ├── code-analysis-template.md +│ │ ├── code-analysis-template-guide.md +│ │ └── code-analysis-template-examples.md +│ ├── knowledge/ +│ │ ├── index.toon +│ │ ├── features/ +│ │ ├── checks/ +│ │ └── releases/ +│ ├── docs/ +│ │ ├── features/ +│ │ ├── checks/ +│ │ └── releases/ +│ └── plugin/ +│ ├── plugin.json +│ ├── README.md +│ ├── LICENSE +│ └── CHANGELOG.md +``` + +**Characteristics**: +- ✅ Immediate testing with `/nabledge-6` +- ✅ Easy demo and dogfooding +- ✅ Fast edit-test-debug cycle +- ❌ Not installable as plugin + +### Distribution (nabledge) + +``` +nabledge/ +├── .claude-plugin/ +│ └── plugin.json # Plugin manifest +├── skills/ +│ └── nabledge-6/ +│ └── SKILL.md # Main skill definition +├── workflows/ +│ ├── keyword-search.md +│ ├── section-judgement.md +│ └── code-analysis.md +├── assets/ +│ ├── code-analysis-template.md +│ ├── code-analysis-template-guide.md +│ └── code-analysis-template-examples.md +├── knowledge/ +│ ├── index.toon +│ ├── features/ +│ ├── checks/ +│ └── releases/ +├── docs/ +│ ├── features/ +│ ├── checks/ +│ └── releases/ +├── README.md # Installation & usage +├── LICENSE # Apache 2.0 or MIT +└── CHANGELOG.md # Version history +``` + +**Characteristics**: +- ✅ Installable via `/plugin marketplace add nablarch/nabledge` +- ✅ Automatic updates for users +- ✅ Standard plugin structure +- ✅ Proper versioning with plugin.json + +## File Mapping + +| Source (nabledge-dev) | Destination (nabledge) | Action | +|----------------------|------------------------|--------| +| `.claude/skills/nabledge-6/SKILL.md` | `skills/nabledge-6/SKILL.md` | Move | +| `.claude/skills/nabledge-6/workflows/` | `workflows/` | Move to root | +| `.claude/skills/nabledge-6/assets/` | `assets/` | Move to root | +| `.claude/skills/nabledge-6/knowledge/` | `knowledge/` | Move to root | +| `.claude/skills/nabledge-6/docs/` | `docs/` | Move to root | +| `.claude/skills/nabledge-6/plugin/plugin.json` | `.claude-plugin/plugin.json` | Move | +| `.claude/skills/nabledge-6/plugin/README.md` | `README.md` | Move | +| `.claude/skills/nabledge-6/plugin/LICENSE` | `LICENSE` | Move | +| `.claude/skills/nabledge-6/plugin/CHANGELOG.md` | `CHANGELOG.md` | Move and update | + +## GitHub Action Design + +### Current Workflow (sync-to-nabledge.yml) + +**File**: `.github/workflows/sync-to-nabledge.yml` + +**Trigger**: Push to `dummy-from` branch + +**Current behavior**: +1. Checkout nabledge-dev repository +2. Checkout nabledge repository (dummy-to branch) +3. Copy `.claude/skills/nabledge-6` to `nabledge-repo/.claude/skills/nabledge-6` +4. Commit and push to nabledge repository + +**Issue**: Copies development structure, not plugin format + +### Updated Workflow Design + +**New behavior**: +1. Checkout nabledge-dev repository +2. Checkout nabledge repository (dummy-to branch) +3. **Transform to plugin structure**: + - Create `.claude-plugin/` directory + - Move `SKILL.md` to `skills/nabledge-6/SKILL.md` + - Move `workflows/`, `assets/`, `knowledge/`, `docs/` to root + - Move `plugin/plugin.json` to `.claude-plugin/plugin.json` + - Move `plugin/README.md` to root + - Move `plugin/LICENSE` to root + - Move `plugin/CHANGELOG.md` to root and update with sync info +4. Commit and push to nabledge repository + +### Workflow Steps Detail + +#### Step 1: Checkout repositories + +```yaml +- name: Checkout nabledge-dev + uses: actions/checkout@v4 + with: + fetch-depth: 0 + +- name: Checkout nabledge repository + uses: actions/checkout@v4 + with: + repository: nablarch/nabledge + ref: dummy-to + token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} + path: nabledge-repo +``` + +#### Step 2: Clean destination + +```yaml +- name: Clean nabledge repository + run: | + cd nabledge-repo + # Remove all files except .git/ + find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + +``` + +#### Step 3: Transform to plugin structure + +```yaml +- name: Transform to plugin structure + run: | + # Create plugin directories + mkdir -p nabledge-repo/.claude-plugin + mkdir -p nabledge-repo/skills/nabledge-6 + + # Move SKILL.md to skills/nabledge-6/ + cp .claude/skills/nabledge-6/SKILL.md nabledge-repo/skills/nabledge-6/ + + # Move supporting directories to root + cp -r .claude/skills/nabledge-6/workflows nabledge-repo/ + cp -r .claude/skills/nabledge-6/assets nabledge-repo/ + cp -r .claude/skills/nabledge-6/knowledge nabledge-repo/ + cp -r .claude/skills/nabledge-6/docs nabledge-repo/ + + # Move plugin files to root + cp .claude/skills/nabledge-6/plugin/plugin.json nabledge-repo/.claude-plugin/ + cp .claude/skills/nabledge-6/plugin/README.md nabledge-repo/ + cp .claude/skills/nabledge-6/plugin/LICENSE nabledge-repo/ + cp .claude/skills/nabledge-6/plugin/CHANGELOG.md nabledge-repo/ +``` + +#### Step 4: Update CHANGELOG.md + +```yaml +- name: Update CHANGELOG.md + run: | + TRIGGER_COMMIT_SHA="${{ github.sha }}" + TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" + DATE=$(date +%Y-%m-%d) + + # Append sync entry to CHANGELOG + sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/CHANGELOG.md +``` + +**Note**: The plugin.json, README.md, LICENSE, and CHANGELOG.md are now stored in the development repository and reviewed during development, rather than being generated each time. + +#### Step 5: Commit and push + +```yaml +- name: Commit and Push to nabledge + working-directory: nabledge-repo + run: | + git add . + + if git diff --staged --quiet; then + echo "No changes to commit" + exit 0 + fi + + TRIGGER_COMMIT_SHA="${{ github.sha }}" + TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" + + git commit -m "Sync nabledge-6 plugin from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" + + git push origin dummy-to +``` + +## README.md Template + +The generated README.md should include: + +```markdown +# Nabledge-6: Nablarch 6 Plugin for Claude Code + +Structured knowledge base for Nablarch 6 framework with code analysis capabilities. + +## Features + +- **Knowledge Search**: Query Nablarch 6 APIs, patterns, configurations +- **Code Analysis**: Analyze existing Nablarch code and generate documentation + +## Installation + +### Prerequisites + +- [Claude Code CLI](https://claude.com/claude-code) installed +- Nablarch 6 project + +### Install Plugin + +```bash +# In Claude Code +/plugin marketplace add nablarch/nabledge + +# Enable plugin (if not auto-enabled) +/plugin enable nabledge-6 +``` + +## Usage + +### Interactive Mode + +```bash +/nabledge-6 +``` + +Shows greeting and lets you choose between knowledge search and code analysis. + +### Knowledge Search + +```bash +/nabledge-6 "UniversalDaoの使い方" +/nabledge-6 "バッチ処理の実装方法" +``` + +### Code Analysis + +```bash +/nabledge-6 code-analysis +``` + +Then specify target code (class, feature, or package). + +## Knowledge Coverage + +- Nablarch batch processing (On-demand) +- RESTful web services (JAX-RS) +- Core handlers (DB connection, transaction, data read) +- Core libraries (UniversalDao, database access, validation, etc.) +- Testing framework (NTF) +- Security checklist + +See [docs/](docs/) for detailed knowledge documentation. + +## Scope + +### In Scope + +- Nablarch Batch (On-demand) +- RESTful Web Services + +### Out of Scope + +- Jakarta Batch +- Resident Batch (Table Queue) +- Web Applications (JSP/UI) +- Messaging (MOM) + +## Version + +- **Target**: Nablarch 6u2 / 6u3 +- **Plugin Version**: 0.1.0 + +## License + +Apache License 2.0 - See [LICENSE](LICENSE) + +## Repository + +- **Distribution**: https://github.com/nablarch/nabledge +- **Development**: https://github.com/nablarch/nabledge-dev +``` + +## Version Management Strategy + +### Semantic Versioning + +Follow [Semantic Versioning 2.0.0](https://semver.org/): + +- **MAJOR**: Incompatible API changes (e.g., SKILL.md structure change) +- **MINOR**: New knowledge files, new features (backward compatible) +- **PATCH**: Bug fixes, knowledge corrections + +### Version Management + +Store `plugin.json` in `.claude/skills/nabledge-6/plugin/plugin.json` with version field. + +Update version manually when releasing: + +1. Edit `.claude/skills/nabledge-6/plugin/plugin.json` to update version +2. Update `.claude/skills/nabledge-6/plugin/CHANGELOG.md` with release notes +3. Commit and push to dummy-from branch +4. GitHub Action syncs to nabledge repository +5. Tag nabledge repository with same version (e.g., `v0.2.0`) +6. Create GitHub release + +This approach allows: +- ✅ Version controlled in development repo +- ✅ Reviewable during development +- ✅ No dynamic generation needed +- ✅ Simple and maintainable + +## Workflow File Structure + +### Recommended Split + +**Option A: Single workflow** (simpler) + +``` +.github/workflows/ +└── sync-to-nabledge.yml # All-in-one: transform + sync +``` + +**Option B: Separate workflows** (more flexible) + +``` +.github/workflows/ +├── sync-to-nabledge.yml # Main sync workflow +└── scripts/ + └── transform-to-plugin.sh # Transformation script +``` + +### Recommendation + +Use **Option B** with separate script for: +- ✅ Easier testing locally +- ✅ Better maintainability +- ✅ Reusable for manual releases + +## Testing Strategy + +### Local Testing + +Before pushing to dummy-from branch, developers can test transformation locally: + +```bash +# Run transformation script +.github/scripts/transform-to-plugin.sh + +# Test plugin structure +cd /tmp/nabledge-plugin-test +claude --plugin-dir . +``` + +### CI Validation + +Add validation step in workflow: + +```yaml +- name: Validate plugin structure + run: | + # Check required files exist + test -f nabledge-repo/.claude-plugin/plugin.json + test -f nabledge-repo/skills/nabledge-6/SKILL.md + test -f nabledge-repo/README.md + test -f nabledge-repo/LICENSE + + # Validate plugin.json format + jq empty nabledge-repo/.claude-plugin/plugin.json +``` + +## Deployment Flow + +### Development to Distribution + +``` +Developer + │ + ├─> Edit .claude/skills/nabledge-6/ in nabledge-dev + │ + ├─> Test locally: /nabledge-6 + │ + ├─> Commit to dummy-from branch + │ + ├─> GitHub Action triggered + │ │ + │ ├─> Transform to plugin structure + │ ├─> Generate plugin.json, README, etc. + │ └─> Push to nabledge (dummy-to branch) + │ + └─> Users: /plugin marketplace add nablarch/nabledge +``` + +### Release Process + +1. **Prepare release** in nabledge-dev: + - Update `.claude/skills/nabledge-6/plugin/plugin.json` version (e.g., `0.1.0` → `0.2.0`) + - Update `.claude/skills/nabledge-6/plugin/CHANGELOG.md` with release notes + - Update docs if needed + - Test locally + +2. **Push to dummy-from**: + - GitHub Action syncs to nabledge (dummy-to) + +3. **Create release** in nabledge repository: + - Tag release (e.g., `v0.2.0`) + - Create GitHub release with changelog + - Users get automatic update or can pin version + +## Branch Strategy + +### nabledge-dev + +- **dummy-from**: Development branch (push triggers sync) +- **main**: Stable branch (not used for sync) + +### nabledge + +- **dummy-to**: Distribution branch (receives syncs from dummy-from) +- **main**: Could be used for stable releases (optional) + +### Future Consideration + +When moving from dummy branches to production: + +- nabledge-dev: `dummy-from` → `develop` or `main` +- nabledge: `dummy-to` → `main` + +Update workflow trigger accordingly. + +## Implementation Checklist + +- [ ] Create `.claude/skills/nabledge-6/plugin/` directory in nabledge-dev +- [ ] Create `plugin.json` in plugin directory +- [ ] Create `README.md` in plugin directory +- [ ] Create or copy `LICENSE` to plugin directory +- [ ] Create `CHANGELOG.md` in plugin directory +- [ ] Create transform-to-plugin.sh script +- [ ] Update sync-to-nabledge.yml workflow + - [ ] Add transformation steps to move plugin files + - [ ] Add CHANGELOG.md update with sync info + - [ ] Add validation steps +- [ ] Test locally with transform script +- [ ] Test GitHub Action with dummy-from push +- [ ] Verify nabledge repository structure +- [ ] Test plugin installation: `/plugin marketplace add nablarch/nabledge` +- [ ] Test plugin usage: `/nabledge-6` +- [ ] Document release process +- [ ] Update nabledge-dev README with distribution info + +## Future Enhancements + +1. **Automated testing**: Run nabledge-6 skill tests before sync +2. **Version bumping**: Auto-increment version based on commit messages +3. **Release automation**: Auto-create GitHub releases with tags +4. **Marketplace submission**: Submit to official Claude Code marketplace +5. **Multi-version support**: Support Nablarch 5 and 6 simultaneously + +## References + +- [Claude Code Plugin Specification](https://claude.com/docs/plugins) +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Semantic Versioning](https://semver.org/) From 7778fe588bfa058d388bbe9f6a8384ef351f3eea Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 14:23:33 +0900 Subject: [PATCH 34/89] fix: Fix nested code block in design document Simplified README.md template section to avoid markdown parsing issues --- .../github-action-plugin-distribution.md | 106 +++--------------- 1 file changed, 13 insertions(+), 93 deletions(-) diff --git a/work/20260212/github-action-plugin-distribution.md b/work/20260212/github-action-plugin-distribution.md index 3ae6ae6..23096bd 100644 --- a/work/20260212/github-action-plugin-distribution.md +++ b/work/20260212/github-action-plugin-distribution.md @@ -225,99 +225,19 @@ nabledge/ ## README.md Template -The generated README.md should include: - -```markdown -# Nabledge-6: Nablarch 6 Plugin for Claude Code - -Structured knowledge base for Nablarch 6 framework with code analysis capabilities. - -## Features - -- **Knowledge Search**: Query Nablarch 6 APIs, patterns, configurations -- **Code Analysis**: Analyze existing Nablarch code and generate documentation - -## Installation - -### Prerequisites - -- [Claude Code CLI](https://claude.com/claude-code) installed -- Nablarch 6 project - -### Install Plugin - -```bash -# In Claude Code -/plugin marketplace add nablarch/nabledge - -# Enable plugin (if not auto-enabled) -/plugin enable nabledge-6 -``` - -## Usage - -### Interactive Mode - -```bash -/nabledge-6 -``` - -Shows greeting and lets you choose between knowledge search and code analysis. - -### Knowledge Search - -```bash -/nabledge-6 "UniversalDaoの使い方" -/nabledge-6 "バッチ処理の実装方法" -``` - -### Code Analysis - -```bash -/nabledge-6 code-analysis -``` - -Then specify target code (class, feature, or package). - -## Knowledge Coverage - -- Nablarch batch processing (On-demand) -- RESTful web services (JAX-RS) -- Core handlers (DB connection, transaction, data read) -- Core libraries (UniversalDao, database access, validation, etc.) -- Testing framework (NTF) -- Security checklist - -See [docs/](docs/) for detailed knowledge documentation. - -## Scope - -### In Scope - -- Nablarch Batch (On-demand) -- RESTful Web Services - -### Out of Scope - -- Jakarta Batch -- Resident Batch (Table Queue) -- Web Applications (JSP/UI) -- Messaging (MOM) - -## Version - -- **Target**: Nablarch 6u2 / 6u3 -- **Plugin Version**: 0.1.0 - -## License - -Apache License 2.0 - See [LICENSE](LICENSE) - -## Repository - -- **Distribution**: https://github.com/nablarch/nabledge -- **Development**: https://github.com/nablarch/nabledge-dev -``` +The plugin README.md (stored in `.claude/skills/nabledge-6/plugin/README.md`) should include: + +- Plugin name and description +- Features (Knowledge Search, Code Analysis) +- Installation instructions (`/plugin marketplace add nablarch/nabledge`) +- Usage examples (`/nabledge-6`, `/nabledge-6 "question"`, `/nabledge-6 code-analysis`) +- Knowledge coverage (batch, REST, handlers, libraries, tools) +- Scope (in/out of scope) +- Version information (Nablarch 6u2/6u3, plugin version) +- License (Apache 2.0) +- Repository links (distribution and development) + +See example content in the actual plugin/README.md file in the repository. ## Version Management Strategy From 4a138128088e325d4595a6a5ff7999a64074d6ad Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 14:38:31 +0900 Subject: [PATCH 35/89] fix: Simplify version management strategy per review feedback - Replace detailed semver documentation with CI validation approach - Add validation step to fail sync if plugin.json/CHANGELOG.md not updated - Clarify branch strategy for production transition (main/develop) Co-Authored-By: Claude Opus 4.6 --- .../github-action-plugin-distribution.md | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/work/20260212/github-action-plugin-distribution.md b/work/20260212/github-action-plugin-distribution.md index 23096bd..b192c7c 100644 --- a/work/20260212/github-action-plugin-distribution.md +++ b/work/20260212/github-action-plugin-distribution.md @@ -241,32 +241,23 @@ See example content in the actual plugin/README.md file in the repository. ## Version Management Strategy -### Semantic Versioning +Store `plugin.json` and `CHANGELOG.md` in `.claude/skills/nabledge-6/plugin/` directory. -Follow [Semantic Versioning 2.0.0](https://semver.org/): - -- **MAJOR**: Incompatible API changes (e.g., SKILL.md structure change) -- **MINOR**: New knowledge files, new features (backward compatible) -- **PATCH**: Bug fixes, knowledge corrections - -### Version Management - -Store `plugin.json` in `.claude/skills/nabledge-6/plugin/plugin.json` with version field. +### CI Validation -Update version manually when releasing: +Add validation step to fail sync workflow if version files are not updated: -1. Edit `.claude/skills/nabledge-6/plugin/plugin.json` to update version -2. Update `.claude/skills/nabledge-6/plugin/CHANGELOG.md` with release notes -3. Commit and push to dummy-from branch -4. GitHub Action syncs to nabledge repository -5. Tag nabledge repository with same version (e.g., `v0.2.0`) -6. Create GitHub release +```yaml +- name: Validate version updates + run: | + # Check if plugin.json or CHANGELOG.md were modified in the last commit + if ! git diff HEAD~1 HEAD --name-only | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md"; then + echo "Error: plugin.json or CHANGELOG.md must be updated before sync" + exit 1 + fi +``` -This approach allows: -- ✅ Version controlled in development repo -- ✅ Reviewable during development -- ✅ No dynamic generation needed -- ✅ Simple and maintainable +This ensures developers always update version information when making changes that trigger a sync. ## Workflow File Structure @@ -381,10 +372,11 @@ Developer When moving from dummy branches to production: -- nabledge-dev: `dummy-from` → `develop` or `main` -- nabledge: `dummy-to` → `main` +- **nabledge-dev**: `dummy-from` → `main` (trigger branch for sync) + - `develop` will be used for development → `main` for releases +- **nabledge**: `dummy-to` → `main` (distribution branch) -Update workflow trigger accordingly. +Update workflow trigger accordingly when transitioning. ## Implementation Checklist From b02779914558fdded15b6fb593da0968511a4013 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 14:55:49 +0900 Subject: [PATCH 36/89] fix: Use threaded replies in PR review comment workflow Updated resolve.md to use GitHub API with in_reply_to parameter instead of gh pr comment. This creates threaded replies directly under review comments for better context and reviewer experience. Changes: - Use gh api to get review comments and post replies - Add in_reply_to parameter to create threaded replies - Remove "Advanced Operation" section (now default behavior) - Update field names (author.login -> user.login) Co-Authored-By: Claude Opus 4.6 --- .claude/skills/pr/workflows/resolve.md | 60 ++++++++++++++------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/.claude/skills/pr/workflows/resolve.md b/.claude/skills/pr/workflows/resolve.md index 3c54a7e..a584711 100644 --- a/.claude/skills/pr/workflows/resolve.md +++ b/.claude/skills/pr/workflows/resolve.md @@ -44,18 +44,24 @@ Options: ### 2. Get Unresolved Review Comments -**2.1 Get Review Threads** +**2.1 Get Review Comments** ```bash -gh pr view "$pr_number" --json reviewThreads +gh api "repos/{owner}/{repo}/pulls/$pr_number/comments" --jq '.[] | select(.in_reply_to_id == null)' +``` + +Get repository owner and name: +```bash +owner=$(gh repo view --json owner -q .owner.login) +repo=$(gh repo view --json name -q .name) ``` **2.2 Filtering** -Extract only comments meeting all these conditions: -- `thread.isResolved === false` -- `thread.isOutdated === false` -- `thread.path !== null` (comments on files) +Extract only comments meeting these conditions: +- Not a reply (no `in_reply_to_id`) +- Has not been replied to yet (check if comment has replies) +- Not outdated (`original_position` should exist or match `position`) If 0 unresolved comments: ``` @@ -75,10 +81,13 @@ For each unresolved comment, execute the following: **3.1 Analysis** Get comment information: +- `comment.id`: Comment ID (required for replying) - `comment.body`: Comment body - `comment.path`: File to fix - `comment.line`: Line number (if exists) -- `comment.author.login`: Reviewer name +- `comment.user.login`: Reviewer name + +Store the comment ID for later use in replies. Use Read tool to load file and check relevant section. @@ -136,10 +145,15 @@ repo_url=$(gh repo view --json url -q .url) **3.4 Reply** +Reply directly to the review comment using the stored comment ID: + **For fixes**: ```bash -gh pr comment "$pr_number" --body "$(cat <<'EOF' +gh api \ + -X POST \ + "repos/$owner/$repo/pulls/$pr_number/comments" \ + -f body="$(cat <<'EOF' Fixed **Commit**: {repo_url}/commit/{commit_sha} @@ -148,23 +162,28 @@ Fixed Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) EOF -)" +)" \ + -F in_reply_to=${comment_id} ``` **For questions**: ```bash -gh pr comment "$pr_number" --body "$(cat <<'EOF' +gh api \ + -X POST \ + "repos/$owner/$repo/pulls/$pr_number/comments" \ + -f body="$(cat <<'EOF' Please clarify {Question content} Co-Authored-By: Claude (jp.anthropic.claude-sonnet-4-5-20250929-v1:0) EOF -)" +)" \ + -F in_reply_to=${comment_id} ``` -**Note**: `gh pr comment` adds a comment to the overall PR. Direct replies to specific review comments require advanced operations using `gh api`. +**Note**: This creates threaded replies directly under review comments using the `in_reply_to` parameter, providing better context and reviewer experience. ### 4. Resolve Review Comments @@ -210,19 +229,4 @@ Please request reviewer to resolve threads 4. **Test Execution**: Run related tests if they exist after fixing 5. **Multiple Files**: When one comment requires multiple file fixes, fix all before creating a single commit 6. **Thread Resolution**: GitHub CLI lacks direct resolve functionality, so request reviewer resolution - -## Advanced Operation: Reply to Specific Comments - -To reply directly to specific review comments, use GitHub API: - -```bash -# Get review comment ID (from reviewThreads) -comment_id="{thread.comments[0].id}" - -# Add reply -gh api \ - "repos/{owner}/{repo}/pulls/{pr_number}/comments/$comment_id/replies" \ - -f body="Fixed. Please review." -``` - -However, PR-level comments are usually sufficient, so use this as needed. +7. **Threaded Replies**: Always reply directly to review comments for better threading and reviewer experience From 43066efca61ad98bd30e255129335b876bf25cdb Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 15:05:50 +0900 Subject: [PATCH 37/89] fix: Remove VERSION file per updated version strategy The VERSION file is no longer needed. Per review feedback, version management will be handled through plugin.json and CHANGELOG.md with CI validation. Relates to commit 4a13812 (simplified version management strategy). Co-Authored-By: Claude Opus 4.6 --- VERSION | 1 - 1 file changed, 1 deletion(-) delete mode 100644 VERSION diff --git a/VERSION b/VERSION deleted file mode 100644 index 6e8bf73..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1.0 From 27f42424b386db546d3d0566f3c1df0ea42bd660 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 15:27:18 +0900 Subject: [PATCH 38/89] feat: Implement plugin distribution workflow Added complete plugin distribution infrastructure per design document: Plugin Directory Structure: - Created .claude/skills/nabledge-6/plugin/ directory - Added plugin.json with version 0.1.0 - Added README.md with installation and usage instructions - Added LICENSE (Apache 2.0) - Added CHANGELOG.md Transform Script: - Created .github/scripts/transform-to-plugin.sh - Transforms dev structure to plugin format - Copies files to appropriate locations GitHub Action Workflow: - Updated .github/workflows/sync-to-nabledge.yml - Added version validation (requires plugin.json or CHANGELOG.md updates) - Added transformation step using transform script - Added plugin structure validation - Syncs to nablarch/nabledge (dummy-to branch) Trigger: Push to dummy-from branch Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 18 +++++ .claude/skills/nabledge-6/plugin/LICENSE | 16 +++++ .claude/skills/nabledge-6/plugin/README.md | 67 +++++++++++++++++++ .claude/skills/nabledge-6/plugin/plugin.json | 22 ++++++ .github/scripts/transform-to-plugin.sh | 51 ++++++++++++++ .github/workflows/sync-to-nabledge.yml | 54 +++++++++++---- 6 files changed, 216 insertions(+), 12 deletions(-) create mode 100644 .claude/skills/nabledge-6/plugin/CHANGELOG.md create mode 100644 .claude/skills/nabledge-6/plugin/LICENSE create mode 100644 .claude/skills/nabledge-6/plugin/README.md create mode 100644 .claude/skills/nabledge-6/plugin/plugin.json create mode 100755 .github/scripts/transform-to-plugin.sh diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md new file mode 100644 index 0000000..d015ea5 --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +All notable changes to the nabledge-6 plugin will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.0] - 2026-02-12 + +### Added +- Initial release of nabledge-6 skill +- Knowledge search functionality for Nablarch 6 documentation +- Code analysis capability with structured templates +- Support for batch processing (On-demand batch) +- Support for RESTful web services (JAX-RS) +- Coverage for Nablarch 6u2 and 6u3 + +[0.1.0]: https://github.com/nablarch/nabledge/releases/tag/v0.1.0 diff --git a/.claude/skills/nabledge-6/plugin/LICENSE b/.claude/skills/nabledge-6/plugin/LICENSE new file mode 100644 index 0000000..0e072a6 --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/LICENSE @@ -0,0 +1,16 @@ +Apache License +Version 2.0, January 2004 + +Copyright 2026 Nablarch + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md new file mode 100644 index 0000000..c10b3a5 --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -0,0 +1,67 @@ +# Nabledge-6 Plugin + +Nablarch 6 skill for AI-assisted development with Claude Code. + +## Features + +- **Knowledge Search**: Search Nablarch 6 documentation and best practices +- **Code Analysis**: Analyze Nablarch code with structured templates + +## Installation + +```bash +/plugin marketplace add nablarch/nabledge +``` + +## Usage + +### Basic Usage + +```bash +/nabledge-6 +``` + +### Knowledge Search + +```bash +/nabledge-6 "How do I implement batch processing?" +``` + +### Code Analysis + +```bash +/nabledge-6 code-analysis +``` + +## Coverage + +### Supported Features +- On-demand Batch (FILE to DB, DB to DB, DB to FILE) +- RESTful Web Services (JAX-RS) +- Handlers and Libraries +- Tools and Testing + +### Nablarch Versions +- Nablarch 6u2 +- Nablarch 6u3 + +## Scope + +### In Scope +- Batch processing (On-demand) +- RESTful web services (JAX-RS) + +### Out of Scope +- Jakarta Batch +- Resident Batch (Table Queue) +- Web Applications (JSP/UI) +- Messaging (MOM) + +## License + +Apache-2.0 + +## Links + +- Distribution Repository: nablarch/nabledge +- Development Repository: nablarch/nabledge-dev diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json new file mode 100644 index 0000000..d7160c9 --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -0,0 +1,22 @@ +{ + "name": "nabledge-6", + "version": "0.1.0", + "description": "Nablarch 6 skill for AI-assisted development with Claude Code", + "author": "Nablarch", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/nablarch/nabledge" + }, + "keywords": [ + "nablarch", + "nablarch6", + "jakarta-ee", + "batch", + "rest", + "jax-rs" + ], + "engines": { + "claude": ">=1.0.0" + } +} diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh new file mode 100755 index 0000000..d08eef4 --- /dev/null +++ b/.github/scripts/transform-to-plugin.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -e + +# Transform nabledge-6 skill from development format to plugin format +# Usage: ./transform-to-plugin.sh + +SOURCE_DIR="${1:-.}" +DEST_DIR="${2:-nabledge-repo}" + +echo "Transforming nabledge-6 skill to plugin format..." +echo "Source: $SOURCE_DIR" +echo "Destination: $DEST_DIR" + +# Validate source directory +if [ ! -d "$SOURCE_DIR/.claude/skills/nabledge-6" ]; then + echo "Error: Source directory does not contain .claude/skills/nabledge-6" + exit 1 +fi + +# Create plugin directories +echo "Creating plugin directory structure..." +mkdir -p "$DEST_DIR/.claude-plugin" +mkdir -p "$DEST_DIR/skills/nabledge-6" + +# Move SKILL.md to skills/nabledge-6/ +echo "Copying SKILL.md..." +cp "$SOURCE_DIR/.claude/skills/nabledge-6/SKILL.md" "$DEST_DIR/skills/nabledge-6/" + +# Move supporting directories to root +echo "Copying workflows..." +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/" + +echo "Copying assets..." +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/" + +echo "Copying knowledge..." +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/" + +echo "Copying docs..." +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/" + +# Move plugin files to root +echo "Copying plugin files..." +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/plugin.json" "$DEST_DIR/.claude-plugin/" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/CHANGELOG.md" "$DEST_DIR/" + +echo "Transformation complete!" +echo "" +echo "Plugin structure created in: $DEST_DIR" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index b44c74c..bedf05f 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -8,16 +8,20 @@ on: jobs: sync: runs-on: ubuntu-latest + steps: - name: Checkout nabledge-dev uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Configure Git + - name: Validate version updates run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" + # Check if plugin.json or CHANGELOG.md were modified in the last commit + if ! git diff HEAD~1 HEAD --name-only | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md"; then + echo "Error: plugin.json or CHANGELOG.md must be updated before sync" + exit 1 + fi - name: Checkout nabledge repository uses: actions/checkout@v4 @@ -27,30 +31,56 @@ jobs: token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} path: nabledge-repo - - name: Sync nabledge-6 skill + - name: Clean nabledge repository + run: | + cd nabledge-repo + # Remove all files except .git/ + find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + + + - name: Transform to plugin structure + run: | + # Use transform script + .github/scripts/transform-to-plugin.sh . nabledge-repo + + - name: Update CHANGELOG.md + run: | + TRIGGER_COMMIT_SHA="${{ github.sha }}" + TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" + DATE=$(date +%Y-%m-%d) + + # Append sync entry to CHANGELOG + sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/CHANGELOG.md + + - name: Validate plugin structure run: | - # Remove old skill files if exists - rm -rf nabledge-repo/.claude/skills/nabledge-6 + # Check required files exist + test -f nabledge-repo/.claude-plugin/plugin.json + test -f nabledge-repo/skills/nabledge-6/SKILL.md + test -f nabledge-repo/README.md + test -f nabledge-repo/LICENSE - # Copy nabledge-6 skill - mkdir -p nabledge-repo/.claude/skills - cp -r .claude/skills/nabledge-6 nabledge-repo/.claude/skills/ + # Validate plugin.json format + jq empty nabledge-repo/.claude-plugin/plugin.json + + - name: Configure Git + working-directory: nabledge-repo + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - name: Commit and Push to nabledge working-directory: nabledge-repo run: | git add . - # Check if there are changes to commit if git diff --staged --quiet; then echo "No changes to commit" exit 0 fi - # Create commit message with link to trigger commit TRIGGER_COMMIT_SHA="${{ github.sha }}" TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" - git commit -m "Sync nabledge-6 skill from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" + git commit -m "Sync nabledge-6 plugin from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" git push origin dummy-to From 06985e75f09580e28c1421148058a55616569446 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 17:16:13 +0900 Subject: [PATCH 39/89] fix: Remove AI tool references and simplify plugin metadata - Remove specific AI tool mentions (Claude Code) for broader compatibility - Simplify keywords to just 'nablarch' to avoid maintenance overhead - Clarify code analysis feature description - Merge Coverage and Scope sections for better organization - Show only latest Nablarch version (6u3) Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/README.md | 21 +++++++------------- .claude/skills/nabledge-6/plugin/plugin.json | 9 ++------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index c10b3a5..e5ed1a1 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -1,11 +1,11 @@ # Nabledge-6 Plugin -Nablarch 6 skill for AI-assisted development with Claude Code. +Nablarch 6 skill for AI-assisted development. ## Features - **Knowledge Search**: Search Nablarch 6 documentation and best practices -- **Code Analysis**: Analyze Nablarch code with structured templates +- **Code Analysis**: Analyze application code from Nablarch perspective ## Installation @@ -33,24 +33,17 @@ Nablarch 6 skill for AI-assisted development with Claude Code. /nabledge-6 code-analysis ``` -## Coverage +## Coverage and Scope -### Supported Features +### Nablarch Version +- Nablarch 6u3 + +### Supported Features (In Scope) - On-demand Batch (FILE to DB, DB to DB, DB to FILE) - RESTful Web Services (JAX-RS) - Handlers and Libraries - Tools and Testing -### Nablarch Versions -- Nablarch 6u2 -- Nablarch 6u3 - -## Scope - -### In Scope -- Batch processing (On-demand) -- RESTful web services (JAX-RS) - ### Out of Scope - Jakarta Batch - Resident Batch (Table Queue) diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index d7160c9..f827c32 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "nabledge-6", "version": "0.1.0", - "description": "Nablarch 6 skill for AI-assisted development with Claude Code", + "description": "Nablarch 6 skill for AI-assisted development", "author": "Nablarch", "license": "Apache-2.0", "repository": { @@ -9,12 +9,7 @@ "url": "https://github.com/nablarch/nabledge" }, "keywords": [ - "nablarch", - "nablarch6", - "jakarta-ee", - "batch", - "rest", - "jax-rs" + "nablarch" ], "engines": { "claude": ">=1.0.0" From 8f49f1beb37b41b72d36245c33770e68844f3988 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 17:17:16 +0900 Subject: [PATCH 40/89] refactor: Move test scenarios to nabledge-6/tests and remove nabledge-test skill - Move code-analysis-scenarios.json to nabledge-6/tests - Move keyword-search-scenarios.json to nabledge-6/tests - Remove standalone nabledge-test skill (tests will be done separately) Co-Authored-By: Claude Opus 4.6 --- .../tests}/code-analysis-scenarios.json | 0 .../tests}/keyword-search-scenarios.json | 0 .claude/skills/nabledge-test/README.md | 154 ----------- .claude/skills/nabledge-test/skill.json | 32 --- .claude/skills/nabledge-test/skill.md | 80 ------ .../skills/nabledge-test/templates/review.md | 200 -------------- .../templates/scenario-result.md | 104 ------- .../workflows/evaluate-results.md | 255 ------------------ .../nabledge-test/workflows/run-scenarios.md | 245 ----------------- 9 files changed, 1070 deletions(-) rename .claude/skills/{nabledge-test/scenarios/nabledge-6 => nabledge-6/tests}/code-analysis-scenarios.json (100%) rename .claude/skills/{nabledge-test/scenarios/nabledge-6 => nabledge-6/tests}/keyword-search-scenarios.json (100%) delete mode 100644 .claude/skills/nabledge-test/README.md delete mode 100644 .claude/skills/nabledge-test/skill.json delete mode 100644 .claude/skills/nabledge-test/skill.md delete mode 100644 .claude/skills/nabledge-test/templates/review.md delete mode 100644 .claude/skills/nabledge-test/templates/scenario-result.md delete mode 100644 .claude/skills/nabledge-test/workflows/evaluate-results.md delete mode 100644 .claude/skills/nabledge-test/workflows/run-scenarios.md diff --git a/.claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json b/.claude/skills/nabledge-6/tests/code-analysis-scenarios.json similarity index 100% rename from .claude/skills/nabledge-test/scenarios/nabledge-6/code-analysis-scenarios.json rename to .claude/skills/nabledge-6/tests/code-analysis-scenarios.json diff --git a/.claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json b/.claude/skills/nabledge-6/tests/keyword-search-scenarios.json similarity index 100% rename from .claude/skills/nabledge-test/scenarios/nabledge-6/keyword-search-scenarios.json rename to .claude/skills/nabledge-6/tests/keyword-search-scenarios.json diff --git a/.claude/skills/nabledge-test/README.md b/.claude/skills/nabledge-test/README.md deleted file mode 100644 index 2496e51..0000000 --- a/.claude/skills/nabledge-test/README.md +++ /dev/null @@ -1,154 +0,0 @@ -# Nabledge Test Skill - -Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4). - -## Overview - -This skill provides automated testing capabilities for nabledge skills: -- Execute test scenarios -- Evaluate results against criteria -- Generate improvement recommendations - -## Usage - -### Run Test Scenarios - -Execute test scenarios for a specific nabledge skill version: - -``` -/nabledge-test run-scenarios -``` - -Examples: -``` -/nabledge-test run-scenarios nabledge-6 -/nabledge-test run-scenarios nabledge-5 -``` - -This will: -1. Load scenarios from `scenarios//` -2. Execute each scenario using the target skill -3. Record results in `results/YYYYMMDD-HHMM/` -4. Create work log summary in `work/YYYYMMDD/` - -### Evaluate Results - -Evaluate test results and generate review report: - -``` -/nabledge-test evaluate-results -``` - -Example: -``` -/nabledge-test evaluate-results results/20260210-1430 -``` - -This will: -1. Analyze all scenario results -2. Evaluate against criteria -3. Identify common issues -4. Generate improvement recommendations -5. Create review report - -## Directory Structure - -``` -.claude/skills/nabledge-test/ -├── skill.json # Skill definition -├── README.md # This file -├── workflows/ -│ ├── run-scenarios.md # Scenario execution workflow -│ └── evaluate-results.md # Results evaluation workflow -├── templates/ -│ ├── scenario-result.md # Scenario result template -│ └── review.md # Review report template -├── scenarios/ -│ ├── nabledge-6/ -│ │ ├── code-analysis-scenarios.json -│ │ └── keyword-search-scenarios.json -│ ├── nabledge-5/ # Future -│ └── nabledge-1.4/ # Future -└── results/ - └── YYYYMMDD-HHMM/ # Test session results - ├── code-analysis/ - ├── keyword-search/ - └── *-scenarios-review.md -``` - -## Workflows - -### 1. run-scenarios - -Executes test scenarios for specified nabledge skill version. - -**Input**: Nabledge version (e.g., "nabledge-6") - -**Output**: -- Scenario results in `results/YYYYMMDD-HHMM/` -- Work log summary in `work/YYYYMMDD/` - -### 2. evaluate-results - -Evaluates test results and generates review report. - -**Input**: Test session directory (e.g., "results/20260210-1430") - -**Output**: -- Review reports in test session directory -- Improvement recommendations - -## Templates - -### scenario-result.md - -Template for recording individual scenario execution results: -- Metadata (ID, category, date, time) -- Test input (question, target, expectations) -- Execution results (workflow, resource usage, tool calls) -- Generated output -- Evaluation against criteria -- Issues found -- Status (PASS/FAIL/PARTIAL) - -### review.md - -Template for test session review report: -- Test session metadata -- Summary and pass rates -- Detailed results by scenario -- Common issues (by priority) -- Improvement recommendations -- Action items -- Next steps - -## Test Scenarios - -### nabledge-6 - -**code-analysis-scenarios.json** (5 scenarios): -- Full batch action structure analysis -- Initialization process analysis -- Database read process analysis -- File write process analysis -- Test code implementation analysis - -**keyword-search-scenarios.json** (5 scenarios): -- Handlers: Data read handler -- Libraries: UniversalDao paging -- Tools: NTF test data preparation -- Processing: Batch basic structure -- Adapters: SLF4J adapter configuration - -## Evaluation Criteria - -Each scenario is evaluated against: -- Workflow execution correctness -- Output quality (structure, completeness) -- Knowledge integration (proper citation) -- Token efficiency (target range) -- Tool call efficiency (target range) - -## Language - -All test content is in English, following repository language rules. diff --git a/.claude/skills/nabledge-test/skill.json b/.claude/skills/nabledge-test/skill.json deleted file mode 100644 index 4800466..0000000 --- a/.claude/skills/nabledge-test/skill.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "nabledge-test", - "version": "1.0.0", - "description": "Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4)", - "triggers": [ - "nabledge-test", - "test nabledge", - "run nabledge tests" - ], - "capabilities": [ - "Execute test scenarios for nabledge skills", - "Evaluate test results against criteria", - "Generate test reports with improvement recommendations" - ], - "workflows": [ - { - "name": "run-scenarios", - "description": "Execute test scenarios for specified nabledge skill version", - "file": "workflows/run-scenarios.md" - }, - { - "name": "evaluate-results", - "description": "Evaluate test results and generate review report", - "file": "workflows/evaluate-results.md" - } - ], - "assets": { - "templates": "templates/", - "scenarios": "scenarios/", - "results": "results/" - } -} diff --git a/.claude/skills/nabledge-test/skill.md b/.claude/skills/nabledge-test/skill.md deleted file mode 100644 index 382a58f..0000000 --- a/.claude/skills/nabledge-test/skill.md +++ /dev/null @@ -1,80 +0,0 @@ -# Nabledge Test Skill - -Testing framework for nabledge skills (nabledge-6, nabledge-5, nabledge-1.4). - -## Execution Flow - -### 1. Parse Arguments - -Extract workflow and parameters from invocation: - -``` -/nabledge-test → No args → AskUserQuestion for workflow -/nabledge-test run-scenarios → workflow="run-scenarios", version= -/nabledge-test evaluate-results → workflow="evaluate-results", session_dir= -``` - -**If no args**: Use AskUserQuestion to select workflow: -- Question: "Which testing workflow do you want to execute?" -- Options: - 1. "Run Scenarios (run-scenarios)" - Execute test scenarios for nabledge skill - 2. "Evaluate Results (evaluate-results)" - Evaluate test results and generate review - -### 2. Execute Workflow - -Delegate to specialized workflow via Task tool: - -#### A. run-scenarios Workflow - -``` -Task - subagent_type: "general-purpose" - description: "Execute test scenarios workflow" - prompt: "Follow the workflow to execute test scenarios for nabledge skill. - -{Read and include workflows/run-scenarios.md} - -## Input Context -- Version: {version} -" -``` - -#### B. evaluate-results Workflow - -``` -Task - subagent_type: "general-purpose" - description: "Execute results evaluation workflow" - prompt: "Follow the workflow to evaluate test results. - -{Read and include workflows/evaluate-results.md} - -## Input Context -- Test session directory: {test_session_dir} -" -``` - -## Implementation Notes - -1. **No args**: Use AskUserQuestion for user-friendly workflow selection -2. **Version required**: For run-scenarios, version must be specified or selected -3. **Session dir required**: For evaluate-results, session directory must be specified or selected -4. **Task tool usage**: Workflows execute in separate context with full workflow content -5. **Error handling**: Display clear error messages when parameters missing - -## Error Handling - -| Error | Response | -|-------|----------| -| Invalid workflow | Use AskUserQuestion for workflow selection | -| Missing version (run-scenarios) | List available versions, ask user to select | -| Missing session dir (evaluate-results) | List available sessions, ask user to select | -| Scenarios not found | Display error with available versions | -| Session not found | Display error with available sessions | - -## Workflows - -- **run-scenarios**: Execute test scenarios for specified nabledge skill version -- **evaluate-results**: Evaluate test results and generate review report - -For detailed workflow documentation, see `workflows/` directory. diff --git a/.claude/skills/nabledge-test/templates/review.md b/.claude/skills/nabledge-test/templates/review.md deleted file mode 100644 index 4ccb80c..0000000 --- a/.claude/skills/nabledge-test/templates/review.md +++ /dev/null @@ -1,200 +0,0 @@ -# Test Review: {scenario-file-name} - -## Test Session Metadata - -| Item | Value | -|------|-------| -| Test Date | {date} | -| Test Time | {time} | -| Test Directory | scenario-test-{hhmm} | -| Total Scenarios | {total} | -| Passed | {passed} | -| Failed | {failed} | -| Partial | {partial} | - -## Summary - -### Overall Assessment - -{overall_assessment_summary} - -### Pass Rate - -| Category | Pass Rate | Status | -|----------|-----------|--------| -| Workflow Execution | {percentage}% | {pass/warning/fail} | -| Output Quality | {percentage}% | {pass/warning/fail} | -| Knowledge Integration | {percentage}% | {pass/warning/fail} | -| Resource Efficiency | {percentage}% | {pass/warning/fail} | - -## Detailed Results by Scenario - -### {scenario-id-1} - -**Status**: {PASS/FAIL/PARTIAL} - -**Strengths**: -- {strength_1} -- {strength_2} - -**Issues**: -- {issue_1} -- {issue_2} - -**Metrics**: -- Tokens: {tokens} ({target_range}) -- Tool Calls: {calls} ({target_range}) - ---- - -### {scenario-id-2} - -{repeat for each scenario} - ---- - -## Common Issues - -### High Priority - -1. **Issue**: {issue_description} - - **Scenarios Affected**: {scenario_ids} - - **Impact**: {impact_description} - - **Recommendation**: {recommendation} - -2. **Issue**: {issue_description} - - **Scenarios Affected**: {scenario_ids} - - **Impact**: {impact_description} - - **Recommendation**: {recommendation} - -### Medium Priority - -{repeat structure} - -### Low Priority - -{repeat structure} - -## Improvement Recommendations - -### スキル構造の改善 - -#### 1. {improvement_area_1} - -**現状の問題**: -{problem_description} - -**改善案**: -{improvement_suggestion} - -**期待される効果**: -{expected_benefit} - -**実装優先度**: {High/Medium/Low} - ---- - -#### 2. {improvement_area_2} - -{repeat structure} - ---- - -### ワークフローの改善 - -#### 1. {workflow_improvement_1} - -**現状の問題**: -{problem_description} - -**改善案**: -{improvement_suggestion} - -**期待される効果**: -{expected_benefit} - -**実装優先度**: {High/Medium/Low} - ---- - -### 知識ファイルの改善 - -#### 1. {knowledge_improvement_1} - -**対象ファイル**: {file_path} - -**現状の問題**: -{problem_description} - -**改善案**: -{improvement_suggestion} - -**期待される効果**: -{expected_benefit} - -**実装優先度**: {High/Medium/Low} - ---- - -### パフォーマンス最適化 - -#### Token Usage - -**現状**: -- 平均: {average} tokens -- 最大: {max} tokens -- 目標範囲: {target_range} - -**改善案**: -{optimization_suggestions} - ---- - -#### Tool Call Efficiency - -**現状**: -- 平均: {average} calls -- 最大: {max} calls -- 目標範囲: {target_range} - -**改善案**: -{optimization_suggestions} - ---- - -## Action Items - -### Immediate (実装必須) - -- [ ] {action_item_1} -- [ ] {action_item_2} - -### Short-term (1週間以内) - -- [ ] {action_item_1} -- [ ] {action_item_2} - -### Long-term (1ヶ月以内) - -- [ ] {action_item_1} -- [ ] {action_item_2} - -## Next Steps - -1. {next_step_1} -2. {next_step_2} -3. {next_step_3} - -## Appendix - -### Test Environment - -- Claude Model: {model_version} -- Skill Version: {skill_version} -- Test Framework Version: {framework_version} - -### Reference - -- Test Scenarios: `{scenario_file_path}` -- Test Results: `scenario-test-{hhmm}/` -- Previous Review: `{previous_review_path}` (if applicable) diff --git a/.claude/skills/nabledge-test/templates/scenario-result.md b/.claude/skills/nabledge-test/templates/scenario-result.md deleted file mode 100644 index 32ec81c..0000000 --- a/.claude/skills/nabledge-test/templates/scenario-result.md +++ /dev/null @@ -1,104 +0,0 @@ -# Scenario Result: {scenario-id} - -## Metadata - -| Item | Value | -|------|-------| -| Scenario ID | {scenario-id} | -| Category | {category} | -| Test Date | {date} | -| Test Time | {time} | -| Duration | {duration}s | - -## Test Input - -### Question -``` -{question} -``` - -### Target -``` -{target_code or target_file} -``` - -### Expected Components -{expected_components_list} - -### Expected Knowledge -{expected_knowledge_list} - -## Execution Results - -### Workflow Execution - -| Step | Status | Details | -|------|--------|---------| -| Workflow Start | {status} | {details} | -| Target Identification | {status} | {details} | -| Dependency Analysis | {status} | {details} | -| Knowledge Retrieval | {status} | {details} | -| Output Generation | {status} | {details} | - -### Resource Usage - -| Metric | Value | Target | Status | -|--------|-------|--------|--------| -| Total Tokens | {tokens} | {target_range} | {pass/fail} | -| Tool Calls | {tool_calls} | {target_range} | {pass/fail} | -| Execution Time | {time}s | - | - | - -### Tool Calls Summary - -{list of tool calls with parameters} - -## Generated Output - -### Output Sections Present - -- [ ] Overview -- [ ] Architecture (if applicable) -- [ ] Components -- [ ] Flow -- [ ] Nablarch Framework Usage - -### Output Content - -```markdown -{actual_output_content} -``` - -## Evaluation Against Criteria - -### Workflow Execution -{evaluation_details} - -### Code Explanation Output (code-analysis only) -{evaluation_details} - -### Keyword Matching (keyword-search only) -{evaluation_details} - -### Knowledge Integration -{evaluation_details} - -### Section Relevance -{evaluation_details} - -### Token Efficiency -{evaluation_details} - -### Tool Call Efficiency -{evaluation_details} - -## Issues Found - -{list of issues} - -## Status - -**Overall Result**: {PASS/FAIL/PARTIAL} - -## Notes - -{additional_notes} diff --git a/.claude/skills/nabledge-test/workflows/evaluate-results.md b/.claude/skills/nabledge-test/workflows/evaluate-results.md deleted file mode 100644 index 51f5ca2..0000000 --- a/.claude/skills/nabledge-test/workflows/evaluate-results.md +++ /dev/null @@ -1,255 +0,0 @@ -# Evaluate Results Workflow - -Evaluate test results and generate review report with improvement recommendations. - -## Input - -- **test_session_dir**: Path to test session directory (e.g., "results/20260210-1430" or "20260210-1430") - -## Output - -- Review reports in test session directory: - - `{scenario-file-name}-review.md` for each scenario file - -## Execution Steps - -### 1. Parse Arguments and Setup - -**1.1 Parse Test Session Directory** - -Extract test session directory from skill invocation: -``` -/nabledge-test evaluate-results results/20260210-1430 → dir="results/20260210-1430" -/nabledge-test evaluate-results 20260210-1430 → dir="results/20260210-1430" -``` - -If no directory specified, list available sessions and ask user to select: -```bash -ls -d .claude/skills/nabledge-test/results/*/ -``` - -**1.2 Verify Session Directory Exists** - -Check that test session directory exists: -```bash -ls .claude/skills/nabledge-test/results/{timestamp}/ -``` - -If not found, display error: -``` -Error: Test session directory not found: {test_session_dir} - -Available test sessions: -{list_of_available_sessions} - -Please specify a valid test session directory. -``` - -### 2. Load Scenario Files and Results - -**2.1 Identify Scenario Files** - -Find all unique scenario file names from result files: -```bash -find .claude/skills/nabledge-test/results/{timestamp}/ -name "*.md" -type f -``` - -Extract scenario file names (e.g., "code-analysis", "keyword-search"). - -**2.2 Load Original Scenario Definitions** - -For each identified scenario file: -- Determine version from session (check which version's scenarios were used) -- Load original scenario JSON file from `scenarios/{version}/{scenario-file-name}-scenarios.json` -- Extract evaluation criteria - -**2.3 Load All Result Files** - -For each scenario file: -- Find all result files in `results/{timestamp}/{category}/` -- Parse each result file to extract: - - Scenario ID - - Status (PASS/FAIL/PARTIAL) - - Execution metrics (tokens, tool calls) - - Issues found - - Generated output - -### 3. Analyze Results - -For each scenario file: - -**3.1 Calculate Statistics** - -- Total scenarios -- Pass count / percentage -- Fail count / percentage -- Partial count / percentage -- Average token usage -- Token usage range (min/max) -- Average tool calls -- Tool calls range (min/max) - -**3.2 Evaluate Each Scenario Against Criteria** - -From original scenario JSON `evaluation_criteria`: - -**Workflow Execution**: -- Check if expected workflow was executed -- Verify required steps were completed -- Assess tool usage appropriateness - -**Output Quality** (for code-analysis): -- Verify expected output sections present -- Check for Mermaid diagrams -- Validate component explanations -- Confirm source code links -- Confirm knowledge file links - -**Keyword Matching** (for keyword-search): -- Calculate keyword match percentage -- Identify missing keywords - -**Knowledge Integration**: -- Verify expected knowledge files were referenced -- Check knowledge content was properly cited -- Assess code-knowledge correspondence - -**Section Relevance** (for keyword-search): -- Verify expected sections were identified -- Check high-relevance sections prioritized - -**Knowledge File Only** (for keyword-search): -- Confirm no LLM training data used -- Verify no external knowledge added -- Check only knowledge file content used - -**Token Efficiency**: -- Compare actual vs target token range -- Calculate efficiency percentage - -**Tool Call Efficiency**: -- Compare actual vs target tool call range -- Calculate efficiency percentage - -**3.3 Identify Common Issues** - -Group issues across scenarios by: -- Issue type (workflow, output, knowledge, efficiency) -- Frequency (how many scenarios affected) -- Severity (impact on results) - -Categorize by priority: -- **High**: Affects multiple scenarios, significant impact -- **Medium**: Affects some scenarios, moderate impact -- **Low**: Affects few scenarios, minor impact - -### 4. Generate Improvement Recommendations - -**4.1 Skill Structure Improvements** - -Analyze patterns and recommend: -- Knowledge file additions/updates -- Workflow refinements -- Tool usage optimizations -- Context management improvements - -**4.2 Workflow Improvements** - -Recommend: -- Step sequence optimization -- Decision logic refinement -- Error handling enhancement -- Context efficiency improvements - -**4.3 Knowledge File Improvements** - -For each knowledge file with issues: -- Identify missing information -- Suggest content additions -- Recommend structure improvements -- Propose example enhancements - -**4.4 Performance Optimization** - -Token usage optimization: -- Identify verbose outputs -- Suggest content reduction strategies -- Recommend context management improvements - -Tool call optimization: -- Identify redundant calls -- Suggest call consolidation -- Recommend caching strategies - -### 5. Generate Review Report - -**5.1 Create Review File** - -Use template from `templates/review.md` and populate with: - -- **Test Session Metadata**: Date, time, directory, counts -- **Summary**: Overall assessment, pass rates by category -- **Detailed Results**: Each scenario with strengths, issues, metrics -- **Common Issues**: Grouped by priority with recommendations -- **Improvement Recommendations**: By area (skill, workflow, knowledge, performance) -- **Action Items**: Categorized by urgency (Immediate/Short-term/Long-term) -- **Next Steps**: Recommended actions - -Save to: -``` -.claude/skills/nabledge-test/results/{timestamp}/{scenario-file-name}-review.md -``` - -**5.2 Generate One Review Per Scenario File** - -Create separate review for: -- code-analysis-scenarios-review.md -- keyword-search-scenarios-review.md -- (future scenario files) - -### 6. Display Summary - -``` -## Evaluation Complete - -**Test Session**: {timestamp} -**Scenario Files Evaluated**: {count} - -**Overall Results**: -- Pass Rate: {overall_pass_percentage}% -- Average Token Usage: {avg_tokens} -- Average Tool Calls: {avg_calls} - -**Generated Reviews**: -- {scenario-file-1}-review.md -- {scenario-file-2}-review.md - -**Top Priority Issues** ({count}): -1. {issue_1} -2. {issue_2} -3. {issue_3} - -**Review Reports**: .claude/skills/nabledge-test/results/{timestamp}/ - -**Recommended Next Steps**: -{next_steps_list} -``` - -## Error Handling - -| Error | Response | -|-------|----------| -| Session directory not specified | List available sessions, ask user to select | -| Session directory not found | Display error with available sessions | -| Result files missing | Display error, suggest re-running tests | -| Template not found | Display error and stop | -| Scenario JSON not found | Display warning, use default criteria | - -## Important Notes - -1. **Objective evaluation**: Use criteria from scenario JSON files -2. **Pattern recognition**: Identify common issues across scenarios -3. **Actionable recommendations**: Provide specific, implementable suggestions -4. **Priority guidance**: Categorize issues and actions by priority/urgency -5. **Comprehensive coverage**: Evaluate all aspects (workflow, output, knowledge, efficiency) -6. **Clear reporting**: Use consistent format across all reviews diff --git a/.claude/skills/nabledge-test/workflows/run-scenarios.md b/.claude/skills/nabledge-test/workflows/run-scenarios.md deleted file mode 100644 index a8f06cf..0000000 --- a/.claude/skills/nabledge-test/workflows/run-scenarios.md +++ /dev/null @@ -1,245 +0,0 @@ -# Run Scenarios Workflow - -Execute test scenarios for specified nabledge skill version. - -## Input - -- **version**: Target nabledge skill version (e.g., "nabledge-6", "nabledge-5") - -## Output - -- Scenario result files in `results/YYYYMMDD-HHMM//.md` -- Work log summary in `work/YYYYMMDD/scenario-test.md` - -## Execution Steps - -### 1. Parse Arguments and Setup - -**1.1 Parse Version Argument** - -Extract version from skill invocation: -``` -/nabledge-test run-scenarios nabledge-6 → version="nabledge-6" -/nabledge-test run-scenarios nabledge-5 → version="nabledge-5" -``` - -If no version specified, ask user to select: -- nabledge-6 -- nabledge-5 (if scenarios exist) -- nabledge-1.4 (if scenarios exist) - -**1.2 Verify Scenarios Exist** - -Check that `scenarios/{version}/` directory exists and contains scenario files: -```bash -ls .claude/skills/nabledge-test/scenarios/{version}/ -``` - -If not found, display error: -``` -Error: No scenarios found for {version}. - -Available versions: -- nabledge-6 - -Please specify a valid version. -``` - -**1.3 Create Test Session Directory** - -Create timestamped directory for test results: -```bash -timestamp=$(date '+%Y%m%d-%H%M') -mkdir -p .claude/skills/nabledge-test/results/${timestamp} -``` - -Record start time: -```bash -date '+%Y-%m-%d %H:%M:%S' -``` - -### 2. Load Scenario Files - -**2.1 Find All Scenario Files** - -```bash -find .claude/skills/nabledge-test/scenarios/{version}/ -name "*-scenarios.json" -``` - -**2.2 Parse Each Scenario File** - -For each scenario file: -- Read JSON content -- Extract metadata (version, description, total_scenarios) -- Extract scenarios array -- Extract evaluation_criteria - -### 3. Execute Scenarios - -For each scenario in each scenario file: - -**3.1 Prepare Scenario Context** - -Extract from scenario JSON: -- id -- category -- question -- target_code or file (depending on workflow type) -- expected_components -- expected_knowledge -- expected_output_sections (if applicable) - -**3.2 Determine Workflow Type** - -Based on category: -- `code-analysis` → Use code-analysis workflow -- `handlers`, `libraries`, `tools`, `processing`, `adapters` → Use keyword-search workflow - -**3.3 Execute Skill with Scenario** - -Record start time: -```bash -start_time=$(date '+%Y-%m-%d %H:%M:%S') -``` - -Execute nabledge skill: - -**For code-analysis scenarios**: -``` -/{version} code-analysis - -Target: {target_code} -Question: {question} -``` - -**For keyword-search scenarios**: -``` -/{version} keyword-search - -Question: {question} -``` - -Record end time: -```bash -end_time=$(date '+%Y-%m-%d %H:%M:%S') -``` - -**IMPORTANT**: Clear skill context between scenarios to ensure independent execution. - -**3.4 Capture Execution Metrics** - -Record the following: -- Start time -- End time -- Skill output -- Token usage (estimate from output length) -- Tool calls (count from skill output if visible) - -**3.5 Generate Scenario Result File** - -Use template from `templates/scenario-result.md` and populate with: -- Metadata (scenario ID, category, dates, times) -- Test input (question, target, expectations) -- Execution results (workflow steps, resource usage) -- Generated output (skill response) -- Evaluation against criteria (from scenario JSON) -- Issues found (manual review needed) -- Status (PASS/FAIL/PARTIAL based on criteria) - -Save to: -``` -.claude/skills/nabledge-test/results/{timestamp}/{category}/{scenario-id}.md -``` - -**3.6 Display Progress** - -Show progress after each scenario: -``` -[{current}/{total}] Completed: {scenario-id} ({status}) -``` - -### 4. Generate Summary - -**4.1 Calculate Statistics** - -- Total scenarios executed -- Pass count -- Fail count -- Partial count -- Average token usage -- Average tool calls - -**4.2 Create Work Log Summary** - -Create `work/{YYYYMMDD}/scenario-test.md`: - -```markdown -# Scenario Test: {version} - -## Metadata - -- Date: {date} -- Test Session: {timestamp} -- Total Scenarios: {total} - -## Results - -| Status | Count | Percentage | -|--------|-------|------------| -| Pass | {pass_count} | {pass_percentage}% | -| Fail | {fail_count} | {fail_percentage}% | -| Partial | {partial_count} | {partial_percentage}% | - -## Key Findings - -{list_of_major_issues} - -## Details - -Full test results: `.claude/skills/nabledge-test/results/{timestamp}/` - -## Next Steps - -{recommended_next_steps} -``` - -**4.3 Display Summary** - -``` -## Test Execution Complete - -**Version**: {version} -**Test Session**: {timestamp} -**Total Scenarios**: {total} - -**Results**: -- Pass: {pass_count} -- Fail: {fail_count} -- Partial: {partial_count} - -**Pass Rate**: {pass_percentage}% - -**Details**: .claude/skills/nabledge-test/results/{timestamp}/ -**Work Log**: work/{YYYYMMDD}/scenario-test.md - -To evaluate results and generate review: -/nabledge-test evaluate-results {timestamp} -``` - -## Error Handling - -| Error | Response | -|-------|----------| -| Version not specified | Ask user to select version | -| Scenarios not found | Display error with available versions | -| Skill execution failed | Record as FAIL, continue with next scenario | -| Template not found | Display error and stop | - -## Important Notes - -1. **Context isolation**: Clear skill context between scenarios -2. **Independent execution**: Each scenario runs independently -3. **Record everything**: Capture all execution details for evaluation -4. **Progress feedback**: Show progress after each scenario -5. **Work log summary**: Create concise summary for daily work log -6. **Next step guidance**: Prompt user to run evaluate-results From deb777902d5affc8fbcda7289ed0cab6121cc6c4 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 17:32:39 +0900 Subject: [PATCH 41/89] fix: Address PR review feedback for plugin setup and documentation - Add GitHub Copilot setup instructions with curl-based installation - Create scripts/setup.sh for automated .claude directory setup - Simplify README section headers (Coverage and Scope -> Scope) - Remove redundant test documentation files per reviewer request Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/README.md | 12 +- .claude/skills/nabledge-6/scripts/setup.sh | 28 + .claude/skills/nabledge-6/tests/README.md | 225 ------ .../skills/nabledge-6/tests/scenarios.json | 557 ------------- .claude/skills/nabledge-6/tests/scenarios.md | 729 ------------------ 5 files changed, 38 insertions(+), 1513 deletions(-) create mode 100755 .claude/skills/nabledge-6/scripts/setup.sh delete mode 100644 .claude/skills/nabledge-6/tests/README.md delete mode 100644 .claude/skills/nabledge-6/tests/scenarios.json delete mode 100644 .claude/skills/nabledge-6/tests/scenarios.md diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index e5ed1a1..0c9931f 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -9,10 +9,18 @@ Nablarch 6 skill for AI-assisted development. ## Installation +### For Claude Code (WSL) + ```bash /plugin marketplace add nablarch/nabledge ``` +### For GitHub Copilot (WSL or GitBash) + +```bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash +``` + ## Usage ### Basic Usage @@ -33,12 +41,12 @@ Nablarch 6 skill for AI-assisted development. /nabledge-6 code-analysis ``` -## Coverage and Scope +## Scope ### Nablarch Version - Nablarch 6u3 -### Supported Features (In Scope) +### Supported Features - On-demand Batch (FILE to DB, DB to DB, DB to FILE) - RESTful Web Services (JAX-RS) - Handlers and Libraries diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup.sh new file mode 100755 index 0000000..e5d53db --- /dev/null +++ b/.claude/skills/nabledge-6/scripts/setup.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +# Navigate to repository root +cd "$(git rev-parse --show-toplevel)" + +echo "Setting up Nabledge-6 skill for GitHub Copilot..." + +# Download .claude directory from nablarch/nabledge repository +REPO_URL="https://github.com/nablarch/nabledge" +TEMP_DIR=$(mktemp -d) + +echo "Downloading .claude directory from $REPO_URL..." +cd "$TEMP_DIR" +git clone --depth 1 --filter=blob:none --sparse "$REPO_URL" +cd nabledge +git sparse-checkout set .claude + +# Copy .claude directory to project root +echo "Copying .claude directory to project..." +cd - +cp -r "$TEMP_DIR/nabledge/.claude" . + +# Clean up +rm -rf "$TEMP_DIR" + +echo "Setup complete! The nabledge-6 skill is now available in your project." +echo "You can use it with GitHub Copilot by typing '/nabledge-6' in your editor." diff --git a/.claude/skills/nabledge-6/tests/README.md b/.claude/skills/nabledge-6/tests/README.md deleted file mode 100644 index 5b20076..0000000 --- a/.claude/skills/nabledge-6/tests/README.md +++ /dev/null @@ -1,225 +0,0 @@ -# Nabledge-6 Test Scenarios - -## Overview - -This directory contains test scenarios for validating the nabledge-6 skill workflow execution. - -## Files - -| File | Format | Purpose | -|------|--------|---------| -| `scenarios.json` | JSON | Machine-readable test scenarios for automated evaluation | -| `scenarios.md` | Markdown | Human-readable test scenarios for manual testing | -| `README.md` | Markdown | This file - usage instructions | - -## Test Scenarios - -**Total**: 25 scenarios (5 per category) - -**Categories**: -- **handlers**: Transaction management, DB connection, data reading -- **libraries**: UniversalDao, database access, file path, business date, data bind -- **tools**: NTF (test framework), assertions, test data -- **processing**: Nablarch batch architecture and implementation -- **adapters**: SLF4J logging adapter - -## Scenario Structure - -Each scenario contains: - -```json -{ - "id": "unique-id", - "category": "handlers|libraries|tools|processing|adapters", - "file": "path/to/knowledge-file.json", - "question": "User's question in Japanese", - "expected_keywords": ["keyword1", "keyword2", ...], - "expected_sections": ["section1", "section2"], - "relevance": "high|partial" -} -``` - -## Evaluation Criteria - -### 1. Workflow Execution ✓ -- keyword-search workflow executed -- section-judgement workflow executed -- Appropriate tool calls (Read, Bash+jq) - -### 2. Keyword Matching (≥80%) -- Expected keywords present in answer -- Related technical terms used correctly - -### 3. Section Relevance ✓ -- Correct sections identified -- High-relevance sections prioritized -- None-relevance sections filtered out - -### 4. Knowledge File Only ✓ -- No LLM training data used -- No external knowledge supplemented -- Only knowledge file content used - -### 5. Token Efficiency (5,000-15,000 tokens) -- No unnecessary full-file reads -- Section-level extraction working - -### 6. Tool Call Efficiency (10-20 calls) -- Read: index.toon (1 call) -- Bash+jq: .index extraction (5-10 calls) -- Bash+jq: .sections extraction (5-10 calls) - -## Usage - -### Manual Testing - -Test individual scenarios by asking the question: - -``` -"データリードハンドラでファイルを読み込むにはどうすればいいですか?" -``` - -**Expected behavior**: -1. Message: "keyword-searchワークフローを実行します" -2. Read index.toon -3. Bash+jq for section extraction -4. Answer contains expected keywords -5. Answer uses only knowledge file content - -### Automated Testing (Future) - -Create an evaluation agent that: - -1. Loads `scenarios.json` -2. For each scenario: - - Executes the question - - Monitors workflow execution - - Validates keyword matching - - Checks section relevance - - Measures token usage - - Counts tool calls -3. Generates evaluation report - -**Evaluation agent prompt template**: - -``` -Execute the test scenario and evaluate the response: - -Question: {question} -Expected Keywords: {expected_keywords} -Expected Sections: {expected_sections} - -Evaluation checklist: -- [ ] Workflow execution (keyword-search + section-judgement) -- [ ] Keyword matching (≥80%) -- [ ] Section relevance (expected sections identified) -- [ ] Knowledge file only (no external knowledge) -- [ ] Token efficiency (5,000-15,000 tokens) -- [ ] Tool call efficiency (10-20 calls) - -Score each criterion and provide overall pass/fail. -``` - -## Example Test Case - -### handlers-001: データリードハンドラの使い方 - -**Question**: -``` -データリードハンドラでファイルを読み込むにはどうすればいいですか? -``` - -**Expected Workflow**: -1. Extract keywords: ["データリードハンドラ", "ファイル", "読み込み", "DataReader"] -2. Read index.toon → match "data-read-handler.json" -3. Bash+jq '.index' data-read-handler.json → find relevant sections -4. Bash+jq '.sections.overview' → read content -5. Judge relevance: High (directly answers question) -6. Answer using only section content - -**Expected Answer Content**: -- DataReadHandler explanation -- DataReader interface usage -- File reading configuration -- Code examples or method signatures - -**Expected Keywords in Answer** (≥4/5): -- ✓ DataReadHandler -- ✓ DataReader -- ✓ ファイル読み込み -- ✓ データ入力 -- ✓ レコード処理 - -## Success Metrics - -A test scenario passes if: - -- [ ] Workflow executed correctly (both keyword-search and section-judgement) -- [ ] ≥80% of expected keywords present in answer -- [ ] Relevant sections identified and used -- [ ] Answer uses only knowledge file content (no LLM training data) -- [ ] Token usage: 5,000-15,000 tokens -- [ ] Tool calls: 10-20 calls - -## Known Limitations - -### Not Yet Created Knowledge Files - -Some expected sections may not exist in knowledge files yet. In these cases: - -**Expected behavior**: -- Message: "この情報は知識ファイルに含まれていません" -- List related available knowledge -- Show "not yet created" entries from index.toon -- No answer from LLM training data - -**Test scenarios affected**: -- Any scenario with expected_sections that don't exist in the actual knowledge files - -### Section Name Variations - -Expected section names are estimates based on typical knowledge file structure. Actual section IDs may differ. - -**If section names don't match**: -- Workflow should still find related sections by keyword matching -- Evaluate based on content relevance, not exact section ID match - -## Contributing - -To add new test scenarios: - -1. Choose a knowledge file from `knowledge/features/` -2. Read the file's `.index` field to see available sections -3. Create a question that maps to a specific section -4. List expected keywords from that section -5. Add to `scenarios.json` with unique ID -6. Update `scenarios.md` for human readability - -**ID format**: `{category}-{number:03d}` -- Example: `handlers-006`, `libraries-006` - -## Maintenance - -### When Knowledge Files Change - -If knowledge files are updated: - -1. Review affected scenarios in `scenarios.json` -2. Update `expected_keywords` if section content changed -3. Update `expected_sections` if section IDs changed -4. Re-run tests to verify scenarios still pass - -### When Workflow Changes - -If keyword-search or section-judgement workflows change: - -1. Update `evaluation_criteria` in `scenarios.json` -2. Update success metrics in this README -3. Re-run all scenarios to establish new baseline - -## Version History - -- **1.0.0** (2026-02-09): Initial test scenarios created - - 25 scenarios across 5 categories - - JSON and Markdown formats - - Evaluation criteria defined diff --git a/.claude/skills/nabledge-6/tests/scenarios.json b/.claude/skills/nabledge-6/tests/scenarios.json deleted file mode 100644 index 1119f5c..0000000 --- a/.claude/skills/nabledge-6/tests/scenarios.json +++ /dev/null @@ -1,557 +0,0 @@ -{ - "metadata": { - "version": "1.1.0", - "created": "2026-02-09", - "updated": "2026-02-10", - "description": "Test scenarios for nabledge-6 skill workflow validation", - "total_scenarios": 30 - }, - "scenarios": [ - { - "id": "handlers-001", - "category": "handlers", - "file": "handlers/batch/data-read-handler.json", - "question": "データリードハンドラでファイルを読み込むにはどうすればいいですか?", - "expected_keywords": [ - "DataReadHandler", - "DataReader", - "ファイル読み込み", - "データ入力", - "レコード処理" - ], - "expected_sections": ["overview", "usage"], - "relevance": "high" - }, - { - "id": "handlers-002", - "category": "handlers", - "file": "handlers/common/transaction-management-handler.json", - "question": "トランザクション管理ハンドラでロールバックする方法は?", - "expected_keywords": [ - "TransactionManagementHandler", - "ロールバック", - "rollback", - "エラー処理", - "トランザクション制御" - ], - "expected_sections": ["rollback", "error-handling"], - "relevance": "high" - }, - { - "id": "handlers-003", - "category": "handlers", - "file": "handlers/common/db-connection-management-handler.json", - "question": "データベース接続管理ハンドラの設定方法を教えてください", - "expected_keywords": [ - "DbConnectionManagementHandler", - "データベース接続", - "コネクション管理", - "設定", - "コンポーネント定義" - ], - "expected_sections": ["configuration", "setup"], - "relevance": "high" - }, - { - "id": "handlers-004", - "category": "handlers", - "file": "handlers/common/transaction-management-handler.json", - "question": "トランザクションのコミットタイミングはいつですか?", - "expected_keywords": [ - "コミット", - "commit", - "トランザクション", - "タイミング", - "正常終了" - ], - "expected_sections": ["commit", "lifecycle"], - "relevance": "high" - }, - { - "id": "handlers-005", - "category": "handlers", - "file": "handlers/batch/data-read-handler.json", - "question": "データリードハンドラで大量データを処理するには?", - "expected_keywords": [ - "大量データ", - "データ処理", - "バッチ", - "DataReader", - "ループ処理" - ], - "expected_sections": ["large-data", "performance"], - "relevance": "high" - }, - { - "id": "libraries-001", - "category": "libraries", - "file": "libraries/universal-dao.json", - "question": "UniversalDaoでページングを実装したい", - "expected_keywords": [ - "ページング", - "paging", - "per", - "page", - "Pagination", - "EntityList" - ], - "expected_sections": ["paging"], - "relevance": "high" - }, - { - "id": "libraries-002", - "category": "libraries", - "file": "libraries/universal-dao.json", - "question": "UniversalDaoで楽観的ロックを使う方法は?", - "expected_keywords": [ - "楽観的ロック", - "@Version", - "OptimisticLockException", - "排他制御", - "バージョンカラム" - ], - "expected_sections": ["optimistic-lock"], - "relevance": "high" - }, - { - "id": "libraries-003", - "category": "libraries", - "file": "libraries/database-access.json", - "question": "データベースアクセスでSQLを実行する方法を教えてください", - "expected_keywords": [ - "SQL実行", - "Database", - "SqlPStatement", - "クエリ", - "検索" - ], - "expected_sections": ["sql-execution", "query"], - "relevance": "high" - }, - { - "id": "libraries-004", - "category": "libraries", - "file": "libraries/file-path-management.json", - "question": "ファイルパス管理でファイルパスを取得するには?", - "expected_keywords": [ - "ファイルパス", - "FilePathSetting", - "論理名", - "物理パス", - "パス取得" - ], - "expected_sections": ["usage", "configuration"], - "relevance": "high" - }, - { - "id": "libraries-005", - "category": "libraries", - "file": "libraries/business-date.json", - "question": "業務日付を取得する方法は?", - "expected_keywords": [ - "業務日付", - "SystemTimeUtil", - "日付取得", - "システム日付" - ], - "expected_sections": ["overview", "usage"], - "relevance": "high" - }, - { - "id": "tools-001", - "category": "tools", - "file": "tools/ntf-test-data.json", - "question": "NTFでテストデータを準備する方法を教えてください", - "expected_keywords": [ - "テストデータ", - "NTF", - "データ準備", - "Excel", - "データベース" - ], - "expected_sections": ["preparation", "setup"], - "relevance": "high" - }, - { - "id": "tools-002", - "category": "tools", - "file": "tools/ntf-assertion.json", - "question": "NTFのアサーション機能の使い方は?", - "expected_keywords": [ - "アサーション", - "検証", - "期待値", - "実測値", - "NTF" - ], - "expected_sections": ["assertion", "verification"], - "relevance": "high" - }, - { - "id": "tools-003", - "category": "tools", - "file": "tools/ntf-batch-request-test.json", - "question": "バッチのリクエスト単体テストを実行するには?", - "expected_keywords": [ - "リクエスト単体テスト", - "バッチテスト", - "NTF", - "テスト実行", - "BatchRequestTestSupport" - ], - "expected_sections": ["test-execution", "setup"], - "relevance": "high" - }, - { - "id": "tools-004", - "category": "tools", - "file": "tools/ntf-test-data.json", - "question": "テストデータの初期化はどうやりますか?", - "expected_keywords": [ - "初期化", - "データクリア", - "セットアップ", - "テストデータ", - "前処理" - ], - "expected_sections": ["initialization", "cleanup"], - "relevance": "high" - }, - { - "id": "tools-005", - "category": "tools", - "file": "tools/ntf-overview.json", - "question": "NTFの基本的な使い方を教えてください", - "expected_keywords": [ - "NTF", - "自動テストフレームワーク", - "テスト実行", - "JUnit", - "テストケース" - ], - "expected_sections": ["overview", "getting-started"], - "relevance": "high" - }, - { - "id": "processing-001", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "Nablarchバッチの基本構造を教えてください", - "expected_keywords": [ - "バッチ", - "基本構造", - "アーキテクチャ", - "ハンドラ構成", - "処理フロー" - ], - "expected_sections": ["overview", "architecture"], - "relevance": "high" - }, - { - "id": "processing-002", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチアクションの実装方法は?", - "expected_keywords": [ - "BatchAction", - "アクション実装", - "バッチ処理", - "execute", - "ビジネスロジック" - ], - "expected_sections": ["action-implementation", "business-logic"], - "relevance": "high" - }, - { - "id": "processing-003", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチで大量データを処理する方法は?", - "expected_keywords": [ - "大量データ", - "データ処理", - "ループ処理", - "DataReader", - "パフォーマンス" - ], - "expected_sections": ["large-data-processing", "performance"], - "relevance": "high" - }, - { - "id": "processing-004", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチのエラーハンドリングはどうすればいいですか?", - "expected_keywords": [ - "エラーハンドリング", - "例外処理", - "エラー処理", - "リトライ", - "異常終了" - ], - "expected_sections": ["error-handling", "exception"], - "relevance": "high" - }, - { - "id": "processing-005", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "バッチの起動方法を教えてください", - "expected_keywords": [ - "バッチ起動", - "Main", - "コマンドライン", - "起動クラス", - "実行" - ], - "expected_sections": ["launch", "execution"], - "relevance": "high" - }, - { - "id": "adapters-001", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jアダプタの設定方法を教えてください", - "expected_keywords": [ - "SLF4J", - "アダプタ", - "設定", - "ログ出力", - "log4j" - ], - "expected_sections": ["configuration", "setup"], - "relevance": "high" - }, - { - "id": "adapters-002", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログレベルを変更するには?", - "expected_keywords": [ - "ログレベル", - "設定変更", - "DEBUG", - "INFO", - "ERROR" - ], - "expected_sections": ["log-level", "configuration"], - "relevance": "high" - }, - { - "id": "adapters-003", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログファイルを出力する設定は?", - "expected_keywords": [ - "ログファイル", - "ファイル出力", - "Appender", - "設定", - "ログ出力先" - ], - "expected_sections": ["file-output", "appender"], - "relevance": "high" - }, - { - "id": "adapters-004", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "NablarchとSLF4Jを連携させる方法は?", - "expected_keywords": [ - "連携", - "統合", - "Nablarch", - "SLF4J", - "アダプタ" - ], - "expected_sections": ["integration", "overview"], - "relevance": "high" - }, - { - "id": "adapters-005", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jでログフォーマットを変更するには?", - "expected_keywords": [ - "ログフォーマット", - "フォーマット設定", - "出力形式", - "パターン", - "カスタマイズ" - ], - "expected_sections": ["format", "pattern"], - "relevance": "high" - }, - { - "id": "code-analysis-001", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java", - "question": "ProjectActionの構造を理解したい", - "expected_components": [ - "ProjectAction (Action)", - "ProjectForm (Form)", - "Project (Entity)", - "UniversalDao (Nablarch)" - ], - "expected_knowledge": [ - "libraries/universal-dao.json", - "libraries/data-bind.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-002", - "category": "code-analysis", - "target_code": "proman-batch", - "question": "proman-batchモジュール全体の構造を教えてください", - "expected_components": [ - "BatchAction (multiple)", - "Entity classes", - "Nablarch handlers" - ], - "expected_knowledge": [ - "processing/nablarch-batch.json", - "handlers/batch/data-read-handler.json", - "handlers/common/transaction-management-handler.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components" - ], - "relevance": "high" - }, - { - "id": "code-analysis-003", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/form", - "question": "Formクラスの設計パターンを理解したい", - "expected_components": [ - "Form classes (multiple)", - "Bean Validation annotations", - "Domain validation" - ], - "expected_knowledge": [ - "libraries/data-bind.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-004", - "category": "code-analysis", - "target_code": "proman-common/src/main/java/com/nablarch/example/proman/entity", - "question": "Entityクラスの設計を理解したい", - "expected_components": [ - "Entity classes (multiple)", - "Table annotations", - "UniversalDao integration" - ], - "expected_knowledge": [ - "libraries/universal-dao.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components" - ], - "relevance": "high" - }, - { - "id": "code-analysis-005", - "category": "code-analysis", - "target_code": "proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java", - "question": "ログイン機能の実装を詳しく知りたい", - "expected_components": [ - "LoginAction (Action)", - "LoginForm (Form)", - "SystemAccount (Entity)", - "UniversalDao (Nablarch)", - "Bean Validation (Nablarch)" - ], - "expected_knowledge": [ - "libraries/universal-dao.json", - "libraries/data-bind.json", - "libraries/database-access.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - } - ], - "evaluation_criteria": { - "workflow_execution": { - "description": "ワークフローが正しく実行されたか", - "checks": [ - "keyword-search workflowが実行された", - "section-judgement workflowが実行された", - "適切なツール呼び出しが行われた(Read, Bash+jq)" - ] - }, - "keyword_matching": { - "description": "期待されるキーワードが回答に含まれているか", - "threshold": "80%以上のキーワードが含まれている" - }, - "section_relevance": { - "description": "適切なセクションが特定されたか", - "checks": [ - "expected_sectionsに含まれるセクションが特定された", - "関連性の高いセクション(High relevance)が優先された" - ] - }, - "knowledge_file_only": { - "description": "知識ファイルのみを使って回答したか", - "checks": [ - "LLM訓練データを使用していない", - "外部知識を補足していない", - "知識ファイルに記載されている情報のみを使用" - ] - }, - "token_efficiency": { - "description": "トークン効率が適切か", - "target": "5,000-15,000 tokens per query" - }, - "tool_call_efficiency": { - "description": "ツール呼び出し回数が適切か", - "target": "10-20 tool calls per query" - }, - "code_explanation_workflow": { - "description": "code-analysisワークフローが正しく実行されたか", - "checks": [ - "対象コードが正しく識別された", - "依存関係が適切に分析された", - "構成要素が適切に分解された", - "関連するNablarch知識が検索された", - "ドキュメントが生成された(Markdown + Mermaid図)", - "ソースコードへの相対パスリンクが含まれている", - "Nablarch知識ファイルへのリンクが含まれている" - ] - }, - "code_explanation_output": { - "description": "出力ドキュメントの品質が適切か", - "checks": [ - "Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている", - "Mermaid図が適切に生成されている", - "構成要素の説明が明確である", - "ソースコードへのリンクが正しい", - "Nablarch知識の引用が適切である" - ] - } - } -} diff --git a/.claude/skills/nabledge-6/tests/scenarios.md b/.claude/skills/nabledge-6/tests/scenarios.md deleted file mode 100644 index b5dac17..0000000 --- a/.claude/skills/nabledge-6/tests/scenarios.md +++ /dev/null @@ -1,729 +0,0 @@ -# Test Scenarios for Nabledge-6 Skill - -## Metadata - -- **Version**: 1.1.0 -- **Created**: 2026-02-09 -- **Updated**: 2026-02-10 -- **Total Scenarios**: 30 (5 per category) -- **Purpose**: Validate nabledge-6 skill workflows (keyword-search + section-judgement + code-analysis) - ---- - -## Category 1: Handlers (5 scenarios) - -### handlers-001: データリードハンドラの使い方 - -**Question**: データリードハンドラでファイルを読み込むにはどうすればいいですか? - -**Expected Keywords**: -- DataReadHandler -- DataReader -- ファイル読み込み -- データ入力 -- レコード処理 - -**Expected Sections**: overview, usage - -**Knowledge File**: handlers/batch/data-read-handler.json - -**Expected Relevance**: High - ---- - -### handlers-002: トランザクションのロールバック - -**Question**: トランザクション管理ハンドラでロールバックする方法は? - -**Expected Keywords**: -- TransactionManagementHandler -- ロールバック -- rollback -- エラー処理 -- トランザクション制御 - -**Expected Sections**: rollback, error-handling - -**Knowledge File**: handlers/common/transaction-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-003: データベース接続管理の設定 - -**Question**: データベース接続管理ハンドラの設定方法を教えてください - -**Expected Keywords**: -- DbConnectionManagementHandler -- データベース接続 -- コネクション管理 -- 設定 -- コンポーネント定義 - -**Expected Sections**: configuration, setup - -**Knowledge File**: handlers/common/db-connection-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-004: トランザクションのコミットタイミング - -**Question**: トランザクションのコミットタイミングはいつですか? - -**Expected Keywords**: -- コミット -- commit -- トランザクション -- タイミング -- 正常終了 - -**Expected Sections**: commit, lifecycle - -**Knowledge File**: handlers/common/transaction-management-handler.json - -**Expected Relevance**: High - ---- - -### handlers-005: 大量データの処理 - -**Question**: データリードハンドラで大量データを処理するには? - -**Expected Keywords**: -- 大量データ -- データ処理 -- バッチ -- DataReader -- ループ処理 - -**Expected Sections**: large-data, performance - -**Knowledge File**: handlers/batch/data-read-handler.json - -**Expected Relevance**: High - ---- - -## Category 2: Libraries (5 scenarios) - -### libraries-001: ページング実装 - -**Question**: UniversalDaoでページングを実装したい - -**Expected Keywords**: -- ページング -- paging -- per -- page -- Pagination -- EntityList - -**Expected Sections**: paging - -**Knowledge File**: libraries/universal-dao.json - -**Expected Relevance**: High - ---- - -### libraries-002: 楽観的ロック - -**Question**: UniversalDaoで楽観的ロックを使う方法は? - -**Expected Keywords**: -- 楽観的ロック -- @Version -- OptimisticLockException -- 排他制御 -- バージョンカラム - -**Expected Sections**: optimistic-lock - -**Knowledge File**: libraries/universal-dao.json - -**Expected Relevance**: High - ---- - -### libraries-003: SQL実行 - -**Question**: データベースアクセスでSQLを実行する方法を教えてください - -**Expected Keywords**: -- SQL実行 -- Database -- SqlPStatement -- クエリ -- 検索 - -**Expected Sections**: sql-execution, query - -**Knowledge File**: libraries/database-access.json - -**Expected Relevance**: High - ---- - -### libraries-004: ファイルパス取得 - -**Question**: ファイルパス管理でファイルパスを取得するには? - -**Expected Keywords**: -- ファイルパス -- FilePathSetting -- 論理名 -- 物理パス -- パス取得 - -**Expected Sections**: usage, configuration - -**Knowledge File**: libraries/file-path-management.json - -**Expected Relevance**: High - ---- - -### libraries-005: 業務日付取得 - -**Question**: 業務日付を取得する方法は? - -**Expected Keywords**: -- 業務日付 -- SystemTimeUtil -- 日付取得 -- システム日付 - -**Expected Sections**: overview, usage - -**Knowledge File**: libraries/business-date.json - -**Expected Relevance**: High - ---- - -## Category 3: Tools (5 scenarios) - -### tools-001: テストデータ準備 - -**Question**: NTFでテストデータを準備する方法を教えてください - -**Expected Keywords**: -- テストデータ -- NTF -- データ準備 -- Excel -- データベース - -**Expected Sections**: preparation, setup - -**Knowledge File**: tools/ntf-test-data.json - -**Expected Relevance**: High - ---- - -### tools-002: アサーション機能 - -**Question**: NTFのアサーション機能の使い方は? - -**Expected Keywords**: -- アサーション -- 検証 -- 期待値 -- 実測値 -- NTF - -**Expected Sections**: assertion, verification - -**Knowledge File**: tools/ntf-assertion.json - -**Expected Relevance**: High - ---- - -### tools-003: バッチのリクエスト単体テスト - -**Question**: バッチのリクエスト単体テストを実行するには? - -**Expected Keywords**: -- リクエスト単体テスト -- バッチテスト -- NTF -- テスト実行 -- BatchRequestTestSupport - -**Expected Sections**: test-execution, setup - -**Knowledge File**: tools/ntf-batch-request-test.json - -**Expected Relevance**: High - ---- - -### tools-004: テストデータ初期化 - -**Question**: テストデータの初期化はどうやりますか? - -**Expected Keywords**: -- 初期化 -- データクリア -- セットアップ -- テストデータ -- 前処理 - -**Expected Sections**: initialization, cleanup - -**Knowledge File**: tools/ntf-test-data.json - -**Expected Relevance**: High - ---- - -### tools-005: NTF基本的な使い方 - -**Question**: NTFの基本的な使い方を教えてください - -**Expected Keywords**: -- NTF -- 自動テストフレームワーク -- テスト実行 -- JUnit -- テストケース - -**Expected Sections**: overview, getting-started - -**Knowledge File**: tools/ntf-overview.json - -**Expected Relevance**: High - ---- - -## Category 4: Processing (5 scenarios) - -### processing-001: バッチの基本構造 - -**Question**: Nablarchバッチの基本構造を教えてください - -**Expected Keywords**: -- バッチ -- 基本構造 -- アーキテクチャ -- ハンドラ構成 -- 処理フロー - -**Expected Sections**: overview, architecture - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-002: バッチアクション実装 - -**Question**: バッチアクションの実装方法は? - -**Expected Keywords**: -- BatchAction -- アクション実装 -- バッチ処理 -- execute -- ビジネスロジック - -**Expected Sections**: action-implementation, business-logic - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-003: 大量データ処理 - -**Question**: バッチで大量データを処理する方法は? - -**Expected Keywords**: -- 大量データ -- データ処理 -- ループ処理 -- DataReader -- パフォーマンス - -**Expected Sections**: large-data-processing, performance - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-004: バッチのエラーハンドリング - -**Question**: バッチのエラーハンドリングはどうすればいいですか? - -**Expected Keywords**: -- エラーハンドリング -- 例外処理 -- エラー処理 -- リトライ -- 異常終了 - -**Expected Sections**: error-handling, exception - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -### processing-005: バッチの起動方法 - -**Question**: バッチの起動方法を教えてください - -**Expected Keywords**: -- バッチ起動 -- Main -- コマンドライン -- 起動クラス -- 実行 - -**Expected Sections**: launch, execution - -**Knowledge File**: processing/nablarch-batch.json - -**Expected Relevance**: High - ---- - -## Category 5: Adapters (5 scenarios) - -### adapters-001: SLF4Jアダプタの設定 - -**Question**: SLF4Jアダプタの設定方法を教えてください - -**Expected Keywords**: -- SLF4J -- アダプタ -- 設定 -- ログ出力 -- log4j - -**Expected Sections**: configuration, setup - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-002: ログレベルの変更 - -**Question**: SLF4Jでログレベルを変更するには? - -**Expected Keywords**: -- ログレベル -- 設定変更 -- DEBUG -- INFO -- ERROR - -**Expected Sections**: log-level, configuration - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-003: ログファイル出力 - -**Question**: SLF4Jでログファイルを出力する設定は? - -**Expected Keywords**: -- ログファイル -- ファイル出力 -- Appender -- 設定 -- ログ出力先 - -**Expected Sections**: file-output, appender - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-004: Nablarchとの連携 - -**Question**: NablarchとSLF4Jを連携させる方法は? - -**Expected Keywords**: -- 連携 -- 統合 -- Nablarch -- SLF4J -- アダプタ - -**Expected Sections**: integration, overview - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -### adapters-005: ログフォーマット変更 - -**Question**: SLF4Jでログフォーマットを変更するには? - -**Expected Keywords**: -- ログフォーマット -- フォーマット設定 -- 出力形式 -- パターン -- カスタマイズ - -**Expected Sections**: format, pattern - -**Knowledge File**: adapters/slf4j-adapter.json - -**Expected Relevance**: High - ---- - -## Category 6: Code Analysis (5 scenarios) - -### code-analysis-001: ProjectActionの構造理解 - -**Question**: ProjectActionの構造を理解したい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/ProjectAction.java - -**Expected Components**: -- ProjectAction (Action) -- ProjectForm (Form) -- Project (Entity) -- UniversalDao (Nablarch) - -**Expected Knowledge**: -- libraries/universal-dao.json -- libraries/data-bind.json - -**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -### code-analysis-002: proman-batchモジュール全体の理解 - -**Question**: proman-batchモジュール全体の構造を教えてください - -**Target Code**: proman-batch - -**Expected Components**: -- BatchAction (multiple) -- Entity classes -- Nablarch handlers - -**Expected Knowledge**: -- processing/nablarch-batch.json -- handlers/batch/data-read-handler.json -- handlers/common/transaction-management-handler.json - -**Expected Output Sections**: Overview, Architecture, Components - -**Expected Relevance**: High - ---- - -### code-analysis-003: Formクラスの設計パターン - -**Question**: Formクラスの設計パターンを理解したい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/form - -**Expected Components**: -- Form classes (multiple) -- Bean Validation annotations -- Domain validation - -**Expected Knowledge**: -- libraries/data-bind.json - -**Expected Output Sections**: Overview, Components, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -### code-analysis-004: Entityクラスの設計理解 - -**Question**: Entityクラスの設計を理解したい - -**Target Code**: proman-common/src/main/java/com/nablarch/example/proman/entity - -**Expected Components**: -- Entity classes (multiple) -- Table annotations -- UniversalDao integration - -**Expected Knowledge**: -- libraries/universal-dao.json - -**Expected Output Sections**: Overview, Architecture, Components - -**Expected Relevance**: High - ---- - -### code-analysis-005: ログイン機能の詳細実装 - -**Question**: ログイン機能の実装を詳しく知りたい - -**Target Code**: proman-web/src/main/java/com/nablarch/example/proman/web/action/LoginAction.java - -**Expected Components**: -- LoginAction (Action) -- LoginForm (Form) -- SystemAccount (Entity) -- UniversalDao (Nablarch) -- Bean Validation (Nablarch) - -**Expected Knowledge**: -- libraries/universal-dao.json -- libraries/data-bind.json -- libraries/database-access.json - -**Expected Output Sections**: Overview, Architecture, Components, Flow, Nablarch Framework Usage - -**Expected Relevance**: High - ---- - -## Evaluation Criteria - -### 1. Workflow Execution - -ワークフローが正しく実行されたか確認: - -- [ ] keyword-search workflowが実行された -- [ ] section-judgement workflowが実行された -- [ ] 適切なツール呼び出しが行われた(Read, Bash+jq) -- [ ] index.toonが読み込まれた -- [ ] 候補セクションのindexが抽出された -- [ ] セクション内容が読み込まれた - -### 2. Keyword Matching - -期待されるキーワードが回答に含まれているか: - -- **Threshold**: 80%以上のキーワードが含まれている -- キーワードの出現確認 -- 関連する技術用語の使用 - -### 3. Section Relevance - -適切なセクションが特定されたか: - -- [ ] expected_sectionsに含まれるセクションが特定された -- [ ] 関連性の高いセクション(High relevance)が優先された -- [ ] 不要なセクション(None relevance)が除外された - -### 4. Knowledge File Only - -知識ファイルのみを使って回答したか: - -- [ ] LLM訓練データを使用していない -- [ ] 外部知識を補足していない -- [ ] 知識ファイルに記載されている情報のみを使用 -- [ ] セクションの引用が明示されている - -### 5. Token Efficiency - -トークン効率が適切か: - -- **Target**: 5,000-15,000 tokens per query -- 無駄なファイル全体の読み込みがない -- セクション単位の抽出が機能している - -### 6. Tool Call Efficiency - -ツール呼び出し回数が適切か: - -- **Target**: 10-20 tool calls per query -- Read: index.toon読み込み (1回) -- Bash+jq: .index抽出 (5-10回) -- Bash+jq: .sections抽出 (5-10回) - -### 7. Code Analysis Workflow (code-analysis scenarios only) - -code-analysisワークフローが正しく実行されたか確認: - -- [ ] 対象コードが正しく識別された -- [ ] 依存関係が適切に分析された(Read, Grep, Glob使用) -- [ ] 構成要素が適切に分解された -- [ ] 関連するNablarch知識が検索された(keyword-search workflow実行) -- [ ] ドキュメントが生成された(Write tool使用) -- [ ] Markdown + Mermaid図形式で出力された -- [ ] ソースコードへの相対パスリンクが含まれている -- [ ] Nablarch知識ファイルへのリンクが含まれている - -### 8. Code Analysis Output Quality (code-analysis scenarios only) - -出力ドキュメントの品質が適切か: - -- [ ] Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている -- [ ] Mermaid図(依存関係図、シーケンス図)が適切に生成されている -- [ ] 構成要素の説明が明確である -- [ ] ソースコードへのリンクが正しい(相対パス) -- [ ] Nablarch知識の引用が適切である -- [ ] Expected Componentsが全て記載されている -- [ ] Expected Knowledgeが参照されている -- [ ] ファイルパス形式: `work/YYYYMMDD/code-analysis-.md` - ---- - -## Usage - -### Manual Testing - -各シナリオを個別にテスト: - -```bash -# Example: Test handlers-001 -"データリードハンドラでファイルを読み込むにはどうすればいいですか?" -``` - -期待される動作: -1. "keyword-searchワークフローを実行します"と表示 -2. Read index.toon -3. Bash+jq でセクション抽出 -4. 回答にキーワードが含まれる - -### Automated Testing - -エージェントを使った自動評価: - -```bash -# Load scenarios.json -# For each scenario: -# - Execute question -# - Evaluate workflow execution -# - Check keyword matching -# - Verify section relevance -# - Calculate token usage -# - Count tool calls -``` - ---- - -## Notes - -- すべてのシナリオは実在する知識ファイルに基づいています -- Expected sectionsは実際のファイル構造に基づく推定です -- 知識ファイルに該当セクションがない場合は、"この情報は知識ファイルに含まれていません"と回答されることが期待されます From 823b43d03c1b1da5a653833c26c8ff5ffc6170fb Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 18:11:51 +0900 Subject: [PATCH 42/89] docs: Simplify plugin versioning to two-digit format Simplified version scheme from semantic versioning (0.1.0) to a two-digit format (0.1) since the plugin name already indicates the major version (Nablarch 6). Added versioning documentation to README explaining the minor.patch scheme. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++---- .claude/skills/nabledge-6/plugin/README.md | 8 ++++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index d015ea5..acd229e 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -2,10 +2,9 @@ All notable changes to the nabledge-6 plugin will be documented in this file. -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.1.0] - 2026-02-12 +## [0.1] - 2026-02-12 ### Added - Initial release of nabledge-6 skill @@ -15,4 +14,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for RESTful web services (JAX-RS) - Coverage for Nablarch 6u2 and 6u3 -[0.1.0]: https://github.com/nablarch/nabledge/releases/tag/v0.1.0 +[0.1]: https://github.com/nablarch/nabledge/releases/tag/v0.1 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 0c9931f..a800ad2 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -58,6 +58,14 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skill - Web Applications (JSP/UI) - Messaging (MOM) +## Versioning + +This plugin uses a `minor.patch` versioning scheme: +- **Minor** (first digit): Incremented for feature additions (e.g., 0.1 → 1.0 → 2.0) +- **Patch** (second digit): Incremented for bug fixes and small changes (e.g., 0.1 → 0.2, 1.0 → 1.1) + +The plugin name `nabledge-6` already indicates the major version (Nablarch 6), so the plugin version itself uses a simplified two-digit format. This approach keeps versioning straightforward while maintaining clear compatibility with Nablarch 6. + ## License Apache-2.0 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index f827c32..26648ad 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.1.0", + "version": "0.1", "description": "Nablarch 6 skill for AI-assisted development", "author": "Nablarch", "license": "Apache-2.0", From 5c3426f23b7bb16a5f4bd334920239158442d1a0 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Thu, 12 Feb 2026 18:17:19 +0900 Subject: [PATCH 43/89] docs: Simplify coverage description in plugin metadata Updated CHANGELOG and README to use simpler, less detailed descriptions of coverage. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 ++++--- .claude/skills/nabledge-6/plugin/README.md | 18 +++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index acd229e..a730393 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -10,8 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Initial release of nabledge-6 skill - Knowledge search functionality for Nablarch 6 documentation - Code analysis capability with structured templates -- Support for batch processing (On-demand batch) -- Support for RESTful web services (JAX-RS) -- Coverage for Nablarch 6u2 and 6u3 +- Basic batch processing knowledge +- Database access libraries +- Testing framework basics +- Security checklist [0.1]: https://github.com/nablarch/nabledge/releases/tag/v0.1 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index a800ad2..a318a33 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -46,17 +46,13 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skill ### Nablarch Version - Nablarch 6u3 -### Supported Features -- On-demand Batch (FILE to DB, DB to DB, DB to FILE) -- RESTful Web Services (JAX-RS) -- Handlers and Libraries -- Tools and Testing - -### Out of Scope -- Jakarta Batch -- Resident Batch (Table Queue) -- Web Applications (JSP/UI) -- Messaging (MOM) +### Coverage +- Batch processing basics +- Database access +- Testing framework basics +- Security checklist + +Note: This is an initial release with limited coverage. More features will be added in future versions. ## Versioning From c2ad889a3db578a4f22e8f81280d11bba1e8996a Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:21:45 +0900 Subject: [PATCH 44/89] feat: Migrate to Claude Code marketplace structure This change migrates from single plugin distribution to marketplace structure, enabling multiple plugins (nabledge-6, future nabledge-5) to be distributed from a single repository. Changes: - Add marketplace.json catalog file for plugin listing - Add marketplace-README.md for marketplace overview - Update transform-to-plugin.sh to generate marketplace structure with plugins/ subdirectory - Enhance GitHub Action validation for marketplace structure (checks marketplace.json, plugin.json, and all required files) Distribution structure: .claude-plugin/marketplace.json # Catalog plugins/nabledge-6/ # Individual plugin README.md # Marketplace overview User installation: /plugin marketplace add nablarch/nabledge /plugin install nabledge-6@nablarch-nabledge Co-Authored-By: Claude Opus 4.6 --- .../nabledge-6/plugin/marketplace-README.md | 61 +++++++++++++++++++ .../skills/nabledge-6/plugin/marketplace.json | 21 +++++++ .github/scripts/transform-to-plugin.sh | 56 +++++++++-------- .github/workflows/sync-to-nabledge.yml | 48 ++++++++++++--- 4 files changed, 152 insertions(+), 34 deletions(-) create mode 100644 .claude/skills/nabledge-6/plugin/marketplace-README.md create mode 100644 .claude/skills/nabledge-6/plugin/marketplace.json diff --git a/.claude/skills/nabledge-6/plugin/marketplace-README.md b/.claude/skills/nabledge-6/plugin/marketplace-README.md new file mode 100644 index 0000000..b3646cd --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/marketplace-README.md @@ -0,0 +1,61 @@ +# Nablarch Skills Marketplace + +Nablarch skills for AI-assisted development using Claude Code and GitHub Copilot. + +## Available Plugins + +### nabledge-6 + +Nablarch 6 skill for AI-assisted development. + +**Features**: +- Knowledge Search: Search Nablarch 6 documentation and best practices +- Code Analysis: Analyze application code from Nablarch perspective + +**Installation**: +```bash +# Add marketplace +/plugin marketplace add nablarch/nabledge + +# Install nabledge-6 plugin +/plugin install nabledge-6@nablarch-nabledge +``` + +**Usage**: +```bash +# Basic usage +/nabledge-6 + +# Knowledge search +/nabledge-6 "How do I implement batch processing?" + +# Code analysis +/nabledge-6 code-analysis +``` + +**Coverage**: Nablarch 6u3 +- Batch processing basics +- Database access +- Testing framework basics +- Security checklist + +See [plugins/nabledge-6/README.md](plugins/nabledge-6/README.md) for details. + +### nabledge-5 (Coming Soon) + +Nablarch 5 skill for AI-assisted development will be available in the future. + +## Versioning + +Each plugin has independent versioning: +- **nabledge-6**: Uses `minor.patch` format (e.g., 0.1, 1.0, 2.0) +- Plugin name already indicates Nablarch major version + +## License + +Apache-2.0 + +## Links + +- Distribution Repository: https://github.com/nablarch/nabledge +- Development Repository: https://github.com/nablarch/nabledge-dev diff --git a/.claude/skills/nabledge-6/plugin/marketplace.json b/.claude/skills/nabledge-6/plugin/marketplace.json new file mode 100644 index 0000000..bf6f460 --- /dev/null +++ b/.claude/skills/nabledge-6/plugin/marketplace.json @@ -0,0 +1,21 @@ +{ + "name": "nablarch-nabledge", + "description": "Nablarch skills for AI-assisted development", + "owner": { + "name": "Nablarch" + }, + "homepage": "https://github.com/nablarch/nabledge", + "repository": { + "type": "git", + "url": "https://github.com/nablarch/nabledge" + }, + "license": "Apache-2.0", + "plugins": [ + { + "name": "nabledge-6", + "source": "./plugins/nabledge-6", + "description": "Nablarch 6 skill for AI-assisted development", + "version": "0.1" + } + ] +} diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index d08eef4..ff11494 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -1,13 +1,13 @@ #!/bin/bash set -e -# Transform nabledge-6 skill from development format to plugin format +# Transform nabledge skills from development format to marketplace format # Usage: ./transform-to-plugin.sh SOURCE_DIR="${1:-.}" DEST_DIR="${2:-nabledge-repo}" -echo "Transforming nabledge-6 skill to plugin format..." +echo "Transforming nabledge skills to marketplace format..." echo "Source: $SOURCE_DIR" echo "Destination: $DEST_DIR" @@ -17,35 +17,43 @@ if [ ! -d "$SOURCE_DIR/.claude/skills/nabledge-6" ]; then exit 1 fi -# Create plugin directories -echo "Creating plugin directory structure..." +# Create marketplace directories +echo "Creating marketplace directory structure..." mkdir -p "$DEST_DIR/.claude-plugin" -mkdir -p "$DEST_DIR/skills/nabledge-6" +mkdir -p "$DEST_DIR/plugins/nabledge-6/.claude-plugin" +mkdir -p "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6" -# Move SKILL.md to skills/nabledge-6/ -echo "Copying SKILL.md..." -cp "$SOURCE_DIR/.claude/skills/nabledge-6/SKILL.md" "$DEST_DIR/skills/nabledge-6/" +# Copy marketplace.json to root +echo "Copying marketplace.json..." +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace.json" "$DEST_DIR/.claude-plugin/" -# Move supporting directories to root -echo "Copying workflows..." -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/" +# Copy marketplace README and LICENSE to root +echo "Copying marketplace README and LICENSE..." +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace-README.md" "$DEST_DIR/README.md" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/" -echo "Copying assets..." -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/" +# Copy nabledge-6 plugin files +echo "Copying nabledge-6 plugin..." -echo "Copying knowledge..." -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/" +# Plugin metadata +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/plugin.json" "$DEST_DIR/plugins/nabledge-6/.claude-plugin/" -echo "Copying docs..." -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/" +# SKILL.md +cp "$SOURCE_DIR/.claude/skills/nabledge-6/SKILL.md" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" -# Move plugin files to root -echo "Copying plugin files..." -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/plugin.json" "$DEST_DIR/.claude-plugin/" -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/" -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/" -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/CHANGELOG.md" "$DEST_DIR/" +# Supporting directories +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/plugins/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/plugins/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/plugins/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6/" + +# Plugin-specific files +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/plugins/nabledge-6/" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/plugins/nabledge-6/" +cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/CHANGELOG.md" "$DEST_DIR/plugins/nabledge-6/" echo "Transformation complete!" echo "" -echo "Plugin structure created in: $DEST_DIR" +echo "Marketplace structure created in: $DEST_DIR" +echo " - Marketplace: $DEST_DIR/.claude-plugin/marketplace.json" +echo " - Plugin: $DEST_DIR/plugins/nabledge-6/" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index bedf05f..7e20ebe 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -51,16 +51,44 @@ jobs: # Append sync entry to CHANGELOG sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/CHANGELOG.md - - name: Validate plugin structure + - name: Validate marketplace structure run: | - # Check required files exist - test -f nabledge-repo/.claude-plugin/plugin.json - test -f nabledge-repo/skills/nabledge-6/SKILL.md - test -f nabledge-repo/README.md - test -f nabledge-repo/LICENSE - - # Validate plugin.json format - jq empty nabledge-repo/.claude-plugin/plugin.json + echo "Validating marketplace structure..." + + # Check marketplace files exist + test -f nabledge-repo/.claude-plugin/marketplace.json || { echo "Error: marketplace.json not found"; exit 1; } + test -f nabledge-repo/README.md || { echo "Error: Root README.md not found"; exit 1; } + test -f nabledge-repo/LICENSE || { echo "Error: Root LICENSE not found"; exit 1; } + + # Check nabledge-6 plugin structure + test -f nabledge-repo/plugins/nabledge-6/.claude-plugin/plugin.json || { echo "Error: nabledge-6/plugin.json not found"; exit 1; } + test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/SKILL.md || { echo "Error: nabledge-6/SKILL.md not found"; exit 1; } + test -f nabledge-repo/plugins/nabledge-6/README.md || { echo "Error: nabledge-6/README.md not found"; exit 1; } + test -f nabledge-repo/plugins/nabledge-6/LICENSE || { echo "Error: nabledge-6/LICENSE not found"; exit 1; } + test -f nabledge-repo/plugins/nabledge-6/CHANGELOG.md || { echo "Error: nabledge-6/CHANGELOG.md not found"; exit 1; } + + # Check nabledge-6 supporting directories + test -d nabledge-repo/plugins/nabledge-6/workflows || { echo "Error: nabledge-6/workflows not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/assets || { echo "Error: nabledge-6/assets not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/knowledge || { echo "Error: nabledge-6/knowledge not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/docs || { echo "Error: nabledge-6/docs not found"; exit 1; } + + # Validate JSON formats + echo "Validating JSON formats..." + jq empty nabledge-repo/.claude-plugin/marketplace.json || { echo "Error: Invalid marketplace.json"; exit 1; } + jq empty nabledge-repo/plugins/nabledge-6/.claude-plugin/plugin.json || { echo "Error: Invalid plugin.json"; exit 1; } + + # Validate marketplace.json structure + echo "Validating marketplace.json structure..." + jq -e '.name' nabledge-repo/.claude-plugin/marketplace.json > /dev/null || { echo "Error: marketplace.json missing 'name' field"; exit 1; } + jq -e '.plugins' nabledge-repo/.claude-plugin/marketplace.json > /dev/null || { echo "Error: marketplace.json missing 'plugins' array"; exit 1; } + + # Validate plugin.json structure + echo "Validating plugin.json structure..." + jq -e '.name' nabledge-repo/plugins/nabledge-6/.claude-plugin/plugin.json > /dev/null || { echo "Error: plugin.json missing 'name' field"; exit 1; } + jq -e '.version' nabledge-repo/plugins/nabledge-6/.claude-plugin/plugin.json > /dev/null || { echo "Error: plugin.json missing 'version' field"; exit 1; } + + echo "Marketplace structure validation passed!" - name: Configure Git working-directory: nabledge-repo @@ -81,6 +109,6 @@ jobs: TRIGGER_COMMIT_SHA="${{ github.sha }}" TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" - git commit -m "Sync nabledge-6 plugin from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" + git commit -m "Sync nabledge marketplace from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" git push origin dummy-to From 05fc76aa52f25b3e223cde78947fcf861e667e3b Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:22:45 +0900 Subject: [PATCH 45/89] docs: Update CHANGELOG for marketplace migration Add Unreleased section documenting the migration to Claude Code marketplace distribution structure. This satisfies the version validation requirement in the sync workflow. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index a730393..407d871 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] + +### Changed +- Migrated to Claude Code marketplace distribution structure +- Plugin now distributed via marketplace catalog (nablarch/nabledge) +- Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nablarch-nabledge` + ## [0.1] - 2026-02-12 ### Added From 837ed738efd80cb7fa07691ae15515083dd897ad Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:23:44 +0900 Subject: [PATCH 46/89] fix: Update CHANGELOG path for marketplace structure Fix the Update CHANGELOG.md step in GitHub Action to use the correct path for marketplace structure: plugins/nabledge-6/CHANGELOG.md instead of root CHANGELOG.md. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 7e20ebe..49da3a8 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -48,8 +48,8 @@ jobs: TRIGGER_COMMIT_URL="https://github.com/${{ github.repository }}/commit/${TRIGGER_COMMIT_SHA}" DATE=$(date +%Y-%m-%d) - # Append sync entry to CHANGELOG - sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/CHANGELOG.md + # Append sync entry to nabledge-6 plugin CHANGELOG + sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/plugins/nabledge-6/CHANGELOG.md - name: Validate marketplace structure run: | From 483f004f0699c466f7cfa202d54bb5c295c068c2 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:24:29 +0900 Subject: [PATCH 47/89] fix: Skip version validation for infrastructure-only changes Update version validation logic to skip the check when only infrastructure files are modified (.github/, marketplace files, transform script). This allows GitHub Action fixes to be deployed without requiring version bumps. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 49da3a8..71681dd 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -17,10 +17,28 @@ jobs: - name: Validate version updates run: | - # Check if plugin.json or CHANGELOG.md were modified in the last commit - if ! git diff HEAD~1 HEAD --name-only | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md"; then - echo "Error: plugin.json or CHANGELOG.md must be updated before sync" - exit 1 + # Get list of changed files + CHANGED_FILES=$(git diff HEAD~1 HEAD --name-only) + + # Check if only infrastructure files were changed + INFRA_ONLY=true + while IFS= read -r file; do + if [[ ! "$file" =~ ^\.github/ ]] && \ + [[ ! "$file" =~ plugin/marketplace ]] && \ + [[ "$file" != *"transform-to-plugin.sh"* ]]; then + INFRA_ONLY=false + break + fi + done <<< "$CHANGED_FILES" + + # If non-infrastructure files changed, require version update + if [ "$INFRA_ONLY" = false ]; then + if ! echo "$CHANGED_FILES" | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md"; then + echo "Error: plugin.json or CHANGELOG.md must be updated before sync" + exit 1 + fi + else + echo "Infrastructure-only changes detected, skipping version validation" fi - name: Checkout nabledge repository From 42f4c340acf0f5c0699a085565e16bfec54c0352 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:34:43 +0900 Subject: [PATCH 48/89] fix: Fix CHANGELOG newline formatting in GitHub Action Replace sed command with heredoc approach to properly format newlines in CHANGELOG.md. The previous sed command was outputting literal \n characters instead of actual newlines. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 71681dd..e9d7c6a 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -67,7 +67,27 @@ jobs: DATE=$(date +%Y-%m-%d) # Append sync entry to nabledge-6 plugin CHANGELOG - sed -i "/^# Changelog/a \\\n## [Unreleased] - ${DATE}\\\n\\\n### Changed\\\n- Synced from: ${TRIGGER_COMMIT_URL}\\\n" nabledge-repo/plugins/nabledge-6/CHANGELOG.md + CHANGELOG_FILE="nabledge-repo/plugins/nabledge-6/CHANGELOG.md" + TEMP_FILE=$(mktemp) + + # Read first line (# Changelog) + head -n 1 "$CHANGELOG_FILE" > "$TEMP_FILE" + + # Add new unreleased section + cat >> "$TEMP_FILE" <> "$TEMP_FILE" + + # Replace original file + mv "$TEMP_FILE" "$CHANGELOG_FILE" - name: Validate marketplace structure run: | From 098655dbce97f2e630c1dc1fa904266bb808f82b Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 10:36:05 +0900 Subject: [PATCH 49/89] fix: Use printf instead of heredoc for CHANGELOG update Replace heredoc with printf to avoid YAML syntax issues in GitHub Actions. This should properly format newlines without workflow errors. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index e9d7c6a..e2ec0cb 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -73,15 +73,8 @@ jobs: # Read first line (# Changelog) head -n 1 "$CHANGELOG_FILE" > "$TEMP_FILE" - # Add new unreleased section - cat >> "$TEMP_FILE" <> "$TEMP_FILE" # Append rest of original file tail -n +2 "$CHANGELOG_FILE" >> "$TEMP_FILE" From 0874506476e241b3fd9790e101f9ea0b0312e9ff Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:08:12 +0900 Subject: [PATCH 50/89] refactor: Move LICENSE to repository root Simplify license management by placing a single LICENSE file at the repository root instead of duplicating it in each plugin directory. The root LICENSE applies to the entire repository (marketplace + all plugins). Changes: - Move LICENSE from .claude/skills/nabledge-6/plugin/ to repository root - Update transform-to-plugin.sh to copy root LICENSE only - Remove plugin-level LICENSE validation from GitHub Action - Plugin directories no longer need individual LICENSE files This follows standard GitHub repository conventions where a root LICENSE applies to all contents. Co-Authored-By: Claude Opus 4.6 --- .github/scripts/transform-to-plugin.sh | 3 +-- .github/workflows/sync-to-nabledge.yml | 1 - .claude/skills/nabledge-6/plugin/LICENSE => LICENSE | 0 3 files changed, 1 insertion(+), 3 deletions(-) rename .claude/skills/nabledge-6/plugin/LICENSE => LICENSE (100%) diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index ff11494..13b5ac3 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -30,7 +30,7 @@ cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace.json" "$DEST_DIR/.c # Copy marketplace README and LICENSE to root echo "Copying marketplace README and LICENSE..." cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace-README.md" "$DEST_DIR/README.md" -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/" +cp "$SOURCE_DIR/LICENSE" "$DEST_DIR/" # Copy nabledge-6 plugin files echo "Copying nabledge-6 plugin..." @@ -49,7 +49,6 @@ cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6 # Plugin-specific files cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/plugins/nabledge-6/" -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/LICENSE" "$DEST_DIR/plugins/nabledge-6/" cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/CHANGELOG.md" "$DEST_DIR/plugins/nabledge-6/" echo "Transformation complete!" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index e2ec0cb..2e90d79 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -95,7 +95,6 @@ jobs: test -f nabledge-repo/plugins/nabledge-6/.claude-plugin/plugin.json || { echo "Error: nabledge-6/plugin.json not found"; exit 1; } test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/SKILL.md || { echo "Error: nabledge-6/SKILL.md not found"; exit 1; } test -f nabledge-repo/plugins/nabledge-6/README.md || { echo "Error: nabledge-6/README.md not found"; exit 1; } - test -f nabledge-repo/plugins/nabledge-6/LICENSE || { echo "Error: nabledge-6/LICENSE not found"; exit 1; } test -f nabledge-repo/plugins/nabledge-6/CHANGELOG.md || { echo "Error: nabledge-6/CHANGELOG.md not found"; exit 1; } # Check nabledge-6 supporting directories diff --git a/.claude/skills/nabledge-6/plugin/LICENSE b/LICENSE similarity index 100% rename from .claude/skills/nabledge-6/plugin/LICENSE rename to LICENSE From 0b02c923e6fdfd340f35ee19b6091977db0496f0 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:09:14 +0900 Subject: [PATCH 51/89] docs: Update CHANGELOG for LICENSE simplification Document the LICENSE simplification change in CHANGELOG to satisfy version validation requirement. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 407d871..c24ab58 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Migrated to Claude Code marketplace distribution structure - Plugin now distributed via marketplace catalog (nablarch/nabledge) - Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nablarch-nabledge` +- Simplified license management: single LICENSE at repository root applies to entire marketplace ## [0.1] - 2026-02-12 From 5a2b39efcedbb9d16e508fafbe8ceb7a779ae077 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:27:18 +0900 Subject: [PATCH 52/89] refactor: Simplify marketplace name to 'nabledge' Change marketplace name from 'nablarch-nabledge' to 'nabledge' for simplicity. This makes the plugin installation command shorter: - Before: /plugin install nabledge-6@nablarch-nabledge - After: /plugin install nabledge-6@nabledge Updated references in CHANGELOG and marketplace README. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 2 +- .claude/skills/nabledge-6/plugin/marketplace-README.md | 2 +- .claude/skills/nabledge-6/plugin/marketplace.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index c24ab58..fa93ab0 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Migrated to Claude Code marketplace distribution structure - Plugin now distributed via marketplace catalog (nablarch/nabledge) -- Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nablarch-nabledge` +- Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nabledge` - Simplified license management: single LICENSE at repository root applies to entire marketplace ## [0.1] - 2026-02-12 diff --git a/.claude/skills/nabledge-6/plugin/marketplace-README.md b/.claude/skills/nabledge-6/plugin/marketplace-README.md index b3646cd..55c16c8 100644 --- a/.claude/skills/nabledge-6/plugin/marketplace-README.md +++ b/.claude/skills/nabledge-6/plugin/marketplace-README.md @@ -18,7 +18,7 @@ Nablarch 6 skill for AI-assisted development. /plugin marketplace add nablarch/nabledge # Install nabledge-6 plugin -/plugin install nabledge-6@nablarch-nabledge +/plugin install nabledge-6@nabledge ``` **Usage**: diff --git a/.claude/skills/nabledge-6/plugin/marketplace.json b/.claude/skills/nabledge-6/plugin/marketplace.json index bf6f460..6359d12 100644 --- a/.claude/skills/nabledge-6/plugin/marketplace.json +++ b/.claude/skills/nabledge-6/plugin/marketplace.json @@ -1,5 +1,5 @@ { - "name": "nablarch-nabledge", + "name": "nabledge", "description": "Nablarch skills for AI-assisted development", "owner": { "name": "Nablarch" From ed8dd14f93c28caf05da5c3e86a396e3e7cde481 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:31:23 +0900 Subject: [PATCH 53/89] fix: Correct plugin.json schema to comply with Claude Code spec Fix plugin.json to match Claude Code's official plugin schema: - Change author from string to object: {"name": "Nablarch"} - Change repository from npm-style object to simple string URL - Remove unsupported engines field (npm-specific, not used by Claude Code) This resolves the installation error: "Plugin has an invalid manifest file. Validation errors: author: expected object, received string, repository: expected string, received object, engines: Unrecognized key" Based on official documentation and anthropics/claude-code examples. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 6 ++++++ .claude/skills/nabledge-6/plugin/plugin.json | 14 +++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index fa93ab0..c509fb3 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -12,6 +12,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nabledge` - Simplified license management: single LICENSE at repository root applies to entire marketplace +### Fixed +- Fix plugin.json schema to comply with Claude Code specification + - Changed author from string to object format + - Changed repository from object to string format + - Removed unsupported engines field + ## [0.1] - 2026-02-12 ### Added diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 26648ad..95205fc 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -2,16 +2,12 @@ "name": "nabledge-6", "version": "0.1", "description": "Nablarch 6 skill for AI-assisted development", - "author": "Nablarch", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/nablarch/nabledge" + "author": { + "name": "Nablarch" }, + "license": "Apache-2.0", + "repository": "https://github.com/nablarch/nabledge", "keywords": [ "nablarch" - ], - "engines": { - "claude": ">=1.0.0" - } + ] } From e99ea9736c68b31978891046f03bedb52d79fa5b Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:36:41 +0900 Subject: [PATCH 54/89] fix: Correct marketplace.json schema to comply with Claude Code spec Fix marketplace.json to match Claude Code's official marketplace schema: - Remove homepage, repository, license from root level (not defined in spec) - Move these fields into plugin entry where they are valid - Change repository from npm-style object to simple string URL Root level fields per official spec: - name (required) - owner (required) - plugins (required) - description (optional) Plugin metadata fields like homepage, repository, and license belong in the plugin entry, not at the marketplace root level. Based on official anthropics/claude-plugins-official examples. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 3 +++ .claude/skills/nabledge-6/plugin/marketplace.json | 11 ++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index c509fb3..61b1bdf 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -17,6 +17,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Changed author from string to object format - Changed repository from object to string format - Removed unsupported engines field +- Fix marketplace.json schema to comply with Claude Code specification + - Moved homepage, repository, license from root to plugin entry + - Changed repository from object to string format in plugin entry ## [0.1] - 2026-02-12 diff --git a/.claude/skills/nabledge-6/plugin/marketplace.json b/.claude/skills/nabledge-6/plugin/marketplace.json index 6359d12..dd75d17 100644 --- a/.claude/skills/nabledge-6/plugin/marketplace.json +++ b/.claude/skills/nabledge-6/plugin/marketplace.json @@ -4,18 +4,15 @@ "owner": { "name": "Nablarch" }, - "homepage": "https://github.com/nablarch/nabledge", - "repository": { - "type": "git", - "url": "https://github.com/nablarch/nabledge" - }, - "license": "Apache-2.0", "plugins": [ { "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.1" + "version": "0.1", + "homepage": "https://github.com/nablarch/nabledge", + "repository": "https://github.com/nablarch/nabledge", + "license": "Apache-2.0" } ] } From f428213220d7659bdc751f494ec314503997a6f0 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 11:52:36 +0900 Subject: [PATCH 55/89] docs: Rewrite documentation in Japanese for end users Rewrite all user-facing documentation in Japanese: - CHANGELOG.md: Simplify to initial release (0.1) only, remove development history - README.md: Complete Japanese translation for plugin users - marketplace-README.md: Complete Japanese translation for marketplace overview These files are intended for Nablarch users in Japan, so Japanese is more appropriate than English. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 32 ++-------- .claude/skills/nabledge-6/plugin/README.md | 64 ++++++++++--------- .../nabledge-6/plugin/marketplace-README.md | 60 ++++++++--------- 3 files changed, 71 insertions(+), 85 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 61b1bdf..315dcbd 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,32 +4,14 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [Unreleased] - -### Changed -- Migrated to Claude Code marketplace distribution structure -- Plugin now distributed via marketplace catalog (nablarch/nabledge) -- Users should install via: `/plugin marketplace add nablarch/nabledge` then `/plugin install nabledge-6@nabledge` -- Simplified license management: single LICENSE at repository root applies to entire marketplace - -### Fixed -- Fix plugin.json schema to comply with Claude Code specification - - Changed author from string to object format - - Changed repository from object to string format - - Removed unsupported engines field -- Fix marketplace.json schema to comply with Claude Code specification - - Moved homepage, repository, license from root to plugin entry - - Changed repository from object to string format in plugin entry - -## [0.1] - 2026-02-12 +## [0.1] - 2026-02-13 ### Added -- Initial release of nabledge-6 skill -- Knowledge search functionality for Nablarch 6 documentation -- Code analysis capability with structured templates -- Basic batch processing knowledge -- Database access libraries -- Testing framework basics -- Security checklist +- Nablarch 6u3の知識検索機能 +- コード分析機能(構造化テンプレート) +- バッチ処理の基礎知識 +- データベースアクセスライブラリ +- テスティングフレームワークの基礎 +- セキュリティチェックリスト [0.1]: https://github.com/nablarch/nabledge/releases/tag/v0.1 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index a318a33..1ecf01d 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -1,72 +1,76 @@ -# Nabledge-6 Plugin +# Nabledge-6 プラグイン -Nablarch 6 skill for AI-assisted development. +Nablarch 6のAI支援開発スキルです。 -## Features +## 機能 -- **Knowledge Search**: Search Nablarch 6 documentation and best practices -- **Code Analysis**: Analyze application code from Nablarch perspective +- **知識検索**: Nablarch 6のドキュメントとベストプラクティスを検索 +- **コード分析**: Nablarchの観点からアプリケーションコードを分析 -## Installation +## インストール -### For Claude Code (WSL) +### Claude Code ```bash +# マーケットプレイスを追加 /plugin marketplace add nablarch/nabledge + +# プラグインをインストール +/plugin install nabledge-6@nabledge ``` -### For GitHub Copilot (WSL or GitBash) +### GitHub Copilot (WSL / GitBash) ```bash curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash ``` -## Usage +## 使い方 -### Basic Usage +### 基本的な使い方 ```bash /nabledge-6 ``` -### Knowledge Search +### 知識検索 ```bash -/nabledge-6 "How do I implement batch processing?" +/nabledge-6 "バッチ処理の実装方法を教えて" ``` -### Code Analysis +### コード分析 ```bash /nabledge-6 code-analysis ``` -## Scope +## カバー範囲 -### Nablarch Version +### Nablarchバージョン - Nablarch 6u3 -### Coverage -- Batch processing basics -- Database access -- Testing framework basics -- Security checklist +### 対応内容 +- バッチ処理の基礎 +- データベースアクセス +- テスティングフレームワークの基礎 +- セキュリティチェックリスト -Note: This is an initial release with limited coverage. More features will be added in future versions. +注:初回リリースのため、カバー範囲は限定的です。今後のバージョンで機能を追加していきます。 -## Versioning +## バージョニング -This plugin uses a `minor.patch` versioning scheme: -- **Minor** (first digit): Incremented for feature additions (e.g., 0.1 → 1.0 → 2.0) -- **Patch** (second digit): Incremented for bug fixes and small changes (e.g., 0.1 → 0.2, 1.0 → 1.1) +このプラグインは `minor.patch` 形式のバージョニングを使用します: +- **Minor**(1桁目): 機能追加時にインクリメント(例: 0.1 → 1.0 → 2.0) +- **Patch**(2桁目): バグ修正と小変更時にインクリメント(例: 0.1 → 0.2, 1.0 → 1.1) -The plugin name `nabledge-6` already indicates the major version (Nablarch 6), so the plugin version itself uses a simplified two-digit format. This approach keeps versioning straightforward while maintaining clear compatibility with Nablarch 6. +プラグイン名 `nabledge-6` がすでにメジャーバージョン(Nablarch 6)を示しているため、プラグインバージョンは2桁の簡略形式を使用します。 -## License +## ライセンス Apache-2.0 -## Links +## リンク -- Distribution Repository: nablarch/nabledge -- Development Repository: nablarch/nabledge-dev +- 配布リポジトリ: https://github.com/nablarch/nabledge +- 開発リポジトリ: https://github.com/nablarch/nabledge-dev diff --git a/.claude/skills/nabledge-6/plugin/marketplace-README.md b/.claude/skills/nabledge-6/plugin/marketplace-README.md index 55c16c8..4b16fa6 100644 --- a/.claude/skills/nabledge-6/plugin/marketplace-README.md +++ b/.claude/skills/nabledge-6/plugin/marketplace-README.md @@ -1,61 +1,61 @@ -# Nablarch Skills Marketplace +# Nablarch スキルマーケットプレイス -Nablarch skills for AI-assisted development using Claude Code and GitHub Copilot. +Claude CodeとGitHub Copilot向けのNablarch AI支援開発スキルです。 -## Available Plugins +## 利用可能なプラグイン ### nabledge-6 -Nablarch 6 skill for AI-assisted development. +Nablarch 6のAI支援開発スキルです。 -**Features**: -- Knowledge Search: Search Nablarch 6 documentation and best practices -- Code Analysis: Analyze application code from Nablarch perspective +**機能**: +- 知識検索: Nablarch 6のドキュメントとベストプラクティスを検索 +- コード分析: Nablarchの観点からアプリケーションコードを分析 -**Installation**: +**インストール**: ```bash -# Add marketplace +# マーケットプレイスを追加 /plugin marketplace add nablarch/nabledge -# Install nabledge-6 plugin +# nabledge-6 プラグインをインストール /plugin install nabledge-6@nabledge ``` -**Usage**: +**使い方**: ```bash -# Basic usage +# 基本的な使い方 /nabledge-6 -# Knowledge search -/nabledge-6 "How do I implement batch processing?" +# 知識検索 +/nabledge-6 "バッチ処理の実装方法を教えて" -# Code analysis +# コード分析 /nabledge-6 code-analysis ``` -**Coverage**: Nablarch 6u3 -- Batch processing basics -- Database access -- Testing framework basics -- Security checklist +**カバー範囲**: Nablarch 6u3 +- バッチ処理の基礎 +- データベースアクセス +- テスティングフレームワークの基礎 +- セキュリティチェックリスト -See [plugins/nabledge-6/README.md](plugins/nabledge-6/README.md) for details. +詳細は [plugins/nabledge-6/README.md](plugins/nabledge-6/README.md) を参照してください。 ### nabledge-5 (Coming Soon) -Nablarch 5 skill for AI-assisted development will be available in the future. +Nablarch 5のAI支援開発スキルは今後提供予定です。 -## Versioning +## バージョニング -Each plugin has independent versioning: -- **nabledge-6**: Uses `minor.patch` format (e.g., 0.1, 1.0, 2.0) -- Plugin name already indicates Nablarch major version +各プラグインは独立したバージョン管理を行っています: +- **nabledge-6**: `minor.patch` 形式を使用(例: 0.1, 1.0, 2.0) +- プラグイン名がすでにNablarchのメジャーバージョンを示しています -## License +## ライセンス Apache-2.0 -## Links +## リンク -- Distribution Repository: https://github.com/nablarch/nabledge -- Development Repository: https://github.com/nablarch/nabledge-dev +- 配布リポジトリ: https://github.com/nablarch/nabledge +- 開発リポジトリ: https://github.com/nablarch/nabledge-dev From 764e6a915cc1f3962217dbf7bb13ce73a3b4722a Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 12:51:39 +0900 Subject: [PATCH 56/89] refactor: Move marketplace files to .claude/marketplace directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address PR review feedback: 1. Move marketplace files from .claude/skills/nabledge-6/plugin/ to .claude/marketplace/ - marketplace.json → .claude/marketplace/.claude-plugin/marketplace.json - marketplace-README.md → .claude/marketplace/README.md - LICENSE (copy) → .claude/marketplace/LICENSE 2. Add command explanations to plugin README: - /nabledge-6: Basic skill invocation for interactive questions - /nabledge-6 "query": Knowledge search with specific questions - /nabledge-6 code-analysis: Analyze project code from Nablarch perspective 3. Update transform script and GitHub Action to use new marketplace location This provides clearer separation between marketplace metadata and plugin files. Co-Authored-By: Claude Opus 4.6 --- .../.claude-plugin}/marketplace.json | 0 .claude/marketplace/LICENSE | 16 ++++++++++++++++ .../README.md} | 0 .claude/skills/nabledge-6/plugin/README.md | 6 ++++++ .github/scripts/transform-to-plugin.sh | 9 +++++++-- .github/workflows/sync-to-nabledge.yml | 6 +++--- 6 files changed, 32 insertions(+), 5 deletions(-) rename .claude/{skills/nabledge-6/plugin => marketplace/.claude-plugin}/marketplace.json (100%) create mode 100644 .claude/marketplace/LICENSE rename .claude/{skills/nabledge-6/plugin/marketplace-README.md => marketplace/README.md} (100%) diff --git a/.claude/skills/nabledge-6/plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json similarity index 100% rename from .claude/skills/nabledge-6/plugin/marketplace.json rename to .claude/marketplace/.claude-plugin/marketplace.json diff --git a/.claude/marketplace/LICENSE b/.claude/marketplace/LICENSE new file mode 100644 index 0000000..0e072a6 --- /dev/null +++ b/.claude/marketplace/LICENSE @@ -0,0 +1,16 @@ +Apache License +Version 2.0, January 2004 + +Copyright 2026 Nablarch + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/.claude/skills/nabledge-6/plugin/marketplace-README.md b/.claude/marketplace/README.md similarity index 100% rename from .claude/skills/nabledge-6/plugin/marketplace-README.md rename to .claude/marketplace/README.md diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 1ecf01d..7481479 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -33,18 +33,24 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skill /nabledge-6 ``` +スキルを起動し、対話的にNablarchに関する質問や、コード分析を行うことができます。 + ### 知識検索 ```bash /nabledge-6 "バッチ処理の実装方法を教えて" ``` +Nablarch 6のドキュメントやベストプラクティスから知識を検索し、回答を得ることができます。質問は日本語でも英語でも可能です。 + ### コード分析 ```bash /nabledge-6 code-analysis ``` +現在のプロジェクトのコードをNablarchの観点から分析します。Actionクラス、ハンドラ構成、データベースアクセスパターンなどを評価し、改善提案を提供します。 + ## カバー範囲 ### Nablarchバージョン diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index 13b5ac3..673cb00 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -17,6 +17,11 @@ if [ ! -d "$SOURCE_DIR/.claude/skills/nabledge-6" ]; then exit 1 fi +if [ ! -d "$SOURCE_DIR/.claude/marketplace" ]; then + echo "Error: Source directory does not contain .claude/marketplace" + exit 1 +fi + # Create marketplace directories echo "Creating marketplace directory structure..." mkdir -p "$DEST_DIR/.claude-plugin" @@ -25,11 +30,11 @@ mkdir -p "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6" # Copy marketplace.json to root echo "Copying marketplace.json..." -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace.json" "$DEST_DIR/.claude-plugin/" +cp "$SOURCE_DIR/.claude/marketplace/.claude-plugin/marketplace.json" "$DEST_DIR/.claude-plugin/" # Copy marketplace README and LICENSE to root echo "Copying marketplace README and LICENSE..." -cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/marketplace-README.md" "$DEST_DIR/README.md" +cp "$SOURCE_DIR/.claude/marketplace/README.md" "$DEST_DIR/README.md" cp "$SOURCE_DIR/LICENSE" "$DEST_DIR/" # Copy nabledge-6 plugin files diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 2e90d79..9a0d86e 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -24,7 +24,7 @@ jobs: INFRA_ONLY=true while IFS= read -r file; do if [[ ! "$file" =~ ^\.github/ ]] && \ - [[ ! "$file" =~ plugin/marketplace ]] && \ + [[ ! "$file" =~ \.claude/marketplace ]] && \ [[ "$file" != *"transform-to-plugin.sh"* ]]; then INFRA_ONLY=false break @@ -33,8 +33,8 @@ jobs: # If non-infrastructure files changed, require version update if [ "$INFRA_ONLY" = false ]; then - if ! echo "$CHANGED_FILES" | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md"; then - echo "Error: plugin.json or CHANGELOG.md must be updated before sync" + if ! echo "$CHANGED_FILES" | grep -q "plugin/plugin.json\|plugin/CHANGELOG.md\|marketplace/.claude-plugin/marketplace.json"; then + echo "Error: plugin.json, CHANGELOG.md, or marketplace.json must be updated before sync" exit 1 fi else From 011f3b9754db2566117c4efcf1bf5e653f6cccb6 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 13:02:48 +0900 Subject: [PATCH 57/89] docs: Add CHANGELOG management rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create .claude/rules/changelog.md documenting CHANGELOG maintenance rules: - Structure and format (Keep a Changelog) - Development flow (Unreleased → Version) - When to include Unreleased section (not for initial release) - Change categories (Added/Changed/Fixed/etc.) - Version update requirements This clarifies that Unreleased section should only be added when next development begins, not for initial release. Co-Authored-By: Claude Opus 4.6 --- .claude/rules/changelog.md | 106 +++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 .claude/rules/changelog.md diff --git a/.claude/rules/changelog.md b/.claude/rules/changelog.md new file mode 100644 index 0000000..461a5db --- /dev/null +++ b/.claude/rules/changelog.md @@ -0,0 +1,106 @@ +# CHANGELOG Management + +## Location + +- **File**: `.claude/skills/nabledge-6/plugin/CHANGELOG.md` +- **Format**: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) + +## Structure + +```markdown +# Changelog + +All notable changes to the nabledge-6 plugin will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [Unreleased] + +### Added +- New features + +### Changed +- Changes in existing functionality + +### Fixed +- Bug fixes + +## [0.2] - 2026-XX-XX + +### Added +- Released features + +## [0.1] - 2026-02-13 + +### Added +- Initial release content +``` + +## Development Flow + +### 1. During Development + +Add changes under `## [Unreleased]` section: + +```markdown +## [Unreleased] + +### Added +- New batch processing feature + +### Fixed +- Knowledge search accuracy improvement +``` + +### 2. Before Release + +1. Replace `[Unreleased]` with version number and date +2. Create new empty `[Unreleased]` section at top + +**Before**: +```markdown +## [Unreleased] + +### Added +- New feature X +``` + +**After**: +```markdown +## [Unreleased] + +## [0.2] - 2026-02-20 + +### Added +- New feature X + +## [0.1] - 2026-02-13 +... +``` + +### 3. Initial Release + +For initial release (0.1), **do not include** `[Unreleased]` section. + +Start adding `[Unreleased]` section only when next development begins. + +## Change Categories + +| Category | Description | Example | +|----------|-------------|---------| +| **Added** | New features | New knowledge search functionality | +| **Changed** | Changes in existing functionality | Updated command syntax | +| **Deprecated** | Soon-to-be removed features | Old API marked as deprecated | +| **Removed** | Removed features | Deleted unused workflow | +| **Fixed** | Bug fixes | Fixed search accuracy | +| **Security** | Security fixes | Fixed XSS vulnerability | + +## Version Update Rule + +CHANGELOG must be updated when: +- Adding new features (Added) +- Modifying existing features (Changed) +- Fixing bugs (Fixed) +- Removing features (Removed) + +Infrastructure changes (GitHub Actions, transform scripts) do not require CHANGELOG updates. From d312fa3cc91c52a6061e2b7ac7cda454b75d19c0 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 13:04:48 +0900 Subject: [PATCH 58/89] fix: Add .claude/rules/ to infrastructure file patterns Fix version validation to recognize .claude/rules/ as infrastructure files. Documentation and development rules in .claude/rules/ should not require plugin version updates. This fixes the GitHub Action failure for the CHANGELOG rules commit. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 9a0d86e..ebeead7 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -24,7 +24,8 @@ jobs: INFRA_ONLY=true while IFS= read -r file; do if [[ ! "$file" =~ ^\.github/ ]] && \ - [[ ! "$file" =~ \.claude/marketplace ]] && \ + [[ ! "$file" =~ ^\.claude/marketplace ]] && \ + [[ ! "$file" =~ ^\.claude/rules/ ]] && \ [[ "$file" != *"transform-to-plugin.sh"* ]]; then INFRA_ONLY=false break From d9638165e2e38298cd39eb7ffaca3b7fe8ee490f Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 13:35:13 +0900 Subject: [PATCH 59/89] docs: Improve README user-facing language and structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace technical terms with user-friendly language - Change "カバー範囲" to "対応範囲" (coverage scope) - Organize into "できること" and "今後対応予定" sections - Change "初回リリース" to "評価版" (evaluation version) - Remove versioning, license, and links from plugin README - Keep common sections only in marketplace README Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/README.md | 18 +++++++--- .claude/skills/nabledge-6/plugin/README.md | 38 +++++++--------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/.claude/marketplace/README.md b/.claude/marketplace/README.md index 4b16fa6..cbccde8 100644 --- a/.claude/marketplace/README.md +++ b/.claude/marketplace/README.md @@ -33,11 +33,19 @@ Nablarch 6のAI支援開発スキルです。 /nabledge-6 code-analysis ``` -**カバー範囲**: Nablarch 6u3 -- バッチ処理の基礎 -- データベースアクセス -- テスティングフレームワークの基礎 -- セキュリティチェックリスト +**対応範囲**: Nablarch 6u3 + +できること: +- バッチ処理の基礎知識の検索 +- データベースアクセスの実装方法の検索 +- テスティングフレームワークの使い方の検索 +- セキュリティチェックリストの確認 +- プロジェクトコードのNablarch観点での分析 + +今後対応予定: +- RESTful Webサービスの知識 +- ハンドラの詳細仕様 +- より詳細なコード分析機能 詳細は [plugins/nabledge-6/README.md](plugins/nabledge-6/README.md) を参照してください。 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 7481479..8809e2e 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -51,32 +51,18 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 現在のプロジェクトのコードをNablarchの観点から分析します。Actionクラス、ハンドラ構成、データベースアクセスパターンなどを評価し、改善提案を提供します。 -## カバー範囲 +## 対応範囲(Nablarch 6u3) -### Nablarchバージョン -- Nablarch 6u3 +### できること +- バッチ処理の基礎知識の検索 +- データベースアクセスの実装方法の検索 +- テスティングフレームワークの使い方の検索 +- セキュリティチェックリストの確認 +- プロジェクトコードのNablarch観点での分析 -### 対応内容 -- バッチ処理の基礎 -- データベースアクセス -- テスティングフレームワークの基礎 -- セキュリティチェックリスト +### 今後対応予定 +- RESTful Webサービスの知識 +- ハンドラの詳細仕様 +- より詳細なコード分析機能 -注:初回リリースのため、カバー範囲は限定的です。今後のバージョンで機能を追加していきます。 - -## バージョニング - -このプラグインは `minor.patch` 形式のバージョニングを使用します: -- **Minor**(1桁目): 機能追加時にインクリメント(例: 0.1 → 1.0 → 2.0) -- **Patch**(2桁目): バグ修正と小変更時にインクリメント(例: 0.1 → 0.2, 1.0 → 1.1) - -プラグイン名 `nabledge-6` がすでにメジャーバージョン(Nablarch 6)を示しているため、プラグインバージョンは2桁の簡略形式を使用します。 - -## ライセンス - -Apache-2.0 - -## リンク - -- 配布リポジトリ: https://github.com/nablarch/nabledge -- 開発リポジトリ: https://github.com/nablarch/nabledge-dev +注:評価版のため、対応範囲は限定的です。フィードバックをもとに機能を拡充していきます。 From 4bff68bcf2da9a211dd6b221674eb495d5328d39 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 13:36:18 +0900 Subject: [PATCH 60/89] docs: Update CHANGELOG for README improvements Document README changes in Unreleased section as per CHANGELOG management rules. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 315dcbd..b59b1fd 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [Unreleased] + +### Changed +- READMEの表現を改善:「カバー範囲」を「対応範囲」に変更し、「できること」と「今後対応予定」に分類 +- 「初回リリース」を「評価版」に変更してより適切な表現に改善 +- 共通セクション(バージョニング、ライセンス、リンク)をマーケットプレイスREADMEに集約 + ## [0.1] - 2026-02-13 ### Added From 80cef5c7436aa63335666cbd3cc39a19a617ff96 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 14:15:40 +0900 Subject: [PATCH 61/89] fix: Remove Unreleased section from initial release CHANGELOG Initial release (0.1) should not include Unreleased section. Unreleased section will be added when next development begins. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index b59b1fd..315dcbd 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,13 +4,6 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [Unreleased] - -### Changed -- READMEの表現を改善:「カバー範囲」を「対応範囲」に変更し、「できること」と「今後対応予定」に分類 -- 「初回リリース」を「評価版」に変更してより適切な表現に改善 -- 共通セクション(バージョニング、ライセンス、リンク)をマーケットプレイスREADMEに集約 - ## [0.1] - 2026-02-13 ### Added From 35caec6f5c115192dc1db23658aa226ee2c72f4e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 14:20:15 +0900 Subject: [PATCH 62/89] docs: Restructure READMEs with knowledge and workflow sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marketplace README: - Add clear explanation of Nabledge's purpose - Explain why coding agents need Nablarch-specific knowledge - Simplify plugin table with status column Plugin README: - Separate features into "知識" (knowledge) and "ワークフロー" (workflow) - Clarify current coverage and future plans for both categories - Add future workflow examples (impact analysis, code review) Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/README.md | 63 +++++----------------- .claude/skills/nabledge-6/plugin/README.md | 52 +++++++++++------- 2 files changed, 45 insertions(+), 70 deletions(-) diff --git a/.claude/marketplace/README.md b/.claude/marketplace/README.md index cbccde8..2fa87e0 100644 --- a/.claude/marketplace/README.md +++ b/.claude/marketplace/README.md @@ -1,62 +1,23 @@ -# Nablarch スキルマーケットプレイス +# Nabledge -Claude CodeとGitHub Copilot向けのNablarch AI支援開発スキルです。 +Nabledgeは、NablarchによるAI支援開発スキルです。Claude CodeやGitHub Copilotといったコーディングエージェントに対して、Nablarchの知識とワークフローを提供します。 -## 利用可能なプラグイン +コーディングエージェントはNablarchのような企業フレームワークの知識を十分に持っていません。Nabledgeを導入することで、エージェントがNablarchのドキュメントやベストプラクティスを参照しながら開発を支援できるようになります。 -### nabledge-6 +## プラグイン -Nablarch 6のAI支援開発スキルです。 +| プラグイン | 対応バージョン | 状態 | +|-----------|-------------|------| +| [nabledge-6](plugins/nabledge-6/README.md) | Nablarch 6u3 | 提供中 | +| nabledge-5 | Nablarch 5 | 今後提供予定 | -**機能**: -- 知識検索: Nablarch 6のドキュメントとベストプラクティスを検索 -- コード分析: Nablarchの観点からアプリケーションコードを分析 - -**インストール**: -```bash -# マーケットプレイスを追加 -/plugin marketplace add nablarch/nabledge - -# nabledge-6 プラグインをインストール -/plugin install nabledge-6@nabledge -``` - -**使い方**: -```bash -# 基本的な使い方 -/nabledge-6 - -# 知識検索 -/nabledge-6 "バッチ処理の実装方法を教えて" - -# コード分析 -/nabledge-6 code-analysis -``` - -**対応範囲**: Nablarch 6u3 - -できること: -- バッチ処理の基礎知識の検索 -- データベースアクセスの実装方法の検索 -- テスティングフレームワークの使い方の検索 -- セキュリティチェックリストの確認 -- プロジェクトコードのNablarch観点での分析 - -今後対応予定: -- RESTful Webサービスの知識 -- ハンドラの詳細仕様 -- より詳細なコード分析機能 - -詳細は [plugins/nabledge-6/README.md](plugins/nabledge-6/README.md) を参照してください。 - -### nabledge-5 (Coming Soon) - -Nablarch 5のAI支援開発スキルは今後提供予定です。 +インストール方法や使い方は各プラグインのREADMEを参照してください。 ## バージョニング -各プラグインは独立したバージョン管理を行っています: -- **nabledge-6**: `minor.patch` 形式を使用(例: 0.1, 1.0, 2.0) +各プラグインは独立したバージョン管理を行っています。 + +- nabledge-6: `minor.patch` 形式を使用(例: 0.1, 1.0, 2.0) - プラグイン名がすでにNablarchのメジャーバージョンを示しています ## ライセンス diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 8809e2e..75aea22 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -1,11 +1,41 @@ -# Nabledge-6 プラグイン +# Nabledge-6 Nablarch 6のAI支援開発スキルです。 ## 機能 -- **知識検索**: Nablarch 6のドキュメントとベストプラクティスを検索 -- **コード分析**: Nablarchの観点からアプリケーションコードを分析 +Nabledge-6は **知識** と **ワークフロー** の2種類の機能を提供します。 + +### 知識 + +Nablarch 6のドキュメントやベストプラクティスをエージェントが参照できるようにします。 + +現在カバーしている領域: + +- バッチ処理の基礎知識 +- データベースアクセスの実装方法 +- テスティングフレームワークの使い方 +- セキュリティチェックリスト + +今後追加予定の領域: + +- RESTful Webサービス +- ハンドラの詳細仕様 + +### ワークフロー + +Nablarchの知識を活用した開発支援ワークフローを提供します。 + +現在提供しているワークフロー: + +- **コード分析**: Nablarchの観点からプロジェクトコードを分析し、改善提案を行う + +今後追加予定のワークフロー: + +- **影響調査**: 変更による影響範囲をNablarchの構造を踏まえて調査 +- **コードレビュー**: Nablarchの規約やベストプラクティスに基づくレビュー + +注:評価版のため、知識・ワークフローともにカバー範囲は限定的です。フィードバックをもとに拡充していきます。 ## インストール @@ -50,19 +80,3 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 ``` 現在のプロジェクトのコードをNablarchの観点から分析します。Actionクラス、ハンドラ構成、データベースアクセスパターンなどを評価し、改善提案を提供します。 - -## 対応範囲(Nablarch 6u3) - -### できること -- バッチ処理の基礎知識の検索 -- データベースアクセスの実装方法の検索 -- テスティングフレームワークの使い方の検索 -- セキュリティチェックリストの確認 -- プロジェクトコードのNablarch観点での分析 - -### 今後対応予定 -- RESTful Webサービスの知識 -- ハンドラの詳細仕様 -- より詳細なコード分析機能 - -注:評価版のため、対応範囲は限定的です。フィードバックをもとに機能を拡充していきます。 From 78d6740194c7b6d296cdc278a90e46f29f6947e3 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 14:26:21 +0900 Subject: [PATCH 63/89] chore: Bump version to 0.2 for development Added version 0.2 with README restructuring changes: - Categorized features into knowledge and workflow sections - Enhanced marketplace README with purpose explanation - Simplified plugin table with status column Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/.claude-plugin/marketplace.json | 2 +- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index dd75d17..19f6dce 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.1", + "version": "0.2", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 315dcbd..35bfb00 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2] - 2026-02-13 + +### Changed +- 機能セクションを「知識」と「ワークフロー」に分類 +- マーケットプレイスREADMEにNabledgeの目的と必要性を明記 +- プラグイン一覧を状態列付きテーブル形式に変更 + ## [0.1] - 2026-02-13 ### Added diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 95205fc..81f21ab 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.1", + "version": "0.2", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From b5d6e55a0ad3892ba1d9ae11263e5f02e2865bcd Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:19:22 +0900 Subject: [PATCH 64/89] feat: Add team setup and version tagging GitHub Action: - Add automatic Git tag creation based on plugin.json version - Tags are created in v{version} format (e.g., v0.3) - Skip tag creation if tag already exists on remote Documentation: - Add team setup instructions with project-scoped installation - Add .claude/settings.json configuration examples - Add version update methods for Claude Code and GitHub Copilot - Add --scope project option to installation commands Version: 0.2 -> 0.3 Co-Authored-By: Claude Opus 4.6 --- .../.claude-plugin/marketplace.json | 2 +- .claude/marketplace/README.md | 62 +++++++++++++++++ .claude/skills/nabledge-6/plugin/CHANGELOG.md | 11 +++ .claude/skills/nabledge-6/plugin/README.md | 68 +++++++++++++++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .github/workflows/sync-to-nabledge.yml | 21 ++++++ 6 files changed, 164 insertions(+), 2 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index 19f6dce..508f9bd 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.2", + "version": "0.3", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/marketplace/README.md b/.claude/marketplace/README.md index 2fa87e0..b156df8 100644 --- a/.claude/marketplace/README.md +++ b/.claude/marketplace/README.md @@ -13,6 +13,68 @@ Nabledgeは、NablarchによるAI支援開発スキルです。Claude CodeやGit インストール方法や使い方は各プラグインのREADMEを参照してください。 +## チーム設定 + +プロジェクトメンバー全員がNabledgeプラグインを利用できるよう、プロジェクトスコープで設定できます。 + +### 設定方法 + +プロジェクトルートに `.claude/settings.json` を作成し、以下を追加: + +```json +{ + "extraKnownMarketplaces": [ + { + "name": "nabledge", + "source": "https://github.com/nablarch/nabledge.git" + } + ], + "enabledPlugins": { + "nabledge-6@nabledge": { + "enabled": true + } + } +} +``` + +このファイルをGitにコミットすると、チームメンバーがリポジトリをクローンした際に自動的にプラグインのインストールが促されます。 + +### VS Codeでの設定 + +VS Codeでは `.vscode/settings.json` に以下を追加: + +```json +{ + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "Nablarch framework knowledge is available via nabledge-6 skill" + } + ] +} +``` + +### バージョンアップ + +#### Claude Code + +マーケットプレイスは起動時に自動更新されます。手動で更新する場合: + +```bash +# マーケットプレイスを更新 +/plugin marketplace update nabledge + +# 特定バージョンを指定する場合 +/plugin marketplace add nablarch/nabledge#v0.2 +``` + +#### VS Code (GitHub Copilot) + +最新版を再インストール: + +```bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash +``` + ## バージョニング 各プラグインは独立したバージョン管理を行っています。 diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 35bfb00..c3a3a91 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.3] - 2026-02-13 + +### Added +- チーム設定方法をREADMEに追加(プロジェクトスコープインストール) +- バージョンアップ方法を追加(Claude Code、GitHub Copilot) +- 自動タグ作成機能をGitHub Actionに追加 + +### Changed +- インストールコマンドに`--scope project`オプションを追加 +- マーケットプレイスREADMEにバージョン管理情報を追加 + ## [0.2] - 2026-02-13 ### Changed diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 75aea22..5d27665 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -41,6 +41,8 @@ Nablarchの知識を活用した開発支援ワークフローを提供します ### Claude Code +#### 個人用インストール + ```bash # マーケットプレイスを追加 /plugin marketplace add nablarch/nabledge @@ -49,6 +51,38 @@ Nablarchの知識を活用した開発支援ワークフローを提供します /plugin install nabledge-6@nabledge ``` +#### チーム設定(推奨) + +プロジェクトメンバー全員で利用する場合は、プロジェクトスコープでインストール: + +```bash +# マーケットプレイスを追加 +/plugin marketplace add nablarch/nabledge + +# プロジェクトスコープでインストール +/plugin install nabledge-6@nabledge --scope project +``` + +または、`.claude/settings.json` に直接記述: + +```json +{ + "extraKnownMarketplaces": [ + { + "name": "nabledge", + "source": "https://github.com/nablarch/nabledge.git" + } + ], + "enabledPlugins": { + "nabledge-6@nabledge": { + "enabled": true + } + } +} +``` + +このファイルをGitにコミットすると、チームメンバーがリポジトリをクローンした際に自動的にプラグインのインストールが促されます。 + ### GitHub Copilot (WSL / GitBash) ```bash @@ -80,3 +114,37 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 ``` 現在のプロジェクトのコードをNablarchの観点から分析します。Actionクラス、ハンドラ構成、データベースアクセスパターンなどを評価し、改善提案を提供します。 + +## バージョンアップ + +### Claude Code + +マーケットプレイスは起動時に自動更新されます。手動で更新する場合: + +```bash +# マーケットプレイスを更新(最新版を取得) +/plugin marketplace update nabledge + +# 特定バージョンを指定する場合 +/plugin marketplace add nablarch/nabledge#v0.2 +``` + +プラグインを再インストール: + +```bash +/plugin install nabledge-6@nabledge +``` + +### GitHub Copilot (WSL / GitBash) + +セットアップスクリプトを再実行: + +```bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash +``` + +特定バージョンを指定する場合: + +```bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/v0.2/.claude/skills/nabledge-6/scripts/setup.sh | bash +``` diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 81f21ab..ffd083c 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.2", + "version": "0.3", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index ebeead7..77cad06 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -143,3 +143,24 @@ jobs: git commit -m "Sync nabledge marketplace from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" git push origin dummy-to + + - name: Create and push version tag + working-directory: nabledge-repo + run: | + # Extract version from plugin.json + VERSION=$(jq -r '.version' plugins/nabledge-6/.claude-plugin/plugin.json) + TAG_NAME="v${VERSION}" + + echo "Creating tag: ${TAG_NAME}" + + # Check if tag already exists on remote + if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}"; then + echo "Tag ${TAG_NAME} already exists on remote, skipping tag creation" + exit 0 + fi + + # Create and push tag + git tag -a "${TAG_NAME}" -m "Release version ${VERSION}" + git push origin "${TAG_NAME}" + + echo "Successfully created and pushed tag: ${TAG_NAME}" From cf8f142391437883f3493152d0543ccb44842f66 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:27:12 +0900 Subject: [PATCH 65/89] docs: Simplify READMEs for team-first setup Marketplace README: - Remove team setup section to keep it simple - Keep only plugin list and links Plugin README: - Focus on team setup (no personal installation) - Simplify to "create settings.json and push to Git" for Claude Code - Simplify to "run setup script and push .claude directory" for GitHub Copilot - Remove unnecessary details about --scope project option Version: 0.3 -> 0.4 Co-Authored-By: Claude Opus 4.6 --- .../.claude-plugin/marketplace.json | 2 +- .claude/marketplace/README.md | 62 ------------------- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++ .claude/skills/nabledge-6/plugin/README.md | 57 +++++++---------- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 5 files changed, 30 insertions(+), 100 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index 508f9bd..aef8950 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.3", + "version": "0.4", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/marketplace/README.md b/.claude/marketplace/README.md index b156df8..2fa87e0 100644 --- a/.claude/marketplace/README.md +++ b/.claude/marketplace/README.md @@ -13,68 +13,6 @@ Nabledgeは、NablarchによるAI支援開発スキルです。Claude CodeやGit インストール方法や使い方は各プラグインのREADMEを参照してください。 -## チーム設定 - -プロジェクトメンバー全員がNabledgeプラグインを利用できるよう、プロジェクトスコープで設定できます。 - -### 設定方法 - -プロジェクトルートに `.claude/settings.json` を作成し、以下を追加: - -```json -{ - "extraKnownMarketplaces": [ - { - "name": "nabledge", - "source": "https://github.com/nablarch/nabledge.git" - } - ], - "enabledPlugins": { - "nabledge-6@nabledge": { - "enabled": true - } - } -} -``` - -このファイルをGitにコミットすると、チームメンバーがリポジトリをクローンした際に自動的にプラグインのインストールが促されます。 - -### VS Codeでの設定 - -VS Codeでは `.vscode/settings.json` に以下を追加: - -```json -{ - "github.copilot.chat.codeGeneration.instructions": [ - { - "text": "Nablarch framework knowledge is available via nabledge-6 skill" - } - ] -} -``` - -### バージョンアップ - -#### Claude Code - -マーケットプレイスは起動時に自動更新されます。手動で更新する場合: - -```bash -# マーケットプレイスを更新 -/plugin marketplace update nabledge - -# 特定バージョンを指定する場合 -/plugin marketplace add nablarch/nabledge#v0.2 -``` - -#### VS Code (GitHub Copilot) - -最新版を再インストール: - -```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash -``` - ## バージョニング 各プラグインは独立したバージョン管理を行っています。 diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index c3a3a91..a1c49ff 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.4] - 2026-02-13 + +### Changed +- READMEをチーム設定前提に簡素化 +- マーケットプレイスREADMEをシンプルな構成に戻す +- インストール手順を「settings.jsonをGitにプッシュ」「.claudeディレクトリをGitにプッシュ」に明確化 + ## [0.3] - 2026-02-13 ### Added diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 5d27665..e72447a 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -41,29 +41,7 @@ Nablarchの知識を活用した開発支援ワークフローを提供します ### Claude Code -#### 個人用インストール - -```bash -# マーケットプレイスを追加 -/plugin marketplace add nablarch/nabledge - -# プラグインをインストール -/plugin install nabledge-6@nabledge -``` - -#### チーム設定(推奨) - -プロジェクトメンバー全員で利用する場合は、プロジェクトスコープでインストール: - -```bash -# マーケットプレイスを追加 -/plugin marketplace add nablarch/nabledge - -# プロジェクトスコープでインストール -/plugin install nabledge-6@nabledge --scope project -``` - -または、`.claude/settings.json` に直接記述: +プロジェクトルートに `.claude/settings.json` を作成: ```json { @@ -81,14 +59,18 @@ Nablarchの知識を活用した開発支援ワークフローを提供します } ``` -このファイルをGitにコミットすると、チームメンバーがリポジトリをクローンした際に自動的にプラグインのインストールが促されます。 +このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンすると、自動的にプラグインのインストールが促されます。 ### GitHub Copilot (WSL / GitBash) +プロジェクトルートで以下のコマンドを実行: + ```bash curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash ``` +実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 + ## 使い方 ### 基本的な使い方 @@ -119,21 +101,22 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 ### Claude Code -マーケットプレイスは起動時に自動更新されます。手動で更新する場合: +マーケットプレイスは起動時に自動更新されます。 -```bash -# マーケットプレイスを更新(最新版を取得) -/plugin marketplace update nabledge +特定バージョンを指定したい場合は、`.claude/settings.json` を編集: -# 特定バージョンを指定する場合 -/plugin marketplace add nablarch/nabledge#v0.2 +```json +{ + "extraKnownMarketplaces": [ + { + "name": "nabledge", + "source": "https://github.com/nablarch/nabledge.git#v0.3" + } + ] +} ``` -プラグインを再インストール: - -```bash -/plugin install nabledge-6@nabledge -``` +変更後、ファイルをGitにコミット・プッシュしてください。 ### GitHub Copilot (WSL / GitBash) @@ -146,5 +129,7 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skill 特定バージョンを指定する場合: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/v0.2/.claude/skills/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/v0.3/.claude/skills/nabledge-6/scripts/setup.sh | bash ``` + +更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index ffd083c..4728d4f 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.3", + "version": "0.4", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 0c2c9acc9e84aed6db3d1e2cd88a880c5f1165ec Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:30:02 +0900 Subject: [PATCH 66/89] docs: Fix Claude Code installation to use commands Changed from manual settings.json creation to command-based installation: - Use /plugin install with --scope project - settings.json is automatically updated by commands - Commit the updated settings.json to Git - Version specification also uses commands (marketplace re-add with tag) Version: 0.4 -> 0.5 Co-Authored-By: Claude Opus 4.6 --- .../.claude-plugin/marketplace.json | 2 +- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++ .claude/skills/nabledge-6/plugin/README.md | 44 +++++++------------ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 4 files changed, 24 insertions(+), 31 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index aef8950..66c5e5d 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.4", + "version": "0.5", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index a1c49ff..9515450 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.5] - 2026-02-13 + +### Changed +- Claude Codeのインストール手順をコマンドベースに修正 +- settings.jsonは手動作成ではなく、コマンド実行で自動更新される流れを明記 +- バージョン指定もコマンドで実行(マーケットプレイス再追加) + ## [0.4] - 2026-02-13 ### Changed diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index e72447a..8b77d62 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -41,25 +41,17 @@ Nablarchの知識を活用した開発支援ワークフローを提供します ### Claude Code -プロジェクトルートに `.claude/settings.json` を作成: - -```json -{ - "extraKnownMarketplaces": [ - { - "name": "nabledge", - "source": "https://github.com/nablarch/nabledge.git" - } - ], - "enabledPlugins": { - "nabledge-6@nabledge": { - "enabled": true - } - } -} +プロジェクトルートで以下のコマンドを実行: + +```bash +# マーケットプレイスを追加 +/plugin marketplace add nablarch/nabledge + +# プロジェクトスコープでインストール +/plugin install nabledge-6@nabledge --scope project ``` -このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンすると、自動的にプラグインのインストールが促されます。 +実行後、`.claude/settings.json`が自動的に更新されます。このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンすると、自動的にプラグインのインストールが促されます。 ### GitHub Copilot (WSL / GitBash) @@ -103,20 +95,14 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 マーケットプレイスは起動時に自動更新されます。 -特定バージョンを指定したい場合は、`.claude/settings.json` を編集: - -```json -{ - "extraKnownMarketplaces": [ - { - "name": "nabledge", - "source": "https://github.com/nablarch/nabledge.git#v0.3" - } - ] -} +特定バージョンを指定したい場合は、マーケットプレイスを再追加: + +```bash +# 特定バージョンをタグで指定 +/plugin marketplace add nablarch/nabledge#v0.4 ``` -変更後、ファイルをGitにコミット・プッシュしてください。 +実行後、更新された`.claude/settings.json`をGitにコミット・プッシュしてください。 ### GitHub Copilot (WSL / GitBash) diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 4728d4f..48db5c2 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.4", + "version": "0.5", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 289630e5025c2ddc7b265238913654e2b107ef35 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:34:57 +0900 Subject: [PATCH 67/89] fix: Correct auto-update behavior in documentation User-added marketplaces do NOT auto-update by default (only official Anthropic marketplaces do). Changed version update instructions: - Removed incorrect "auto-update at startup" statement - Added manual update command: /plugin marketplace update nabledge - Kept specific version specification with tag Version: 0.5 -> 0.6 Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/.claude-plugin/marketplace.json | 2 +- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 6 ++++++ .claude/skills/nabledge-6/plugin/README.md | 8 ++++++-- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index 66c5e5d..9c7faff 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.5", + "version": "0.6", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 9515450..147a5ba 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.6] - 2026-02-13 + +### Fixed +- バージョンアップ手順の誤りを修正:ユーザー追加マーケットプレイスは自動更新されない +- 手動更新コマンド `/plugin marketplace update nabledge` を追加 + ## [0.5] - 2026-02-13 ### Changed diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 8b77d62..d67b992 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -93,13 +93,17 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 ### Claude Code -マーケットプレイスは起動時に自動更新されます。 +最新版に更新: + +```bash +/plugin marketplace update nabledge +``` 特定バージョンを指定したい場合は、マーケットプレイスを再追加: ```bash # 特定バージョンをタグで指定 -/plugin marketplace add nablarch/nabledge#v0.4 +/plugin marketplace add nablarch/nabledge#v0.5 ``` 実行後、更新された`.claude/settings.json`をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 48db5c2..eb42231 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.5", + "version": "0.6", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 7fe7b2f7ac630e573089dfd72f0f714c834ada0f Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:43:26 +0900 Subject: [PATCH 68/89] docs: Remove specific version specification instructions Simplified version update instructions to only support latest version: - Removed tag-based version specification for Claude Code - Removed version-specific URL for GitHub Copilot - Focus on straightforward "update to latest" workflow Version: 0.6 -> 0.7 Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/.claude-plugin/marketplace.json | 2 +- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 5 +++++ .claude/skills/nabledge-6/plugin/README.md | 13 ------------- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index 9c7faff..961cb2b 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.6", + "version": "0.7", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 147a5ba..76e9266 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.7] - 2026-02-13 + +### Removed +- 特定バージョン指定の手順を削除(最新版への更新のみをサポート) + ## [0.6] - 2026-02-13 ### Fixed diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index d67b992..93f8513 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -99,13 +99,6 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 /plugin marketplace update nabledge ``` -特定バージョンを指定したい場合は、マーケットプレイスを再追加: - -```bash -# 特定バージョンをタグで指定 -/plugin marketplace add nablarch/nabledge#v0.5 -``` - 実行後、更新された`.claude/settings.json`をGitにコミット・プッシュしてください。 ### GitHub Copilot (WSL / GitBash) @@ -116,10 +109,4 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash ``` -特定バージョンを指定する場合: - -```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/v0.3/.claude/skills/nabledge-6/scripts/setup.sh | bash -``` - 更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index eb42231..b524642 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.6", + "version": "0.7", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 8069dc72b418eb2bd9516148d357765cdec4d908 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:47:41 +0900 Subject: [PATCH 69/89] chore: Reset to version 0.1 for initial release Simplified CHANGELOG to only include user-facing features: - Removed development versions 0.2-0.7 - Kept only version 0.1 with end-user relevant features - Reset version numbers to 0.1 in plugin.json and marketplace.json Version: 0.7 -> 0.1 (initial release) Co-Authored-By: Claude Opus 4.6 --- .../.claude-plugin/marketplace.json | 2 +- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 43 ------------------- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 3 files changed, 2 insertions(+), 45 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index 961cb2b..dd75d17 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -9,7 +9,7 @@ "name": "nabledge-6", "source": "./plugins/nabledge-6", "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.7", + "version": "0.1", "homepage": "https://github.com/nablarch/nabledge", "repository": "https://github.com/nablarch/nabledge", "license": "Apache-2.0" diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 76e9266..315dcbd 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,49 +4,6 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.7] - 2026-02-13 - -### Removed -- 特定バージョン指定の手順を削除(最新版への更新のみをサポート) - -## [0.6] - 2026-02-13 - -### Fixed -- バージョンアップ手順の誤りを修正:ユーザー追加マーケットプレイスは自動更新されない -- 手動更新コマンド `/plugin marketplace update nabledge` を追加 - -## [0.5] - 2026-02-13 - -### Changed -- Claude Codeのインストール手順をコマンドベースに修正 -- settings.jsonは手動作成ではなく、コマンド実行で自動更新される流れを明記 -- バージョン指定もコマンドで実行(マーケットプレイス再追加) - -## [0.4] - 2026-02-13 - -### Changed -- READMEをチーム設定前提に簡素化 -- マーケットプレイスREADMEをシンプルな構成に戻す -- インストール手順を「settings.jsonをGitにプッシュ」「.claudeディレクトリをGitにプッシュ」に明確化 - -## [0.3] - 2026-02-13 - -### Added -- チーム設定方法をREADMEに追加(プロジェクトスコープインストール) -- バージョンアップ方法を追加(Claude Code、GitHub Copilot) -- 自動タグ作成機能をGitHub Actionに追加 - -### Changed -- インストールコマンドに`--scope project`オプションを追加 -- マーケットプレイスREADMEにバージョン管理情報を追加 - -## [0.2] - 2026-02-13 - -### Changed -- 機能セクションを「知識」と「ワークフロー」に分類 -- マーケットプレイスREADMEにNabledgeの目的と必要性を明記 -- プラグイン一覧を状態列付きテーブル形式に変更 - ## [0.1] - 2026-02-13 ### Added diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index b524642..95205fc 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.7", + "version": "0.1", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 809a70e89bb66d39b8c6ff8608cf7abf6d800785 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 15:52:56 +0900 Subject: [PATCH 70/89] fix: Use marketplace LICENSE instead of root LICENSE Changed transform script to copy LICENSE from .claude/marketplace/ instead of repository root for consistency: - README.md comes from .claude/marketplace/ - LICENSE should also come from .claude/marketplace/ - Root LICENSE is for nabledge-dev repository itself Co-Authored-By: Claude Opus 4.6 --- .github/scripts/transform-to-plugin.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index 673cb00..514c1a2 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -35,7 +35,7 @@ cp "$SOURCE_DIR/.claude/marketplace/.claude-plugin/marketplace.json" "$DEST_DIR/ # Copy marketplace README and LICENSE to root echo "Copying marketplace README and LICENSE..." cp "$SOURCE_DIR/.claude/marketplace/README.md" "$DEST_DIR/README.md" -cp "$SOURCE_DIR/LICENSE" "$DEST_DIR/" +cp "$SOURCE_DIR/.claude/marketplace/LICENSE" "$DEST_DIR/" # Copy nabledge-6 plugin files echo "Copying nabledge-6 plugin..." From 3f195e503cb35e0dcc110288591e271624b72cfd Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:04:46 +0900 Subject: [PATCH 71/89] refactor: Remove duplicate metadata from marketplace.json Removed duplicate fields that are already defined in plugin.json: - version - description - homepage - repository - license According to Claude Code spec, plugin.json takes priority. Keep only required fields (name, source) in marketplace.json to avoid double maintenance. Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/.claude-plugin/marketplace.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index dd75d17..f7a4f46 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -7,12 +7,7 @@ "plugins": [ { "name": "nabledge-6", - "source": "./plugins/nabledge-6", - "description": "Nablarch 6 skill for AI-assisted development", - "version": "0.1", - "homepage": "https://github.com/nablarch/nabledge", - "repository": "https://github.com/nablarch/nabledge", - "license": "Apache-2.0" + "source": "./plugins/nabledge-6" } ] } From 4821b33dc3efb28b5636969a5b656fa69512e298 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:08:21 +0900 Subject: [PATCH 72/89] chore: Remove 'v' prefix from version tags Changed tag naming from v0.1 to 0.1 format. Tags now match the version number exactly without prefix. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 77cad06..8010f1a 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -149,7 +149,7 @@ jobs: run: | # Extract version from plugin.json VERSION=$(jq -r '.version' plugins/nabledge-6/.claude-plugin/plugin.json) - TAG_NAME="v${VERSION}" + TAG_NAME="${VERSION}" echo "Creating tag: ${TAG_NAME}" From 29a6b7e7f447a3d541bbe31c6a04a788e8930563 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:09:53 +0900 Subject: [PATCH 73/89] fix: Update CHANGELOG link to match tag format without 'v' prefix Changed release link from v0.1 to 0.1 to match the new tag format. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 315dcbd..ecb1a68 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -14,4 +14,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト -[0.1]: https://github.com/nablarch/nabledge/releases/tag/v0.1 +[0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 From 9fb9bbeb5d2c8863ae8524dee1dfdb04d1d7e2a5 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:16:37 +0900 Subject: [PATCH 74/89] fix: Copy scripts directory to distribution repository Added scripts directory to transform-to-plugin.sh so that setup.sh for GitHub Copilot installation is included in the distribution repository. Co-Authored-By: Claude Opus 4.6 --- .github/scripts/transform-to-plugin.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index 514c1a2..1ec3203 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -51,6 +51,7 @@ cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/plugins/nable cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/plugins/nabledge-6/" cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/plugins/nabledge-6/" cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/scripts" "$DEST_DIR/plugins/nabledge-6/" # Plugin-specific files cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/plugins/nabledge-6/" From 2ca93320d9fa1a6694e2bdb2023d480f2c345455 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:19:19 +0900 Subject: [PATCH 75/89] fix: Fix setup.sh to match distribution repository structure Changed setup.sh to: - Download from plugins/nabledge-6 instead of .claude - Create .claude/skills/nabledge-6/ structure in target project - Work outside of git repositories - Save PROJECT_ROOT path correctly Version: 0.1 -> 0.2 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .claude/skills/nabledge-6/scripts/setup.sh | 29 +++++++++++++------ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index ecb1a68..11cae1e 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2] - 2026-02-13 + +### Fixed +- setup.shのバグ修正:配布リポジトリの構造に合わせてコピー処理を修正 +- Gitリポジトリ外でも実行可能に改善 + ## [0.1] - 2026-02-13 ### Added @@ -14,4 +20,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 95205fc..81f21ab 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.1", + "version": "0.2", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup.sh index e5d53db..2f503ee 100755 --- a/.claude/skills/nabledge-6/scripts/setup.sh +++ b/.claude/skills/nabledge-6/scripts/setup.sh @@ -1,28 +1,39 @@ #!/bin/bash set -e -# Navigate to repository root -cd "$(git rev-parse --show-toplevel)" +# Navigate to repository root (or current directory if not in git repo) +if git rev-parse --show-toplevel &>/dev/null; then + PROJECT_ROOT="$(git rev-parse --show-toplevel)" +else + PROJECT_ROOT="$(pwd)" +fi echo "Setting up Nabledge-6 skill for GitHub Copilot..." +echo "Project root: $PROJECT_ROOT" -# Download .claude directory from nablarch/nabledge repository +# Download nabledge-6 plugin from nablarch/nabledge repository REPO_URL="https://github.com/nablarch/nabledge" TEMP_DIR=$(mktemp -d) -echo "Downloading .claude directory from $REPO_URL..." +echo "Downloading nabledge-6 plugin from $REPO_URL..." cd "$TEMP_DIR" git clone --depth 1 --filter=blob:none --sparse "$REPO_URL" cd nabledge -git sparse-checkout set .claude +git sparse-checkout set plugins/nabledge-6 -# Copy .claude directory to project root -echo "Copying .claude directory to project..." -cd - -cp -r "$TEMP_DIR/nabledge/.claude" . +# Create .claude/skills directory structure in project +echo "Creating .claude/skills directory structure..." +mkdir -p "$PROJECT_ROOT/.claude/skills" + +# Copy nabledge-6 plugin to .claude/skills/ +echo "Copying nabledge-6 plugin to project..." +cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6" "$PROJECT_ROOT/.claude/skills/" # Clean up rm -rf "$TEMP_DIR" +echo "" echo "Setup complete! The nabledge-6 skill is now available in your project." +echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6/" +echo "" echo "You can use it with GitHub Copilot by typing '/nabledge-6' in your editor." From 3a501159a0fdcca543e74d70f2be720079318c3e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:21:07 +0900 Subject: [PATCH 76/89] fix: Correct setup.sh URL paths in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed URLs from development repository structure to distribution structure: - .claude/skills/nabledge-6/scripts/setup.sh → plugins/nabledge-6/scripts/setup.sh Version: 0.2 -> 0.3 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 6 ++++++ .claude/skills/nabledge-6/plugin/README.md | 4 ++-- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 11cae1e..e5b147b 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.3] - 2026-02-13 + +### Fixed +- READMEのsetup.sh URLを配布リポジトリのパスに修正(.claude/skills/ → plugins/) + ## [0.2] - 2026-02-13 ### Fixed @@ -20,5 +25,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.3]: https://github.com/nablarch/nabledge/releases/tag/0.3 [0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 93f8513..3bf71c1 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -58,7 +58,7 @@ Nablarchの知識を活用した開発支援ワークフローを提供します プロジェクトルートで以下のコマンドを実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/scripts/setup.sh | bash ``` 実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 @@ -106,7 +106,7 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 セットアップスクリプトを再実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/.claude/skills/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/scripts/setup.sh | bash ``` 更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 81f21ab..ffd083c 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.2", + "version": "0.3", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From 503eab667383c54808d01abbf319ce2699cda859 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:29:20 +0900 Subject: [PATCH 77/89] fix: Restructure setup.sh to correctly deploy skill structure Changed setup.sh to properly transform distribution structure to user project structure: Distribution (marketplace): plugins/nabledge-6/ skills/nabledge-6/SKILL.md workflows/ assets/ knowledge/ docs/ scripts/ User project (after setup): .claude/skills/nabledge-6/ SKILL.md workflows/ assets/ knowledge/ docs/ scripts/ - Copy skills/nabledge-6/* content to .claude/skills/nabledge-6/ root - Copy supporting directories from plugin root - Skip .claude-plugin/ (not needed in user project) Version: 0.3 -> 0.4 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 8 ++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .claude/skills/nabledge-6/scripts/setup.sh | 25 +++++++++++++------ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index e5b147b..9bbb7b1 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.4] - 2026-02-13 + +### Fixed +- setup.shを修正:配布リポジトリ構造から利用者向けskill構造に正しく展開 +- skills/nabledge-6/の内容を.claude/skills/nabledge-6/直下に配置 +- 不要な.claude-plugin/をコピーしないように修正 + ## [0.3] - 2026-02-13 ### Fixed @@ -25,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.4]: https://github.com/nablarch/nabledge/releases/tag/0.4 [0.3]: https://github.com/nablarch/nabledge/releases/tag/0.3 [0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index ffd083c..4728d4f 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.3", + "version": "0.4", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup.sh index 2f503ee..93c7856 100755 --- a/.claude/skills/nabledge-6/scripts/setup.sh +++ b/.claude/skills/nabledge-6/scripts/setup.sh @@ -21,19 +21,30 @@ git clone --depth 1 --filter=blob:none --sparse "$REPO_URL" cd nabledge git sparse-checkout set plugins/nabledge-6 -# Create .claude/skills directory structure in project -echo "Creating .claude/skills directory structure..." -mkdir -p "$PROJECT_ROOT/.claude/skills" +# Create .claude/skills/nabledge-6 directory +SKILL_DIR="$PROJECT_ROOT/.claude/skills/nabledge-6" +echo "Creating skill directory structure..." +mkdir -p "$SKILL_DIR" + +# Copy skill files from plugins/nabledge-6/skills/nabledge-6/ to .claude/skills/nabledge-6/ +echo "Copying skill files..." +if [ -d "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6" ]; then + cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6/"* "$SKILL_DIR/" +fi -# Copy nabledge-6 plugin to .claude/skills/ -echo "Copying nabledge-6 plugin to project..." -cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6" "$PROJECT_ROOT/.claude/skills/" +# Copy supporting directories from plugin root to skill directory +echo "Copying supporting directories..." +for dir in workflows assets knowledge docs scripts; do + if [ -d "$TEMP_DIR/nabledge/plugins/nabledge-6/$dir" ]; then + cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/$dir" "$SKILL_DIR/" + fi +done # Clean up rm -rf "$TEMP_DIR" echo "" echo "Setup complete! The nabledge-6 skill is now available in your project." -echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6/" +echo "Location: $SKILL_DIR" echo "" echo "You can use it with GitHub Copilot by typing '/nabledge-6' in your editor." From 9c36e504a5068490ec47209d2fdf8fd986560ace Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:34:21 +0900 Subject: [PATCH 78/89] chore: Update setup.sh to use dummy-to branch for testing Changed setup.sh to explicitly clone from dummy-to branch for testing. This will be changed to main branch before final release. Version: 0.4 -> 0.5 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 6 ++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .claude/skills/nabledge-6/scripts/setup.sh | 5 +++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 9bbb7b1..07346c4 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.5] - 2026-02-13 + +### Fixed +- setup.shのブランチ指定をdummy-toに変更(テスト用) + ## [0.4] - 2026-02-13 ### Fixed @@ -32,6 +37,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.5]: https://github.com/nablarch/nabledge/releases/tag/0.5 [0.4]: https://github.com/nablarch/nabledge/releases/tag/0.4 [0.3]: https://github.com/nablarch/nabledge/releases/tag/0.3 [0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 4728d4f..48db5c2 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.4", + "version": "0.5", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup.sh index 93c7856..ac9ed39 100755 --- a/.claude/skills/nabledge-6/scripts/setup.sh +++ b/.claude/skills/nabledge-6/scripts/setup.sh @@ -13,11 +13,12 @@ echo "Project root: $PROJECT_ROOT" # Download nabledge-6 plugin from nablarch/nabledge repository REPO_URL="https://github.com/nablarch/nabledge" +BRANCH="dummy-to" TEMP_DIR=$(mktemp -d) -echo "Downloading nabledge-6 plugin from $REPO_URL..." +echo "Downloading nabledge-6 plugin from $REPO_URL (branch: $BRANCH)..." cd "$TEMP_DIR" -git clone --depth 1 --filter=blob:none --sparse "$REPO_URL" +git clone --depth 1 --filter=blob:none --sparse --branch "$BRANCH" "$REPO_URL" cd nabledge git sparse-checkout set plugins/nabledge-6 From 32bc45811e4c46defb720968ba937d3d1615472e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:45:43 +0900 Subject: [PATCH 79/89] fix: Unify skill directory structure for distribution and usage Changed structure so distribution and usage are identical: Distribution (marketplace): plugins/nabledge-6/skills/nabledge-6/ SKILL.md workflows/ assets/ knowledge/ docs/ scripts/ Usage (after setup): .claude/skills/nabledge-6/ SKILL.md workflows/ assets/ knowledge/ docs/ scripts/ Changes: - transform-to-plugin.sh: Copy supporting dirs into skills/nabledge-6/ - setup.sh: Simplified to copy skills/nabledge-6/ as-is Version: 0.5 -> 0.6 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 ++++++ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .claude/skills/nabledge-6/scripts/setup.sh | 25 ++++++------------- .github/scripts/transform-to-plugin.sh | 14 +++++------ 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 07346c4..85f982f 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.6] - 2026-02-13 + +### Fixed +- スキルディレクトリ構成を修正:配布時と利用時で同じ構造に統一 +- workflows/等をskills/nabledge-6/の中に配置 + ## [0.5] - 2026-02-13 ### Fixed @@ -37,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.6]: https://github.com/nablarch/nabledge/releases/tag/0.6 [0.5]: https://github.com/nablarch/nabledge/releases/tag/0.5 [0.4]: https://github.com/nablarch/nabledge/releases/tag/0.4 [0.3]: https://github.com/nablarch/nabledge/releases/tag/0.3 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 48db5c2..eb42231 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.5", + "version": "0.6", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup.sh index ac9ed39..58364fd 100755 --- a/.claude/skills/nabledge-6/scripts/setup.sh +++ b/.claude/skills/nabledge-6/scripts/setup.sh @@ -22,30 +22,19 @@ git clone --depth 1 --filter=blob:none --sparse --branch "$BRANCH" "$REPO_URL" cd nabledge git sparse-checkout set plugins/nabledge-6 -# Create .claude/skills/nabledge-6 directory -SKILL_DIR="$PROJECT_ROOT/.claude/skills/nabledge-6" -echo "Creating skill directory structure..." -mkdir -p "$SKILL_DIR" - -# Copy skill files from plugins/nabledge-6/skills/nabledge-6/ to .claude/skills/nabledge-6/ -echo "Copying skill files..." -if [ -d "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6" ]; then - cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6/"* "$SKILL_DIR/" -fi +# Create .claude/skills directory +echo "Creating .claude/skills directory..." +mkdir -p "$PROJECT_ROOT/.claude/skills" -# Copy supporting directories from plugin root to skill directory -echo "Copying supporting directories..." -for dir in workflows assets knowledge docs scripts; do - if [ -d "$TEMP_DIR/nabledge/plugins/nabledge-6/$dir" ]; then - cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/$dir" "$SKILL_DIR/" - fi -done +# Copy skills/nabledge-6 directory as-is +echo "Copying nabledge-6 skill to project..." +cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6" "$PROJECT_ROOT/.claude/skills/" # Clean up rm -rf "$TEMP_DIR" echo "" echo "Setup complete! The nabledge-6 skill is now available in your project." -echo "Location: $SKILL_DIR" +echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6" echo "" echo "You can use it with GitHub Copilot by typing '/nabledge-6' in your editor." diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index 1ec3203..77c54d8 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -43,15 +43,13 @@ echo "Copying nabledge-6 plugin..." # Plugin metadata cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/plugin.json" "$DEST_DIR/plugins/nabledge-6/.claude-plugin/" -# SKILL.md +# Copy skill content (SKILL.md and supporting directories) cp "$SOURCE_DIR/.claude/skills/nabledge-6/SKILL.md" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" - -# Supporting directories -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/plugins/nabledge-6/" -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/plugins/nabledge-6/" -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/plugins/nabledge-6/" -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6/" -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/scripts" "$DEST_DIR/plugins/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" +cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/scripts" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" # Plugin-specific files cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/plugins/nabledge-6/" From 4858db3e39ae4b37182bc3edf3ef57b235e74d1e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:46:33 +0900 Subject: [PATCH 80/89] fix: Update validation to match new skill directory structure Updated GitHub Action validation to check for supporting directories inside skills/nabledge-6/ instead of at plugin root. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/sync-to-nabledge.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 8010f1a..78a5c3d 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -98,11 +98,11 @@ jobs: test -f nabledge-repo/plugins/nabledge-6/README.md || { echo "Error: nabledge-6/README.md not found"; exit 1; } test -f nabledge-repo/plugins/nabledge-6/CHANGELOG.md || { echo "Error: nabledge-6/CHANGELOG.md not found"; exit 1; } - # Check nabledge-6 supporting directories - test -d nabledge-repo/plugins/nabledge-6/workflows || { echo "Error: nabledge-6/workflows not found"; exit 1; } - test -d nabledge-repo/plugins/nabledge-6/assets || { echo "Error: nabledge-6/assets not found"; exit 1; } - test -d nabledge-repo/plugins/nabledge-6/knowledge || { echo "Error: nabledge-6/knowledge not found"; exit 1; } - test -d nabledge-repo/plugins/nabledge-6/docs || { echo "Error: nabledge-6/docs not found"; exit 1; } + # Check nabledge-6 supporting directories (inside skills/nabledge-6/) + test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/workflows || { echo "Error: nabledge-6/skills/nabledge-6/workflows not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/assets || { echo "Error: nabledge-6/skills/nabledge-6/assets not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/knowledge || { echo "Error: nabledge-6/skills/nabledge-6/knowledge not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/docs || { echo "Error: nabledge-6/skills/nabledge-6/docs not found"; exit 1; } # Validate JSON formats echo "Validating JSON formats..." From 9395c88dd19619610e535e3bd01268220b4bee54 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 16:52:49 +0900 Subject: [PATCH 81/89] fix: Update setup.sh URL in README to match new structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed URL path to reflect scripts directory inside skills/nabledge-6/: - plugins/nabledge-6/scripts/setup.sh → plugins/nabledge-6/skills/nabledge-6/scripts/setup.sh Version: 0.6 -> 0.7 Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 6 ++++++ .claude/skills/nabledge-6/plugin/README.md | 4 ++-- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 85f982f..23439fd 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.7] - 2026-02-13 + +### Fixed +- READMEのsetup.sh URLをskills/nabledge-6/配下のパスに修正 + ## [0.6] - 2026-02-13 ### Fixed @@ -43,6 +48,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.7]: https://github.com/nablarch/nabledge/releases/tag/0.7 [0.6]: https://github.com/nablarch/nabledge/releases/tag/0.6 [0.5]: https://github.com/nablarch/nabledge/releases/tag/0.5 [0.4]: https://github.com/nablarch/nabledge/releases/tag/0.4 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 3bf71c1..b1e845c 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -58,7 +58,7 @@ Nablarchの知識を活用した開発支援ワークフローを提供します プロジェクトルートで以下のコマンドを実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup.sh | bash ``` 実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 @@ -106,7 +106,7 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 セットアップスクリプトを再実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup.sh | bash ``` 更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index eb42231..b524642 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.6", + "version": "0.7", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From f1586d1ba2d1fc345bf316c915826f9aa0b3806b Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 18:13:17 +0900 Subject: [PATCH 82/89] feat: Split setup scripts for Claude Code and GitHub Copilot - Rename setup.sh to setup-ghc.sh (GitHub Copilot) - Add setup-cc.sh for Claude Code (auto-edits settings.json) - setup-cc.sh safely merges with existing settings - Update README with separate installation instructions - Add workflow validation for both setup scripts Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 8 ++ .claude/skills/nabledge-6/plugin/README.md | 21 ++--- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .claude/skills/nabledge-6/scripts/setup-cc.sh | 85 +++++++++++++++++++ .../scripts/{setup.sh => setup-ghc.sh} | 0 .github/workflows/sync-to-nabledge.yml | 5 ++ 6 files changed, 110 insertions(+), 11 deletions(-) create mode 100755 .claude/skills/nabledge-6/scripts/setup-cc.sh rename .claude/skills/nabledge-6/scripts/{setup.sh => setup-ghc.sh} (100%) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 23439fd..56b743b 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.8] - 2026-02-13 + +### Changed +- セットアップスクリプトを分離:setup-cc.sh(Claude Code用)とsetup-ghc.sh(GitHub Copilot用) +- setup-cc.shがsettings.jsonを自動編集(extraKnownMarketplaces + enabledPlugins) +- 既存設定との安全なマージをサポート + ## [0.7] - 2026-02-13 ### Fixed @@ -48,6 +55,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.8]: https://github.com/nablarch/nabledge/releases/tag/0.8 [0.7]: https://github.com/nablarch/nabledge/releases/tag/0.7 [0.6]: https://github.com/nablarch/nabledge/releases/tag/0.6 [0.5]: https://github.com/nablarch/nabledge/releases/tag/0.5 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index b1e845c..597e78a 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -44,21 +44,22 @@ Nablarchの知識を活用した開発支援ワークフローを提供します プロジェクトルートで以下のコマンドを実行: ```bash -# マーケットプレイスを追加 -/plugin marketplace add nablarch/nabledge - -# プロジェクトスコープでインストール -/plugin install nabledge-6@nabledge --scope project +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh | bash ``` -実行後、`.claude/settings.json`が自動的に更新されます。このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンすると、自動的にプラグインのインストールが促されます。 +実行後、`.claude/settings.json`が自動的に作成または更新されます。このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンしてClaude Codeを起動すると、自動的にプラグインのインストールが促されます。 + +**必要な環境**: `jq` コマンド(JSONパーサー) +- Ubuntu/Debian: `sudo apt-get install jq` +- macOS: `brew install jq` +- Windows (WSL): `sudo apt-get install jq` ### GitHub Copilot (WSL / GitBash) プロジェクトルートで以下のコマンドを実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh | bash ``` 実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 @@ -93,10 +94,10 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 ### Claude Code -最新版に更新: +セットアップスクリプトを再実行: ```bash -/plugin marketplace update nabledge +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh | bash ``` 実行後、更新された`.claude/settings.json`をGitにコミット・プッシュしてください。 @@ -106,7 +107,7 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 セットアップスクリプトを再実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh | bash ``` 更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index b524642..dfe6442 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.7", + "version": "0.8", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.claude/skills/nabledge-6/scripts/setup-cc.sh b/.claude/skills/nabledge-6/scripts/setup-cc.sh new file mode 100755 index 0000000..33a0cd6 --- /dev/null +++ b/.claude/skills/nabledge-6/scripts/setup-cc.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -e + +# Navigate to repository root (or current directory if not in git repo) +if git rev-parse --show-toplevel &>/dev/null; then + PROJECT_ROOT="$(git rev-parse --show-toplevel)" +else + PROJECT_ROOT="$(pwd)" +fi + +echo "Setting up Nabledge-6 plugin for Claude Code..." +echo "Project root: $PROJECT_ROOT" + +# Configuration +REPO_OWNER="nablarch" +REPO_NAME="nabledge" +BRANCH="dummy-to" +MARKETPLACE_NAME="nabledge" +PLUGIN_NAME="nabledge-6" + +# Create .claude directory if it doesn't exist +mkdir -p "$PROJECT_ROOT/.claude" + +SETTINGS_FILE="$PROJECT_ROOT/.claude/settings.json" + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is required but not installed." + echo "Please install jq:" + echo " - Ubuntu/Debian: sudo apt-get install jq" + echo " - macOS: brew install jq" + echo " - Windows (WSL): sudo apt-get install jq" + exit 1 +fi + +# Initialize settings.json if it doesn't exist +if [ ! -f "$SETTINGS_FILE" ]; then + echo "Creating new settings.json..." + echo '{}' > "$SETTINGS_FILE" +fi + +# Read current settings +CURRENT_SETTINGS=$(cat "$SETTINGS_FILE") + +# Build marketplace configuration +MARKETPLACE_CONFIG=$(jq -n \ + --arg repo "$REPO_OWNER/$REPO_NAME" \ + --arg branch "$BRANCH" \ + '{ + "source": { + "source": "github", + "repo": $repo, + "ref": $branch + } + }') + +# Build plugin configuration +PLUGIN_KEY="${PLUGIN_NAME}@${MARKETPLACE_NAME}" + +# Merge configurations +UPDATED_SETTINGS=$(echo "$CURRENT_SETTINGS" | jq \ + --arg marketplace_name "$MARKETPLACE_NAME" \ + --argjson marketplace_config "$MARKETPLACE_CONFIG" \ + --arg plugin_key "$PLUGIN_KEY" \ + ' + .extraKnownMarketplaces = (.extraKnownMarketplaces // {}) | + .extraKnownMarketplaces[$marketplace_name] = $marketplace_config | + .enabledPlugins = (.enabledPlugins // {}) | + .enabledPlugins[$plugin_key] = true + ') + +# Write updated settings +echo "$UPDATED_SETTINGS" > "$SETTINGS_FILE" + +echo "" +echo "Setup complete! The nabledge-6 plugin configuration has been added to:" +echo "$SETTINGS_FILE" +echo "" +echo "Next steps:" +echo "1. Commit .claude/settings.json to your repository" +echo "2. When team members clone the repository and start Claude Code," +echo " they will be prompted to install the marketplace and plugin" +echo "" +echo "You can verify the configuration with:" +echo " cat $SETTINGS_FILE" diff --git a/.claude/skills/nabledge-6/scripts/setup.sh b/.claude/skills/nabledge-6/scripts/setup-ghc.sh similarity index 100% rename from .claude/skills/nabledge-6/scripts/setup.sh rename to .claude/skills/nabledge-6/scripts/setup-ghc.sh diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 78a5c3d..103ad0d 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -103,6 +103,11 @@ jobs: test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/assets || { echo "Error: nabledge-6/skills/nabledge-6/assets not found"; exit 1; } test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/knowledge || { echo "Error: nabledge-6/skills/nabledge-6/knowledge not found"; exit 1; } test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/docs || { echo "Error: nabledge-6/skills/nabledge-6/docs not found"; exit 1; } + test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts || { echo "Error: nabledge-6/skills/nabledge-6/scripts not found"; exit 1; } + + # Check setup scripts exist + test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh || { echo "Error: setup-cc.sh not found"; exit 1; } + test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh || { echo "Error: setup-ghc.sh not found"; exit 1; } # Validate JSON formats echo "Validating JSON formats..." From 110311d0fc66b7237b941db86a534678ce131a17 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 18:30:28 +0900 Subject: [PATCH 83/89] refactor: Relocate setup scripts to repository root for better UX - Move setup scripts from .claude/skills/nabledge-6/scripts/ to /scripts/ - Rename to setup-6-cc.sh and setup-6-ghc.sh for clarity - Copy to distribution repository root for shorter URLs - Update README with simplified installation paths - Update workflow validation for new script locations Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 8 ++++++++ .claude/skills/nabledge-6/plugin/README.md | 8 ++++---- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .github/scripts/transform-to-plugin.sh | 6 +++++- .github/workflows/sync-to-nabledge.yml | 7 +++---- .../scripts/setup-cc.sh => scripts/setup-6-cc.sh | 0 .../scripts/setup-ghc.sh => scripts/setup-6-ghc.sh | 0 7 files changed, 21 insertions(+), 10 deletions(-) rename .claude/skills/nabledge-6/scripts/setup-cc.sh => scripts/setup-6-cc.sh (100%) rename .claude/skills/nabledge-6/scripts/setup-ghc.sh => scripts/setup-6-ghc.sh (100%) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 56b743b..fdb97c1 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.9] - 2026-02-13 + +### Changed +- セットアップスクリプトをリポジトリルートに配置(UX改善) +- setup-6-cc.sh, setup-6-ghc.sh にリネーム(より明確な命名) +- インストールコマンドのパスを短縮 + ## [0.8] - 2026-02-13 ### Changed @@ -55,6 +62,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - テスティングフレームワークの基礎 - セキュリティチェックリスト +[0.9]: https://github.com/nablarch/nabledge/releases/tag/0.9 [0.8]: https://github.com/nablarch/nabledge/releases/tag/0.8 [0.7]: https://github.com/nablarch/nabledge/releases/tag/0.7 [0.6]: https://github.com/nablarch/nabledge/releases/tag/0.6 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 597e78a..6344020 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -44,7 +44,7 @@ Nablarchの知識を活用した開発支援ワークフローを提供します プロジェクトルートで以下のコマンドを実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-cc.sh | bash ``` 実行後、`.claude/settings.json`が自動的に作成または更新されます。このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンしてClaude Codeを起動すると、自動的にプラグインのインストールが促されます。 @@ -59,7 +59,7 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nable プロジェクトルートで以下のコマンドを実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-ghc.sh | bash ``` 実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 @@ -97,7 +97,7 @@ Nablarch 6のドキュメントやベストプラクティスから知識を検 セットアップスクリプトを再実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-cc.sh | bash ``` 実行後、更新された`.claude/settings.json`をGitにコミット・プッシュしてください。 @@ -107,7 +107,7 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nable セットアップスクリプトを再実行: ```bash -curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh | bash +curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-ghc.sh | bash ``` 更新後、`.claude` ディレクトリの変更をGitにコミット・プッシュしてください。 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index dfe6442..21a4da6 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.8", + "version": "0.9", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.github/scripts/transform-to-plugin.sh b/.github/scripts/transform-to-plugin.sh index 77c54d8..d9124c4 100755 --- a/.github/scripts/transform-to-plugin.sh +++ b/.github/scripts/transform-to-plugin.sh @@ -49,12 +49,16 @@ cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/workflows" "$DEST_DIR/plugins/nable cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/assets" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/knowledge" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/docs" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" -cp -r "$SOURCE_DIR/.claude/skills/nabledge-6/scripts" "$DEST_DIR/plugins/nabledge-6/skills/nabledge-6/" # Plugin-specific files cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/README.md" "$DEST_DIR/plugins/nabledge-6/" cp "$SOURCE_DIR/.claude/skills/nabledge-6/plugin/CHANGELOG.md" "$DEST_DIR/plugins/nabledge-6/" +# Copy setup scripts to root +echo "Copying setup scripts to root..." +cp "$SOURCE_DIR/scripts/setup-6-cc.sh" "$DEST_DIR/" +cp "$SOURCE_DIR/scripts/setup-6-ghc.sh" "$DEST_DIR/" + echo "Transformation complete!" echo "" echo "Marketplace structure created in: $DEST_DIR" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 103ad0d..88b1b8d 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -103,11 +103,10 @@ jobs: test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/assets || { echo "Error: nabledge-6/skills/nabledge-6/assets not found"; exit 1; } test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/knowledge || { echo "Error: nabledge-6/skills/nabledge-6/knowledge not found"; exit 1; } test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/docs || { echo "Error: nabledge-6/skills/nabledge-6/docs not found"; exit 1; } - test -d nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts || { echo "Error: nabledge-6/skills/nabledge-6/scripts not found"; exit 1; } - # Check setup scripts exist - test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts/setup-cc.sh || { echo "Error: setup-cc.sh not found"; exit 1; } - test -f nabledge-repo/plugins/nabledge-6/skills/nabledge-6/scripts/setup-ghc.sh || { echo "Error: setup-ghc.sh not found"; exit 1; } + # Check setup scripts exist at root + test -f nabledge-repo/setup-6-cc.sh || { echo "Error: setup-6-cc.sh not found at root"; exit 1; } + test -f nabledge-repo/setup-6-ghc.sh || { echo "Error: setup-6-ghc.sh not found at root"; exit 1; } # Validate JSON formats echo "Validating JSON formats..." diff --git a/.claude/skills/nabledge-6/scripts/setup-cc.sh b/scripts/setup-6-cc.sh similarity index 100% rename from .claude/skills/nabledge-6/scripts/setup-cc.sh rename to scripts/setup-6-cc.sh diff --git a/.claude/skills/nabledge-6/scripts/setup-ghc.sh b/scripts/setup-6-ghc.sh similarity index 100% rename from .claude/skills/nabledge-6/scripts/setup-ghc.sh rename to scripts/setup-6-ghc.sh From c6d3ce9f84eec362efc21d8fb522a5570666ec4c Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 18:49:26 +0900 Subject: [PATCH 84/89] chore: Prepare for production release - Reset CHANGELOG.md to version 0.1 (remove dev versions 0.2-0.9) - Reset plugin.json to version 0.1 - Update workflow to trigger on main branch - Update workflow to sync to nablarch/nabledge main branch - Update setup scripts to use main branch instead of dummy-to Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 58 +------------------ .claude/skills/nabledge-6/plugin/plugin.json | 2 +- .github/workflows/sync-to-nabledge.yml | 6 +- scripts/setup-6-cc.sh | 2 +- scripts/setup-6-ghc.sh | 2 +- 5 files changed, 8 insertions(+), 62 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index fdb97c1..e92fcb9 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,54 +4,6 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.9] - 2026-02-13 - -### Changed -- セットアップスクリプトをリポジトリルートに配置(UX改善) -- setup-6-cc.sh, setup-6-ghc.sh にリネーム(より明確な命名) -- インストールコマンドのパスを短縮 - -## [0.8] - 2026-02-13 - -### Changed -- セットアップスクリプトを分離:setup-cc.sh(Claude Code用)とsetup-ghc.sh(GitHub Copilot用) -- setup-cc.shがsettings.jsonを自動編集(extraKnownMarketplaces + enabledPlugins) -- 既存設定との安全なマージをサポート - -## [0.7] - 2026-02-13 - -### Fixed -- READMEのsetup.sh URLをskills/nabledge-6/配下のパスに修正 - -## [0.6] - 2026-02-13 - -### Fixed -- スキルディレクトリ構成を修正:配布時と利用時で同じ構造に統一 -- workflows/等をskills/nabledge-6/の中に配置 - -## [0.5] - 2026-02-13 - -### Fixed -- setup.shのブランチ指定をdummy-toに変更(テスト用) - -## [0.4] - 2026-02-13 - -### Fixed -- setup.shを修正:配布リポジトリ構造から利用者向けskill構造に正しく展開 -- skills/nabledge-6/の内容を.claude/skills/nabledge-6/直下に配置 -- 不要な.claude-plugin/をコピーしないように修正 - -## [0.3] - 2026-02-13 - -### Fixed -- READMEのsetup.sh URLを配布リポジトリのパスに修正(.claude/skills/ → plugins/) - -## [0.2] - 2026-02-13 - -### Fixed -- setup.shのバグ修正:配布リポジトリの構造に合わせてコピー処理を修正 -- Gitリポジトリ外でも実行可能に改善 - ## [0.1] - 2026-02-13 ### Added @@ -61,13 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - データベースアクセスライブラリ - テスティングフレームワークの基礎 - セキュリティチェックリスト +- Claude Code用セットアップスクリプト(setup-6-cc.sh) +- GitHub Copilot用セットアップスクリプト(setup-6-ghc.sh) -[0.9]: https://github.com/nablarch/nabledge/releases/tag/0.9 -[0.8]: https://github.com/nablarch/nabledge/releases/tag/0.8 -[0.7]: https://github.com/nablarch/nabledge/releases/tag/0.7 -[0.6]: https://github.com/nablarch/nabledge/releases/tag/0.6 -[0.5]: https://github.com/nablarch/nabledge/releases/tag/0.5 -[0.4]: https://github.com/nablarch/nabledge/releases/tag/0.4 -[0.3]: https://github.com/nablarch/nabledge/releases/tag/0.3 -[0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 21a4da6..95205fc 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.9", + "version": "0.1", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 88b1b8d..631e389 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -3,7 +3,7 @@ name: Sync to nabledge repository on: push: branches: - - dummy-from + - main jobs: sync: @@ -46,7 +46,7 @@ jobs: uses: actions/checkout@v4 with: repository: nablarch/nabledge - ref: dummy-to + ref: main token: ${{ secrets.NABLEDGE_SYNC_TOKEN }} path: nabledge-repo @@ -146,7 +146,7 @@ jobs: git commit -m "Sync nabledge marketplace from nabledge-dev" -m "Triggered by: ${TRIGGER_COMMIT_URL}" - git push origin dummy-to + git push origin main - name: Create and push version tag working-directory: nabledge-repo diff --git a/scripts/setup-6-cc.sh b/scripts/setup-6-cc.sh index 33a0cd6..772049c 100755 --- a/scripts/setup-6-cc.sh +++ b/scripts/setup-6-cc.sh @@ -14,7 +14,7 @@ echo "Project root: $PROJECT_ROOT" # Configuration REPO_OWNER="nablarch" REPO_NAME="nabledge" -BRANCH="dummy-to" +BRANCH="main" MARKETPLACE_NAME="nabledge" PLUGIN_NAME="nabledge-6" diff --git a/scripts/setup-6-ghc.sh b/scripts/setup-6-ghc.sh index 58364fd..031cfe2 100755 --- a/scripts/setup-6-ghc.sh +++ b/scripts/setup-6-ghc.sh @@ -13,7 +13,7 @@ echo "Project root: $PROJECT_ROOT" # Download nabledge-6 plugin from nablarch/nabledge repository REPO_URL="https://github.com/nablarch/nabledge" -BRANCH="dummy-to" +BRANCH="main" TEMP_DIR=$(mktemp -d) echo "Downloading nabledge-6 plugin from $REPO_URL (branch: $BRANCH)..." From 94c1b86d9edd098a5d7bd8ee556a7734d2acaef6 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 19:00:20 +0900 Subject: [PATCH 85/89] feat: Auto-install jq in setup scripts - Setup scripts now automatically install jq if not present - Linux/WSL: Uses apt-get with sudo - GitBash: Downloads jq.exe from GitHub releases - macOS: Prompts user to install manually via brew - Update README to reflect automatic installation - Remove manual installation instructions from README Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 7 +++ .claude/skills/nabledge-6/plugin/README.md | 7 +-- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- scripts/setup-6-cc.sh | 46 +++++++++++--- scripts/setup-6-ghc.sh | 60 +++++++++++++++++++ 5 files changed, 110 insertions(+), 12 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index e92fcb9..3945ffc 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.2] - 2026-02-13 + +### Changed +- セットアップスクリプトがjqを自動インストール(Linux/WSL/GitBash) +- READMEから手動インストール手順を削除し、自動インストールについて記載 + ## [0.1] - 2026-02-13 ### Added @@ -16,4 +22,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Claude Code用セットアップスクリプト(setup-6-cc.sh) - GitHub Copilot用セットアップスクリプト(setup-6-ghc.sh) +[0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/README.md b/.claude/skills/nabledge-6/plugin/README.md index 6344020..9acb325 100644 --- a/.claude/skills/nabledge-6/plugin/README.md +++ b/.claude/skills/nabledge-6/plugin/README.md @@ -49,10 +49,7 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-cc.sh 実行後、`.claude/settings.json`が自動的に作成または更新されます。このファイルをGitにコミット・プッシュしてください。チームメンバーがリポジトリをクローンしてClaude Codeを起動すると、自動的にプラグインのインストールが促されます。 -**必要な環境**: `jq` コマンド(JSONパーサー) -- Ubuntu/Debian: `sudo apt-get install jq` -- macOS: `brew install jq` -- Windows (WSL): `sudo apt-get install jq` +**注**: セットアップスクリプトは必要に応じて `jq` コマンドを自動インストールします(Linux/WSL/GitBash環境)。macOSでは手動インストールが必要です(`brew install jq`)。 ### GitHub Copilot (WSL / GitBash) @@ -64,6 +61,8 @@ curl -sSL https://raw.githubusercontent.com/nablarch/nabledge/main/setup-6-ghc.s 実行後、`.claude` ディレクトリがプロジェクトに作成されます。このディレクトリをGitにコミット・プッシュしてください。チームメンバーも同じスキルを利用できるようになります。 +**注**: セットアップスクリプトは必要に応じて `jq` コマンドを自動インストールします(Linux/WSL/GitBash環境)。macOSでは手動インストールが必要です(`brew install jq`)。 + ## 使い方 ### 基本的な使い方 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 95205fc..81f21ab 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.1", + "version": "0.2", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" diff --git a/scripts/setup-6-cc.sh b/scripts/setup-6-cc.sh index 772049c..00beeea 100755 --- a/scripts/setup-6-cc.sh +++ b/scripts/setup-6-cc.sh @@ -23,14 +23,46 @@ mkdir -p "$PROJECT_ROOT/.claude" SETTINGS_FILE="$PROJECT_ROOT/.claude/settings.json" -# Check if jq is installed +# Check if jq is installed, if not, try to install it if ! command -v jq &> /dev/null; then - echo "Error: jq is required but not installed." - echo "Please install jq:" - echo " - Ubuntu/Debian: sudo apt-get install jq" - echo " - macOS: brew install jq" - echo " - Windows (WSL): sudo apt-get install jq" - exit 1 + echo "jq is not installed. Attempting to install..." + + # Detect OS + OS="$(uname -s)" + case "$OS" in + Linux*) + echo "Detected Linux/WSL environment" + echo "Installing jq via apt-get (requires sudo)..." + sudo apt-get update && sudo apt-get install -y jq + ;; + MINGW*|MSYS*|CYGWIN*) + echo "Detected GitBash environment" + echo "Downloading jq..." + JQ_URL="https://github.com/stedolan/jq/releases/latest/download/jq-win64.exe" + JQ_PATH="/usr/bin/jq.exe" + curl -L -o "$JQ_PATH" "$JQ_URL" + chmod +x "$JQ_PATH" + ;; + Darwin*) + echo "Detected macOS" + echo "Please install jq manually:" + echo " brew install jq" + exit 1 + ;; + *) + echo "Error: Unsupported OS: $OS" + echo "Please install jq manually: https://stedolan.github.io/jq/download/" + exit 1 + ;; + esac + + # Verify installation + if ! command -v jq &> /dev/null; then + echo "Error: Failed to install jq" + exit 1 + fi + + echo "jq installed successfully!" fi # Initialize settings.json if it doesn't exist diff --git a/scripts/setup-6-ghc.sh b/scripts/setup-6-ghc.sh index 031cfe2..9fc25b3 100755 --- a/scripts/setup-6-ghc.sh +++ b/scripts/setup-6-ghc.sh @@ -33,6 +33,66 @@ cp -r "$TEMP_DIR/nabledge/plugins/nabledge-6/skills/nabledge-6" "$PROJECT_ROOT/. # Clean up rm -rf "$TEMP_DIR" +# Check if jq is installed, if not, try to install it +if ! command -v jq &> /dev/null; then + echo "" + echo "jq is not installed. The nabledge-6 skill requires jq to run." + echo "Attempting to install..." + + # Detect OS + OS="$(uname -s)" + case "$OS" in + Linux*) + echo "Detected Linux/WSL environment" + echo "Installing jq via apt-get (requires sudo)..." + sudo apt-get update && sudo apt-get install -y jq + ;; + MINGW*|MSYS*|CYGWIN*) + echo "Detected GitBash environment" + echo "Downloading jq..." + JQ_URL="https://github.com/stedolan/jq/releases/latest/download/jq-win64.exe" + JQ_PATH="/usr/bin/jq.exe" + curl -L -o "$JQ_PATH" "$JQ_URL" + chmod +x "$JQ_PATH" + ;; + Darwin*) + echo "Detected macOS" + echo "Please install jq manually:" + echo " brew install jq" + echo "" + echo "Setup complete! The nabledge-6 skill is now available in your project." + echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6" + echo "" + echo "IMPORTANT: Please install jq before using the skill." + exit 0 + ;; + *) + echo "Error: Unsupported OS: $OS" + echo "Please install jq manually: https://stedolan.github.io/jq/download/" + echo "" + echo "Setup complete! The nabledge-6 skill is now available in your project." + echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6" + echo "" + echo "IMPORTANT: Please install jq before using the skill." + exit 0 + ;; + esac + + # Verify installation + if ! command -v jq &> /dev/null; then + echo "Warning: Failed to install jq automatically" + echo "Please install jq manually: https://stedolan.github.io/jq/download/" + echo "" + echo "Setup complete! The nabledge-6 skill is now available in your project." + echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6" + echo "" + echo "IMPORTANT: Please install jq before using the skill." + exit 0 + fi + + echo "jq installed successfully!" +fi + echo "" echo "Setup complete! The nabledge-6 skill is now available in your project." echo "Location: $PROJECT_ROOT/.claude/skills/nabledge-6" From 161d500dd5532219379a6250606ba00a0025f2cd Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 19:00:56 +0900 Subject: [PATCH 86/89] fix: Consolidate changes into version 0.1 - Revert version back to 0.1 (was incorrectly bumped to 0.2) - Merge jq auto-install feature into 0.1 release - This is still the initial release Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 11 ++--------- .claude/skills/nabledge-6/plugin/plugin.json | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index 3945ffc..fa26e7d 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -4,12 +4,6 @@ All notable changes to the nabledge-6 plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.2] - 2026-02-13 - -### Changed -- セットアップスクリプトがjqを自動インストール(Linux/WSL/GitBash) -- READMEから手動インストール手順を削除し、自動インストールについて記載 - ## [0.1] - 2026-02-13 ### Added @@ -19,8 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - データベースアクセスライブラリ - テスティングフレームワークの基礎 - セキュリティチェックリスト -- Claude Code用セットアップスクリプト(setup-6-cc.sh) -- GitHub Copilot用セットアップスクリプト(setup-6-ghc.sh) +- Claude Code用セットアップスクリプト(setup-6-cc.sh、jq自動インストール対応) +- GitHub Copilot用セットアップスクリプト(setup-6-ghc.sh、jq自動インストール対応) -[0.2]: https://github.com/nablarch/nabledge/releases/tag/0.2 [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 diff --git a/.claude/skills/nabledge-6/plugin/plugin.json b/.claude/skills/nabledge-6/plugin/plugin.json index 81f21ab..95205fc 100644 --- a/.claude/skills/nabledge-6/plugin/plugin.json +++ b/.claude/skills/nabledge-6/plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "nabledge-6", - "version": "0.2", + "version": "0.1", "description": "Nablarch 6 skill for AI-assisted development", "author": { "name": "Nablarch" From eb0f2db131c992f0e724e50a9b46930b497a2446 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 19:01:41 +0900 Subject: [PATCH 87/89] docs: Remove setup script mentions from CHANGELOG - Initial release should only list features - Setup scripts are expected to exist, no need to document Co-Authored-By: Claude Opus 4.6 --- .claude/skills/nabledge-6/plugin/CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.claude/skills/nabledge-6/plugin/CHANGELOG.md b/.claude/skills/nabledge-6/plugin/CHANGELOG.md index fa26e7d..ecb1a68 100644 --- a/.claude/skills/nabledge-6/plugin/CHANGELOG.md +++ b/.claude/skills/nabledge-6/plugin/CHANGELOG.md @@ -13,7 +13,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - データベースアクセスライブラリ - テスティングフレームワークの基礎 - セキュリティチェックリスト -- Claude Code用セットアップスクリプト(setup-6-cc.sh、jq自動インストール対応) -- GitHub Copilot用セットアップスクリプト(setup-6-ghc.sh、jq自動インストール対応) [0.1]: https://github.com/nablarch/nabledge/releases/tag/0.1 From 7c6c7e4a2ef75d910bf96d037170a2df5b089e9e Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 19:02:41 +0900 Subject: [PATCH 88/89] chore: Remove tests directory - Tests are managed separately - Already handled elsewhere Co-Authored-By: Claude Opus 4.6 --- .../tests/code-analysis-scenarios.json | 168 ------------------ .../tests/keyword-search-scenarios.json | 138 -------------- 2 files changed, 306 deletions(-) delete mode 100644 .claude/skills/nabledge-6/tests/code-analysis-scenarios.json delete mode 100644 .claude/skills/nabledge-6/tests/keyword-search-scenarios.json diff --git a/.claude/skills/nabledge-6/tests/code-analysis-scenarios.json b/.claude/skills/nabledge-6/tests/code-analysis-scenarios.json deleted file mode 100644 index 068a1ca..0000000 --- a/.claude/skills/nabledge-6/tests/code-analysis-scenarios.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "metadata": { - "version": "1.1.0", - "created": "2026-02-10", - "updated": "2026-02-10", - "description": "Test scenarios for code-analysis workflow validation (Nablarch batch)", - "total_scenarios": 5 - }, - "scenarios": [ - { - "id": "code-analysis-001", - "category": "code-analysis", - "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java", - "question": "ExportProjectsInPeriodActionの全体構造を理解したい", - "expected_components": [ - "ExportProjectsInPeriodAction (BatchAction)", - "ProjectDto (DTO)", - "DatabaseRecordReader (Nablarch)", - "ObjectMapper (Nablarch)", - "FilePathSetting (Nablarch)" - ], - "expected_knowledge": [ - "processing/nablarch-batch.json", - "handlers/batch/data-read-handler.json", - "libraries/file-path-management.json" - ], - "expected_output_sections": [ - "Overview", - "Architecture", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-002", - "category": "code-analysis", - "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:initialize", - "question": "バッチアクションの初期化処理を詳しく知りたい", - "expected_components": [ - "initialize method", - "FilePathSetting", - "ObjectMapperFactory", - "FileOutputStream" - ], - "expected_knowledge": [ - "libraries/file-path-management.json", - "processing/nablarch-batch.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-003", - "category": "code-analysis", - "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:createReader", - "question": "データベースからのデータ読み込み処理を理解したい", - "expected_components": [ - "createReader method", - "DatabaseRecordReader", - "SqlPStatement", - "BusinessDateUtil" - ], - "expected_knowledge": [ - "handlers/batch/data-read-handler.json", - "libraries/database-access.json", - "libraries/business-date.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-004", - "category": "code-analysis", - "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/main/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodAction.java:handle", - "question": "ファイルへのデータ書き込み処理を詳しく知りたい", - "expected_components": [ - "handle method", - "ObjectMapper", - "ProjectDto", - "EntityUtil" - ], - "expected_knowledge": [ - "processing/nablarch-batch.json", - "libraries/database-access.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - }, - { - "id": "code-analysis-005", - "category": "code-analysis", - "target_code": ".lw/nab-official/nablarch-system-development-guide/Sample_Project/Source_Code/proman-project/proman-batch/src/test/java/com/nablarch/example/proman/batch/project/ExportProjectsInPeriodActionRequestTest.java", - "question": "バッチのテストコード実装を理解したい", - "expected_components": [ - "ExportProjectsInPeriodActionRequestTest (Test)", - "PromanBatchRequestTestSupport", - "NTF test framework" - ], - "expected_knowledge": [ - "tools/ntf-batch-request-test.json", - "tools/ntf-test-data.json", - "tools/ntf-assertion.json" - ], - "expected_output_sections": [ - "Overview", - "Components", - "Flow", - "Nablarch Framework Usage" - ], - "relevance": "high" - } - ], - "evaluation_criteria": { - "workflow_execution": { - "description": "ワークフローが正しく実行されたか", - "checks": [ - "code-analysis workflowが実行された", - "対象コードが正しく識別された", - "依存関係が適切に分析された", - "構成要素が適切に分解された", - "関連するNablarch知識が検索された" - ] - }, - "code_explanation_output": { - "description": "出力ドキュメントの品質が適切か", - "checks": [ - "Overview, Architecture, Components, Flow, Nablarch Framework Usageセクションが含まれている", - "Mermaid図が適切に生成されている", - "構成要素の説明が明確である", - "ソースコードへの相対パスリンクが含まれている", - "Nablarch知識ファイルへのリンクが含まれている" - ] - }, - "knowledge_integration": { - "description": "Nablarch知識が適切に引用されているか", - "checks": [ - "expected_knowledgeに含まれる知識ファイルが参照された", - "知識ファイルの内容が適切に引用された", - "コードと知識の対応関係が明確に説明された" - ] - }, - "token_efficiency": { - "description": "トークン効率が適切か", - "target": "10,000-30,000 tokens per query" - }, - "tool_call_efficiency": { - "description": "ツール呼び出し回数が適切か", - "target": "15-40 tool calls per query" - } - } -} diff --git a/.claude/skills/nabledge-6/tests/keyword-search-scenarios.json b/.claude/skills/nabledge-6/tests/keyword-search-scenarios.json deleted file mode 100644 index 0bc8a5c..0000000 --- a/.claude/skills/nabledge-6/tests/keyword-search-scenarios.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "metadata": { - "version": "1.1.0", - "created": "2026-02-10", - "updated": "2026-02-10", - "description": "Test scenarios for keyword-search workflow validation", - "total_scenarios": 5 - }, - "scenarios": [ - { - "id": "handlers-001", - "category": "handlers", - "file": "handlers/batch/data-read-handler.json", - "question": "データリードハンドラでファイルを読み込むにはどうすればいいですか?", - "expected_keywords": [ - "DataReadHandler", - "DataReader", - "ファイル読み込み", - "データ入力", - "レコード処理" - ], - "expected_sections": [ - "overview", - "usage" - ], - "relevance": "high" - }, - { - "id": "libraries-001", - "category": "libraries", - "file": "libraries/universal-dao.json", - "question": "UniversalDaoでページングを実装したい", - "expected_keywords": [ - "ページング", - "paging", - "per", - "page", - "Pagination", - "EntityList" - ], - "expected_sections": [ - "paging" - ], - "relevance": "high" - }, - { - "id": "tools-001", - "category": "tools", - "file": "tools/ntf-test-data.json", - "question": "NTFでテストデータを準備する方法を教えてください", - "expected_keywords": [ - "テストデータ", - "NTF", - "データ準備", - "Excel", - "データベース" - ], - "expected_sections": [ - "preparation", - "setup" - ], - "relevance": "high" - }, - { - "id": "processing-001", - "category": "processing", - "file": "processing/nablarch-batch.json", - "question": "Nablarchバッチの基本構造を教えてください", - "expected_keywords": [ - "バッチ", - "基本構造", - "アーキテクチャ", - "ハンドラ構成", - "処理フロー" - ], - "expected_sections": [ - "overview", - "architecture" - ], - "relevance": "high" - }, - { - "id": "adapters-001", - "category": "adapters", - "file": "adapters/slf4j-adapter.json", - "question": "SLF4Jアダプタの設定方法を教えてください", - "expected_keywords": [ - "SLF4J", - "アダプタ", - "設定", - "ログ出力", - "log4j" - ], - "expected_sections": [ - "configuration", - "setup" - ], - "relevance": "high" - } - ], - "evaluation_criteria": { - "workflow_execution": { - "description": "ワークフローが正しく実行されたか", - "checks": [ - "keyword-search workflowが実行された", - "section-judgement workflowが実行された", - "適切なツール呼び出しが行われた(Read, Bash+jq)" - ] - }, - "keyword_matching": { - "description": "期待されるキーワードが回答に含まれているか", - "threshold": "80%以上のキーワードが含まれている" - }, - "section_relevance": { - "description": "適切なセクションが特定されたか", - "checks": [ - "expected_sectionsに含まれるセクションが特定された", - "関連性の高いセクション(High relevance)が優先された" - ] - }, - "knowledge_file_only": { - "description": "知識ファイルのみを使って回答したか", - "checks": [ - "LLM訓練データを使用していない", - "外部知識を補足していない", - "知識ファイルに記載されている情報のみを使用" - ] - }, - "token_efficiency": { - "description": "トークン効率が適切か", - "target": "5,000-15,000 tokens per query" - }, - "tool_call_efficiency": { - "description": "ツール呼び出し回数が適切か", - "target": "10-20 tool calls per query" - } - } -} From dca7f281f5392e07336a6b8d0b358ced0b97bcd3 Mon Sep 17 00:00:00 2001 From: kiyotis Date: Fri, 13 Feb 2026 19:16:05 +0900 Subject: [PATCH 89/89] refactor: Use marketplace version for Git tags - Add metadata.version to marketplace.json (centralized version) - Move description to metadata.description (proper schema) - Update GitHub Action to read version from marketplace.json - Individual plugins keep their own versions in plugin.json - Marketplace version represents overall release (nabledge-6 + nabledge-5) Co-Authored-By: Claude Opus 4.6 --- .claude/marketplace/.claude-plugin/marketplace.json | 5 ++++- .github/workflows/sync-to-nabledge.yml | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.claude/marketplace/.claude-plugin/marketplace.json b/.claude/marketplace/.claude-plugin/marketplace.json index f7a4f46..9a42f4a 100644 --- a/.claude/marketplace/.claude-plugin/marketplace.json +++ b/.claude/marketplace/.claude-plugin/marketplace.json @@ -1,9 +1,12 @@ { "name": "nabledge", - "description": "Nablarch skills for AI-assisted development", "owner": { "name": "Nablarch" }, + "metadata": { + "version": "0.1", + "description": "Nablarch skills for AI-assisted development" + }, "plugins": [ { "name": "nabledge-6", diff --git a/.github/workflows/sync-to-nabledge.yml b/.github/workflows/sync-to-nabledge.yml index 631e389..bb8dd7e 100644 --- a/.github/workflows/sync-to-nabledge.yml +++ b/.github/workflows/sync-to-nabledge.yml @@ -151,8 +151,8 @@ jobs: - name: Create and push version tag working-directory: nabledge-repo run: | - # Extract version from plugin.json - VERSION=$(jq -r '.version' plugins/nabledge-6/.claude-plugin/plugin.json) + # Extract version from marketplace.json + VERSION=$(jq -r '.metadata.version' .claude-plugin/marketplace.json) TAG_NAME="${VERSION}" echo "Creating tag: ${TAG_NAME}"