AI Unified Process Spring Boot layers - service, REST API, and external system client implementation and tests
95%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
aiup-spring-boot is the AI Unified Process layer plugin for the service, API, and client layers of a
Spring Boot application: the business logic with its transactions and
business rules, a REST API with RFC 9457 Problem Details, and the calls to the external systems a use case names as
secondary actors — each with its test skill.
It is one layer of a stack, not a stack. Combine it with aiup-core (3.9.0 or later) and one plugin per other layer
of your project. /stack records which plugin builds which layer in docs/architecture/stack.md; /use-case-implement,
/use-case-test, and /use-case-coverage run the layer skills from there.
| Layer | Skill | Result |
|---|---|---|
| Client | /spring-client | Outbound port and adapter per external system, from its OpenAPI or AsyncAPI contract: RestClient/@HttpExchange or a Kafka/AMQP producer, error mapping to domain exceptions |
| Service | /spring-service | @Service methods, @Transactional boundaries, business rules with markers, domain exceptions, Bean Validation |
| API | /spring-rest | @RestController endpoints, request/response DTO records, Problem Details, status codes, paging; an agreed OpenAPI operation built as written |
| Client | /spring-client-test | <System>ClientTest: the adapter against a stub of the contract, every flow the system causes; <System>ClientFake for the tests above |
| Service | /spring-service-test | UC001<Name>ServiceTest: every business rule allowed and rejected, against a real database or a fake port |
| API | /spring-rest-test | UC001<Name>ApiTest: statuses, JSON contract, Problem Details bodies, through the full stack |
Each skill is normally run by /use-case-implement UC-XXX or /use-case-test UC-XXX, which pass the Handover of the layer
below — the repository methods, the service methods and exceptions, the endpoints — to the next. Each can also be
run directly, for example /spring-rest UC-001 to change only the API of a use case.
The service layer is used by every UI: a Vaadin Flow view calls it directly, a Hilla @BrowserCallable endpoint
(built by /hilla-ui in aiup-vaadin) delegates to it, and /spring-rest exposes it to a client-side UI such as
Angular. The service never depends on a web or UI type.
An external system the use case calls — a payment provider, a channel manager — is listed with its contract under
## External systems in docs/architecture/stack.md. /spring-client runs only for a use case whose Secondary
Actors line names such a system, before the service, and hands over the port the service calls. No test reaches the
system: /spring-client-test stubs the contract and writes a fake of the port, which the service, API, and UI tests
put in place of the adapter.
The other direction — an external system that calls us — is the use case's primary actor and reaches it through
the API layer. When its team has agreed an OpenAPI contract with yours, the use case links the operation on its
**API:** line ([registerGuest](../api/booking-portal.yaml#registerGuest)). In a contract-first project
/spring-rest builds that operation exactly as written — path, property names, statuses, error responses — instead
of choosing them, and /spring-rest-test takes its expected values from it. Where contract and specification
disagree, neither skill decides: the gap goes to docs/open-questions.md.
| Project | Plugins next to aiup-core |
|---|---|
| REST API, Spring Boot, jOOQ | aiup-flyway, aiup-jooq, aiup-spring-boot |
| REST API, Spring Boot, JPA | aiup-flyway, aiup-jpa, aiup-spring-boot |
| Vaadin Flow, jOOQ | aiup-flyway, aiup-jooq, aiup-spring-boot, aiup-vaadin |
| Hilla, jOOQ | aiup-flyway, aiup-jooq, aiup-spring-boot, aiup-vaadin |
| Angular, Spring Boot, JPA | aiup-flyway, aiup-jpa, aiup-spring-boot, aiup-angular, aiup-playwright |
A use case is tested once, in the integration layer of the entry layer it is offered through, which /stack
records in the Integration layer table of docs/architecture/stack.md:
| Project | Integration layer | What this plugin's test skills write |
|---|---|---|
| REST API only, or Angular | API | /spring-rest-test: every business rule; /spring-service-test nothing new |
| Vaadin Flow (with or without REST) | UI | /spring-rest-test: the endpoint contract only; /spring-service-test nothing new |
| Hilla (with or without REST) | Service | /spring-service-test: every business rule; /spring-rest-test: the contract only |
| No entry layer | Service | /spring-service-test: every business rule |
A REST API next to a Vaadin Flow or Hilla UI serves other clients; the UI does not call it, so it is the integration
layer only of the use cases offered through the API alone. Below the integration layer, /spring-service-test only reconciles existing tests and covers
units the integration layer's skill reports it cannot reach. In a Vaadin or Hilla application without a public API,
the API layer is marked – in docs/architecture/stack.md and /spring-rest does not run.
Do not install this plugin together with a combined stack plugin (aiup-vaadin-jooq, aiup-angular-jpa) in one
project.
The skills follow the module layout recorded in docs/architecture/stack.md:
Existing conventions are preserved rather than rewritten into a textbook architecture. The detection rules, used
when docs/architecture/stack.md does not record the layout, are in
skills/spring-service/references/module-layout.md.
| Kind | Marker |
|---|---|
| Code | // UC-XXX BR-YYY: <rule> above the service guard clause that enforces a business rule |
| Code | UC-XXX in the Javadoc of the service method and the controller method that realize a step |
| Test | @UseCase(id = "UC-XXX", scenario = "…", businessRules = {…}, requirements = {…}) on every test method |
| Name | UC<id><Name>ServiceTest, UC<id><Name>ApiTest / ApiIT |
Every skill writes its rows into the Markers table of docs/architecture/stack.md, which /use-case-coverage reads.
tessl install ai-unified-process/aiup-core
tessl install ai-unified-process/aiup-spring-boot/plugin marketplace add ai-unified-process/marketplace
/plugin install aiup-core
/plugin install aiup-spring-bootInstall the plugins of the other layers (migration, persistence, UI) the same way. See the marketplace installation guides for other agents and manual adoption.
The plugin configures the optional JavaDocs MCP server for Spring API lookups; see
rules/mcp-servers.md. The skills work without it.
Apache-2.0 · © 2025-2026 Simon Martinelli and the AI Unified Process contributors
See LICENSE and NOTICE. "AI Unified Process" identifies the original methodology; derived works must retain the NOTICE file and must not present themselves as the official AI Unified Process.