Creates a DTO (Data Transfer Object) class for an entity. Use this skill when a DTO class needs to be created, either standalone or as part of a larger task (e.g. REST controller, service layer, replacing entity usage with a DTO).
This skill is part of the Spring Agent Toolkit and is designed to work with the Spring MCP server (provided by the Amplicode IntelliJ plugin). Before doing anything else, check your tool list for any Spring MCP tool — they are exposed under the amplicode MCP server (e.g. get_project_summary, list_module_dependencies, get_entity_details); harnesses that flatten MCP tools into the tool list use the mcp__amplicode__ prefix on the same names.
If at least one Amplicode tool is available — MCP is connected. Proceed with the skill below.
If none are available — stop and invoke the amplicode-install skill (bundled with the Spring Agent Toolkit). It installs the Amplicode plugin and walks the user through the «Настроить Spring Agent» welcome-screen button + MCP-client restart. After it completes, the MCP tools become available — resume this skill.
If amplicode-install is not registered in your skill list, tell the user (in their language): "This skill needs the Amplicode IntelliJ plugin and its MCP server. Install it from https://amplicode.ru/marketplace into IntelliJ IDEA Ultimate/Community or GigaIDE, open any project, click «Настроить Spring Agent» on the Amplicode welcome screen, then restart your MCP client."
DTO Creator
Creates a DTO class (Java class, Java record, Java+Lombok, or Kotlin data class) for an entity with selected attributes, constructors, getters/setters, equals/hashCode, toString, and optional features.
CRITICAL: Code ONLY from examples/ files. If no matching example -- STOP and ask user.CRITICAL: For questions with a fixed set of choices, prefer AskUserQuestion > its analogue > plain text list. Plain numbered text lists are the last resort when no interactive tool is available.CRITICAL: Read the conversation context BEFORE running Step 1. Half the questions in Steps 2–7 may already be answered by the user's prompt and prior turns. Re-asking what was already said is the #1 reason this skill feels slow.
Step 7 (mapper) is automatic when conversion is needed. If from context it is clear that the DTO will be used in code that converts entities to/from DTOs (controller, service, endpoint replacement, etc.), the skill MUST delegate to mapper-creator — never write manual mapping code inline. The mapper-creator skill decides the implementation (MapStruct, Custom, adding dependencies) — this skill just delegates.
Defaults
Option
Default
Always ask?
Notes
entity
--
YES
main branching: which entity to create DTO for
attributes
all entity fields
YES
which fields to include
className
{EntityName}Dto
NO
suggest, confirm only
language
from get_project_summary
NO
auto-detected
variant
auto from language + deps
YES
Java class / Java record / Java+Lombok / Kotlin
mutable
false
NO
skip unless user wants customization
allArgsConstructor
true
NO
Java plain only
equalsHashCode
true
NO
Java plain only
toString
true
NO
Java plain only
fluentSetters
false
NO
only when mutable=true, Java only
jsonIgnoreUnknownProperties
false
NO
Java only, when Jackson on classpath
serializableType
NoSerializable
NO
rarely needed
packageName
same package as entity
NO
auto-detected
subDtoType (per ToOne association)
FLAT with id-only sub
YES
Four options available: New Class / New Nested Class / Existing Class / Flat. "Only ID" does NOT exist as a separate option — it is Flat with only the sub-entity id checked. See references/sub-dto.md.
subDtoType (per ToMany / collection)
NEW_NESTED_CLASS
YES
same 4 options as ToOne. Flat IS supported for collections and produces composite plural fields like Set<Integer> specialtyIds — see references/sub-dto.md.
fieldNameOverride (per field)
none
NO
per-field rename
extraValidations (per field)
none
NO
user-added jakarta validators on top of inherited ones
removedValidations (per field)
none
NO
constraints inherited from entity that the user wants dropped
indent
from .editorconfig (fallback 4-space)
NO
see § Indentation below
Smart defaults: If user says "use defaults", "all defaults", "default settings",
or similar -- skip ALL questions where "Always ask?" = NO. Only ask mandatory questions.
Smart answer recognition: When user provides a value instead of choosing from a numbered
list, accept it directly. Examples:
Question "Which entity?" -> user answers "Order" -> this IS the entity, don't re-ask
Question "Variant?" -> user answers "record" -> this IS Java record, don't show options
If user provides multiple answers in one message -> accept all, skip answered questions
NEVER ask a question that the user already answered (even implicitly)
Batch questions: Group closely related questions into a single
AskUserQuestion call (up to 4 questions per call) when they:
Belong to the same logical section (e.g. both are Java method generation settings)
Don't depend on each other's answers
Have obvious defaults that the user can skip
Rules:
Maximum 3-4 questions per AskUserQuestion call
Mark the recommended option with (Recommended) and place it first
Never batch questions from DIFFERENT decision branches
The primary branching question (entity selection, variant) is always asked ALONE
Prefer AskUserQuestion for choices; fall back to plain text lists only if the tool is unavailable
Decision-making principle — context first, then ask
Before asking the user any question, attempt to derive the answer from
the context already gathered: project summary, module dependencies, entity
details, existing files in the package, prior turns of this conversation,
and the user's original prompt. Only ask when the context yields no
clear default or when the choice is genuinely user-specific (e.g. which
entity, which fields).
Hierarchy of decisions:
Context is unambiguous → decide silently, do NOT ask.
Examples: language and JDK from get_project_summary; Lombok / Jackson /
Hibernate Validator from list_module_dependencies; package from the
entity FQN; className from {Entity}Dto; back-reference @ManyToOne
filtering; auto-selection of sub-entity scalars; record vs. plain class
when JDK ≥ 16 and no Lombok and the user did not request otherwise.
Exception: subDtoType is NEVER decided silently — it always requires
at minimum principle 2 (one-line confirmation), unless the USER explicitly
stated the shape in their own message (not in ARGUMENTS).
Context gives a strong signal → state the decision + alternatives in one line, let the user override or stay silent.
Format:
Will create `ScheduleTemplateDto` as a Java record with nested `SlotDto` (record).
Alternatives: plain class, Lombok, separate file for SlotDto. OK?
The user can answer "ok" / "yes" / silence → accept; or name an
alternative → switch. This is not the same as the numbered question
format — it is a single confirmation line.
Context yields no clear default → ask with AskUserQuestion (preferred) or its analogue, with the recommended option first.
When AskUserQuestion is available, use it with preview fields so the
user sees the concrete code shape for each option. Mark the recommended
option with (Recommended) in its label and place it first. If no
interactive choice tool is available, fall back to a plain text list.
Never ask iteratively ("which variant?" → user picks → "which fields?" → …)
when one batched call would do.
Context is fully empty for a critical input → ask plainly.
This applies to: which entity, which fields (when not "all"), the
user's intent itself.
How to ask — prefer AskUserQuestion
When a question must be asked, prefer the AskUserQuestion tool (or
its analogue) over writing a numbered list in the response body. Fall back
to plain text only if no interactive choice tool is available.
Rules for AskUserQuestion calls in this skill:
Each call may contain up to 4 questions that are independent of each
other (the tool will render them together). Use this to batch related
decisions in one round-trip.
Each question has 2–4 options. The tool auto-adds an "Other" choice
for free-form input — never include it manually.
Mark the recommended option by putting it first with (Recommended)
appended to the label.
Use multiSelect: true for "which fields to include" or "which
validators to add" — anything where multiple answers are valid.
header is a 12-char chip label (e.g. "Variant", "Sub-DTO", "Fields").
Each option has a description explaining what the choice means or its
consequence (one short sentence).
When AskUserQuestion is not the right tool:
Free-form input where there is no enumerable set of options
(e.g. arbitrary class name, arbitrary field rename) — ask in plain text.
The "single confirmation line" form from principle 2 — that is a plain
question with an obvious yes/no, not an enumerated choice.
The screen-driven question lists in Steps 2–5 below are a fallback for
case 4. They are NOT a script to execute top-to-bottom. If a question's
answer is already determined by principles 1–3, skip the question.
Plugin-wizard fidelity is not a goal — generation correctness is. The
plugin's UI exists because a screen can show many controls at once; a
chat cannot, so the skill must compensate by deciding more on its own.
Step 0 -- Conversation context first (REQUIRED, no tool calls)
Before any MCP call, before any question, re-read the user's prompt and
the prior turns of this conversation and extract whatever is already
stated. This step costs nothing and prevents the most common failure mode
of this skill — asking the user something they already said.
Build a mental checklist of inputs and tick off everything the user has
already provided, explicitly or implicitly:
Input
Look for in the prompt / context
entity
a class name (Vet, Owner, ScheduleTemplate); "for X"; an open file in the IDE; a file path; a recently discussed entity in this conversation
purpose
"for REST", "for controller", "for API", "for mapping", "projection", "for service" — drives field selection and the mapper question
fields
"all fields", "only id and name", "without password", "with associations", "flat"
variant
"record", "plain class", "Lombok", "data class" — also implied by language: Kotlin → data class, no question
mapper
"and mapper", "with mapper", "only DTO", "no mapper"
className
"name it OwnerSummaryDto", "class Foo"
package
"in package …", "next to controller"
smart defaults
"use defaults", "all defaults", "default settings", "as usual"
sub-DTO shape
"nested", "separate class", "only id", "flat"
prior project facts
language, JDK, dependencies — already known if discussed earlier in this conversation; do not re-fetch
For every input that is explicitly or strongly implicitly answered:
mark it as decided and skip the corresponding question in Steps 2–7. Do
NOT ask "what entity?" if the user wrote "create DTO for Vet" — Vet is
the answer. Do NOT ask "Java record or class?" if the user wrote "make
record DtoX" — record is the answer.
For every input that is not answered: defer to the Decision-making
principle below — try to derive it from project context first (Step 1),
and only then ask.
CRITICAL: ARGUMENTS ≠ user intent. The ARGUMENTS block at the bottom
of this prompt is written by the invoking assistant, NOT by the user. It
may contain the assistant's own analysis, assumptions, or field-level
details that the user never stated. When determining what the user
"already said", look ONLY at the actual user messages in the conversation
history — never treat ARGUMENTS as a substitute for user input. In
particular, do NOT skip asking about sub-DTO shape just because ARGUMENTS
describes one.
Step 0 is mental, not a tool call. Do not announce it to the user. Do not
write "Step 0 done". Just internalize what the user already said before
proceeding to Step 1.
Step 1 -- Gather minimal project context (automatic, no questions)
Call only the MCP tools whose result is actually consumed by a later
step. Do not pre-fetch "in case we need it" — every variable here must
have a concrete downstream user.
Tool
Variable
Used for
get_project_summary
language, jdkVersion, moduleName
language → variant selection (Step 4) and reference file (java vs kotlin); jdkVersion → canUseRecords = jdkVersion >= 16; moduleName → multi-module disambiguation + parameter for list_module_dependencies
springBootVersion / bootMajor — no branching depends on it
buildFile — DTO generation does not edit the build file (no
dependencies to add); a DTO needs only language constructs
mainPackage — the DTO's package is derived from the entity's FQN,
not from the project root
list_application_properties_files / propsFile — DTO writes nothing
to application.properties
list_all_domain_entities — needed only if the user did not name an
entity in their prompt. Defer to Step 2 as a lazy fallback.
get_entity_details / list_entity_dtos — depend on knowing the
entity, which happens in Step 2. Defer to Step 2.
Derived variables (all from presentDeps and get_project_summary):
hasLombok = presentDeps contains lombok
hasJackson = presentDeps contains jackson-databind or jackson-core
hasValidation = presentDeps contains hibernate-validator or jakarta.validation-api or spring-boot-starter-validation
canUseRecords = language == JAVA AND jdkVersion >= 16
If multi-module project (multiple modules in get_project_summary):
Ask which module to use. Then re-call list_module_dependencies for
that module.
Step 2 -- Entity selection
By Step 0 you should already know the entity if the user mentioned it.
Most common case: the user wrote "create DTO for Vet" → entity is
Vet, skip the question, go straight to the parallel fetch below.
Lazy fallback — only when entity is unknown: call
list_all_domain_entities(moduleName) → entities, then ask via
AskUserQuestion (options = entity names from the list, max 4; if more
than 4 entities, use the 4 most likely candidates based on context and
add a note that the user can type a different name via "Other").
This is the only place list_all_domain_entities should be called. If
the user named the entity in their prompt, do NOT call it.
After the entity FQN is known, call (in parallel):
Tool
Variable
Used for
get_entity_details(entityFqn)
entityDetails
Step 3 attribute selection, association analysis, validation inheritance, generation order in every variant reference
list_entity_dtos(entityFqn) for the parent entity is NOT called
here — it has no downstream consumer. Sub-entity calls
(list_entity_dtos(subEntityFqn)) are still needed for EXIST_CLASS
detection in references/sub-dto.md, but they are lazy and per-association,
fired only when the user is offered the EXIST_CLASS option. See
references/sub-dto.md for the exact place.
DTO name collision is handled by a different lazy call —
list_existing_classes(package) — fired right before generation in
Step 6 (see anti-hallucination checklist). It is not part of Step 2.
Step 3 -- Attribute selection
Default: include every scalar attribute and every association (with the
sub-DTO defaults from references/sub-dto.md). Ask only when context
signals that the user wants something narrower.
Decide from context (preferred over asking)
Use the purpose captured in Step 0 to pick a sensible default set:
Purpose signal
Default field set
"for REST", "for controller", "for API"
all scalars + all associations expanded (NEW_NESTED_CLASS for ToMany, FLAT id for ToOne) — the user wants the response shape, including related data
"projection", "summary", "list view", "for list"
scalars only, ToOne associations as Flat id, ToMany excluded
"for mapping", "for service", "DTO for storage"
all scalars + all associations expanded
"only id and name" / explicit field list
exactly what the user named, nothing else
no purpose signal
all scalars + all associations expanded (richest reasonable default)
If the chosen default matches the user's apparent intent, do not ask.
Just generate. State the choice in the one-line confirmation form
(principle 2) at most.
When to ask
Ask only if:
The user explicitly said "choose fields" / "ask about fields" / "fine-tune
settings", OR
The entity has many fields and the purpose signal is ambiguous AND the
user did not say "use defaults".
When asking, use AskUserQuestion with multiSelect: true:
Question
Header
Options (first = recommended)
Which fields to include in DTO {Entity}Dto?
Fields
All fields + associations (Recommended) / Scalars only / Only id and name / Specify manually
For each association included, apply the sub-DTO defaults from
references/sub-dto.md. Do NOT ask per-association unless the user
explicitly requested fine-grained control.
Step 4 -- Variant selection
Apply the Decision-making principle above. The variant is almost always
derivable from context — explicit asking should be the exception, not the
default.
If language=KOTLIN: route to references/kotlin.md. No question.
If language=JAVA: decide as follows.
Context
Action
Variant
hasLombok = true AND user prompt explicitly mentions Lombok
decide silently
references/java-lombok.md
canUseRecords = true AND hasLombok = false AND user did not ask for mutability/setters/Lombok
decide silently, mention in the one-line confirmation from principle 2
references/java-record.md
canUseRecords = false AND hasLombok = false
decide silently
references/java-plain.md
hasLombok = true AND canUseRecords = true AND user gave no signal
use the one-line confirmation form (principle 2): "Will create as Java record (JDK ≥ 16, no Lombok). Alternatives: plain class, Lombok. OK?"
depends on answer
User explicitly said "plain class" / "mutable" / "with setters"
decide silently
references/java-plain.md
User explicitly said "record"
decide silently
references/java-record.md
User explicitly said "Lombok"
decide silently (only if hasLombok = true; otherwise warn and fall back)
references/java-lombok.md
Only fall back to the full numbered question when none of the rows
above matches AND the user has not said "use defaults". Even then, prefer the
"all variants with default marked" format from principle 3 over an
iterative question.
Map answer to variant:
plain → references/java-plain.md
record → references/java-record.md
Lombok → references/java-lombok.md
Step 5 -- Variant-specific questions
Follow the variant-specific questions from the selected reference file.
Only ask if user did NOT say "all defaults".
Follow the Generation Order from the selected reference file.
For each step:
If skeleton (new file):
Read the skeleton .md from examples/_skeletons/
Apply variable substitutions
Use Write tool to create the file
If fragment:
Read the fragment .md from examples/_fragments/
Read the Insert Point to know WHERE to insert
Use Edit tool to insert code at the specified point
Apply variable substitutions
Variable substitution rules:
{packageName} -> from entity package or user choice
{className} -> from user or default {EntityName}Dto
Field-level variables -> from entity details
NEVER substitute anything not listed in Variables
NEVER add imports, methods, or code not in the example
FQN handling (CRITICAL): examples contain FQNs (e.g. java.util.Objects,
java.util.List, jakarta.validation.constraints.NotNull). When writing the
final file, you MUST:
Replace every FQN in the body of the class with its short name
(e.g. java.util.Objects.hash(...) -> Objects.hash(...),
java.util.List<Integer> -> List<Integer>,
@jakarta.validation.constraints.NotNull -> @NotNull).
Collect every FQN you shortened and emit a corresponding import line
right after the package statement, sorted, no duplicates.
Types from java.lang (String, Integer, Object, ...) must NOT be
imported and must appear as short names.
Classes from the same package as the DTO must NOT be imported.
Javadoc {@link ...} references — UNIFORM: Generate short name + import in {@link …} for every shape:
top-level Java class, top-level Java record, nested static class,
nested record, and separate-file sub-DTO (NEW_CLASS). There is no
asymmetry. Always shorten the entity reference and always add the
corresponding import line (unless the entity is in the same
package).
Group imports in two blocks separated by ONE blank line:
Block 1 — all third-party / project imports together:
jakarta.*, com.fasterxml.*, org.springframework.*,
org.hibernate.*, project packages, etc. (alphabetical inside the
block).
(blank line)
Block 2 — java.* and javax.* (alphabetical).
Do NOT split block 1 into per-package sub-blocks.
The final file must contain short names in the body (including every
Javadoc {@link …}) and a clean, grouped import block at the top.
For sub-DTOs (subDtoType=NEW_CLASS): create a separate file by repeating Steps 6.1-6.4 recursively for the sub-entity.
For nested classes (subDtoType=NEW_NESTED_CLASS): add inner class to the parent DTO file, then fill it following the same fragment rules.
Nested in a record parent — MANDATORY: when the parent DTO is a Java
record, every NEW_NESTED_CLASS association MUST be emitted as a nested
public record inside the parent record's body. The skill MUST NOT
silently fall back to NEW_CLASS (separate file) just because the
record-form fragment looks shorter. The full procedure is in
references/java-record.md Step 6 and
examples/_fragments/nested-class/java/nested-class.md ("Java record"
variant). If those instructions seem ambiguous to you, that is a bug in
the skill — fix the docs, do NOT work around it by changing the
subDtoType.
Step 7 -- Mapper (automatic when conversion is needed)
Decide whether a mapper is needed based on context, then act:
Signal
Action
User said "only DTO" / "no mapper" / "without mapper"
Skip Step 7 entirely. Do NOT mention the mapper.
User explicitly asked for a mapper ("and mapper", "with mapper", "create mapper too")
Delegate to mapper-creator immediately.
From context it is clear that entity↔DTO conversion will happen (user asked to replace entity with DTO in a controller/service/endpoint, user asked to convert/map/transform, DTO is for REST API, etc.)
Delegate to mapper-creator immediately. The conversion is inevitable — creating the DTO without a mapper would force manual inline mapping code, which is never acceptable.
Context is silent — no signal about how the DTO will be used
Skip Step 7. Do not mention the mapper.
CRITICAL: Never write manual mapping code (inline toDto/fromDto methods in controllers, services, or anywhere else). If conversion is needed, always delegate to mapper-creator. That skill decides the implementation strategy (MapStruct, Custom mapper, adding dependencies) — this skill just delegates.
Never ask AskUserQuestion for the mapper. If delegating, invoke the
mapper-creator skill with the DTO and entity information directly —
do not ask the user to confirm the delegation.
Indentation
The skill MUST detect the project's indentation style — never hardcode tabs
or spaces. Detection order:
.editorconfig at the project root (or any parent of the target
file's directory). For Java files, look up the [*.java] or [*]
section and read indent_style (tab or space) and indent_size /
tab_width.
Sample existing Java files in the same package (or the nearest
ancestor package that contains Java files). Detect whether the leading
whitespace on indented lines uses \t or spaces, and how many.
Default to 4-space if neither source is conclusive. (Tabs are also
acceptable as a default if the developer explicitly prefers them, but
the skill must never silently assume one over the other.)
Whatever style is chosen, apply it uniformly to every line of every
generated fragment (fields, constructors, getters/setters, equals/hashCode,
toString, nested classes/records). Never mix tabs and spaces inside the
same file.
Per-field options
The skill must support the following per-field controls:
Field rename (fieldNameOverride): the DTO field name can differ from
the entity attribute name. Mapper generation still maps it from the
original attribute.
Add validations (extraValidations): the user can add jakarta /
hibernate-validator constraints on top of the ones inherited from the
entity. The list of allowed constraints depends on the field type — see
references/validation.md.
Remove inherited validations (removedValidations): the user can drop
any constraint that came from the entity field.
Edit annotation parameters (message, min, max, regexp, …): all
parameters of every constraint are editable.
These options never appear unless the user explicitly asks for "fine-tune
field settings", "per-field validation" or similar. By default the skill
just inherits everything from the entity.
Anti-hallucination checklist
Before writing ANY code, verify:
The code comes from an examples/ file (cite which one)
Only declared variables were substituted
No framework API calls were added "from knowledge"
Import list matches the example exactly
Method signatures match the example exactly
No comments or convenience methods were added
FQNs from examples are shortened in the body AND corresponding import lines were added after package
Every Javadoc shape — top-level class, top-level record, nested static class, nested record, separate-file sub-DTO — uses short name {@link Pet} AND adds a matching import (unless the entity is in the same package). Uniform rule, no asymmetry.
If a sub-DTO name (separate file or nested) would collide with an existing class in the target package, auto-suffix with a number (e.g. PetDto1). The skill must do the same — call list_existing_classes(package) before generating, and append 1, 2, … until the name is free.
When generating a Java record, the inner class for any NEW_NESTED_CLASS association is also a record (not a static class). All component validators are inlined onto the record component parameters (e.g. @NotBlank String firstName), not on separate field declarations.
When isJavaRecord = true, the skill MUST NOT emit equals(), hashCode(), toString(), mutable setters, or fluent setters — records auto-generate these and these options should not be available for record DTOs.
Class-level Javadoc is multi-line (/**\n * DTO for {@link …}\n */), never collapsed to one line.
Getters and setters are multi-line (signature line, indented body, closing brace), never one-liners.
In mutable=true && fluentSetters=false mode, getters and setters are interleaved (getX, setX, getY, setY, …), not grouped.
In mutable=true mode, both the no-args constructor and the all-args constructor are emitted.
The skill does NOT offer "Only ID" as a separate option — this option does not exist (neither for ToOne nor for ToMany). The "association id only" effect is produced by Flat with only the sub-entity id checked, and the skill must implement it that way.
For collection associations (List<X>, Set<X>), Flat is offered and produces composite plural fields (Set<Integer> specialtyIds, List<Integer> petIds), provided the skill auto-checks the sub-entity scalars.
Back-reference @ManyToOne fields are filtered out of the attribute list (e.g. Pet.owner is not offered when creating PetDto).
Imports are grouped with a blank line between jakarta.* / com.* / org.* / java.* blocks.
Indentation matches the project's detected style (.editorconfig first, then sampling existing files in the same package, then 4-space default). Never hardcode tabs or spaces. Apply uniformly across every fragment in the file.
@JsonIgnoreProperties is NOT added for Kotlin (Java-only feature)
Validation annotations use @field: prefix in Kotlin
Java types are converted to Kotlin types for Kotlin DTOs
1---2name: dto-creator3description: Creates a DTO (Data Transfer Object) class for an entity. Use this skill when a DTO class needs to be created, either standalone or as part of a larger task (e.g. REST controller, service layer, replacing entity usage with a DTO).4---56# Preflight: Spring MCP78This skill is part of the **Spring Agent Toolkit** and is designed to work with the **Spring MCP server** (provided by the Amplicode IntelliJ plugin). Before doing anything else, check your tool list for any Spring MCP tool — they are exposed under the `amplicode` MCP server (e.g. `get_project_summary`, `list_module_dependencies`, `get_entity_details`); harnesses that flatten MCP tools into the tool list use the `mcp__amplicode__` prefix on the same names.910- **If at least one Amplicode tool is available** — MCP is connected. Proceed with the skill below.11- **If none are available** — stop and invoke the **`amplicode-install`** skill (bundled with the Spring Agent Toolkit). It installs the Amplicode plugin and walks the user through the **«Настроить Spring Agent»** welcome-screen button + MCP-client restart. After it completes, the MCP tools become available — resume this skill.12- If `amplicode-install` is not registered in your skill list, tell the user (in their language): *"This skill needs the Amplicode IntelliJ plugin and its MCP server. Install it from https://amplicode.ru/marketplace into IntelliJ IDEA Ultimate/Community or GigaIDE, open any project, click «Настроить Spring Agent» on the Amplicode welcome screen, then restart your MCP client."*1314---1516# DTO Creator1718Creates a DTO class (Java class, Java record, Java+Lombok, or Kotlin data class) for an entity with selected attributes, constructors, getters/setters, equals/hashCode, toString, and optional features.1920---2122> **CRITICAL: Code ONLY from examples/ files. If no matching example -- STOP and ask user.**23> **CRITICAL: For questions with a fixed set of choices, prefer `AskUserQuestion` > its analogue > plain text list. Plain numbered text lists are the last resort when no interactive tool is available.**24> **CRITICAL: Read the conversation context BEFORE running Step 1.** Half the questions in Steps 2–7 may already be answered by the user's prompt and prior turns. Re-asking what was already said is the #1 reason this skill feels slow.25> **Step 7 (mapper) is automatic when conversion is needed.** If from context it is clear that the DTO will be used in code that converts entities to/from DTOs (controller, service, endpoint replacement, etc.), the skill MUST delegate to `mapper-creator` — never write manual mapping code inline. The `mapper-creator` skill decides the implementation (MapStruct, Custom, adding dependencies) — this skill just delegates.2627---2829## Defaults3031| Option | Default | Always ask? | Notes |32|--------|---------|-------------|-------|33| entity | -- | YES | main branching: which entity to create DTO for |34| attributes | all entity fields | YES | which fields to include |35| className | `{EntityName}Dto` | NO | suggest, confirm only |36| language | from `get_project_summary` | NO | auto-detected |37| variant | auto from language + deps | YES | Java class / Java record / Java+Lombok / Kotlin |38| mutable | false | NO | skip unless user wants customization |39| allArgsConstructor | true | NO | Java plain only |40| equalsHashCode | true | NO | Java plain only |41| toString | true | NO | Java plain only |42| fluentSetters | false | NO | only when mutable=true, Java only |43| jsonIgnoreUnknownProperties | false | NO | Java only, when Jackson on classpath |44| serializableType | NoSerializable | NO | rarely needed |45| packageName | same package as entity | NO | auto-detected |46| subDtoType (per ToOne association) | FLAT with id-only sub | YES | Four options available: New Class / New Nested Class / Existing Class / Flat. "Only ID" does NOT exist as a separate option — it is Flat with only the sub-entity `id` checked. See `references/sub-dto.md`. |47| subDtoType (per ToMany / collection) | NEW_NESTED_CLASS | YES | same 4 options as ToOne. Flat IS supported for collections and produces composite plural fields like `Set<Integer> specialtyIds` — see `references/sub-dto.md`. |48| fieldNameOverride (per field) | none | NO | per-field rename |49| extraValidations (per field) | none | NO | user-added jakarta validators on top of inherited ones |50| removedValidations (per field) | none | NO | constraints inherited from entity that the user wants dropped |51| indent | from `.editorconfig` (fallback 4-space) | NO | see § Indentation below |5253**Smart defaults:** If user says "use defaults", "all defaults", "default settings",54or similar -- skip ALL questions where "Always ask?" = NO. Only ask mandatory questions.5556**Smart answer recognition:** When user provides a value instead of choosing from a numbered57list, accept it directly. Examples:58- Question "Which entity?" -> user answers "Order" -> this IS the entity, don't re-ask59- Question "Variant?" -> user answers "record" -> this IS Java record, don't show options60- If user provides multiple answers in one message -> accept all, skip answered questions61- NEVER ask a question that the user already answered (even implicitly)6263**Batch questions:** Group closely related questions into a single64`AskUserQuestion` call (up to 4 questions per call) when they:65- Belong to the same logical section (e.g. both are Java method generation settings)66- Don't depend on each other's answers67- Have obvious defaults that the user can skip6869Rules:70- Maximum **3-4 questions** per `AskUserQuestion` call71- Mark the recommended option with `(Recommended)` and place it first72- Never batch questions from DIFFERENT decision branches73- The primary branching question (entity selection, variant) is always asked ALONE74- Prefer `AskUserQuestion` for choices; fall back to plain text lists only if the tool is unavailable7576---7778## Decision-making principle — context first, then ask7980Before asking the user **any** question, attempt to derive the answer from81the context already gathered: project summary, module dependencies, entity82details, existing files in the package, prior turns of this conversation,83and the user's original prompt. Only ask when the context yields **no84clear default** or when the choice is genuinely user-specific (e.g. which85entity, which fields).8687Hierarchy of decisions:88891. **Context is unambiguous → decide silently, do NOT ask.**90 Examples: language and JDK from `get_project_summary`; Lombok / Jackson /91 Hibernate Validator from `list_module_dependencies`; package from the92 entity FQN; className from `{Entity}Dto`; back-reference `@ManyToOne`93 filtering; auto-selection of sub-entity scalars; record vs. plain class94 when JDK ≥ 16 and no Lombok and the user did not request otherwise.95 **Exception: subDtoType is NEVER decided silently** — it always requires96 at minimum principle 2 (one-line confirmation), unless the USER explicitly97 stated the shape in their own message (not in ARGUMENTS).98992. **Context gives a strong signal → state the decision + alternatives in one line, let the user override or stay silent.**100 Format:101 ```102 Will create `ScheduleTemplateDto` as a Java record with nested `SlotDto` (record).103 Alternatives: plain class, Lombok, separate file for SlotDto. OK?104 ```105 The user can answer "ok" / "yes" / silence → accept; or name an106 alternative → switch. This is **not** the same as the numbered question107 format — it is a single confirmation line.1081093. **Context yields no clear default → ask with `AskUserQuestion` (preferred) or its analogue, with the recommended option first.**110 When `AskUserQuestion` is available, use it with `preview` fields so the111 user sees the concrete code shape for each option. Mark the recommended112 option with `(Recommended)` in its label and place it first. If no113 interactive choice tool is available, fall back to a plain text list.114 **Never** ask iteratively ("which variant?" → user picks → "which fields?" → …)115 when one batched call would do.1161174. **Context is fully empty for a critical input → ask plainly.**118 This applies to: which entity, which fields (when not "all"), the119 user's intent itself.120121### How to ask — prefer `AskUserQuestion`122123When a question must be asked, prefer the **`AskUserQuestion`** tool (or124its analogue) over writing a numbered list in the response body. Fall back125to plain text only if no interactive choice tool is available.126127Rules for `AskUserQuestion` calls in this skill:128129- Each call may contain up to **4 questions** that are independent of each130 other (the tool will render them together). Use this to batch related131 decisions in one round-trip.132- Each question has **2–4 options**. The tool auto-adds an "Other" choice133 for free-form input — never include it manually.134- Mark the recommended option by putting it **first** with `(Recommended)`135 appended to the label.136- Use `multiSelect: true` for "which fields to include" or "which137 validators to add" — anything where multiple answers are valid.138- `header` is a 12-char chip label (e.g. "Variant", "Sub-DTO", "Fields").139- Each option has a `description` explaining what the choice means or its140 consequence (one short sentence).141142When `AskUserQuestion` is **not** the right tool:143- Free-form input where there is no enumerable set of options144 (e.g. arbitrary class name, arbitrary field rename) — ask in plain text.145- The "single confirmation line" form from principle 2 — that is a plain146 question with an obvious yes/no, not an enumerated choice.147148The screen-driven question lists in Steps 2–5 below are a **fallback** for149case 4. They are NOT a script to execute top-to-bottom. If a question's150answer is already determined by principles 1–3, **skip the question**.151Plugin-wizard fidelity is not a goal — generation correctness is. The152plugin's UI exists because a screen can show many controls at once; a153chat cannot, so the skill must compensate by deciding more on its own.154155---156157## Step 0 -- Conversation context first (REQUIRED, no tool calls)158159Before any MCP call, before any question, **re-read the user's prompt and160the prior turns of this conversation** and extract whatever is already161stated. This step costs nothing and prevents the most common failure mode162of this skill — asking the user something they already said.163164Build a mental checklist of inputs and tick off everything the user has165already provided, explicitly or implicitly:166167| Input | Look for in the prompt / context |168|---|---|169| **entity** | a class name (`Vet`, `Owner`, `ScheduleTemplate`); "for X"; an open file in the IDE; a file path; a recently discussed entity in this conversation |170| **purpose** | "for REST", "for controller", "for API", "for mapping", "projection", "for service" — drives field selection and the mapper question |171| **fields** | "all fields", "only id and name", "without password", "with associations", "flat" |172| **variant** | "record", "plain class", "Lombok", "data class" — also implied by language: Kotlin → data class, no question |173| **mapper** | "and mapper", "with mapper", "only DTO", "no mapper" |174| **className** | "name it `OwnerSummaryDto`", "class `Foo`" |175| **package** | "in package `…`", "next to controller" |176| **smart defaults** | "use defaults", "all defaults", "default settings", "as usual" |177| **sub-DTO shape** | "nested", "separate class", "only id", "flat" |178| **prior project facts** | language, JDK, dependencies — already known if discussed earlier in this conversation; do not re-fetch |179180For every input that is **explicitly or strongly implicitly answered**:181mark it as decided and skip the corresponding question in Steps 2–7. Do182NOT ask "what entity?" if the user wrote "create DTO for Vet" — `Vet` is183the answer. Do NOT ask "Java record or class?" if the user wrote "make184record DtoX" — record is the answer.185186For every input that is **not** answered: defer to the Decision-making187principle below — try to derive it from project context first (Step 1),188and only then ask.189190**CRITICAL: ARGUMENTS ≠ user intent.** The ARGUMENTS block at the bottom191of this prompt is written by the invoking assistant, NOT by the user. It192may contain the assistant's own analysis, assumptions, or field-level193details that the user never stated. When determining what the user194"already said", look ONLY at the actual user messages in the conversation195history — never treat ARGUMENTS as a substitute for user input. In196particular, do NOT skip asking about sub-DTO shape just because ARGUMENTS197describes one.198199Step 0 is mental, not a tool call. Do not announce it to the user. Do not200write "Step 0 done". Just internalize what the user already said before201proceeding to Step 1.202203---204205## Step 1 -- Gather minimal project context (automatic, no questions)206207Call only the MCP tools whose result is **actually consumed** by a later208step. Do not pre-fetch "in case we need it" — every variable here must209have a concrete downstream user.210211| Tool | Variable | Used for |212|------|----------|----------|213| `get_project_summary` | `language`, `jdkVersion`, `moduleName` | language → variant selection (Step 4) and reference file (java vs kotlin); jdkVersion → `canUseRecords = jdkVersion >= 16`; moduleName → multi-module disambiguation + parameter for `list_module_dependencies` |214| `list_module_dependencies(moduleName)` | `presentDeps` | derived flags below — Lombok/Jackson/Validation feature gates |215216That is the entire Step 1. **Do NOT** fetch:217- `springBootVersion` / `bootMajor` — no branching depends on it218- `buildFile` — DTO generation does not edit the build file (no219 dependencies to add); a DTO needs only language constructs220- `mainPackage` — the DTO's package is derived from the entity's FQN,221 not from the project root222- `list_application_properties_files` / `propsFile` — DTO writes nothing223 to `application.properties`224- `list_all_domain_entities` — needed only if the user did not name an225 entity in their prompt. Defer to Step 2 as a lazy fallback.226- `get_entity_details` / `list_entity_dtos` — depend on knowing the227 entity, which happens in Step 2. Defer to Step 2.228229Derived variables (all from `presentDeps` and `get_project_summary`):230- `hasLombok` = `presentDeps` contains `lombok`231- `hasJackson` = `presentDeps` contains `jackson-databind` or `jackson-core`232- `hasValidation` = `presentDeps` contains `hibernate-validator` or `jakarta.validation-api` or `spring-boot-starter-validation`233- `canUseRecords` = `language == JAVA` AND `jdkVersion >= 16`234235If multi-module project (multiple modules in `get_project_summary`):236Ask which module to use. Then re-call `list_module_dependencies` for237that module.238239---240241## Step 2 -- Entity selection242243By Step 0 you should already know the entity if the user mentioned it.244Most common case: the user wrote "create DTO for `Vet`" → entity is245`Vet`, skip the question, go straight to the parallel fetch below.246247**Lazy fallback — only when entity is unknown:** call248`list_all_domain_entities(moduleName)` → `entities`, then ask via249`AskUserQuestion` (options = entity names from the list, max 4; if more250than 4 entities, use the 4 most likely candidates based on context and251add a note that the user can type a different name via "Other").252253This is the only place `list_all_domain_entities` should be called. If254the user named the entity in their prompt, do NOT call it.255256After the entity FQN is known, call (in parallel):257258| Tool | Variable | Used for |259|------|----------|----------|260| `get_entity_details(entityFqn)` | `entityDetails` | Step 3 attribute selection, association analysis, validation inheritance, generation order in every variant reference |261262`list_entity_dtos(entityFqn)` for the **parent** entity is NOT called263here — it has no downstream consumer. Sub-entity calls264(`list_entity_dtos(subEntityFqn)`) are still needed for `EXIST_CLASS`265detection in `references/sub-dto.md`, but they are lazy and per-association,266fired only when the user is offered the EXIST_CLASS option. See267`references/sub-dto.md` for the exact place.268269DTO **name collision** is handled by a different lazy call —270`list_existing_classes(package)` — fired right before generation in271Step 6 (see anti-hallucination checklist). It is not part of Step 2.272273---274275## Step 3 -- Attribute selection276277**Default: include every scalar attribute and every association** (with the278sub-DTO defaults from `references/sub-dto.md`). Ask only when context279signals that the user wants something narrower.280281### Decide from context (preferred over asking)282283Use the **purpose** captured in Step 0 to pick a sensible default set:284285| Purpose signal | Default field set |286|---|---|287| "for REST", "for controller", "for API" | all scalars + all associations expanded (NEW_NESTED_CLASS for ToMany, FLAT id for ToOne) — the user wants the response shape, including related data |288| "projection", "summary", "list view", "for list" | scalars only, ToOne associations as Flat id, ToMany excluded |289| "for mapping", "for service", "DTO for storage" | all scalars + all associations expanded |290| "only id and name" / explicit field list | exactly what the user named, nothing else |291| no purpose signal | all scalars + all associations expanded (richest reasonable default) |292293If the chosen default matches the user's apparent intent, **do not ask**.294Just generate. State the choice in the one-line confirmation form295(principle 2) at most.296297### When to ask298299Ask only if:300- The user explicitly said "choose fields" / "ask about fields" / "fine-tune301 settings", OR302- The entity has many fields and the purpose signal is ambiguous AND the303 user did not say "use defaults".304305When asking, use `AskUserQuestion` with `multiSelect: true`:306307| Question | Header | Options (first = recommended) |308|----------|--------|-------------------------------|309| Which fields to include in DTO `{Entity}Dto`? | Fields | All fields + associations (Recommended) / Scalars only / Only id and name / Specify manually |310311For each **association** included, apply the sub-DTO defaults from312`references/sub-dto.md`. Do NOT ask per-association unless the user313explicitly requested fine-grained control.314315---316317## Step 4 -- Variant selection318319Apply the **Decision-making principle** above. The variant is almost always320derivable from context — explicit asking should be the exception, not the321default.322323**If language=KOTLIN:** route to `references/kotlin.md`. No question.324325**If language=JAVA:** decide as follows.326327| Context | Action | Variant |328|---|---|---|329| `hasLombok = true` AND user prompt explicitly mentions Lombok | decide silently | `references/java-lombok.md` |330| `canUseRecords = true` AND `hasLombok = false` AND user did not ask for mutability/setters/Lombok | decide silently, mention in the one-line confirmation from principle 2 | `references/java-record.md` |331| `canUseRecords = false` AND `hasLombok = false` | decide silently | `references/java-plain.md` |332| `hasLombok = true` AND `canUseRecords = true` AND user gave no signal | use the one-line confirmation form (principle 2): "Will create as Java record (JDK ≥ 16, no Lombok). Alternatives: plain class, Lombok. OK?" | depends on answer |333| User explicitly said "plain class" / "mutable" / "with setters" | decide silently | `references/java-plain.md` |334| User explicitly said "record" | decide silently | `references/java-record.md` |335| User explicitly said "Lombok" | decide silently (only if `hasLombok = true`; otherwise warn and fall back) | `references/java-lombok.md` |336337Only fall back to the full numbered question when **none** of the rows338above matches AND the user has not said "use defaults". Even then, prefer the339"all variants with default marked" format from principle 3 over an340iterative question.341342Map answer to variant:343- plain → `references/java-plain.md`344- record → `references/java-record.md`345- Lombok → `references/java-lombok.md`346347---348349## Step 5 -- Variant-specific questions350351Follow the variant-specific questions from the selected reference file.352Only ask if user did NOT say "all defaults".353354---355356## Step 6 -- Generate code3573581. Determine target path:359 `src/main/{java|kotlin}/{packagePath}/{className}.{java|kt}`3603612. Follow the **Generation Order** from the selected reference file.3623633. For each step:364365 **If skeleton (new file):**366 - Read the skeleton `.md` from `examples/_skeletons/`367 - Apply variable substitutions368 - Use Write tool to create the file369370 **If fragment:**371 - Read the fragment `.md` from `examples/_fragments/`372 - Read the Insert Point to know WHERE to insert373 - Use Edit tool to insert code at the specified point374 - Apply variable substitutions3753764. Variable substitution rules:377 - `{packageName}` -> from entity package or user choice378 - `{className}` -> from user or default `{EntityName}Dto`379 - Field-level variables -> from entity details380 - **NEVER substitute anything not listed in Variables**381 - **NEVER add imports, methods, or code not in the example**382 - **FQN handling (CRITICAL):** examples contain FQNs (e.g. `java.util.Objects`,383 `java.util.List`, `jakarta.validation.constraints.NotNull`). When writing the384 final file, you MUST:385 1. Replace every FQN in the body of the class with its **short name**386 (e.g. `java.util.Objects.hash(...)` -> `Objects.hash(...)`,387 `java.util.List<Integer>` -> `List<Integer>`,388 `@jakarta.validation.constraints.NotNull` -> `@NotNull`).389 2. Collect every FQN you shortened and emit a corresponding `import` line390 right after the `package` statement, sorted, no duplicates.391 3. Types from `java.lang` (`String`, `Integer`, `Object`, ...) must NOT be392 imported and must appear as short names.393 4. Classes from the same package as the DTO must NOT be imported.394 5. **Javadoc `{@link ...}` references — UNIFORM:** Generate **short name + import** in `{@link …}` for **every** shape:395 top-level Java class, top-level Java record, nested static class,396 nested record, and separate-file sub-DTO (NEW_CLASS). There is no397 asymmetry. Always shorten the entity reference and always add the398 corresponding `import` line (unless the entity is in the same399 package).400 6. **Group imports** in two blocks separated by ONE blank line:401 - **Block 1** — all third-party / project imports together:402 `jakarta.*`, `com.fasterxml.*`, `org.springframework.*`,403 `org.hibernate.*`, project packages, etc. (alphabetical inside the404 block).405 - **(blank line)**406 - **Block 2** — `java.*` and `javax.*` (alphabetical).407 Do NOT split block 1 into per-package sub-blocks.408 The final file must contain short names in the body (including every409 Javadoc `{@link …}`) and a clean, grouped import block at the top.4104115. For **sub-DTOs** (subDtoType=NEW_CLASS): create a separate file by repeating Steps 6.1-6.4 recursively for the sub-entity.4124136. For **nested classes** (subDtoType=NEW_NESTED_CLASS): add inner class to the parent DTO file, then fill it following the same fragment rules.4144157. **Nested in a record parent — MANDATORY:** when the parent DTO is a Java416 record, every `NEW_NESTED_CLASS` association MUST be emitted as a nested417 `public record` inside the parent record's body. The skill MUST NOT418 silently fall back to `NEW_CLASS` (separate file) just because the419 record-form fragment looks shorter. The full procedure is in420 `references/java-record.md` Step 6 and421 `examples/_fragments/nested-class/java/nested-class.md` ("Java record"422 variant). If those instructions seem ambiguous to you, that is a bug in423 the skill — fix the docs, do NOT work around it by changing the424 `subDtoType`.425426---427428## Step 7 -- Mapper (automatic when conversion is needed)429430Decide whether a mapper is needed based on context, then act:431432| Signal | Action |433|---|---|434| User said "only DTO" / "no mapper" / "without mapper" | Skip Step 7 entirely. Do NOT mention the mapper. |435| User explicitly asked for a mapper ("and mapper", "with mapper", "create mapper too") | Delegate to `mapper-creator` immediately. |436| From context it is clear that entity↔DTO conversion will happen (user asked to replace entity with DTO in a controller/service/endpoint, user asked to convert/map/transform, DTO is for REST API, etc.) | Delegate to `mapper-creator` immediately. The conversion is inevitable — creating the DTO without a mapper would force manual inline mapping code, which is never acceptable. |437| Context is silent — no signal about how the DTO will be used | Skip Step 7. Do not mention the mapper. |438439**CRITICAL:** Never write manual mapping code (inline `toDto`/`fromDto` methods in controllers, services, or anywhere else). If conversion is needed, always delegate to `mapper-creator`. That skill decides the implementation strategy (MapStruct, Custom mapper, adding dependencies) — this skill just delegates.440441Never ask `AskUserQuestion` for the mapper. If delegating, invoke the442`mapper-creator` skill with the DTO and entity information directly —443do not ask the user to confirm the delegation.444445---446447## Indentation448449The skill MUST detect the project's indentation style — never hardcode tabs450or spaces. Detection order:4514521. **`.editorconfig`** at the project root (or any parent of the target453 file's directory). For Java files, look up the `[*.java]` or `[*]`454 section and read `indent_style` (`tab` or `space`) and `indent_size` /455 `tab_width`.4562. **Sample existing Java files** in the same package (or the nearest457 ancestor package that contains Java files). Detect whether the leading458 whitespace on indented lines uses `\t` or spaces, and how many.4593. **Default to 4-space** if neither source is conclusive. (Tabs are also460 acceptable as a default if the developer explicitly prefers them, but461 the skill must never silently assume one over the other.)462463Whatever style is chosen, apply it **uniformly** to every line of every464generated fragment (fields, constructors, getters/setters, equals/hashCode,465toString, nested classes/records). Never mix tabs and spaces inside the466same file.467468## Per-field options469470The skill must support the following per-field controls:471472- **Field rename** (`fieldNameOverride`): the DTO field name can differ from473 the entity attribute name. Mapper generation still maps it from the474 original attribute.475- **Add validations** (`extraValidations`): the user can add jakarta /476 hibernate-validator constraints on top of the ones inherited from the477 entity. The list of allowed constraints depends on the field type — see478 `references/validation.md`.479- **Remove inherited validations** (`removedValidations`): the user can drop480 any constraint that came from the entity field.481- **Edit annotation parameters** (`message`, `min`, `max`, `regexp`, …): all482 parameters of every constraint are editable.483484These options never appear unless the user explicitly asks for "fine-tune485field settings", "per-field validation" or similar. By default the skill486just inherits everything from the entity.487488## Anti-hallucination checklist489490Before writing ANY code, verify:491- [ ] The code comes from an examples/ file (cite which one)492- [ ] Only declared variables were substituted493- [ ] No framework API calls were added "from knowledge"494- [ ] Import list matches the example exactly495- [ ] Method signatures match the example exactly496- [ ] No comments or convenience methods were added497- [ ] FQNs from examples are shortened in the body AND corresponding `import` lines were added after `package`498- [ ] **Every** Javadoc shape — top-level class, top-level record, nested static class, nested record, separate-file sub-DTO — uses short name `{@link Pet}` AND adds a matching `import` (unless the entity is in the same package). Uniform rule, no asymmetry.499- [ ] If a sub-DTO name (separate file or nested) would collide with an existing class in the target package, **auto-suffix with a number** (e.g. `PetDto1`). The skill must do the same — call `list_existing_classes(package)` before generating, and append `1`, `2`, … until the name is free.500- [ ] When generating a **Java record**, the inner class for any `NEW_NESTED_CLASS` association is also a **record** (not a static class). All component validators are inlined onto the record component parameters (e.g. `@NotBlank String firstName`), not on separate field declarations.501- [ ] When `isJavaRecord = true`, the skill MUST NOT emit `equals()`, `hashCode()`, `toString()`, mutable setters, or fluent setters — records auto-generate these and these options should not be available for record DTOs.502- [ ] Class-level Javadoc is **multi-line** (`/**\n * DTO for {@link …}\n */`), never collapsed to one line.503- [ ] Getters and setters are **multi-line** (signature line, indented body, closing brace), never one-liners.504- [ ] In `mutable=true && fluentSetters=false` mode, getters and setters are **interleaved** (`getX, setX, getY, setY, …`), not grouped.505- [ ] In `mutable=true` mode, **both** the no-args constructor and the all-args constructor are emitted.506- [ ] The skill does NOT offer "Only ID" as a separate option — this option does not exist (neither for ToOne nor for ToMany). The "association id only" effect is produced by **Flat with only the sub-entity `id` checked**, and the skill must implement it that way.507- [ ] For collection associations (`List<X>`, `Set<X>`), Flat **is** offered and produces composite plural fields (`Set<Integer> specialtyIds`, `List<Integer> petIds`), provided the skill auto-checks the sub-entity scalars.508- [ ] Back-reference `@ManyToOne` fields are filtered out of the attribute list (e.g. `Pet.owner` is not offered when creating `PetDto`).509- [ ] Imports are grouped with a blank line between `jakarta.*` / `com.*` / `org.*` / `java.*` blocks.510- [ ] Indentation matches the project's detected style (`.editorconfig` first, then sampling existing files in the same package, then 4-space default). Never hardcode tabs or spaces. Apply uniformly across every fragment in the file.511- [ ] @JsonIgnoreProperties is NOT added for Kotlin (Java-only feature)512- [ ] Validation annotations use `@field:` prefix in Kotlin513- [ ] Java types are converted to Kotlin types for Kotlin DTOs
Run npx skillmds@latest add amplicode/dto-creator in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Creates a DTO (Data Transfer Object) class for an entity. Use this skill when a DTO class needs to be created, either standalone or as part of a larger task (e.g. REST controller, service layer, replacing entity usage with a DTO). It is listed under Integrations & APIs on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
amplicode (@amplicode) published this skill. Their other Agent Skills are listed on their SkillMD profile.