Tutorial

Eine Web-App mit dem AI Unified Process bauen

Book Library: von der leeren Leinwand zur getesteten Anwendung.
Durchlaufen Sie den AI Unified Process von Anfang bis Ende, indem Sie die Skills von aiup-core und den Layer-Plugins für Flyway, jOOQ, Spring Boot und Vaadin in Claude Code verketten. Jeder Schritt produziert ein konkretes Artefakt (eine Markdown-Spezifikation, ein Diagramm, ein Architekturdokument, ein SQL-Skript, Java-Code oder eine Testklasse), auf dem der nächste Schritt aufbaut.
Warum überhaupt ein Prozess?

Struktur schlägt Improvisation #

KI-Agenten sind gut darin, Code zu erzeugen, aber ohne Struktur neigen sie zur Improvisation. Der AI Unified Process (AIUP) gibt der KI eine vordefinierte Kette von Artefakten vor, die jeweils den Lösungsraum für den nächsten Schritt einengen.

Die Kette #

Wenn Sie bei /use-case-implement ankommen, hat die KI bereits eine Vision, eine Use-Case-Spezifikation, ein Entitätsmodell und eine Stack-Datei, die für jede Schicht den Skill benennt, an denen sie sich orientieren kann; der erzeugte Code wurzelt in Ihrer Domäne, nicht in einer generischen Vorlage.

Startkette, einmal pro Projekt:

vision.md → /requirements → /entity-model
  → /stack → /use-case-diagram
/architecture-decision  # immer, wenn das Team eine Technologie- oder Strukturentscheidung trifft

Use-Case-Kette, für jeden Use Case:

/next → /use-case-spec UC-001 → /spec-review UC-001
  → /use-case-implement UC-001 → /use-case-test UC-001
  → /use-case-coverage UC-001 → /acceptance-protocol
/open-questions  # immer, wenn eine Lücke die Antwort eines Menschen braucht

Am Ende eines Release schreibt /release-notes die fachlichen Release Notes aus den Use Cases, die Done erreicht haben.

/release-notes

Starten Sie für jeden Skill-Lauf eine neue Claude-Code-Session: Jeder Skill liest, was er braucht, aus den Dateien in docs/, und eine lange Session, die ihren Kontext mehrmals komprimiert, verliert Details und wird langsam.

Voraussetzungen #

Was Sie brauchen, bevor Sie die Kette starten:

  • Java 25 – das Projekt enthält einen mvnw-Wrapper
  • Docker – oder Testcontainers Cloud für den PostgreSQL-Container
  • Claude Code – mit installiertem aiup-core und den Layer-Plugins für den Stack der Book Library (siehe unten). Dieselben Skills laufen in Codex CLI, Cursor, GitHub Copilot, Gemini CLI und OpenCode; siehe andere KI-Coding-Tools
  • Das Starterprojekt – frisch aus dem book-library-Repository geklont

Die Book Library kombiniert Flyway, jOOQ, Spring Boot und Vaadin Flow und braucht deshalb neben aiup-core ein Plugin pro Schicht:

/plugin marketplace add ai-unified-process/marketplace
/plugin install aiup-core
/plugin install aiup-flyway
/plugin install aiup-jooq
/plugin install aiup-spring-boot
/plugin install aiup-vaadin

Noch mit dem kombinierten Plugin aiup-vaadin-jooq unterwegs? Es ist abgekündigt und wird mit aiup-core 4.0.0 entfernt. Layer-Plugins erklärt den Umstieg und ordnet die alten Befehle den neuen zu.

Schritt für Schritt

Die neun Schritte zur lauffähigen App #

Abgesehen von der Vision, die Sie zuerst prüfen, und dem Testlauf am Schluss entspricht jeder Schritt einem Slash-Befehl in Claude Code. Führen Sie sie der Reihe nach aus; jeder Schritt baut auf den Artefakten des vorherigen auf.

  1. Die Vision prüfen #

    Die Vision ist das einzige Artefakt, das Sie selbst schreiben. Alles Weitere wird daraus generiert.

    Für dieses Tutorial liegt die Vision bereits unter docs/vision.md bereit; öffnen Sie sie und lesen Sie sie, bevor Sie weitermachen. Sie ist die Quelle der Wahrheit für jeden folgenden Schritt. Halten Sie sie kurz; eine Seite reicht: das Problem, die Lösung, die Zielnutzer, die Ziele und die Nicht-Ziele.

    Tipp. Seien Sie explizit bei den Nicht-Zielen. Wer klar formuliert, was nicht zum Umfang gehört (keine Bezahlung, keine Reservierungen, keine Selbstregistrierung), verhindert, dass die KI unnötige Features einbaut.
    Vorbereitete Sicherheit. Das Starterprojekt bringt Spring Security, eine app_user-Tabelle (nur Identität), eine Login-View und zwei vorbefüllte Accounts mit (librarian / librarian, alice / alice). Authentifizierung ist daher kein Thema dieses Tutorials; Ihre generierten Views benötigen nur @RolesAllowed("MEMBER") für die Views, die nur Mitglieder nutzen (Ausleihen, Zurückgeben, meine Ausleihen: die Bibliothekarin hat keine Member-Zeile und leiht nicht aus, wie docs/architecture.md festhält), @RolesAllowed("LIBRARIAN") für die, die nur der Bibliothekarin offenstehen, und @RolesAllowed({"MEMBER", "LIBRARIAN"}) für die Katalogsuche, die beide nutzen.
  2. Anforderungskatalog generieren #

    /requirements

    Dieser Skill liest docs/vision.md, stellt bis zu fünf Rückfragen, wo die Vision eine Entscheidung offenlässt, und produziert einen strukturierten Anforderungskatalog in docs/requirements.md sowie die Fachbegriffe in docs/glossary.md. Der Katalog enthält:

    • Funktionale Anforderungen als User Stories (Als Mitglied möchte ich den Katalog durchsuchen, damit ich ein Buch finde, ohne die Bibliothekarin zu fragen).
    • Nicht-funktionale Anforderungen (Performance, Usability, Wartbarkeit).
    • Rahmenbedingungen (der Tech-Stack aus der README, die Nicht-Ziele aus der Vision, ...).

    Prüfen Sie den Katalog, bevor Sie weitermachen; das ist Ihre letzte Gelegenheit, kostengünstig nachzusteuern. Jeder spätere Schritt baut auf dieser Liste auf.

  3. Entitätsmodell aufbauen #

    /entity-model

    Aus den Anforderungen identifiziert der Skill die Domänenentitäten und schreibt docs/entity_model.md: ein Mermaid-ER-Diagramm der Entitäten, ihrer Beziehungen und Kardinalitäten sowie eine Attributtabelle pro Entität mit Datentypen, Länge oder Genauigkeit und Validierungsregeln (Pflichtfelder, Längen, Eindeutigkeit).

    Für die Book Library erwartet Sie etwa Folgendes:

    • Book (id, title, author, isbn, copies)
    • Member (id, user_id, name, email) – ein Mitglied der Bibliothek, 1:1 mit einer bestehenden app_user-Zeile verknüpft.
    • Loan (id, book_id, member_id, borrowed_at, returned_at)

    Die Entität AppUser (id, username, password_hash, role, created_at) gehört zum Starterprojekt und muss nicht im Entitätsmodell auftauchen; behandeln Sie sie als externe Grenze.

  4. Architektur festhalten #

    /stack

    Vor der ersten Zeile Code hält der Skill fest, welcher Layer-Skill jede technische Schicht baut und testet. Er erkennt Flyway, jOOQ, Spring Boot und Vaadin an der pom.xml und am Quellbaum des Starterprojekts und schreibt die Stack-Datei nach docs/architecture/stack.md. Die Stack-Datei enthält:

    • Die Schichtentabelle Migration mit /flyway-schema, Persistenz mit /jooq-persistence, Service mit /spring-service, UI mit /vaadin-flow-ui, den Test-Skill jeder Schicht, die einen hat, und die E2E-Schicht mit /vaadin-e2e-test
    • Die Tabelle der Integrationsschicht wo ein Use Case getestet wird, je Einstiegsschicht: einer, den die UI anbietet, in der UI, deren Browserless-Tests im Prozess gegen die echte Datenbank laufen, und einer, den nur der Service anbietet, etwa ein zeitgesteuerter Job, im Service
    • Der E2E-Umfang Use cases and test cases: Jeder über die UI angebotene Use Case erhält auch einen Browsertest; mit Test cases only entstehen Browsertests nur für die Journeys
    • Modulaufbau und Befehle wo der Code jeder Schicht liegt und wie man ihn baut und testet

    Das Starterprojekt bringt bereits ein docs/architecture.md mit seinen Package-Konventionen mit; der Skill liest es als Eingabe und lässt es, wo es ist; die Stack-Datei liegt neben dem Architekturdokument des Teams. Diesen Schritt führen Sie einmal pro Projekt aus und danach nur, wenn sich eine Schicht ändert. Prüfen Sie die Datei wie jedes andere Artefakt: Die Schritte zum Implementieren und Testen lesen sie.

    Die eine Rückfrage. Die Schichten erkennt der Skill selbst, nicht aber, wie viele Browsertests Sie wollen; deshalb fragt er nach dem E2E-Umfang. Antworten Sie mit Use cases and test cases: Schritt 8 schreibt dann den Browsertest, den Schritt 9 ausführt. Mit Test cases only schreibt /use-case-test keinen UC001SearchCatalogIT, und Sie verlangen ihn mit /use-case-test UC-001 e2e.
    Einstiegsschichten. Alle Use Cases der Book Library werden über die UI angeboten, die Spezifikationen, die Sie in Schritt 6 schreiben, brauchen deshalb keine Schichten-Zeile. In einer App, die zusätzlich eine REST-API hat, hält ein Use Case, der nur über eine der beiden angeboten wird, das mit einer Zeile wie Schichten: UI fest.
  5. Use-Case-Diagramm zeichnen #

    /use-case-diagram

    Der Skill erzeugt aus den Anforderungen ein PlantUML-Use-Case-Diagramm unter docs/use_cases.puml. Es zeigt die beiden Akteure (Member, Librarian) und die Use Cases, an denen sie beteiligt sind:

    UC-001Katalog durchsuchen
    UC-002Buch ausleihen
    UC-003Buch zurückgeben
    UC-004Aktive Ausleihen ansehen (Librarian)
    UC-005Katalog verwalten (Librarian)
    UC-006Mitglieder verwalten (Librarian)
    UC-007Meine Ausleihen ansehen

    Nutzen Sie das Diagramm zur Abdeckungsprüfung: Jede Anforderung sollte mindestens einem Use Case zugeordnet sein, und jeder Use Case sollte auf eine Anforderung zurückführbar sein.

  6. Erste Use-Case-Spezifikation schreiben #

    /use-case-spec UC-001

    Wählen Sie den Use Case, der die anderen freischaltet, zuerst. Für die Book Library ist das UC-001 Katalog durchsuchen; er hat keine Vorbedingungen, gibt dem Mitglied sofort etwas zu tun und liefert die Datenstrukturen, die UC-002 braucht.

    Der Skill schreibt docs/use_cases/UC-001-search-catalog.md mit primärem und sekundären Akteuren, Auslöser, den verknüpften Anforderungen, Vorbedingungen, dem Hauptablauf als nummerierte Schritte, Alternativabläufen, Nachbedingungen für Erfolg und Misserfolg und Geschäftsregeln (BR-001, …). Sie beginnt mit Status: Draft.

    Konkret bleiben. Ein Schritt wie "das System zeigt die Bücher" reicht nicht; "das System zeigt die Bücher mit den Spalten Titel, Autor, ISBN und verfügbare Exemplare, sortiert aufsteigend nach Titel" reicht. Nennen Sie, was der Akteur sieht, nicht das Widget: /spec-review meldet ein Grid oder eine Buttonfarbe als falsche Ebene.
    Prüfen vor dem Implementieren. Führen Sie /spec-review UC-001 aus, sobald die Spezifikation stimmig ist; nennen Sie den Use Case, denn ohne ID prüft der Befehl das ganze Projekt und meldet jeden Use Case des Diagramms, der noch keine Spezifikation hat, als Fehler. Der Befehl prüft, ob jeder Verweis aufgelöst wird und ob der Use Case mit den Anforderungen, dem Entitätsmodell und den anderen Use Cases übereinstimmt, und meldet Schritte, die fehlschlagen können, ohne dass ein Alternativablauf greift. Er berichtet nur; beheben Sie die Befunde mit /use-case-spec und prüfen Sie erneut. Ist die Prüfung sauber, setzen Sie die Status-Zeile auf Approved; bei einem Use Case in Draft oder Reviewed fragt /use-case-implement nach, bevor er baut.
  7. Use Case implementieren #

    /use-case-implement UC-001

    Hier zahlt sich die Kette aus. Der Skill liest die Use-Case-Spezifikation, die verlinkten Anforderungen, das Entitätsmodell und die Stack-Datei, fragt Lücken in der Spezifikation in einer Runde ab und führt dann die Layer-Skills von unten nach oben aus. Jede Schicht übergibt die Typen und Methoden, die sie angelegt hat, an die nächste:

    • /flyway-schema schreibt ein versioniertes Flyway-Skript unter src/main/resources/db/migration/. Da das Starterprojekt bereits V001__create_app_user.sql enthält, ergänzt es eine neue Version (z. B. V002__create_member_book_loan.sql) mit den Tabellen, Primär- und Fremdschlüsseln (inklusive member.user_id → app_user.id) sowie den NOT-NULL-, UNIQUE- und CHECK-Constraints aus dem Entitätsmodell.
    • /jooq-persistence schreibt ein jOOQ-basiertes Repository (BookRepository) gegen die Klassen, die jOOQ aus der Migration generiert, und projiziert die Ergebnisse in Java-Records.
    • /spring-service schreibt den Service mit den Transaktionsgrenzen und den Geschäftsregeln des Use Case.
    • /vaadin-flow-ui schreibt die Vaadin-View (SearchCatalogView), an MainLayout angebunden und direkt mit dem Service verbunden.

    Zwischendurch führt der Skill den Build aus, damit die jOOQ-Klassen aktuell sind, bevor das Repository entsteht. Tests schreibt er keine. Starten Sie die App über TestApplication aus Ihrer IDE oder mit ./mvnw spring-boot:test-run auf der Kommandozeile, melden Sie sich als alice / alice an und öffnen Sie den Katalog. Er ist noch leer: Kein Use Case legt bisher Bücher an, und die produktiven Migrationen enthalten keine Demodaten, deshalb sehen Sie die Leer-Meldung aus der Spezifikation. Die Bücher kommen mit den Testdaten des nächsten Schritts.

  8. Tests für den Use Case schreiben #

    /use-case-test UC-001

    Der Skill testet den Use Case einmal, in der Integrationsschicht. Bei Vaadin Flow ist das die UI, also schreibt /vaadin-flow-ui-test unter src/test/java die Klasse UC001SearchCatalogTest, die die AbstractBrowserlessTest des Starters erweitert, einen SpringBrowserlessTest mit der Testcontainers-Datenbank. Sie steuert die View ohne Browser, aber gegen den echten Service und die echte Datenbank: zur View navigieren, Suchfeld und Grid finden, eine Anfrage eintippen, prüfen, dass das Grid die erwarteten Zeilen zeigt, und jeden Alternativablauf und jede Geschäftsregel der Spezifikation abdecken. Jede Testmethode trägt @UseCase(id = "UC-001"), die Testdaten landen in einer wiederholbaren Migration, src/test/resources/db/migration/R__uc001_search_catalog.sql, die Flyway ohne Profil und ohne @TestPropertySource neben den Produktionsmigrationen findet. Sobald diese Testdaten den Katalog füllen, lässt sich der Ablauf mit leerem Katalog mit ihnen nicht mehr herstellen; seine Testmethode ist deshalb mit @Transactional annotiert, löscht die Bücher innerhalb der Testtransaktion und prüft die Meldung für den leeren Katalog; der Rollback stellt die Testdaten wieder her.

    Mit dem E2E-Umfang Use cases and test cases endet derselbe Lauf mit der E2E-Schicht und schreibt auch gleich den End-to-End-Test des nächsten Schritts.

    Weil diese Tests durch alle darunterliegenden Schichten laufen, bekommen Repository und Service keine eigenen Tests. Ausführen mit ./mvnw test. Die Tests sind schnell, unter einer Sekunde pro Test, und bilden die innere Feedback-Schleife beim Iterieren an der View.

    Starten Sie TestApplication jetzt erneut (oder ./mvnw spring-boot:test-run): Sie läuft auf dem Test-Classpath und lädt deshalb dieselben Testdaten aus src/test/resources/db/migration, also können Sie eine Suchanfrage eingeben, die Filterung des Grids sehen und die Ergebnisse so sortiert vorfinden, wie es die Spezifikation verlangt.

  9. End-to-End-Test ausführen #

    ./mvnw verify

    Mit dem E2E-Umfang Use cases and test cases hat der /use-case-test-Lauf aus Schritt 8 den Browsertest bereits geschrieben: /vaadin-e2e-test hat einen Playwright + Drama Finder Test erzeugt, UC001SearchCatalogIT, der AbstractBasePlaywrightIT erweitert. Er bootet die komplette Spring-Boot-App auf einem zufälligen Port und steuert einen echten Browser durch den Use Case: App mit frischer Datenbank starten, über die Login-View anmelden, Katalogseite öffnen, Suchanfrage eintippen und prüfen, dass die sichtbaren Zeilen der Spezifikation entsprechen. Der Ablauf mit leerem Katalog bekommt keinen Browsertest: Die laufende App hat einen einzigen Datensatz, und der Browserless-Test deckt ihn bereits ab.

    ./mvnw verify führt die Browserless-Tests und danach die Integrationstests aus. Das ist Ihre äussere Feedback-Schleife: langsamer als die Browserless-Tests, beweist aber, dass JavaScript, CSS, Routing und Datenbank zusammenspielen. Um nur den Browsertest zu schreiben oder abzugleichen, etwa nach einer Änderung an der View, führen Sie /use-case-test UC-001 e2e aus; mit dem E2E-Umfang Test cases only verlangen Sie so überhaupt erst einen Browsertest für einen Use Case.

Abschluss

Was Sie am Ende haben #

Nach dem vollständigen Durchlauf für UC-001 haben Sie eine dokumentierte Vision und einen Anforderungskatalog, ein Entitätsmodell und ein Use-Case-Diagramm für die ganze App sowie eine Stack-Datei der Schichten und für den ersten Use Case eine Spezifikation, eine Migration, eine Implementierung über vier Schichten, Browserless-Tests in der Integrationsschicht und einen End-to-End-Test.

Nächsten Use Case ergänzen #

Für einen neuen Use Case benötigen Sie nur die Schritte 6, 7, 8, 9; Anforderungen, Entitätsmodell, Diagramm und Stack-Datei decken die ganze App ab und müssen nicht neu erstellt werden. Braucht ein Use Case neue Tabellen oder Spalten, ergänzt /use-case-implement als erste Schicht eine neue V003__...-Migration.

Bestehenden Use Case ändern #

Ein neues Feature, eine Änderung oder ein Bug landen alle am selben Ort: Spezifikation anpassen, dann die Schritte 7, 8 und 9 erneut ausführen. /use-case-implement findet die bestehende View, den Service und das Repository und ändert nur, was die Spezifikation jetzt verlangt; /use-case-test aktualisiert die bestehenden Testklassen, statt zweite anzulegen. Braucht die Änderung eine neue Spalte, entsteht eine neue Migration; bereits angewendete Migrationen werden nie bearbeitet.

Wie es weitergeht #

  • Prüfen Sie mit /use-case-coverage UC-001 das eben Gebaute gegen seine Spezifikation: Der Befehl zeigt, welche Szenarioschritte, Alternativabläufe und Geschäftsregeln durch Code und Tests abgedeckt sind und was noch offen ist. Auch jede NFR und jede Randbedingung auf der Anforderungen-Zeile des Use Cases ist eine Einheit: Eine Grenze, die ein Test beobachten kann, etwa eine Antwortzeit, bleibt offen, bis ein Test sie prüft, und erst dann schlägt der Audit Tested vor. Verlinken Sie nur die NFRs, die der Use Case selbst belegen muss; eine, die für das ganze System gilt, etwa die Anmeldung, braucht keinen Link. Den nächsten Status schlägt der Audit nur vor: Implemented, sobald jede Einheit Code hat, Tested, sobald jede Einheit einen Test hat und die Suite grün ist. Die Status-Zeile setzen Sie selbst, wie zuvor Approved; kein Skill ändert sie, und /requirements zieht danach den Status der verlinkten Anforderungen nach.
  • Lassen Sie die Kette erneut für UC-002 Buch ausleihen laufen; sie wird Book und Member wiederverwenden und Zeilen zu Loan hinzufügen. Das vorbereitete Konto alice hat noch keine Member-Zeile, deshalb verknüpfen die Testdaten ein eigenes Mitglied; um in der laufenden App als alice auszuleihen, geben Sie ihr eine in den Testdaten oder mit UC-006 Mitglieder verwalten.
  • Weiter mit UC-003 Buch zurückgeben, um den Lebenszyklus zu schliessen.
  • Ergänzen Sie den Librarian-Use-Case UC-004 Aktive Ausleihen ansehen für die operative Sicht.
  • Entscheiden Sie vor UC-005 Katalog verwalten, was das Entfernen eines Buchs bedeutet, das schon ausgeliehen wurde: Seine Ausleihen verweisen weiter darauf, und die Ausleihhistorie muss bleiben. Entweder lässt sich nur ein nie ausgeliehenes Buch entfernen, oder ein Buch wird aus dem Katalog zurückgezogen statt gelöscht; halten Sie die Wahl mit /requirements und /entity-model fest, bevor Sie /use-case-spec UC-005 ausführen.
  • Sobald einige Use Cases existieren, schreiben Sie mit /test-case UC-001 UC-002 UC-003 einen Testfall TC-001, der sie zu einem End-to-End-Szenario verkettet, automatisieren Sie ihn mit /test-case-implement TC-001, das /vaadin-e2e-test mit der Journey ausführt, und prüfen Sie ihn mit /test-case-coverage TC-001.
  • Lesen Sie Layer-Plugins, um zu sehen, wie sich die Schichten kombinieren lassen, etwa für eine REST-API neben der UI.
Kontakt

Lust auf einen Hands-on-Walkthrough? #

Workshops und massgeschneiderte Einführungen des AI Unified Process für Ihr Team und Ihren Stack. Vereinbaren Sie einen Termin, um zu besprechen, wie der AI Unified Process zu Ihrem Projekt passt.