Scaffold a complete hexagonal-architecture vertical slice (14 files across domain, application, API, infrastructure, and tests) for a new backend entity using a shell script and a simple spec file. Use this when asked to create a new entity, add CRUD for a resource, or scaffold a domain object.
Scaffold a complete hexagonal-architecture vertical slice for a new backend entity
using the scaffold-entity.sh script. This avoids generating boilerplate via the LLM —
the script produces 14 files instantly from a simple spec.
Do NOT use this skill when:
Create a spec file at .github/skills/scaffold-entity/references/<entity-lowercase>.spec.
Derive the fields from the user's request. Ask only if truly ambiguous.
See .github/skills/scaffold-entity/references/entity-spec.example for the format:
ENTITY="Checkpoint" # PascalCase
PLURAL="Checkpoints" # For irregular plurals (default: ${ENTITY}s)
TABLE="checkpoints" # DB table name (default: lowercased + s)
ENDPOINT="/checkpoints" # REST path (default: /${TABLE})
FIELDS="name:String location:String elevationM:Integer distanceFromStartKm:BigDecimal"
Supported field types: String, Integer, Long, Double, Boolean,
BigDecimal, LocalDate, LocalDateTime, LocalTime, Duration.
cd /Users/ronnieschaniel/dev/spring-hexagonal
./.github/skills/scaffold-entity/scripts/scaffold-entity.sh .github/skills/scaffold-entity/references/<entity>.spec
The script generates 14 files and never overwrites existing ones:
| # | Layer | File |
|---|---|---|
| 1 | Domain | <Entity>.java |
| 2 | Domain | <Entity>Repository.java |
| 3 | Application | Create<Entity>UseCase.java |
| 4 | Application | Get<Entity>UseCase.java |
| 5 | Application | GetAll<Plural>UseCase.java |
| 6 | Application | Delete<Entity>UseCase.java |
| 7 | Application | Create<Entity>Command.java |
| 8 | Application | <Entity>NotFoundException.java |
| 9 | API | <Entity>Controller.java |
| 10 | Infrastructure | <Entity>Entity.java |
| 11 | Infrastructure | <Entity>RepositoryAdapter.java |
| 12 | Infrastructure | Jpa<Entity>Repository.java |
| 13 | Test | Create<Entity>UseCaseTest.java |
| 14 | Test | <Entity>ControllerTest.java |
Use --dry-run to preview without writing: ./.github/skills/scaffold-entity/scripts/scaffold-entity.sh <spec> --dry-run
The script generates standard CRUD. The agent MUST complete these manual steps:
Register the NotFoundException — Add the new <Entity>NotFoundException to
src/main/java/com/ultratrail/api/ApiExceptionHandler.java:
@ExceptionHandler({...}) listAdd enums — If the entity needs a status enum or other enums:
public enum <Name> { ... } inside the domain entity@Enumerated(EnumType.STRING) field in the JPA entityfromDomain() / toDomain() in the JPA entityAdd custom finders — If the entity needs queries beyond findAll/findById:
Add business logic — If the create use case needs defaults, validation, or computed fields beyond the simple field-copy the script generates.
Run the full test suite to verify ArchUnit compliance, compilation, and tests:
cd /Users/ronnieschaniel/dev/spring-hexagonal && mvn test
All tests MUST pass before considering the task complete.
If the user wants frontend integration, use the controller-data-to-ts-models skill to generate TypeScript models from the new controller.
User says: "Create a Checkpoint entity with name, location, elevation, and distance from start"
Create .github/skills/scaffold-entity/references/checkpoint.spec:
ENTITY="Checkpoint"
TABLE="checkpoints"
ENDPOINT="/checkpoints"
FIELDS="name:String location:String elevationM:Integer distanceFromStartKm:BigDecimal"
Run: ./.github/skills/scaffold-entity/scripts/scaffold-entity.sh .github/skills/scaffold-entity/references/checkpoint.spec
Add CheckpointNotFoundException to ApiExceptionHandler.java
Run: mvn test → all green
Done. 14 files created, 0 lines of boilerplate written by the LLM.