Zum Inhalt

Architektur-Überblick

Explanation · Stand: 2026-09-22

Worum geht es?

Wenn ein Händler für einen Verschleiß-Servicefall einen Kostenvoranschlag (KVA) einreicht, muss das Benefit-Portal entscheiden: automatisch freigeben oder manuell prüfen? Diese Entscheidung soll nicht pauschal fallen, sondern anhand des bisherigen Verhaltens des Händlers (Händler-KPIs) und der Eigenschaften des konkreten Falls (Servicefall-KPIs).

Der Supplier-Cluster-Service (dieses Repository) ist ein eigenständiger Laravel-Service, der genau diese Bewertung übernimmt. Er kommuniziert mit dem Benefit-Portal (Monolith) ausschließlich über RabbitMQ-Messages und hat keine gemeinsame Datenbank mit dem Portal.

Warum ein eigener Service?

  • Datengetriebene Regeln: Grenzwerte und KPI-Zusammensetzung liegen als Zeilen in der Tabelle evaluation_rules, nicht im Code. Eine KPI aufnehmen oder einen Grenzwert ändern erfordert kein Portal-Deployment.
  • Entkoppelte Deploys: Das Portal kann eine neue KPI publizieren, bevor der Service eine Regel dafür hat (der Wert wird gespeichert und ignoriert) — und umgekehrt.
  • Klare Ownership: Die Bewertungslogik (Bänder, Cluster, Matrix) hat genau einen Ort. Das Portal kennt nur das Ergebnis.

Die drei Verantwortungen des Service

flowchart LR
    subgraph Portal [Benefit-Portal Monolith]
        P1[KPI-Berechnung je Händler]
        P2[Servicefall im Status KVA-Prüfung]
        P3[Auto-Freigabe oder manuelle Prüfung]
    end
    subgraph Cluster [Supplier-Cluster-Service]
        C1[Ingest: kpi_values versioniert speichern]
        C2[Evaluation: Bänder, Cluster, Matrix]
        C3[UI: Händler-Übersicht + manueller Override]
    end
    P1 -- "kpi-message" --> C1
    P2 -- "evaluation-request" --> C2
    C1 --> C2
    C2 -- "evaluation-result" --> P3
  1. Ingest — Das Portal publiziert periodisch je Händler die berechneten KPI-Werte (kpi-message). Der Service speichert sie versioniert in kpi_values: Werte einer neueren Messperiode lösen die alten ab (superseded_at), gleiche Perioden werden in place aktualisiert. Ein täglicher Job löscht abgelöste Werte nach 90 Tagen.
  2. Evaluation — Ein evaluation-request trägt die Servicefall-KPIs im Payload; die Händler-KPIs kommen aus dem gespeicherten Bestand. Beide Seiten werden zu je einem Ampel-Cluster verdichtet und über eine Matrix zur Prüfungsintensität (0–100 %) gekreuzt. Details: Ampel-Logik. Das Ergebnis geht als evaluation-result zurück.
  3. Übersicht & Override — Unter /suppliers (Basic-Auth) zeigt eine Livewire-Seite alle Händler mit ihren aktuellen KPI-Bändern. Dort kann der Status eines Händlers manuell festgepinnt werden (Override mit Begründung). Der Override soll dabei auch die automatische Bewertung übersteuern — aktuell wirkt er jedoch nur auf die Übersicht (bekannter Bug, CU-123wka4jt6a; Details: Händler-Status übersteuern).

Der Service entscheidet nicht selbst über „automatisch vs. manuell". Er liefert nur die Prüfungsintensität; die Konsequenz daraus zieht der Konsument (das Portal, siehe unten).

Die Portal-Seite der Integration

Die Integration ist auf beiden Seiten produktiv. Im Monolith (Modul TechnicalServices/Cluster) sieht sie so aus:

  • Händler-KPIs monatlich: Der Command technical-services:publish-cluster-kpis läuft am 1. jedes Monats (03:00) und publiziert pro aktivem Händler eine kpi-message (Kostenquote, beide Einreichungsquoten, Korrektur-Quote; 12-Monats-Betrachtungsfenster).
  • Score-Anfrage je Servicefall: SupplierScoreService berechnet die Servicefall-KPIs aus echten Vertragsdaten (UVP = productListPrice des Vertrags, Verschleißkosten = Brutto-Summe des Falls, gewöhnlicher Verschleiß aus den max_contract_exchanges-Limits der Verschleißteile), setzt den Fall auf den Status ScoreRequested und publiziert den evaluation-request — transaktional, damit keine Antwort vor dem Statuswechsel eintreffen kann.
  • Entscheidung per Stichprobe: Der Handler für evaluation-result speichert das Ergebnis als ClusterEvaluation am Servicefall (Audit-Trail inkl. Cluster und KPI-Bändern) und nutzt die Prüfungsintensität als Stichproben-Wahrscheinlichkeit (Lottery): Bei X % Prüfungsintensität geht der Fall mit X % Wahrscheinlichkeit in die manuelle Prüfung, sonst in die Auto-Freigabe. Ein incomplete-Ergebnis geht immer in die manuelle Prüfung.

Details zu Queues und Payloads: Messages und Queues.