ClaudeCode スラッシュコマンドで行うドメインファーストな開発

に公開

先日「永続化と切り離したドメインモデリング 」という記事を読み、そこで紹介されているドメインモデル、イベントを最初に定義し後から他を実装するフローを知りました。
ドメインの本来あるべき姿が合理的に実現できていいなと感じたのと同時に ClaudeCode のスラッシュコマンドで開発フローを表現すればより厳密に(設計からそれずに)ドメインファーストな開発ができるのではないかとも思いました。

弊社には I/O day という業務に関係のないインプット、アウトプットを1日してもいいという制度があり、それを利用してドメインファーストな開発を支援する ClaudeCode スラッシュコマンドを作成してみました。

厳密なドメイン駆動開発ではないと思っているのでこの記事では「ドメインファーストな開発」という回りくどい表現をしています。

この記事で紹介すること

  • レイヤードアーキテクチャにおける「中心から外へ」の設計思想
  • Claude Code のスラッシュコマンドを活用した開発ワークフロー

この記事で触れないこと

  • 具体的なプロジェクトの内容やビジネスドメイン
  • 各技術スタックの詳細な実装方法

導入の動機

永続化と切り離したドメインモデリング

はじめに記載した通りきっかけは「永続化と切り離したドメインモデリング 」という記事でした。

この記事で紹介されている Decider パターンでは:

  • ステート:現在の状態を表すイミュータブルなレコード
  • イベント:状態変化を記述するイミュータブルなレコード
  • Validate / Evolve 関数:「判断」と「状態遷移」の明確な分離

という構成でドメインロジックを純粋に保ち、永続化はフレームワーク側の責務として完全に分離しています。

この考え方を取り入れることで:

  • ビジネスロジックが特定のデータベース構造に依存しない
  • DB モックなしで単体テストが可能
  • インフラの変更(PostgreSQL → 別の DB 等)がドメインコードに影響しない

といったメリットが得られます。

Claude スラッシュコマンドとの相性

この開発手法は「レイヤーごとに順序立てて設計・実装する」という明確なプロセスを持っています。

Claude Code のスラッシュコマンド機能を使えば、この設計思想を開発ワークフローとして定義し、AI と協働で一貫した開発を進められると考えました。


設計思想

ドメインファーストな開発

このアーキテクチャの核心は、ドメイン(モデルと振る舞い)を最も重要なリソースとして中心に据え、そこから依存関係を遡るように実装を進めるという考え方です。

       +---------------------------+
       |      presentation         |   ← 最後に実装
       +---------------------------+
       |        use_case           |
       +---------------------------+
       |    ports / repository     |
       +---------------------------+
       |         domain            |   ← 最初に実装
       +---------------------------+

なぜドメインファーストなのか

従来の開発では、DB スキーマや API 仕様を先に決め、それに合わせてビジネスロジックを書くことが多いです。
しかしこのアプローチでは:

  • ビジネスルールが永続化の都合で歪められる
  • テーブル設計の変更がドメインコード全体に波及する
  • 本質的なビジネスロジックがインフラコードに埋もれる

という問題が起こりがちです。

このアプローチでは:

  1. まず純粋なビジネスロジックをドメイン層に定義
  2. ドメイン層は永続化や外部システムの存在を知らない形で設計
  3. 外側のレイヤー(repository、presentation 等)は後から実装

この順序により、ドメインロジックが技術的詳細に汚染されることを防ぎます。

レイヤーの責務と依存関係

レイヤー 責務
domain モデルとアクション(純粋なビジネスロジック)。何にも依存しない
ports リポジトリのトレイト定義。domain のみに依存
use_case アクションのオーケストレーション。ports と domain に依存
infrastructure DB 接続など純粋な技術機能。外部ライブラリに依存
repository ports の実装。infrastructure を利用して永続化
presentation リクエスト、レスポンスを扱う use_case を呼び出す薄い層
presentation → use_case → ports → domain
                           ↑
                      repository → infrastructure

domain は何にも依存せず、repositoryports のトレイトを実装することで、ドメインコードを変更せずにインフラを差し替え可能にしています。


Claude スラッシュコマンドによる開発ワークフロー

この設計思想を実践するため、Claude Code のスラッシュコマンドを活用した2つのコマンドを用意しました。

/design - 設計コマンド

機能要件からレイヤー別の設計仕様を作成するコマンドです。

/design {機能要件}

このコマンドが行うこと

  1. 要件分析

    • 機能要件・非機能要件の整理
    • 各レイヤーへの影響範囲の特定
  2. タスク分解

    • レイヤーごとにタスクを分割
    • レイヤーの依存関係に従った順序でタスクを定義
  3. 設計ドキュメントの出力

    • Feature 仕様(全体の要件分析)
    • Task 仕様(各タスクの詳細設計)

タスク分解の原則

レイヤーの依存関係に従い、内側から順に実装することがポイントです:

1. domain         ← 何にも依存しない(最初に実装)
2. ports          ← domain に依存
3. use_case       ← ports, domain に依存
4. infrastructure ← 外部技術に依存
5. migration      ← DB スキーマ定義
6. repository     ← ports, infrastructure に依存
7. presentation   ← use_case に依存(最後に実装)

この順序により、各タスクが独立してコンパイル・テスト可能になります。

出力例

.agents/features/archive-project/
├── spec.md                        # 要件分析 + タスク一覧
└── tasks/
    ├── 01-domain-model/
    │   └── spec.md
    ├── 02-domain-action/
    │   └── spec.md
    ├── 03-ports/
    │   └── spec.md
    └── ...

/dev - 実装コマンド

/design で作成されたタスク仕様に基づいて、単一タスクを実装するコマンドです。

/dev archive-project/01-domain-model

このコマンドが行うこと

  1. タスク仕様の読み込み

    • 指定されたパスの spec.md を解析
    • 依存タスクの完了状況を確認
  2. 実装計画の提示

    • 変更対象ファイルと実装順序を提示
    • ユーザーの承認を得てから実装開始
  3. 実装

    • レイヤー境界を厳守(domain タスクでは domain 配下のみ変更)
    • コンパイル確認・テスト実行
  4. 完了報告

    • 変更ファイル一覧
    • 完了条件の確認結果
    • 次のタスクの提示

レイヤー境界の厳守

/dev コマンドの重要なルールは、タスクが対象とするレイヤー以外のコードは絶対に変更しないことです。

例えば 01-domain-model タスクでは domain/ 配下のみを変更し、use_case/presentation/ には一切触れません。

これにより:

  • 各タスクの変更範囲が明確
  • レビューとロールバックが容易
  • 依存関係の逆転を防止

ワークフローの全体像

これらのコマンドを使った開発フローは以下のようになります:

┌─────────────────────────────────────────────────────────┐
│  1. 機能要件を整理                                        │
│     ユーザー:「〇〇の機能を追加したい」                     │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  2. /design で設計                                       │
│     - 要件分析                                           │
│     - レイヤー別の影響範囲を特定                          │
│     - タスクを依存順序で分解                              │
│     - 設計ドキュメントを出力                              │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  3. /dev でタスクごとに実装                               │
│     - 01-domain-model → 02-domain-action → 03-ports...  │
│     - 各タスクでコンパイル・テスト確認                     │
│     - 内側から外側へ順に完成していく                       │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  4. 機能完成                                             │
│     - すべてのタスクが完了                                │
│     - 設計からテストまで一貫した品質                       │
└─────────────────────────────────────────────────────────┘

この手法のメリット

1. 設計と実装の一貫性

/design で作成した設計が /dev の入力になるため、設計と実装の乖離が起きにくくなります。設計ドキュメントがそのまま実装の指示書として機能します。

2. レイヤー責務の強制

/dev コマンドがレイヤー境界を厳守するため、ドメインロジックがインフラ層に漏れ出すことを防げます。これは人間がコードレビューで担保するよりも確実です。

3. 段階的な実装

依存順序に従ったタスク分解により、各タスクが独立してコンパイル・テスト可能になります。大きな機能追加でも「ここまでは動く」という状態を保ちながら進められます。

4. 知識の外部化

設計思想やレイヤーごとのルールがスラッシュコマンドのプロンプトに明文化されているため、チームの暗黙知に依存しません。


おわりに

ドメインファーストな開発アプローチと ClaudeCode スラッシュコマンドの組み合わせは、設計思想を開発ワークフローとして実装する一つの方法です。

この仕組みの本質は:

  • ドメインを中心に据えるという設計思想を
  • スラッシュコマンドというワークフローとして定義し
  • AI と協働で一貫した開発を進める

という点にあります。

特に「レイヤー境界の厳守」は人間だけでは維持が難しいルールですが、スラッシュコマンドとして定義することで、AI がそのルールを守りながら実装を進めてくれます。

ENECHANGE

Discussion