CtrlK
BlogDocsLog inGet started
Tessl Logo
PluginPublic

apavithraa/springboot-architecture

Skills for creating, testing, reviewing, migrating and guarding Spring Boot 4 projects with Java 25: project scaffolding with architecture patterns, Boot 4 test templates, code review, Boot 3 to 4 migration, and a team harness of build gates and agent hooks.

Quality

93%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

progen-integration.mdskills/creating-springboot-projects/references/

Progen Integration

Progen is an offline CLI that generates a Spring Boot 4 project: build file, Docker Compose, Testcontainers, security, migrations, CI, and ArchUnit/Modulith tests. Use it for the base project. Then add the architecture layer from this skill on top.

Progen has no architecture option. Its layout is always package-by-module with Spring Modulith (config/, shared/, users/).

Tested with progen v1.0.4 on 2026-10-31 (REST, Maven, PostgreSQL). Progen pins Spring Boot 4.1.2 and Java 25. v1.0.4 (2026-10-24) changed ArchUnitTests and has not been tested here.

When to use progen

Use progen when all of these are true:

  • command -v progen finds it, or the user agrees to install it.
  • The project is a REST API, a server-rendered web app (Thymeleaf), or a Spring Boot + Angular app.
  • The database is PostgreSQL, MySQL, or MariaDB.
  • The user accepts Spring Security with a sample users module. Progen always generates it.

Otherwise, use Spring Initializr (Step 3 of SKILL.md).

Install: go install github.com/sivaprasadreddy/progen@latest, or download a binary from the releases page. On macOS the binary is unsigned. The user must allow it in Finder (Control-click, Open).

Safety rules

  • Progen deletes ./<AppName>/ before it generates. Never run it where that directory exists. The helper script refuses to run in that case.
  • Run progen with JDK 25 on PATH. On JDK 27 the formatting step always fails with NoSuchFieldError ... JCCompilationUnit: Spotless 3.10.4 (progen pins 3.10.0) fixes its unused-imports step, but palantir-java-format fails on JDK 27 in every version up to 2.102.0 (checked 2026-10-21). The project then doesn't compile, because the step that failed is the one that removes an unused AntPathRequestMatcher import (Spring Security 7 removed the class) from config/WebSecurityConfig.java. The helper script stops with exit code 6 on a JDK newer than 25. If you're stuck on JDK 27: pass --ignore-jdk-check, delete that import and build with -Dspotless.check.skip=true. On JDK 25 progen's output passes ./mvnw verify as generated (10 tests).
  • Progen does not validate most values. An invalid value becomes the default, with only a WARNING. Use the helper script. It rejects invalid values.
  • Progen runs spotless:apply (Maven) or spotlessApply (Gradle) at the end. This needs Java on PATH and network access on the first run. If only that step fails, progen prints "failed to format project code" and exits with 1, but the files exist; the script reports this as a warning. Any other progen failure stops the script with exit code 4.

Step 1: Map the assessment to progen options

Assessment answerScript optionProgen value
JSON API--app-type rest (default)REST API
Server-rendered UI--app-type webWeb App (Thymeleaf is on)
Angular SPA--app-type angularSpring Boot + Angular Full Stack
Maven / Gradle--build-tool maven|gradleMaven / Gradle
JPA (all architectures in this skill)--persistence jpa (default)Spring Data JPA
SQL-first, user asks for it--persistence jdbc|jooqSpring JdbcClient / jOOQ
Database--db postgresql|mysql|mariadbPostgreSQL / MySQL / MariaDB
Migrations--migration flyway|liquibaseFlyway / Liquibase
Optional features--features aws,email,rabbitmq,redis,k8s,htmx*Support: true
Java other than 25--java 21Script edits the build file after generation

Rules:

  • Tomato and DDD+Hexagonal need --persistence jpa. The templates in assets/ assume JPA.
  • With jdbc or jooq, do not apply JPA templates (assets/rich-entity.java, assets/repository.java).
  • htmx needs --app-type web.
  • Don't pass otel. Step 6 of SKILL.md runs the harness, whose observability pack replaces it.
  • Read java-version-policy.md before you pass --java above 25.

Step 2: Generate

${CLAUDE_SKILL_DIR} is the creating-springboot-projects folder. Codex doesn't set it, so there use that folder's path.

python3 "${CLAUDE_SKILL_DIR}/scripts/progen_config.py" \
  --app-name shop --base-package com.acme.shop \
  --build-tool maven --db postgresql --features redis \
  --out-dir /path/to/parent --run
  • Without --run, the script only writes and prints .progen.json. Show it to the user before you generate.
  • The project goes to <out-dir>/<app-name>/.
  • Exit codes: 0 = success (warnings may print, for example a failed formatting step), 1 = invalid input, 2 = target directory exists, 3 = progen not installed, 4 = progen failed or the project may be incomplete, 5 = generated but the Java version could not be set, 6 = the JDK in use (JAVA_HOME, else java on PATH) is newer than 25.

Step 3: Add the architecture layer

ArchitectureWhat to do after generation
package-by-moduleMatches progen. Add feature packages next to users/.
modular-monolithMatches progen. Add *API.java and internal/ per module. ModularityTests.java exists; do not add assets/modularity-test.java again. Copy only extra checks from it.
tomatoAdd domain/vo/, rich entities, and rest/converters/ per module. Apply assets/value-object.java, assets/rich-entity.java, assets/spring-converter.java, assets/service-cqrs.java.
ddd-hexagonalAdd application/, domain/, infra/, interfaces/ per module. On progen v1.0.3, change ArchUnitTests.java as shown below, because *Handler services fail the name rule.
layeredAdd controller/, service/, repository/, domain/. The tests pass, but Modulith treats each layer as a module, which adds no value. Keep users/ as the one feature package, and tell the user.

Templates to skip (progen already has them)

Skip this assetProgen file
assets/exception-handler.javaconfig/GlobalExceptionHandler.java. Add a DomainException handler there if needed.
assets/base-entity.javashared/BaseEntity.java (has @Version)
assets/docker-compose.ymlcompose.yml
assets/testcontainers-test.javaTestcontainersConfig.java, BaseIT.java
assets/modularity-test.javaModularityTests.java
assets/pom-additions.xmlAdd only entries the pom does not have: jspecify, hypersistence-utils-* (TSID IDs), spring-modulith-starter-jpa (event registry).

progen's ArchUnit test

Keep src/test/java/<base>/ArchUnitTests.java as progen generates it. The harness (Step 6 of SKILL.md) adds CodeRulesTests next to it, with the runtime-trap rules progen doesn't have. Don't copy rules from one file into the other.

What ArchUnitTests checks depends on the progen version:

  • v1.0.3 uses Taikai: name suffixes (Controller, Service, Repository, Config), package-private controllers and test classes, the LOG logger convention, no generic throws Exception, no import cycles, and layer-direction and @Disabled rules.
  • v1.0.4 uses ArchUnit directly: no access from domain to web packages, package-private repositories and JPA entities, and @Service classes used only from their own module. Check that its BASE_PACKAGE constant is the project's base package. In the template it is a fixed dev.sivalabs.feedbackhub, which matches no other project.

Change a rule only when it conflicts with the chosen architecture:

  • ddd-hexagonal on v1.0.3: services may be command handlers, so replace namesShouldEndWithService() with namesShouldMatch(".+(Service|Handler)").
  • Spring Data custom repository fragments on v1.0.3: replace namesShouldEndWithRepository() with namesShouldMatch(".+Repository(Impl)?").
  • layered on v1.0.4: the module rule reads the first package under the base as the module, so each layer counts as one. Remove services_must_not_be_used_from_other_modules.

Other differences

  • Progen creates V001__create_users_table.sql. Start new Flyway files at V002__. Flyway reads V1 and V001 as the same version and fails.
  • Progen sets spring.modulith.events.republish-outstanding-events-on-restart=true and spring.modulith.events.jdbc.schema-initialization.enabled=true. Spring Modulith advises against both for production: republishing duplicates events when several instances run, and the table should come from a Flyway migration. Tell the user before production use.
  • Progen sets spring.threads.virtual.enabled=true. This skill enables virtual threads only with workload evidence. Tell the user, and keep or remove it based on their answer.
  • Progen adds BootUI, devtools, springdoc, JWT (for REST), Spotless, JaCoCo, and git-commit-id. Remove what the user does not want.

Step 4: Verify

./mvnw test          # or ./gradlew test; Testcontainers needs Docker

Run ArchUnitTests and ModularityTests first. They run without Docker and catch layout errors quickly.

Align the project with the harness

scripts/align_progen_project.py adjusts a new project to the harness rules. progen_config.py --run runs it after generating. When you run progen another way, run it yourself before the harness.

FileChangeWhy
users/AuthUtils, users/TokenHelperMarks three methods that can return null as @NullableNullAway in all mode
config/GlobalExceptionHandlerReturns a generic detail from the catch-all handlerCodeRulesTests.catchAllHandlersKeepTheExceptionServerSide
config/GlobalExceptionHandlerLeaves the logging of failures to HandledFailureFilterEach 5xx is logged once
users/AuthController, users/UserRestControllerRemoves the email address from log linesLogLeakCheck

Each edit matches exact generated text. If the script prints skipped, the generated code differs: check it against these rules, then update the script. Checked on progen v1.0.4 with REST, Maven, JPA and PostgreSQL.

tile.json