Files
ki-eit/08-vertikale-slices-ueber-den-stack.md
grok-bot 8e00712fb8 Kapitel-Review (MUSS): Metriken, Golden Paths und eBook neu.
Composite-Korridore und Primärquellen in Kap. 2 ehrlich kalibriert;
DoD/Verify, Surfaces und Anhänge in 04–16 geschärft; eBook 119 S. neu gebaut.
2026-08-10 22:11:27 +02:00

9.4 KiB
Raw Permalink Blame History

8. Vertikale Slices über den Stack

Kern: Ein Slice ist eine nutzbare Scheibe UI ↔ API ↔ Daten — nicht „erst alle DTOs, dann alle Services, dann irgendwann UI“.

Die Slice-Idee kommt aus dem Theorie-Schwesterbuch (Coding Agents in der Praxis, Kap. 8): Komplexität begrenzen, reviewbar bleiben, DoD am echten Outcome messen. Hier die Enterprise-Übersetzung für Angular + Spring Boot (oder Quarkus) mit Agents — wo Multi-Repo, Contracts und getrennte Sessions die Regel sind, nicht die Ausnahme.

Kapitel 5–7 haben die Idiome pro Schicht. Dieses Kapitel verbindet sie: ein Use-Case, dünn, end-to-end, mit messbarer Fertigstellung. Ohne diesen Schnitt multiplizieren Agents Fehler über den Stack — und Review wird zur Archäologie.

Vertikaler Slice: dünnes, fertiges Outcome über den Stack.{width=90%}

8.1 Warum horizontal teuer wird

Typischer Auftrag im Backlog: „Customer-Domain vorbereiten.“ Der Agent modelliert Entities, DTOs, Mapper, leere Services, Angular-Modelle — Wochen später fehlt die eine Liste, die der Nutzer braucht. Jede Schicht ist „fast fertig“, nichts ist nutzbar, und der Context jeder Session war voller spekulativer Typen.

Du merkst den horizontalen Big-Bang daran, dass:

  • der Diff viele Dateien hat, aber kein einzelnes grünes Outcome,
  • Frontend und Backend parallel raten, was der Contract werden könnte,
  • Review den Auftrag nicht in einem Satz wiedergeben kann.

Vertikal heißt: eine nutzbare Scheibe zuerst. Komplexitätsbudget ist Review-Budget (Kap. 2.2.4): was du im Diff nicht in endlicher Zeit verstehst, war zu groß — auch wenn CI irgendwann grün war.

8.2 Schnitt: von Outcome zu Schritten

Formuliere den Slice vom Nutzer her, nicht vom Layer her.

Beispiel-Outcome: „Benutzer kann X anlegen und in der Liste sehen.“

Sinnvolle Reihenfolge (anpassen, nicht dogmatisieren):

  1. Contract — OpenAPI (oder bestehendes Endpoint-Pattern) erweitern bzw. festnageln
  2. Backend — Handler/Resource + scoped Test (+ Persistenz nur soweit nötig)
  3. Angular — Feature (Liste/Form) + Unit-Test gegen euer HTTP-Muster
  4. Tight-Loop pro Schicht nach sinnvollen Patches; Slice-DoD wenn Outcome baubar und zum Auftrag passt
  5. Heavy — optional e2e / Integration nach Policy (Kap. 9)

In Multi-Repo sind 2 und 3 oft getrennte Sessions mit Handoff (Kap. 2.5): Backend grün und Contract gemerged, dann Frontend-Session mit Contract-Pfad in den Dateien mit Vorrang. Eine Session über drei Repos ist Context-Selbstmord.

Task-Formel (Kap. 2.4) bleibt der Kleber:

Outcome: …
Nebenbedingungen: bestehende Patterns, Security, OpenAPI
Ausschlüsse: kein Payment-Refactor, keine neuen NgModules, kein Native
DoD: Backend-Command && Frontend-Command (+ Contract aktualisiert)

Vorlage: templates/task-prompt-fullstack-slice.md. Skill: templates/skill-fullstack-slice/.

Do this Avoid that
Ein Outcome, ein Slice, eine DoD „Domain fertig machen“ ohne UI-Nutzen
Contract vor oder mit dem ersten schreibenden Patch FE und BE raten parallel ohne Repo-Wahrheit
Handoff an Slice-Grenze FE/BE Eine Session über Monorepo und drei Services

8.3 Contracts als Kleber

In Multi-Repos (und oft im Monorepo) ist OpenAPI oder ein äquivalenter Contract die gemeinsame Wahrheit. Agents bekommen den Contract im Repo, nicht nur als Chat-Paste, der nach Compact verschwindet.

Mini-Artefakt (imitierbar): Enum und Endpoint im Contract, nicht nur in der Tabelle:

# packages/contracts/openapi/orders.yaml (Auszug)
components:
  schemas:
    OrderStatus:
      type: string
      enum: [NEW, CONFIRMED, SHIPPED]
    Order:
      type: object
      required: [id, status]
      properties:
        id: { type: integer, format: int64 }
        status: { $ref: '#/components/schemas/OrderStatus' }
paths:
  /api/orders/{id}:
    get:
      operationId: getOrder
      # …

Handoff an der FE/BE-Grenze (Vorlage: templates/handoff-stack.md):

Contract: packages/contracts/openapi/orders.yaml (Order.status enum)
Endpoint: GET /api/orders/{id} — BE-Verify: ./mvnw -q -Dtest=OrderControllerTest test
Nicht gebaut: Checkout, Mail, Payment-Refactor
FE-nächste Session: List-Component + Typ/Client aus Contract; kein parallel erfundenes Interface

FE-Konsum — eine erlaubte Wahrheit (Policy im Repo, nicht im Chat):

Erlaubt (eine wählen und pinnen) Avoid
OpenAPI-Source → generierter Client/Types parallel erfundene FE-Interfaces „nur fürs UI“
bewusst gepflegte FE-Types mit DoD „bei API-Change mitziehen“ Mock-Welt über Wochen ohne Contract-Update
Rolle Contract im Repo Nur Chat / Wiki
Backend-Session spezifiziert Request/Response, generiert Client optional Agent erfindet Felder
Frontend-Session liest Operation + Schema mockt eine Parallelwelt
Review Diff gegen spezifizierte API „fühlt sich an wie REST“
Teach-back Generator/Pipeline als eine Wahrheit drei Versionen der Wahrheit

Contract-Drift ist die stille Variante des horizontalen Big-Bangs: Backend ändert ein Feld, Frontend-Session von gestern kennt es nicht, Integration scheitert im Heavy. Gegenmittel: Contract-Pfad in beiden AGENTS.md; DoD-Zeile „Contract aktualisiert bei API-Change“; nach API-Merge kurze Frontend-Session statt „machen wir später“.

Do this Avoid that
OpenAPI (o. Ä.) versioniert im Repo „Schau in Confluence / frag Team X“
Contract in Dateien mit Vorrang Nur generiertes Artefakt ohne Source
Breaking Changes bewusst + Handoff Stille Feld-Umbenennungen im Agent-Flow

8.4 Anti-Patterns

Anti-Pattern Was passiert Besser
Horizontaler Layer-Big-Bang viele Dateien, kein nutzbares Outcome ein Use-Case end-to-end dünn
Frontend-Mock-Welt über Wochen UI-Polish auf erfundener API Contract + echter Endpoint früh
„Erst die ganze Domain modellieren“ spekulative Typen, Context-Müll Persistenz nur für diesen Slice
Ein Agent, alle Repos, ein Thread Rot, falsche Module, Ownership-Wirrwarr Session pro Seite + Handoff
DoD nur „compiles“ falsches Grün scoped Tests FE und BE
Slice ohne Ausschlüsse Scope-Creep über Nachbar-Domains Task-Template mit Ausschlüssen

Diese Liste ist die Checkliste vor dem Prompt — nicht die Moral danach.

8.5 Mini-Walkthrough (Angular + Spring)

Outcome: Bestellstatus in der Liste anzeigen (Anschluss an Kap. 2 und 5–6).

  1. Plan: nur Anzeige + Mapping; kein Checkout, kein Payment, keine neuen Module.
  2. Contract: Order-Schema um status (enum) erweitern, falls noch nicht spezifiziert.
  3. Backend-Session (Tight-Loop): Controller/DTO + OrderControllerTest — Commands aus Package-AGENTS.md (Maven-Muster: ./mvnw -Dtest=OrderControllerTest test; Gradle: ./gradlew test --tests …OrderControllerTest); Security-Pattern beibehalten.
  4. Handoff: Contract-Pfad, Endpoint, was nicht gebaut wurde.
  5. Frontend-Session (Tight-Loop): List-Component + ggf. Typ aus Contract/Client; npm test -- --include=order-list + Lint.
  6. Slice-DoD: Diff matcht Auftrag; Tight grün + baubar (Maven package / Gradle build -x test nach Repo-Wahrheit); Contract konsistent; kein Drive-by.
  7. Heavy (optional): e2e oder manuelle Checkliste nur wenn Policy es verlangt.

Vertikaler Slice „Bestellstatus“: UI bis Persistenz mit DoD-Checkpoints und einer Wahrheit.{width=90%}

Dasselbe Muster mit Quarkus: Resource + @QuarkusTest statt Spring-Slice; Idiom aus Kap. 7, Schnitt aus diesem Kapitel.

8.6 Feature-Flags und Strangler (kurz)

Manchmal ist der Slice hinter einem Flag oder nur auf einer Legacy-Route live. Das ändert nicht den vertikalen Schnitt — es ändert nur Deploy- und Review-Ampel (oft gelb/rot, Kap. 12). Strangler-Migration mit engen Slices: Kap. 11. Hier zählt: auch Migrationsarbeit in nutzbare Scheiben schneiden, nicht „erst das neue Domänenmodell fertig“.

Key Takeaways

  • End-to-end dünn schneiden; DoD pro Slice — nicht pro Layer.
  • Contract im Repo hält Front- und Backend-Sessions zusammen.
  • Horizontale Monster-Tasks multiplizieren Agent-Fehler und Review-Kosten.
  • Multi-Repo: Session-Grenzen + Handoff sind Teil des Slices, nicht Overhead.
  • Task-Formel (Outcome, Nebenbedingungen, Ausschlüsse, DoD) ist der operative Kleber.

Praktische nächste Schritte

  1. Nächstes Feature als vertikalen Slice formulieren — Vorlage templates/task-prompt-fullstack-slice.md.
  2. Contract-Datei im Repo verlinken (beide Seiten: FE- und BE-AGENTS.md).
  3. Backend- und Frontend-Verify als Tight-Loop getrennt in die DoD; Integration/e2e als Heavy (Kap. 9).
  4. Einmal bewusst Handoff an der FE/BE-Grenze fahren (templates/handoff-stack.md).
  5. Danach Kap. 9 — Kanon Tight-Loop · Slice-DoD · Heavy so schärfen, dass der Slice prüfbar bleibt.

Ein guter Slice fühlt sich klein an und ist trotzdem fertig im Sinne des Nutzers. Das nächste Kapitel macht aus „fertig“ Exit-Codes — sonst bleibt der vertikale Schnitt eine schöne Zeichnung.