Tutorial

Build a web app with the AI Unified Process

Book Library — from a blank canvas to a tested app.
Walk through the AI Unified Process end-to-end by chaining the skills from the aiup-core and aiup-vaadin-jooq Claude Code plugins. Each step produces a concrete artifact — a markdown spec, a diagram, a SQL script, Java code, or a test class — that the next step builds on.
Why a process?

Structure beats improvisation #

AI agents are great at producing code, but without structure they tend to improvise. The AI Unified Process (AIUP) gives the AI a predefined chain of artifacts to produce, each one narrowing the design space for the next.

The chain #

By the time you reach /implement, the AI already has a vision, a use case spec, an entity model, and a database schema to anchor its output — so the code it writes is grounded in your domain, not in a generic template.

vision.md → /requirements → /entity-model
  → /use-case-diagram → /use-case-spec
  → /flyway-migration → /implement
  → /browserless-test → /playwright-test

Prerequisites #

What you need before running the chain:

Step by step

The nine steps to a working app #

Each step corresponds to one slash command you run inside Claude Code. Run them in order — every step builds on the artifacts of the previous one.

  1. Review the Vision #

    The vision is the only artifact you write by hand. Everything else is generated from it.

    For this tutorial the vision is already prepared at docs/vision.md — open it and read it before continuing. It is the source of truth for every step that follows. Keep it short — one page is plenty: the problem, the solution, the target users, the goals, and the non-goals.

    Tip. Be explicit about non-goals. Calling out what is out of scope (no payments, no reservations, no self service sign-up) tells the AI not to scaffold features you do not need yet.
    Pre-seeded security. The starter ships Spring Security, an app_user table (identity only), a login view, and two seeded accounts. The tutorial therefore does not cover authentication — your generated views just need @RolesAllowed("MEMBER") or @RolesAllowed("LIBRARIAN").
  2. Generate the Requirements Catalog #

    /requirements

    This skill reads docs/vision.md and produces a structured requirements catalog in docs/requirements.md, including:

    • Functional requirements as user stories (As a member, I want to search the catalog so that I can find a book quickly).
    • Non-functional requirements (performance, usability, maintainability).
    • Constraints (the tech stack from the README, the non-goals from the vision, ...).

    Review the catalog before continuing — this is your last chance to course-correct cheaply. Every later step compounds on this list.

  3. Build the Entity Model #

    /entity-model

    From the requirements the skill identifies the domain entities and produces a Mermaid ER diagram in docs/architecture/entity-model.md, including entities and attributes with types, relationships and cardinalities, and validation rules (required fields, lengths, uniqueness).

    For the Book Library you should expect roughly:

    • Book (id, title, author, isbn, copies)
    • Member (id, user_id, name, email) — a library patron, linked 1:1 to an existing app_user row.
    • Loan (id, book_id, member_id, borrowed_at, returned_at)

    The AppUser entity (id, username, password_hash, role) is part of the starter and does not need to appear in the entity model — treat it as an external boundary.

  4. Draw the Use Case Diagram #

    /use-case-diagram

    The skill renders a PlantUML use case diagram from the requirements at docs/architecture/use-case-diagram.puml. It shows the two actors (Member, Librarian) and the use cases they participate in:

    UC-001Search catalog
    UC-002Borrow book
    UC-003Return book
    UC-004View active loans (Librarian)
    UC-005Manage catalog (Librarian)

    Use the diagram to confirm coverage: every requirement should land on at least one use case, and every use case should trace back to a requirement.

  5. Write the First Use Case Specification #

    /use-case-spec UC-001

    Pick the use case that unblocks the others to go first. For the Book Library that is UC-001 Search catalog — it has no preconditions, gives the member something to do the moment they land on the page, and produces the data structures that UC-002 needs.

    The skill writes docs/use_cases/UC-001-search-catalog.md with actors and stakeholders, preconditions and postconditions, the main success flow as numbered steps, alternative flows, and acceptance criteria.

    Be concrete. A step like "the system shows the books" is not enough — "the system shows a Grid with columns Title, Author, ISBN, and Available Copies, sorted by Title ascending" is.
  6. Generate the Flyway Migration #

    /flyway-migration

    The skill reads the entity model and the use case spec and emits a versioned Flyway script under src/main/resources/db/migration/. The starter already contains V001__create_app_user.sql, so the skill produces a new version (e.g. V002__create_member_book_loan.sql) for the missing tables, including:

    • CREATE TABLE statements for member, book, and loan
    • Primary and foreign keys including member.user_id → app_user.id
    • NOT NULL constraints driven by the validation rules in the entity model
    • Useful indexes e.g. on loan.book_id and loan.member_id
    • Seed data linking the seeded alice user to a freshly inserted member row

    Run ./mvnw compile once after this step — it will start a Testcontainers Postgres, apply the migration, and regenerate the jOOQ metamodel so the next step has typed references to your new tables.

  7. Implement the Use Case #

    /implement UC-001

    This is where the chain pays off. The skill reads the use case spec, the entity model, and the generated jOOQ classes, and produces:

    • A jOOQ-based repository (BookRepository) in the domain package
    • A service layer if the flow needs business logic
    • A Vaadin view (SearchCatalogView) in the ui package, wired to MainLayout
    • DTOs / records for the data passed between layers

    Run the app via TestApplication from your IDE and click through the flow. You should be able to type a query, see the Grid filter, and see the results sorted as the spec requires.

  8. Write Browserless UI Tests #

    /browserless-test UC-001

    The skill creates a UI unit test under src/test/java/.../SearchCatalogViewTest.java that extends AbstractBrowserlessTest. It exercises the view without a browser by driving the Vaadin component tree directly: navigate to the view, look up the search field and the grid, type a query, assert the grid shows the expected rows, and cover the alternative flows from the spec.

    Run it with ./mvnw test. These tests are fast — under a second per test — so they form the inner feedback loop while you iterate on the view.

  9. Write the End-to-End Test #

    /playwright-test UC-001

    The final skill produces a Playwright + Drama Finder E2E test under src/test/java/.../SearchCatalogIT.java extending AbstractBasePlaywrightIT. It boots the full Spring Boot app on a random port and drives a real browser through the use case: start the app with a fresh database, open the catalog page, type a search query, and assert the visible rows match what the spec requires.

    Run with ./mvnw verify to execute the integration tests. This is your outer feedback loop — slower than the browserless tests, but it proves that the JavaScript, CSS, routing, and database layers all line up.

Wrap up

What you have at the end #

After running the full chain for UC-001 you have a documented vision and requirements catalog, an entity model and use case diagram covering the whole app, plus a spec, migration, implementation, and two layers of tests for the first use case.

Add the next use case #

To add a new use case, you only need steps 5, 7, 8, 9 — the requirements, entity model, and diagram cover the whole app, so they do not need to be regenerated. Use cases that need new tables or columns will also re-trigger step 6 with a new V003__... migration.

Change an existing use case #

A new feature, a change request, or a bug all end up in the same place: edit the specification, then re-run steps 7, 8, and 9. /implement finds the existing view and repository and changes only what the spec now requires, and the test commands update the existing test class rather than adding a second one. A change that needs a new column also re-triggers step 6 with a new migration — never edit one that has already been applied.

Where to go next #

  • Run the chain again for UC-002 Borrow book — it will reuse Book and Member and add rows to Loan.
  • Continue with UC-003 Return book to close the lifecycle.
  • Add the librarian-facing UC-004 View active loans for the operational view.
  • Once a few use cases exist, explore the aiup-vaadin-jooq testing skills to improve coverage.
Talk to us

Want a hands-on walkthrough? #

Workshops and tailored rollouts of the AI Unified Process for your team and stack. Book a call to talk through how AIUP fits your project.