Wenn die Logik eines SaaS mit Bedingungen wie if ($tenant->plan === 'pro') beginnt, wirkt das wie eine direkte Lösung. Das Problem tritt bei der zweiten Änderung des Tarifkatalogs auf: Ein Tarif wird umbenannt, eine Fähigkeit wird separat verkauft, ein Kunde behält alte Konditionen bei oder der Support muss etwas vorübergehend aktivieren. Dann beschreibt der kommerzielle Name keine stabile Regel mehr und verteilt sich stattdessen auf Controller, geplante Tasks, Abfragen, API und Benutzeroberfläche.
Die Verwaltung von Fähigkeiten in PHP-SaaS muss das kommerzielle Angebot in überprüfbare Domain-Entscheidungen übersetzen. Der Code sollte nicht fragen, ob ein Unternehmen „Pro“ ist, sondern ob es eine konkrete Aktion ausführen darf, mit welchem Limit, unter welchen Bedingungen und bis wann. Diese Trennung ermöglicht es, Preise oder Paketierungen zu ändern, ohne operative Regeln neu zu schreiben.
Tarif, Fähigkeit, Limit, Berechtigung und Konfiguration trennen

Diese Konzepte stehen in Beziehung, sind aber nicht austauschbar. Ein Tarif ist eine kommerzielle Paketierung. Eine Fähigkeit ermöglicht eine Produktmöglichkeit, etwa Daten zu exportieren, Automatisierungen zu erstellen oder eine Integration zu verwenden. Ein Limit definiert eine erlaubte Menge oder Rate, zum Beispiel aktive Projekte, abrechenbare Benutzer oder API-Anfragen pro Zeitraum.
Eine Berechtigung beantwortet eine andere Frage: Welche Identität darf innerhalb eines Unternehmens eine Aktion ausführen? Dass eine Organisation die Fähigkeit zum Datenexport besitzt, bedeutet nicht, dass jeder Benutzer Daten exportieren darf. Schließlich sind die Kundenkonfigurationen Optionen, die für ein konkretes Unternehmen gültig sind, etwa der ausgewählte Identitätsanbieter, eine Aufbewahrungsrichtlinie oder eine Benachrichtigungsvorlage. Es ist nicht ratsam, freie Konfiguration zu verwenden, um kommerzielle Entscheidungen oder Autorisierungsentscheidungen zu verbergen.
- Tarif: kommerzielle Zusammenstellung von Rechten und Limits.
- Fähigkeit: funktionale Regel, ausgedrückt in Begriffen des Produkts.
- Limit: quantifizierbarer Schwellenwert, der einer Fähigkeit oder Ressource zugeordnet ist.
- Berechtigung: Autorisierung eines Akteurs zur Ausführung einer Aktion.
- Konfiguration: Verhaltensparameter, der innerhalb der bereits gewährten Regeln verfügbar ist.
Eine Entscheidung kann alle Ebenen erfordern. Um eine Automatisierung zu erstellen, benötigt das Unternehmen die entsprechende Fähigkeit, muss unter dem Limit aktiver Automatisierungen liegen, und der Benutzer muss über eine Verwaltungsberechtigung verfügen. Anschließend kann der Ablauf die Zielkonfiguration validieren.
Domain-Regeln modellieren, nicht Tarifnamen
Pflegen Sie einen stabilen Katalog von Fähigkeiten mit technischen Kennungen, die vom Marketing unabhängig sind: automation.create, data.export oder api.webhooks. Der Katalog kann den erwarteten Werttyp enthalten: boolesch, Ganzzahl, Optionsmenge oder strukturierte Richtlinie. Die Kennung drückt einen Produktbedarf aus; sie darf weder den Namen eines Tarifs noch einer Kampagne enthalten.
Die kommerzielle Zuweisung kann in einer getrennten Schicht aufgelöst werden. Ein aktueller Tarif bringt eine Reihe von Rechtegewährungen mit, aber es kann auch Add-ons, Legacy-Migrationen und explizite Ausnahmen geben. Das Ergebnis für jedes Unternehmen ist eine effektive Ermittlung der Rechte mit nachvollziehbarer Quelle.
Fähigkeit: automation.create
effektiver Wert: true
Quelle: Automatisierungs-Add-on
Gültigkeit: bis zur Kündigung
Diese Quelle ist entscheidend. Wenn eine Fähigkeit aktiv ist, müssen Produkt, Support und Abrechnung wissen, ob sie aus dem aktuellen Tarif, aus einer Legacy-Klausel oder aus einer Ausnahme mit Ablaufdatum stammt. Vermeiden Sie es, nur ein Feld plan im Unternehmen zu speichern und alles Übrige an jedem Nutzungspunkt abzuleiten.
Ein zentraler Entscheidungsservice
Stellen Sie in PHP einen Domain-Service bereit, zum Beispiel EntitlementResolver oder CapabilityGate, der das Unternehmen, die Fähigkeit und den erforderlichen Kontext erhält. Er muss eine erklärbare Entscheidung zurückgeben, nicht nur einen Boolean: erlaubt oder abgelehnt, aufgelöster Wert, Grund, Quellregel und Bewertungszeitpunkt. Dieser Zeitpunkt steht für den Moment, zu dem der Resolver die Entscheidung ermittelt hat, und ermöglicht es, Gültigkeiten, Abläufe und spätere Tarifänderungen korrekt zu interpretieren. Controller, Commands, Listener und asynchrone Worker fragen diesen Service ab; sie rekonstruieren nicht ihre eigenen Abonnementabfragen.
Messbare Limits definieren, bevor sie programmiert werden
Ein mehrdeutiges Limit erzeugt Konflikte und Implementierungsfehler. „Bis zu 100 Benutzer“ erfordert eine Antwort darauf, was als Benutzer zählt: ausstehende Einladung, gesperrter Benutzer, während des Zyklus gelöschtes Mitglied, Servicekonto? „Tausend Exporte“ erfordert die Definition von Zeitraum, Zeitzone, Wiederholungsversuchen und der Frage, ob ein fehlgeschlagener Export Kontingent verbraucht.
Dokumentieren Sie für jedes Limit mindestens:
- Die Ressource, das Ereignis oder den Verbrauch, die beziehungsweise der gezählt wird.
- Den Geltungsbereich: Unternehmen, Projekt, Benutzer oder Integration.
- Das Fenster: gesamte Gültigkeit, Kalendertag, Abrechnungsmonat oder gleitendes Fenster.
- Den Kontrollzeitpunkt: vor dem Erstellen, bei der Aktivierung, beim Senden oder nach der Konsolidierung.
- Die Reaktion: blockieren, mit Warnung zulassen, in die Warteschlange stellen, degradieren oder Genehmigung verlangen.
- Die Behandlung von Parallelität, Wiederholungsversuchen, Stornierungen und Rückabwicklung.
Limits für aktive Objekte werden üblicherweise mit einer transaktionalen Operation oder einer Reservierung validiert, die verhindert, dass bei parallelen Anfragen der Schwellenwert überschritten wird. Verbrauchslimits benötigen einen Zähler mit klarer Semantik und Idempotenz durch einen Ereignisschlüssel. Verlassen Sie sich nicht nur auf einen in der Benutzeroberfläche angezeigten Zähler: Zwei gleichzeitige Anfragen können eine Vorabprüfung bestehen und das Maximum überschreiten.
Unterscheiden Sie außerdem zwischen Warnung und Blockierung. Eine Warnung bei 80 % verbessert die Vorhersehbarkeit, ersetzt aber keinen echten Schutz an der Stelle, an der die Ressource erstellt oder ausgeführt wird.
Die Regeln auf allen Ausführungspfaden anwenden
Eine Schaltfläche auszublenden, verbessert die Nutzererfahrung, ist aber keine Zugriffskontrolle. Die Validierung muss im serverseitigen Use Case vorhanden sein, der die Aktion ausführt. Damit decken Sie die Weboberfläche, die öffentliche API, Integrationen und interne Aufrufe ab.
Asynchrone Prozesse erfordern eine zusätzliche Entscheidung: beim Einreihen prüfen und bei der Ausführung erneut prüfen, wenn sich die Ausführung verzögern kann. Wenn ein Unternehmen zwischen diesen beiden Zeitpunkten eine Fähigkeit verliert, muss die Richtlinie definieren, ob die Aufgabe abgebrochen wird, abgeschlossen wird, weil sie zuvor angenommen wurde, oder überprüft werden muss. Die Wahl hängt von der Art der Operation ab, muss jedoch konsistent sein und protokolliert werden.
Support- und Verwaltungswerkzeuge sollten die Regeln nicht stillschweigend umgehen. Sie können mit einer anderen administrativen Autorisierung arbeiten, müssen jedoch Nachvollziehbarkeit hinterlassen und angeben, ob sie eine formale Rechtegewährung, eine Datenkorrektur oder eine außergewöhnliche Aktion erzeugen.
Änderungen, Legacy-Regeln und Ausnahmen verwalten, ohne das Produkt zu verzweigen
Ein Tarifwechsel bedeutet nicht nur, ein Label zu aktualisieren. Er kann ein Limit unter die aktuelle Nutzung senken oder eine Fähigkeit entziehen, die aktive Prozesse trägt. Definieren Sie Richtlinien nach Ressourcentyp: neue Erstellungen verhindern und Bestehendes erhalten, Überschreitungen explizit deaktivieren, einen Übergangszeitraum gewähren oder eine Entscheidung durch den Unternehmensadministrator verlangen.
Temporäre Ausnahmen müssen erstklassige Rechtegewährungen mit Geltungsbereich, Wert, Grund, Aussteller und Ablauf sein. Ein manuelles Feld wie is_vip ist schwer zu interpretieren und überlebt häufig seinen ursprünglichen Anlass. Modellieren Sie für Legacy-Kunden eine Migrationszuweisung mit präzisen Regeln und einem Überprüfungsdatum, statt dauerhafte Code-Verzweigungen zu erstellen.
Eine nachhaltige Ausnahme ist eine auditierbare Datenangabe, die derselbe Resolver interpretiert; eine gefährliche Ausnahme ist eine spezielle Bedingung, die einem konkreten Ablauf hinzugefügt wurde.
Fähigkeiten, Rollen und Mandantenisolierung kombinieren
In einer mandantenfähigen Plattform muss jede Abfrage von Rechten, Verbrauch und Konfiguration auf das richtige Unternehmen begrenzt sein. Leiten Sie den Kontext nicht allein aus Werten ab, die vom Client gesendet werden. Lösen Sie ihn aus der Authentifizierung, der angeforderten Domain oder dem validierten internen Kontext auf und propagieren Sie ihn an Queue-Jobs und Ereignisse.
Die endgültige Entscheidung ist üblicherweise eine Schnittmenge: Das Unternehmen verfügt über die Fähigkeit, das Limit ist nicht ausgeschöpft, und der Akteur hat die erforderliche Berechtigung. Die Zentralisierung von Fähigkeiten ersetzt kein Rollenmodell; sie verhindert, dass Rollen und Tarife vermischt werden. Eine Rolle kann gewähren, wer Automatisierungen verwaltet, während die Fähigkeit bestimmt, ob das Unternehmen Automatisierungen verwenden kann.
Daten, Auditierung und Tests, die Entscheidungen erklärbar machen
Bewahren Sie Rechtezuweisungen mit Gültigkeit und Vorrang auf, zusammen mit Verbrauchsereignissen, wenn ein Aggregat nicht ausreicht. Protokollieren Sie relevante Entscheidungen: Unternehmen, Akteur oder Prozess, Fähigkeit, ausgewerteter Wert, Ergebnis, Quelle und Anfragekorrelation. Speichern Sie in diesen Protokollen keine unnötigen personenbezogenen Daten und legen Sie eine Aufbewahrung gemäß Ihren Verpflichtungen fest.
Die Auditierung muss beantworten, warum eine Aktion abgelehnt wurde, ohne dass historischer Code gelesen werden muss. Das ist besonders nützlich bei kommerziellen Änderungen, Abrechnungsvorfällen und Supportvorgängen.
Die Tests müssen eine Matrix von Fähigkeiten und Werten, Limits an der exakten Grenze, Parallelität, Tarifwechsel, Ablauf von Ausnahmen und Wiederholungsversuche von Ereignissen umfassen. Führen Sie dieselben Fälle über HTTP, API und Queue-Worker aus, wenn sie denselben Use Case teilen. Fügen Sie Isolationstests hinzu, um zu bestätigen, dass ein Unternehmen weder die Rechte eines anderen Unternehmens abfragen noch dessen Rechte nutzen kann.
Schrittweiser Plan zur Zentralisierung einer bestehenden PHP-Plattform
- Inventarisieren Sie Tarifnamen, Bedingungen, Zähler und manuelle Ausnahmen im Code und im Betrieb.
- Wählen Sie eine Fähigkeit oder ein Limit mit hoher Auswirkung aus und definieren Sie vor der Migration deren vollständige Semantik.
- Führen Sie den Resolver als Fassade ein, die zunächst mit den aktuellen Quellen kompatibel ist.
- Verschieben Sie die Anwendungspunkte in den zentralen Use Case, nicht nur in die Benutzeroberfläche.
- Protokollieren Sie Entscheidungen und vergleichen Sie das neue mit dem bisherigen Verhalten, bevor Sie alte Verzweigungen entfernen.
- Migrieren Sie Tarif für Tarif zu expliziten Zuweisungen und entfernen Sie kommerzielle Referenzen aus der Domain.
Checkliste vor der Veröffentlichung einer Änderung

- Hat die Fähigkeit eine stabile Kennung und eine eindeutige fachliche Definition?
- Spezifiziert das Limit Einheit, Geltungsbereich, Zeitraum, Parallelität und Reaktion auf Überschreitungen?
- Wird die Regel auf dem Server, in der API und in asynchronen Prozessen angewendet?
- Werden Rollen, Fähigkeiten und Unternehmenskontext getrennt validiert?
- Haben Tarifwechsel und Ausnahmen Gültigkeit, Quelle und Auditierung?
- Gibt es Tests für die Limitgrenze, den Entzug und die Mandantenisolierung?
Mit diesem Modell kann sich der kommerzielle Katalog weiterentwickeln, ohne dass jede Änderung zu einer Suche nach tarifabhängigen Bedingungen wird. Die Plattform behält verständliche, messbare und sowohl für Produkt als auch Engineering vertretbare Regeln bei.



