Claude-skill-registry infer-intent

Git履歴から設計意図・歴史的文脈を推論し、変更の背景を理解

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/infer-intent" ~/.claude/skills/majiayu000-claude-skill-registry-infer-intent && rm -rf "$T"
manifest: skills/data/infer-intent/SKILL.md
source content

civicship-api 設計意図推論

Git履歴・コミットメッセージから設計の意図歴史的文脈を推論します。なぜこのコードがこう書かれているのか、過去の変更理由を理解することで、安全な変更を支援します。

使用方法

# 特定ファイルの設計意図を推論
/infer-intent src/application/domain/account/wallet/service.ts

# ドメイン全体の歴史を分析
/infer-intent wallet

# 特定の実装パターンの理由を調査
/infer-intent "なぜWalletServiceはトランザクションを必須にしているのか"

引数:

  • $ARGUMENTS
    : ファイルパス、ドメイン名、または質問

意図推論プロセス

ステップ1: Git履歴の取得

対象ファイル・ドメインのコミット履歴を取得:

# ファイルの全履歴
git log --follow --oneline src/application/domain/account/wallet/service.ts

# 詳細な変更履歴
git log -p --follow src/application/domain/account/wallet/service.ts

# 特定期間のコミット
git log --since="1 year ago" --oneline -- src/application/domain/account/wallet

# コミット統計
git log --stat --oneline -- src/application/domain/account/wallet

履歴レポート:

## Git履歴の概要

### 変更統計

| 項目 | 値 |
|------|-----|
| 総コミット数 | 45件 |
| 最初のコミット | 2023-06-20 |
| 最新のコミット | 2026-01-10 |
| 期間 | 2年7ヶ月 |
| 主要コントリビューター | 3名 |

---

### コミット頻度

| 期間 | コミット数 |
|------|-----------|
| 2023年 | 12件 |
| 2024年 | 20件 |
| 2025年 | 10件 |
| 2026年 | 3件 |

**トレンド:** 2024年にピーク(機能追加が活発)

---

### 主要なコミット

#### 1. 初期実装(2023-06-20)

commit a1b2c3d feat: Add wallet domain with basic CRUD operations


**変更内容:**
- WalletService, WalletRepository の初期実装
- 基本的なCRUD操作のみ

---

#### 2. トランザクション対応(2023-08-15)

commit e4f5g6h fix: Add transaction support to wallet operations


**変更内容:**
- すべてのメソッドに `tx` パラメータ追加
- トランザクション内での操作を保証

**理由(コミットメッセージから推論):**
- ポイント送受信で不整合が発生したバグ修正
- トランザクションなしでは残高計算にレースコンディション

---

#### 3. バリデーション強化(2024-02-10)

commit i7j8k9l feat: Add strict validation for negative balance


**変更内容:**
- 残高がマイナスにならないチェック追加

**理由:**
- 本番環境でマイナス残高が発生
- ビジネスルール違反を防ぐため

---

#### 4. パフォーマンス最適化(2024-06-20)

commit m1n2o3p perf: Optimize wallet balance calculation with cache


**変更内容:**
- 残高計算にキャッシュ導入
- クエリ回数を削減

**理由:**
- ユーザー増加によりレスポンスタイム劣化
- 100ms → 30ms に改善

---

#### 5. セキュリティ修正(2025-03-15)

commit q4r5s6t security: Add RLS to all wallet queries


**変更内容:**
- すべてのクエリに `ctx.issuer` を適用

**理由:**
- 他ユーザーのウォレット情報が見えるバグ
- セキュリティ監査で指摘

ステップ2: コミットメッセージの分析

コミットメッセージから設計判断を推論:

## コミットメッセージ分析

### カテゴリ別の分類

| カテゴリ | 件数 | 割合 |
|---------|------|------|
| feat (機能追加) | 18件 | 40% |
| fix (バグ修正) | 12件 | 27% |
| perf (パフォーマンス) | 5件 | 11% |
| security (セキュリティ) | 3件 | 7% |
| refactor (リファクタリング) | 4件 | 9% |
| test (テスト) | 3件 | 7% |

**傾向:** 機能追加が多いが、バグ修正も頻繁

---

### 頻出キーワード分析

| キーワード | 出現回数 | 文脈 |
|-----------|---------|------|
| transaction | 8回 | トランザクション対応 |
| validation | 6回 | バリデーション強化 |
| balance | 10回 | 残高計算ロジック |
| security | 5回 | セキュリティ修正 |
| performance | 4回 | パフォーマンス改善 |

**解釈:**
- トランザクションが重要な関心事
- 残高計算は複雑で頻繁に修正
- セキュリティ問題が過去に複数回発生

---

### 重要な設計決定

#### 決定1: トランザクション必須化

**コミット:** e4f5g6h (2023-08-15)

**メッセージ:**

fix: Add transaction support to wallet operations

ポイント送受信でレースコンディションが発生し、 残高の不整合が発生した。 今後すべてのウォレット操作はトランザクション内で 実行することを必須とする。


**推論される意図:**
- データ整合性が最優先
- 並行アクセスでのレースコンディションを防ぐ
- パフォーマンスよりも正確性を重視

---

#### 決定2: マイナス残高の禁止

**コミット:** i7j8k9l (2024-02-10)

**メッセージ:**

feat: Add strict validation for negative balance

本番環境でマイナス残高が発生したため、 厳密なバリデーションを追加。 ポイント使用時に残高不足の場合はエラーを返す。


**推論される意図:**
- ビジネスルール: ポイントは借金できない
- 既存のバリデーションが不十分だった
- 信頼性向上のための防御的プログラミング

---

#### 決定3: キャッシュ導入

**コミット:** m1n2o3p (2024-06-20)

**メッセージ:**

perf: Optimize wallet balance calculation with cache

ユーザー増加によりウォレットクエリが ボトルネックになっていた。 残高計算に10秒のキャッシュを導入し、 レスポンスタイムを100ms→30msに改善。


**推論される意図:**
- スケーラビリティへの対応
- リアルタイム性よりパフォーマンスを優先(10秒は許容)
- 将来的なユーザー増加を見越した設計

---

#### 決定4: RLS(Row-Level Security)の徹底

**コミット:** q4r5s6t (2025-03-15)

**メッセージ:**

security: Add RLS to all wallet queries

セキュリティ監査で、一部のクエリでRLSが 適用されていないことが判明。 全てのクエリで ctx.issuer を使用するよう修正。


**推論される意図:**
- セキュリティが最重要課題
- 一度でも情報漏洩があった(またはリスクがあった)
- 再発防止のための徹底的な対策

ステップ3: コード変更パターンの分析

コード変更の傾向から設計思想を推論:

# ファイルパスを引数から取得
FILE_PATH="${ARGUMENTS}"

# 追加された行数と削除された行数
git log --stat --oneline -- "${FILE_PATH}" | \
  grep "$(basename "${FILE_PATH}")" | awk '{sum+=$4} END {print sum}'

# 特定関数の変更履歴(例: createWallet関数)
git log -L :createWallet:"${FILE_PATH}"

変更パターンレポート:

## コード変更パターン

### メソッド別の変更頻度

| メソッド | 変更回数 | 最終変更日 |
|---------|---------|-----------|
| createWallet | 8回 | 2025-01-10 |
| findByUserId | 12回 | 2024-11-20 |
| transferPoints | 15回 | 2025-12-05 |
| calculateBalance | 10回 | 2024-06-20 |

**解釈:**
- `transferPoints` が最も変更が多い(複雑なロジック)
- `findByUserId` も頻繁に変更(セキュリティ、パフォーマンス改善)

---

### createWallet メソッドの進化

#### Version 1(2023-06-20)
```typescript
async createWallet(userId: string) {
  return this.repo.create({ userId, balance: 0 });
}

特徴: シンプル、トランザクションなし


Version 2(2023-08-15)

async createWallet(userId: string, tx: Prisma.TransactionClient) {
  return this.repo.create({ userId, balance: 0 }, tx);
}

変更: トランザクション対応


Version 3(2024-02-10)

async createWallet(ctx: IContext, userId: string, tx: Prisma.TransactionClient) {
  // バリデーション追加
  const existing = await this.repo.findByUserId(ctx, userId, tx);
  if (existing) {
    throw new Error("WALLET_ALREADY_EXISTS");
  }
  return this.repo.create({ userId, balance: 0 }, tx);
}

変更: 重複チェック追加


Version 4(現在)

async createWallet(
  ctx: IContext,
  input: GqlWalletCreateInput,
  communityId: string,
  tx: Prisma.TransactionClient
): Promise<PrismaWallet> {
  // バリデーション
  const existing = await this.repo.findByUserId(ctx, input.userId, tx);
  if (existing) {
    throw new Error("WALLET_ALREADY_EXISTS");
  }

  // 入力変換
  const data = this.converter.toCreateData(input, communityId);

  // 作成
  return await this.repo.create(ctx, data, tx);
}

変更: Clean Architecture パターンに準拠、Converter導入

推論:

  • 段階的にアーキテクチャを改善
  • 最初はシンプルだったが、バグを経験して厳格化
  • 最終的にDDDパターンに完全準拠

---

### ステップ4: 関連IssueとPRの調査

GitHubのIssue/PRから背景を調査:

```bash
# 関連PRを検索
gh pr list --search "wallet" --state all --limit 20

# 特定PRの詳細(PR番号を引数から取得)
PR_NUMBER="${ARGUMENTS}"
gh pr view "$PR_NUMBER"

# PRのコメントを確認
gh api repos/Hopin-inc/civicship-api/pulls/"$PR_NUMBER"/comments

Issue/PR分析:

## 関連Issue/PRの分析

### 重要なPR

#### PR #45: トランザクション対応
**タイトル:** Add transaction support to wallet operations
**作成日:** 2023-08-15
**状態:** Merged

**説明:**

問題

ポイント送受信で以下のバグが発生:

  1. ユーザーAが100ptをユーザーBに送信
  2. 同時にユーザーBが100ptをユーザーAに送信
  3. 両者のポイントが増加(残高の不整合)

原因

トランザクション管理がなく、レースコンディション

対策

すべてのウォレット操作をトランザクション内で実行


**レビューコメント:**
- "トランザクションを必須にするのは良い判断"
- "パフォーマンスへの影響は?" → "問題なし、10ms以下"

**推論:**
- 実際に本番でバグが発生していた
- データ整合性を最優先する文化
- パフォーマンスよりも正確性

---

#### PR #78: セキュリティ修正
**タイトル:** Add RLS to all wallet queries
**作成日:** 2025-03-15
**状態:** Merged

**説明:**

問題

セキュリティ監査で指摘: ユーザーAが他ユーザーのウォレット情報を取得可能

原因

一部のクエリで ctx.issuer を使用していない

対策

全てのRepositoryメソッドでRLSを適用


**レビューコメント:**
- "Critical なセキュリティバグ、即座にマージすべき"
- "テストカバレッジを100%にして"

**推論:**
- セキュリティインシデントが発生した可能性
- 監査プロセスが機能している
- セキュリティを非常に重視

ステップ5: コードレビューコメントの分析

過去のコードレビューから設計思想を推論:

# PRのレビューコメントを取得
gh api repos/Hopin-inc/civicship-api/pulls/45/reviews

レビューコメント分析:

## コードレビューから見える設計思想

### 頻出するレビュー指摘

#### 1. トランザクション管理

**コメント例:**

このメソッドはトランザクション内で呼ばれる可能性があるので、 tx パラメータを追加してください。


**頻度:** 10回以上

**推論される原則:**
- トランザクション管理は必須
- 全てのメソッドで tx を伝播すべき
- データ整合性への強いこだわり

---

#### 2. エラーハンドリング

**コメント例:**

バリデーションエラーは Error ではなく、 ビジネス例外クラスを使ってください。


**頻度:** 5回以上

**推論される原則:**
- エラーを適切に分類
- クライアントに意味のあるエラーメッセージ
- デバッグしやすいコード

---

#### 3. テストカバレッジ

**コメント例:**

このメソッドのテストが不足しています。 エッジケースもカバーしてください。


**頻度:** 8回以上

**推論される原則:**
- テストを重視
- カバレッジ目標: 90%以上
- エッジケースを見逃さない

---

#### 4. パフォーマンス

**コメント例:**

このクエリはN+1問題を引き起こします。 DataLoaderを使用してください。


**頻度:** 3回以上

**推論される原則:**
- パフォーマンスを意識
- N+1問題は許容しない
- スケーラビリティを考慮

ステップ6: チーム文化の推論

コミットメッセージ、PR、レビューから組織文化を推論:

## チーム文化の推論

### 開発プロセス

#### コードレビュー文化
- **全PRにレビュー必須**
- 平均レビュー数: 2-3名
- レビュー期間: 1-2日
- マージ条件: 全レビュアーの承認 + CI通過

**推論:**
- 品質を重視する文化
- チーム間のナレッジ共有
- 属人化を防ぐ仕組み

---

#### テスト文化
- **テストなしのPRはマージされない**
- カバレッジ目標: 90%
- E2Eテストも重視

**推論:**
- テスト駆動開発(TDD)に近い文化
- 品質保証を最優先

---

#### セキュリティ意識
- **セキュリティ監査を定期実施**
- RLSを徹底
- センシティブデータの取り扱いに厳格

**推論:**
- 金融系・個人情報を扱うプロダクト
- セキュリティインシデントを経験している可能性
- コンプライアンスを重視

---

### 技術的な価値観

#### 優先順位

1. **正確性 > パフォーマンス**
   - トランザクション必須化
   - 厳格なバリデーション

2. **セキュリティ > 利便性**
   - 全クエリにRLS
   - 認証・認可の徹底

3. **保守性 > 開発速度**
   - Clean Architecture準拠
   - リファクタリングを厭わない

4. **テスト > 機能追加**
   - 高いカバレッジ要求
   - エッジケースの網羅

**推論:**
- 長期的な運用を見据えた設計
- 技術的負債を許容しない文化

ステップ7: 設計パターンの推論

コードの進化から設計パターンを推論:

## 設計パターンの進化

### パターン1: トランザクション管理

**進化:**

V1: トランザクションなし ↓ V2: 一部のメソッドにトランザクション ↓ V3: 全メソッドでトランザクション必須 ↓ V4: UseCaseでトランザクション管理、Serviceは伝播のみ


**推論される設計思想:**
- レイヤー責任の明確化
- UseCaseがトランザクション境界
- Serviceはビジネスロジックのみ

---

### パターン2: エラーハンドリング

**進化:**

V1: 例外をそのままthrow ↓ V2: カスタムエラークラス導入 ↓ V3: エラーコードの統一 ↓ V4: GraphQLエラーとの統合


**推論される設計思想:**
- ユーザーフレンドリーなエラーメッセージ
- デバッグしやすいエラー情報
- クライアント側での適切なハンドリング

---

### パターン3: データアクセス

**進化:**

V1: Serviceが直接Prismaを呼ぶ ↓ V2: Repository層を導入 ↓ V3: Converter層を導入(入力変換) ↓ V4: Presenter層を導入(出力変換)


**推論される設計思想:**
- Clean Architectureへの段階的移行
- 各レイヤーの責任を明確化
- テストしやすい構造

ステップ8: 技術的決定の背景推論

なぜこの技術選択をしたのかを推論:

## 技術的決定の背景

### 決定1: Prisma ORM 採用

**推論される理由:**
1. **型安全性:** TypeScriptとの親和性
2. **マイグレーション:** スキーマ管理が容易
3. **開発効率:** 生SQLを書く必要がない
4. **コミュニティ:** 活発なエコシステム

**裏付け:**
- 初期コミットからPrisma使用
- マイグレーションファイルが整然と管理されている
- Prisma独自の機能(RLS、トランザクション)を活用

---

### 決定2: GraphQL 採用

**推論される理由:**
1. **柔軟性:** クライアントが必要なデータのみ取得
2. **型安全性:** スキーマ駆動開発
3. **フロントエンドとの親和性:** React/Apollo との統合
4. **N+1防止:** DataLoaderでパフォーマンス最適化

**裏付け:**
- DataLoaderの積極的な活用
- GraphQL Code Generatorでの型生成
- スキーマファーストな開発プロセス

---

### 決定3: tsyringe(DI) 採用

**推論される理由:**
1. **テスタビリティ:** モック化が容易
2. **疎結合:** 依存関係の明確化
3. **保守性:** インターフェースベースの設計
4. **スケーラビリティ:** 依存関係の管理が容易

**裏付け:**
- 全てのクラスで `@injectable()` を使用
- テストでのモック差し替えが一貫している
- インターフェース(IXxxRepository)の徹底

ステップ9: 暗黙的な制約の発見

コードから暗黙的なビジネスルール・制約を推論:

## 暗黙的な制約

### 制約1: 1ユーザー = 1ウォレット

**コード:**
```typescript
const wallet = await this.repo.findByUserId(ctx, userId, tx);
// 配列ではなく単一オブジェクトを返す

推論:

  • ビジネスルール: ユーザーは1つのウォレットのみ
  • 将来的に複数ウォレット対応は想定外
  • データモデル:
    userId UNIQUE
    制約

制約2: ポイントは整数のみ

コード:

balance: Int  // Prismaスキーマ

推論:

  • ビジネスルール: 小数点以下のポイントは存在しない
  • 1pt = 最小単位
  • 将来的に小数対応は大きな変更

制約3: マイナス残高は許容しない

コード:

if (balance < requiredPoints) {
  throw new Error("INSUFFICIENT_BALANCE");
}

推論:

  • ビジネスルール: 借金(マイナス残高)は不可
  • 前払いシステム
  • 与信機能は存在しない

制約4: ポイント送受信は同一コミュニティ内のみ

コード:

const fromWallet = await this.repo.findByCommunity(ctx, fromUserId, communityId, tx);
const toWallet = await this.repo.findByCommunity(ctx, toUserId, communityId, tx);

推論:

  • ビジネスルール: コミュニティをまたいだポイント移動は不可
  • コミュニティごとに独立した経済圏
  • 将来的にクロスコミュニティ機能は大きな変更

---

### ステップ10: 意図推論レポートの生成

```markdown
# 設計意図推論レポート

**対象:** WalletService
**分析日:** 2026-01-15

---

## エグゼクティブサマリー

### 設計の核心

**このコードは何のために存在するか:**
- ポイント経済システムの中核
- データ整合性とセキュリティを最優先
- スケーラブルで保守しやすい設計

**主要な設計判断:**
1. トランザクション必須化(データ整合性)
2. RLS徹底(セキュリティ)
3. Clean Architecture準拠(保守性)
4. 厳格なバリデーション(信頼性)

---

## 歴史的文脈

### タイムライン

**2023年6月:** 初期実装
- シンプルなCRUD操作
- トランザクション未対応

**2023年8月:** レースコンディション発生
- 本番でバグ → トランザクション必須化
- データ整合性への意識向上

**2024年2月:** マイナス残高バグ
- バリデーション不足 → 厳格化
- 防御的プログラミングへ

**2024年6月:** スケーラビリティ問題
- ユーザー増加 → パフォーマンス最適化
- キャッシュ導入

**2025年3月:** セキュリティ監査
- RLS漏れ → 全面適用
- セキュリティ最優先へ

---

## 変更時の注意事項

### してはいけないこと

1. **トランザクションを削除しない**
   - 理由: 過去にレースコンディションで不整合発生
   - 正確性 > パフォーマンス

2. **RLSをスキップしない**
   - 理由: セキュリティ監査で指摘された過去あり
   - 全クエリで `ctx.issuer` 必須

3. **バリデーションを緩和しない**
   - 理由: マイナス残高バグの再発防止
   - ビジネスルールの厳格な適用

4. **1ユーザー1ウォレットの前提を崩さない**
   - 理由: システム全体がこの前提で設計
   - 変更は全体への影響大

---

### 推奨される変更方法

**新機能追加時:**
1. 既存のトランザクションパターンに従う
2. テストカバレッジ 90%以上
3. セキュリティレビュー必須

**パフォーマンス改善時:**
1. 正確性を損なわない
2. キャッシュ導入は慎重に
3. ベンチマークで検証

**リファクタリング時:**
1. Clean Architecture パターンを維持
2. レイヤー責任を明確に
3. 段階的に実施

---

## 将来の方向性

### 予想される課題

1. **複数ウォレット対応**
   - 現状: 1ユーザー1ウォレット
   - 変更影響: システム全体

2. **クロスコミュニティ送金**
   - 現状: 同一コミュニティ内のみ
   - 変更影響: トランザクション境界の再設計

3. **小数点ポイント対応**
   - 現状: 整数のみ
   - 変更影響: 型定義、計算ロジック全体

---

## 参考資料

- PR #45: トランザクション対応
- PR #78: セキュリティ修正
- Issue #23: マイナス残高バグ
- Issue #67: パフォーマンス劣化

活用例

例1: なぜこのコードがこう書かれているか

/infer-intent "WalletServiceのtxパラメータが必須な理由"

出力:

  • Git履歴からレースコンディションのバグを発見
  • トランザクション必須化の背景を説明

例2: 変更してはいけない箇所の特定

/infer-intent src/application/domain/account/wallet/service.ts

出力:

  • 過去のバグ修正履歴
  • 変更時の注意事項

注意事項

推論の限界

  • ❌ コミットメッセージが不明確な場合、推論不可
  • ❌ 口頭での決定事項は把握できない
  • ❌ ビジネス要件の詳細は不明

推奨される使い方

  • ✅ 変更前に設計意図を理解
  • ✅ 新メンバーのオンボーディング
  • ✅ リファクタリング前の調査

参考資料

以下については

@CLAUDE.md
を参照してください:

  • アーキテクチャパターン
  • トランザクション管理
  • RLSの使い方