dto-creator について
dto-creatorは、SpringプロジェクトでエンティティからDTOを生成するSpring Agent Toolkitのスキルです。Javaクラス、record、Lombok、Kotlin data classに対応し、利用可能なサンプルに沿ってコードを作成します。
主な機能
- 01エンティティからDTOを作成
- 02Javaクラスとrecordに対応
- 03LombokとKotlin data classに対応
- 04フィールド、バリデーション、サブDTOを設定
- 05Spring MCPツールとコードサンプルが必要
活用シーン
- 01エンティティからAPI用DTOを生成
- 02エンティティのフィールドと関連DTOを選択
- 03プロジェクトの言語や依存関係に応じたDTO形式の選択
MCP 対応
Amplicode IntelliJプラグインが提供するSpring MCPサーバーを利用し、プロジェクト、依存関係、エンティティの情報を取得します。ツールが使えない場合は、プラグインを導入してMCPを接続する必要があります。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ amplicode/ spring-skills --skill dto-creatorインストール後、Claude Code で/dto-creatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/_fragments/constructor/java/all-args.mdexamples/_fragments/equals-hashcode/java/equals-hashcode-hibernate.mdequals-hashcode.mdexamples/_fragments/fields/java-lombok.mdjava-record.mdjava.mdkotlin.mdexamples/_fragments/fluent-setters/java/fluent-setters.mdexamples/_fragments/getters-setters/java/getters.mdsetters.mdexamples/_fragments/javadoc/java/javadoc.mdexamples/_fragments/json-ignore/java/json-ignore.mdexamples/_fragments/lombok/lombok.mdexamples/_fragments/nested-class/java/nested-class.mdexamples/_fragments/nested-class/kotlin/nested-class.mdexamples/_fragments/serializable/java/serializable.mdexamples/_fragments/serializable/kotlin/serializable.mdexamples/_fragments/tostring/java/tostring.mdexamples/_skeletons/java/class.mdrecord.mdexamples/_skeletons/kotlin/class.mddata-class.mdreferences/java-lombok.mdjava-plain.mdjava-record.mdkotlin.mdsub-dto.mdvalidation.md詳細
事前確認:Spring MCP
このスキルは Spring Agent Toolkit の一部であり、Spring MCP サーバー(Amplicode IntelliJ プラグインが提供)と連携するよう設計されています。ほかの作業を始める前に、ツール一覧に Spring MCP ツールがあるか確認してください。これらは amplicode MCP サーバー配下に公開されます(例:get_project_summary、list_module_dependencies、get_entity_details)。MCP ツールをツール一覧にまとめるハーネスでは、同じ名前に mcp__amplicode__ プレフィックスが付きます。
- Amplicode ツールが1つ以上ある場合 — MCP は接続されています。以下のスキルを続行してください。
- 使えるツールがない場合 — 停止して
amplicode-installスキル(Spring Agent Toolkit に同梱)を呼び出してください。このスキルは Amplicode プラグインをインストールし、ウェルカム画面の «Настроить Spring Agent» ボタンの操作と MCP クライアントの再起動をユーザーに案内します。完了すると MCP ツールが使えるようになります。その後、このスキルを再開してください。 - スキル一覧に
amplicode-installが登録されていない場合は、ユーザーの言語で次のように伝えてください:"このスキルには Amplicode IntelliJ プラグインとその MCP サーバーが必要です。https://amplicode.ru/marketplace から IntelliJ IDEA Ultimate/Community または GigaIDE にインストールし、任意のプロジェクトを開いて、Amplicode のウェルカム画面にある «Настроить Spring Agent» をクリックしてから、MCP クライアントを再起動してください。"
DTO 作成
選択した属性を持ち、コンストラクター、ゲッター/セッター、equals/hashCode、toString、およびオプション機能を備えた、エンティティ用の DTO クラス(Java クラス、Java レコード、Java+Lombok、Kotlin データクラス)を作成します。
重要:コードは必ず examples/ ファイルの例に基づいて作成してください。一致する例がない場合は、処理を停止してユーザーに確認してください。 重要:選択肢が決まっている質問では、
AskUserQuestion> その類似機能 > 通常のテキスト一覧の順に優先してください。番号付きのテキスト一覧は、対話型ツールが使えない場合の最終手段です。 重要:ステップ1を実行する前に、会話のコンテキストを確認してください。 ステップ2~7の質問の半分は、ユーザーのプロンプトや過去のやり取りですでに回答されている可能性があります。すでに伝えられた内容を再度尋ねることが、このスキルが遅く感じられる最大の理由です。 ステップ7(マッパー)は、変換が必要な場合は自動的に実行します。 DTO がエンティティと DTO の相互変換を行うコード(コントローラー、サービス、エンドポイントの置き換えなど)で使用されることがコンテキストから明らかな場合、このスキルは必ずmapper-creatorに委任してください。インラインで手動のマッピングコードを書いてはいけません。実装方法(MapStruct、Custom、依存関係の追加)はmapper-creatorスキルが判断します。このスキルは委任のみを行います。
デフォルト
| オプション | デフォルト | 常に確認する? | 備考 |
|---|---|---|---|
| entity | -- | YES | 主な分岐点:DTO を作成するエンティティ |
| attributes | エンティティの全フィールド | YES | 含めるフィールド |
| className | {EntityName}Dto | NO | 提案のみ。確認は不要 |
| language | get_project_summary から取得 | NO | 自動検出 |
| variant | 言語と依存関係から自動判定 | YES | Java クラス/Java レコード/Java+Lombok/Kotlin |
| mutable | false | NO | ユーザーがカスタマイズを希望しない限り省略 |
| allArgsConstructor | true | NO | Java のプレーンなクラスのみ |
| equalsHashCode | true | NO | Java のプレーンなクラスのみ |
| toString | true | NO | Java のプレーンなクラスのみ |
| fluentSetters | false | NO | mutable=true の場合のみ。Java のみ |
| jsonIgnoreUnknownProperties | false | NO | Java のみ。Jackson がクラスパスにある場合 |
| serializableType | NoSerializable | NO | 必要になることはまれ |
| packageName | エンティティと同じパッケージ | NO | 自動検出 |
| subDtoType(ToOne 関連ごと) | ID のみのサブ DTO を使う FLAT | YES | 4 つの選択肢があります:新しいクラス/新しいネストされたクラス/既存のクラス/フラット。「ID のみ」は独立した選択肢としてはありません。サブエンティティの id のみを選択したフラット形式です。references/sub-dto.md を参照してください。 |
| subDtoType(ToMany/コレクションごと) | NEW_NESTED_CLASS | YES | ToOne と同じ 4 つの選択肢です。コレクションでもフラット形式がサポートされており、Set<Integer> specialtyIds のような複合的な複数形のフィールドが生成されます。references/sub-dto.md を参照してください。 |
| fieldNameOverride(フィールドごと) | なし | NO | フィールドごとの名前変更 |
| extraValidations(フィールドごと) | なし | NO | 継承されたものに加えて、ユーザーが追加する jakarta バリデーター |
| removedValidations(フィールドごと) | なし | NO | ユーザーが削除したい、エンティティから継承された制約 |
| indent | .editorconfig から取得(フォールバックは 4 スペース) | NO | 以下の「インデント」を参照 |
スマートデフォルト: ユーザーが「デフォルトを使用」「すべてデフォルト」「デフォルト設定」などと言った場合は、「常に確認する?」が NO の質問をすべて省略してください。必須の質問のみ確認します。
スマート回答認識: ユーザーが番号付きリストから選ぶ代わりに値を指定した場合は、そのまま受け入れてください。例:
- 質問「どのエンティティですか?」→ ユーザーが「Order」と回答 → これをエンティティとして受け入れ、再確認しない
- 質問「バリアントは?」→ ユーザーが「record」と回答 → これを Java レコードとして受け入れ、選択肢を表示しない
- ユーザーが 1 つのメッセージで複数の回答を指定した場合 → すべて受け入れ、回答済みの質問を省略する
- ユーザーがすでに回答した質問は、明示的か暗黙的かを問わず、絶対に尋ねない
質問のまとめ方: 次の条件に当てはまる、密接に関連した質問は、1 回の
AskUserQuestion 呼び出しにまとめてください(1 回につき最大 4 問)。
- 同じ論理セクションに属する(例:どちらも Java メソッド生成の設定)
- 互いの回答に依存しない
- ユーザーが省略できる明確なデフォルトがある
ルール:
- 1 回の
AskUserQuestion呼び出しにつき、質問は最大 3~4 問 - 推奨する選択肢に
(Recommended)を付け、最初に配置する - 異なる分岐の質問をまとめない
- 主な分岐に関する質問(エンティティの選択、バリアント)は必ず単独で尋ねる
- 選択肢には
AskUserQuestionを優先し、ツールを利用できない場合のみ通常のテキストリストを使用する
意思決定の原則 — まずコンテキストを確認し、それから質問する
ユーザーに何か質問する前に、すでに収集したコンテキスト(プロジェクトの概要、モジュールの依存関係、エンティティの詳細、パッケージ内の既存ファイル、この会話の前のやり取り、ユーザーの元のプロンプト)から回答を導き出せるか試してください。コンテキストから明確なデフォルトを導けない場合、または選択が真にユーザー固有の場合(例:どのエンティティか、どのフィールドか)に限って質問してください。
意思決定の優先順位:
-
コンテキストから一意に決まる → 何も言わずに決定し、質問しない。 例:
get_project_summaryから取得する言語と JDK、list_module_dependenciesから取得する Lombok / Jackson / Hibernate Validator、エンティティの FQN から決まるパッケージ、{Entity}Dtoから決まる className、逆参照@ManyToOneのフィルタリング、サブエンティティのスカラー値の自動選択、JDK ≥ 16 で Lombok がなく、ユーザーが別の指定をしていない場合の record と通常のクラスの選択。 例外:subDtoType は、絶対に何も言わずに決定してはいけません — ユーザーが自身のメッセージで形状を明示している場合(ARGUMENTS ではなく)を除き、少なくとも原則 2 に従って一行で確認する必要があります。 -
コンテキストから有力な判断ができる → 決定内容と代替案を一行で伝え、ユーザーが変更するか、何も言わずに受け入れられるようにする。 形式:
Will create `ScheduleTemplateDto` as a Java record with nested `SlotDto` (record). Alternatives: plain class, Lombok, separate file for SlotDto. OK?ユーザーが「ok」/「yes」と答える、または何も答えない場合は、そのまま採用します。代替案を指定した場合は切り替えます。これは、番号付きの質問形式とは異なり、一行で確認する形式です。
-
コンテキストから明確なデフォルトを導けない →
AskUserQuestion(推奨)またはそれに相当する機能を使い、推奨オプションを先頭にして質問する。AskUserQuestionが利用できる場合は、previewフィールドを使って各オプションの具体的なコード形状がユーザーに見えるようにしてください。推奨オプションはラベルに(Recommended)を付けて先頭に置きます。対話形式の選択ツールを利用できない場合は、通常のテキストのリストを使います。 一度にまとめて質問できるのに、「どのバリエーションですか?」→ユーザーが選択→「どのフィールドですか?」→…のように、決して段階的に質問しないでください。 -
重要な入力に関するコンテキストがまったくない → 率直に質問する。 対象となるのは、どのエンティティか、どのフィールドか(「すべて」ではない場合)、ユーザー自身の意図です。
質問の方法 — AskUserQuestion を優先する
質問が必要な場合は、回答本文に番号付きリストを書くよりも、AskUserQuestion ツール(またはそれに相当する機能)を優先してください。対話形式の選択ツールを利用できない場合に限り、通常のテキストを使います。
このスキルでの AskUserQuestion 呼び出しに関するルール:
- 1 回の呼び出しには、互いに独立した質問を最大 4 件含められます(ツールがまとめて表示します)。これを利用して、関連する意思決定を 1 回のやり取りにまとめてください。
- 各質問の選択肢は 2~4 個です。自由入力用の「その他」はツールが自動で追加するため、手動で含めないでください。
- 推奨オプションは、先頭に置き、ラベルの末尾に
(Recommended)を付けて示します。 - 「含めるフィールド」や「追加するバリデーター」のように、複数の回答が有効な質問には
multiSelect: trueを使います。 headerは 12 文字のチップラベルです(例:「Variant」「Sub-DTO」「Fields」)。- 各オプションには、その選択の意味または結果を説明する短い文を
descriptionとして付けます。
AskUserQuestion が適切ではない場合:
- 選択肢を列挙できない自由入力(例:任意のクラス名、任意のフィールド名の変更)は、通常のテキストで質問します。
- 原則 2 の「一行で確認する」形式は、明確な yes / no で答えられる通常の質問です。選択肢の列挙ではありません。
以下のステップ 2~5 にある画面ベースの質問リストは、ケース 4 に対するフォールバックです。上から順に実行するための台本ではありません。原則 1~3 に従って質問の回答がすでに決まっている場合は、その質問を省略してください。プラグインのウィザードを忠実に再現することは目標ではありません。目標は正確に生成することです。画面では多くのコントロールを一度に表示できますが、チャットではできないため、このスキルではより多くの判断を自分で行う必要があります。
ステップ 0 -- まず会話のコンテキストを確認する(必須、ツール呼び出しなし)
MCP を呼び出す前、質問する前に、ユーザーのプロンプトとこの会話のこれまでのやり取りを読み直し、すでに述べられている情報を抽出します。このステップにはコストがかからず、このスキルで最もよくある失敗、つまりユーザーがすでに伝えたことを尋ねてしまうのを防ぎます。
明示的または暗黙的にユーザーがすでに提示した入力をすべて確認し、チェックリストを作成します。
| 入力 | プロンプト/コンテキストで確認する内容 |
|---|---|
| エンティティ | クラス名(Vet、Owner、ScheduleTemplate)、「X 向け」、IDE で開いているファイル、ファイルパス、この会話で最近話題にしたエンティティ |
| 目的 | 「REST 向け」「コントローラー向け」「API 向け」「マッピング向け」「プロジェクション」「サービス向け」—フィールドの選択とマッパーに関する質問を左右します |
| フィールド | 「すべてのフィールド」「id と name のみ」「password なし」「関連を含める」「フラット」 |
| バリエーション | 「record」「通常のクラス」「Lombok」「data class」—言語から推測できる場合もあります。Kotlin なら data class と判断し、質問しません |
| マッパー | 「マッパーも」「マッパー付き」「DTO のみ」「マッパーなし」 |
| className | 「OwnerSummaryDto と命名」「クラス Foo」 |
| パッケージ | 「パッケージ … に」「コントローラーの隣に」 |
| スマートデフォルト | 「デフォルトを使う」「すべてデフォルト」「デフォルト設定」「いつものように」 |
| サブ DTO の形状 | 「ネスト」「別クラス」「id のみ」「フラット」 |
| プロジェクトの既知情報 | 言語、JDK、依存関係 — この会話ですでに話題にした内容は既知です。再取得しないでください |
入力が明示的に、または強く暗示的に回答済みの場合は、決定済みとして印を付け、ステップ 2~7 で該当する質問をスキップします。ユーザーが「Vet の DTO を作成」と書いているなら、「どのエンティティですか?」と尋ねてはいけません。答えは Vet です。ユーザーが「DtoX の record を作成」と書いているなら、「Java record とクラスのどちらですか?」と尋ねてはいけません。答えは record です。
回答されていない入力については、以下の意思決定の原則に従います。まずステップ 1 でプロジェクトのコンテキストから推測し、その後に限り質問します。
重要:引数 ≠ ユーザーの意図。 このプロンプト末尾の ARGUMENTS ブロックは、呼び出し元のアシスタントが記述したものであり、ユーザーが記述したものではありません。アシスタント自身の分析、推測、フィールド単位の詳細が含まれている可能性があり、ユーザーが述べていない内容も含まれます。ユーザーが「すでに述べた」ことを判断するときは、会話履歴にある実際のユーザーメッセージだけを確認してください。ARGUMENTS をユーザーの入力の代わりとして扱ってはいけません。特に、ARGUMENTS にサブ DTO の形状が記載されているからといって、サブ DTO の形状について尋ねるのを省略してはいけません。
ステップ 0 は頭の中で行うものであり、ツール呼び出しではありません。ユーザーに告げてはいけません。「ステップ 0 完了」と書いてはいけません。ステップ 1 に進む前に、ユーザーがすでに伝えた内容を把握しておいてください。
ステップ 1 -- プロジェクトの最小限のコンテキストを収集する(自動、質問なし)
後続のステップで実際に結果を使用するMCP ツールのみを呼び出してください。「必要になるかもしれない」という理由で事前に取得しないでください。ここにあるすべての変数には、具体的な後続の用途が必要です。
| ツール | 変数 | 用途 |
|---|---|---|
get_project_summary | language、jdkVersion、moduleName | language → バリアントの選択(ステップ 4)と参照ファイル(java または kotlin)、jdkVersion → canUseRecords = jdkVersion >= 16、moduleName → 複数モジュールの判別と list_module_dependencies のパラメーター |
list_module_dependencies(moduleName) | presentDeps | 以下の導出フラグ — Lombok/Jackson/Validation の機能ゲート |
ステップ 1 は以上です。次は取得しないでください。
springBootVersion/bootMajor— これに依存する分岐はありませんbuildFile— DTO の生成ではビルドファイルを編集しません(追加する依存関係がありません)。DTO に必要なのは言語の構文だけですmainPackage— DTO のパッケージはプロジェクトルートではなく、エンティティの FQN から導出されますlist_application_properties_files/propsFile— DTO はapplication.propertiesに何も書き込みませんlist_all_domain_entities— ユーザーがプロンプトでエンティティを指定していない場合にのみ必要です。遅延フォールバックとしてステップ 2 に回してくださいget_entity_details/list_entity_dtos— エンティティを特定してから必要になります。それはステップ 2 で行います。ステップ 2 に回してください
導出変数(すべて presentDeps と get_project_summary から導出):
hasLombok=presentDepsにlombokが含まれるhasJackson=presentDepsにjackson-databindまたはjackson-coreが含まれるhasValidation=presentDepsにhibernate-validator、jakarta.validation-api、またはspring-boot-starter-validationが含まれるcanUseRecords=language == JAVAANDjdkVersion >= 16
複数モジュールのプロジェクト(get_project_summary に複数のモジュールがある場合):
どのモジュールを使用するか尋ねてください。その後、そのモジュールについて list_module_dependencies を再度呼び出してください。
ステップ 2 -- エンティティの選択
ステップ 0 の時点で、ユーザーがエンティティに言及していれば、すでに特定できているはずです。
最も一般的なケース:ユーザーが「Vet の DTO を作成して」と書いた場合 → エンティティは Vet です。質問は省略し、以下の並列取得に進んでください。
遅延フォールバック — エンティティが不明な場合のみ: list_all_domain_entities(moduleName) → entities を呼び出し、その後 AskUserQuestion で質問してください(選択肢 = リスト内のエンティティ名、最大 4 件。エンティティが 4 件を超える場合は、コンテキストに基づいて可能性の高い候補を 4 件選び、ユーザーが「Other」から別の名前を入力できる旨を注記します)。
list_all_domain_entities を呼び出すのはここだけです。ユーザーがプロンプトでエンティティを指定している場合は、呼び出さないでください。
エンティティの FQN が判明したら、並列で呼び出してください:
| ツール | 変数 | 用途 |
|---|---|---|
get_entity_details(entityFqn) | entityDetails | ステップ 3 の属性選択、関連の分析、バリデーションの継承、すべてのバリアントの参照における生成順 |
親エンティティに対する list_entity_dtos(entityFqn) はここでは呼び出しません — 後続で使用する箇所がないためです。サブエンティティに対する呼び出し(list_entity_dtos(subEntityFqn))は、references/sub-dto.md での EXIST_CLASS 判定に引き続き必要ですが、遅延実行され、関連ごとに行われます。ユーザーに EXIST_CLASS オプションを提示する場合にのみ呼び出してください。正確な箇所は references/sub-dto.md を参照してください。
DTO の名前の衝突は、別の遅延呼び出し list_existing_classes(package) で処理します。これはステップ 6 の生成直前に呼び出します(幻覚防止チェックリストを参照)。ステップ 2 には含まれません。
ステップ 3 -- 属性の選択
デフォルト:すべてのスカラー属性とすべての関連を含めます(references/sub-dto.md のサブ DTO のデフォルト設定に従います)。コンテキストからユーザーがより限定的な内容を望んでいると判断できる場合にのみ、質問してください。
コンテキストから判断する(質問するより優先)
ステップ 0 で把握した目的を参考に、妥当なデフォルトのフィールドセットを選びます。
| 目的を示す表現 | デフォルトのフィールドセット |
|---|---|
| 「REST 用」「コントローラー用」「API 用」 | すべてのスカラー項目+すべての関連を展開(ToMany は NEW_NESTED_CLASS、ToOne は FLAT id)—関連データも含めたレスポンスの形を求めているため |
| 「プロジェクション」「概要」「一覧表示」「一覧用」 | スカラー項目のみ、ToOne 関連は Flat id、ToMany は除外 |
| 「マッピング用」「サービス用」「保存用 DTO」 | すべてのスカラー項目+すべての関連を展開 |
| 「id と name のみ」/明示的なフィールドリスト | ユーザーが指定したもののみ。それ以外は含めない |
| 目的を示す表現がない | すべてのスカラー項目+すべての関連を展開(妥当な範囲で最も充実したデフォルト) |
選択したデフォルトがユーザーの意図と一致しているようであれば、質問しないでください。 そのまま生成します。原則 2 の 1 行確認形式で、選択内容を伝える場合も 1 行までにしてください。
質問する場合
次の場合に限り質問します。
- ユーザーが明示的に「フィールドを選んで」「フィールドについて質問して」「設定を微調整して」と述べた場合、または
- エンティティにフィールドが多数あり、目的を示す表現が曖昧で、かつユーザーが「デフォルトを使って」と述べていない場合
質問する場合は、multiSelect: true を指定して AskUserQuestion を使用します。
| 質問 | ヘッダー | 選択肢(先頭が推奨) |
|---|---|---|
DTO {Entity}Dto に含めるフィールドはどれですか? | フィールド | すべてのフィールド+関連(推奨)/スカラー項目のみ/id と name のみ/手動で指定 |
含める各関連には、references/sub-dto.md のサブ DTO のデフォルトを適用してください。ユーザーが明示的に細かい制御を求めていない限り、関連ごとに質問しないでください。
ステップ 4 -- バリアントの選択
上記の判断原則を適用します。バリアントはほとんどの場合コンテキストから判断できるため、明示的に質問するのは例外であり、デフォルトではありません。
language=KOTLIN の場合: references/kotlin.md に従います。質問しません。
language=JAVA の場合: 次のように判断します。
| コンテキスト | アクション | バリアント |
|---|---|---|
hasLombok = true かつユーザーがプロンプトで Lombok に明示的に言及している | 何も尋ねずに判断 | references/java-lombok.md |
canUseRecords = true かつ hasLombok = false かつユーザーが可変性/セッター/Lombok を求めていない | 何も尋ねずに判断し、原則 2 の 1 行確認で伝える | references/java-record.md |
canUseRecords = false かつ hasLombok = false | 何も尋ねずに判断 | references/java-plain.md |
hasLombok = true かつ canUseRecords = true で、ユーザーからの指定がない | 原則 2 の 1 行確認形式を使う:「Java record として作成します(JDK ≥ 16、Lombok なし)。ほかの選択肢:通常のクラス、Lombok。よろしいですか?」 | 回答に応じて決定 |
| ユーザーが「通常のクラス」「可変」「セッター付き」と明示した | 何も尋ねずに判断 | references/java-plain.md |
| ユーザーが「record」と明示した | 何も尋ねずに判断 | references/java-record.md |
| ユーザーが「Lombok」と明示した | 何も尋ねずに判断(hasLombok = true の場合のみ。そうでない場合は警告して代替を選択) | references/java-lombok.md |
上記のいずれにも該当せず、かつユーザーが「デフォルトを使って」と述べていない場合に限り、番号付きの質問をすべて行います。その場合も、質問を重ねていく形式より、原則 3 の「デフォルトを明示した全バリアント」形式を優先してください。
回答とバリアントの対応:
- plain →
references/java-plain.md - record →
references/java-record.md - Lombok →
references/java-lombok.md
ステップ 5 -- バリアント固有の質問
選択したリファレンスファイルに記載されている、バリアント固有の質問に従います。 ユーザーが「すべてデフォルト」と述べていない場合に限り質問してください。
ステップ 6 -- コードを生成する
-
出力先のパスを決定します。
src/main/{java|kotlin}/{packagePath}/{className}.{java|kt} -
選択したリファレンスファイルの生成順序に従います。
-
各ステップで、次のようにします。
スケルトン(新規ファイル)の場合:
examples/_skeletons/からスケルトンの.mdを読み取ります- 変数を置換します
- Write ツールを使用してファイルを作成します
フラグメントの場合:
examples/_fragments/からフラグメントの.mdを読み取ります- 挿入ポイントを読み取り、挿入場所を確認します
- Edit ツールを使用して、指定された位置にコードを挿入します
- 変数を置換します
-
変数の置換ルール:
{packageName}-> エンティティのパッケージ、またはユーザーの選択値{className}-> ユーザー指定の値、またはデフォルトの{EntityName}Dto- フィールド単位の変数 -> エンティティの詳細情報
- Variables に記載されていないものは絶対に置換しないでください
- 例に含まれていない import、メソッド、コードは絶対に追加しないでください
- FQN の処理(重要): 例には FQN(例:
java.util.Objects、java.util.List、jakarta.validation.constraints.NotNull)が含まれています。最終ファイルを作成する際は、必ず次の手順に従ってください。- クラス本体にあるすべての FQN を短縮名に置き換えます(例:
java.util.Objects.hash(...)->Objects.hash(...)、java.util.List<Integer>->List<Integer>、@jakarta.validation.constraints.NotNull->@NotNull)。 - 短縮したすべての FQN を集め、対応する
import行をpackage文の直後に、アルファベット順で重複なく出力します。 java.langの型(String、Integer、Objectなど)は import してはならず、短縮名で記述します。- DTO と同じパッケージにあるクラスは import してはなりません。
- Javadoc の
{@link ...}参照 — 統一ルール: あらゆる形式について、{@link …}内では短縮名 + import を使用してください。対象は、トップレベルの Java クラス、トップレベルの Java レコード、ネストされた static クラス、ネストされたレコード、別ファイルのサブ DTO(NEW_CLASS)です。例外はありません。エンティティへの参照は必ず短縮し、対応するimport行を必ず追加してください(エンティティが同じパッケージにある場合を除く)。 importを 2 つのブロックに分け、間に空行を 1 行入れてください。- ブロック 1 — サードパーティおよびプロジェクトの import をまとめます。
jakarta.*、com.fasterxml.*、org.springframework.*、org.hibernate.*、プロジェクトパッケージなどを含みます(ブロック内はアルファベット順)。 - (空行)
- ブロック 2 —
java.*およびjavax.*(アルファベット順)。 ブロック 1 をパッケージごとのサブブロックに分けないでください。 最終ファイルでは、本体(すべての Javadoc{@link …}を含む)に短縮名を使用し、先頭に整理されたグループ別の import ブロックを配置してください。
- ブロック 1 — サードパーティおよびプロジェクトの import をまとめます。
- クラス本体にあるすべての FQN を短縮名に置き換えます(例:
-
サブ DTO(subDtoType=NEW_CLASS)の場合:サブエンティティに対して手順 6.1~6.4 を再帰的に繰り返し、別ファイルを作成します。
-
ネストされたクラス(subDtoType=NEW_NESTED_CLASS)の場合:親 DTO ファイルに内部クラスを追加し、同じフラグメントのルールに従って内容を記述します。
-
レコードを親に持つネスト — 必須: 親 DTO が Java レコードの場合、NEW_NESTED_CLASS の関連はすべて、親レコードの本体内にネストされた
public recordとして出力する必要があります。レコード形式のフラグメントのほうが短く見えるという理由だけで、スキルが暗黙的に NEW_CLASS(別ファイル)へ切り替えてはなりません。手順の全容はreferences/java-record.mdの Step 6 とexamples/_fragments/nested-class/java/nested-class.mdの「Java record」バリアントを参照してください。これらの指示が曖昧に思える場合、それはスキルの不具合です。subDtoTypeを変更して回避するのではなく、ドキュメントを修正してください。
ステップ 7 -- マッパー(変換が必要な場合に自動実行)
コンテキストに基づいてマッパーが必要かどうかを判断し、対応します。
| シグナル | アクション |
|---|---|
| ユーザーが「DTO のみ」「マッパーなし」「マッパーを使わずに」と述べた | ステップ 7 全体をスキップします。マッパーに言及してはいけません。 |
| ユーザーが明示的にマッパーを依頼した(「マッパーも」「マッパー付きで」「マッパーも作成」など) | 直ちに mapper-creator に委任します。 |
| コンテキストから、エンティティ↔DTO の変換が行われることが明らか(コントローラー/サービス/エンドポイントでエンティティを DTO に置き換えるよう依頼された、変換/マッピング/変形を依頼された、DTO が REST API 用である、など) | 直ちに mapper-creator に委任します。変換は避けられません。マッパーなしで DTO を作成すると、インラインで手動マッピングコードを書くことになりますが、これは決して許容されません。 |
| コンテキストから判断できない — DTO の用途に関するシグナルがない | ステップ 7 をスキップします。マッパーに言及してはいけません。 |
重要: 手動のマッピングコード(コントローラー、サービス、その他の場所でのインライン toDto/fromDto メソッド)は決して書いてはいけません。変換が必要な場合は、必ず mapper-creator に委任します。このスキルが実装方針(MapStruct、カスタムマッパー、依存関係の追加)を決定します。このスキルが行うのは委任だけです。
マッパーについて AskUserQuestion で質問してはいけません。委任する場合は、DTO とエンティティの情報を直接 mapper-creator スキルに渡してください。ユーザーに委任の確認を求めてはいけません。
インデント
スキルはプロジェクトのインデントスタイルを必ず検出しなければなりません。タブまたはスペースを決め打ちしてはいけません。検出順序は次のとおりです。
- プロジェクトルート(または対象ファイルのディレクトリの親ディレクトリ)にある
.editorconfig。Java ファイルの場合は[*.java]または[*]セクションを確認し、indent_style(tabまたはspace)とindent_size/tab_widthを読み取ります。 - 同じパッケージ内(または Java ファイルを含む最も近い上位パッケージ内)の既存の Java ファイルのサンプル。インデントされた行の先頭の空白文字が
\tかスペースか、またその数を検出します。 - どちらからも判断できない場合は、デフォルトで 4 スペースにします。(開発者が明示的にタブを好む場合は、タブをデフォルトにしても構いませんが、スキルがどちらかをひそかに決めつけてはいけません。)
どのスタイルを選んでも、生成するすべての断片のすべての行(フィールド、コンストラクター、ゲッター/セッター、equals/hashCode、toString、ネストされたクラス/レコード)に一貫して適用してください。同じファイル内でタブとスペースを混在させてはいけません。
フィールドごとのオプション
スキルは、フィールドごとに次の設定をサポートしなければなりません。
- フィールド名の変更(
fieldNameOverride):DTO フィールド名をエンティティ属性名と異なる名前にできます。マッパーの生成では、引き続き元の属性からマッピングします。 - バリデーションの追加(
extraValidations):ユーザーは、エンティティから継承した制約に加えて jakarta/hibernate-validator の制約を追加できます。許可される制約のリストはフィールドの型によって異なります。references/validation.mdを参照してください。 - 継承したバリデーションの削除(
removedValidations):ユーザーは、エンティティフィールドに由来する任意の制約を削除できます。 - アノテーションパラメーターの編集(
message、min、max、regexp、…):すべての制約のすべてのパラメーターを編集できます。
これらのオプションは、ユーザーが「フィールド設定の微調整」「フィールドごとのバリデーション」などを明示的に依頼した場合に限り使用します。デフォルトでは、スキルはエンティティの設定をすべて継承します。
ハルシネーション防止チェックリスト
コードを書く前に、必ず以下を確認してください。
- コードが
examples/内のファイルに由来している(どのファイルかを明記する) - 宣言済みの変数のみを置き換えた
- 「知識をもとに」フレームワーク API 呼び出しを追加していない
- インポート一覧がサンプルと完全に一致している
- メソッドシグネチャがサンプルと完全に一致している
- コメントや便利なメソッドを追加していない
- サンプル内の FQN は本体では短縮し、対応する
import行をpackageの後に追加した - すべての Javadoc の形式(トップレベルクラス、トップレベルレコード、ネストされた静的クラス、ネストされたレコード、別ファイルのサブ DTO)で、短縮名
{@link Pet}を使用し、一致するimportを追加する(同じパッケージ内のエンティティの場合を除く)。例外なく、統一したルールを適用する - サブ DTO 名(別ファイルまたはネストされたクラス)が対象パッケージ内の既存クラス名と衝突する場合、自動的に数字を付けて(例:
PetDto1)名前を変更する。スキルも同様に、生成前にlist_existing_classes(package)を呼び出し、名前が空いていることを確認するまで1、2、…を追加する - Java レコードを生成する場合、
NEW_NESTED_CLASS関連付けの内部クラスも(静的クラスではなく)レコードにする。すべてのコンポーネントバリデーターは、個別のフィールド宣言ではなく、レコードコンポーネントのパラメーターにインラインで指定する(例:@NotBlank String firstName) -
isJavaRecord = trueの場合、スキルはequals()、hashCode()、toString()、ミュータブルなセッター、フルーエントセッターを出力してはならない。レコードではこれらが自動生成されるため、レコード DTO ではこれらのオプションを使用できないようにする - クラスレベルの Javadoc は複数行にする(
/**\n * DTO for {@link …}\n */)。1 行にまとめてはならない - ゲッターとセッターは複数行にする(シグネチャ行、インデントされた本体、閉じかっこ)。1 行にまとめてはならない
-
mutable=true && fluentSetters=falseモードでは、ゲッターとセッターをグループ化せず、交互に並べる(getX, setX, getY, setY, …) -
mutable=trueモードでは、引数なしコンストラクターと全引数コンストラクターの両方を出力する - スキルでは「ID のみ」を独立したオプションとして提示しない。このオプションは存在しない(ToOne、ToMany のいずれも)。「関連付け ID のみ」の効果は、サブエンティティの
idのみを選択した Flat によって実現し、スキルもその方法で実装する - コレクション関連付け(
List<X>、Set<X>)では Flat を選択肢として提示し、スキルがサブエンティティのスカラー項目を自動選択したうえで、複合の複数形フィールド(Set<Integer> specialtyIds、List<Integer> petIds)を生成する - 逆参照の
@ManyToOneフィールドは属性一覧から除外する(例:PetDtoの作成時にPet.ownerは選択肢として提示しない) - インポートは、
jakarta.*/com.*/org.*/java.*のブロック間に空行を入れてグループ化する - インデントは、プロジェクトで検出したスタイルに合わせる(まず
.editorconfig、次に同じパッケージ内の既存ファイルを調べ、最後にデフォルトの 4 スペースを使用する)。タブやスペースをハードコードしてはならない。ファイル内のすべてのコード片で統一して適用する - Kotlin では
@JsonIgnorePropertiesを追加しない(Java 専用の機能) - Kotlin では、バリデーションアノテーションに
@field:プレフィックスを使用する - Kotlin DTO では、Java の型を Kotlin の型に変換する