Vai al contenuto
DedicatedPHP Contatto

Capacità e limiti in un SaaS PHP senza condizionali per piano

Progetta capacità, limiti ed eccezioni verificabili in un SaaS PHP, evitando che i piani commerciali si disperdano in condizionali.

Diagramma editoriale di capacità, limiti, permessi e regole centralizzate per una piattaforma SaaS PHP multi-tenant

Quando la logica di un SaaS inizia con condizioni come if ($tenant->plan === 'pro'), sembra una soluzione diretta. Il problema emerge alla seconda modifica del catalogo: un piano viene rinominato, una capacità viene venduta separatamente, un cliente mantiene condizioni precedenti oppure il supporto deve abilitare temporaneamente qualcosa. A quel punto il nome commerciale smette di descrivere una regola stabile e finisce distribuito tra controller, attività pianificate, query, API e interfaccia.

La gestione delle capacità in SaaS PHP deve tradurre l'offerta commerciale in decisioni di dominio verificabili. Il codice non dovrebbe chiedersi se un'azienda è “Pro”, ma se può eseguire un'azione concreta, con quale limite, a quali condizioni e fino a quando. Questa separazione consente di modificare prezzi o pacchetti senza riscrivere le regole operative.

Separare piano, capacità, limite, permesso e configurazione

Separare piano, capacità, limite, permesso e configurazione — guía visual de DedicatedPHP

Questi concetti sono correlati, ma non intercambiabili. Un piano è un pacchetto commerciale. Una capacità abilita una possibilità del prodotto, come esportare dati, creare automazioni o usare un'integrazione. Un limite definisce una quantità o una frequenza consentita, per esempio progetti attivi, utenti fatturabili o richieste API per periodo.

Un permesso risponde a un'altra domanda: quale identità può compiere un'azione all'interno di un'azienda. Il fatto che un'organizzazione disponga della capacità di esportare dati non significa che qualsiasi utente possa esportarli. Infine, la configurazione del cliente comprende opzioni valide per una specifica azienda, come il provider di identità scelto, una policy di conservazione o un modello di notifiche. Non è opportuno usare una configurazione libera per nascondere decisioni commerciali o di autorizzazione.

  • Piano: composizione commerciale di diritti e limiti.
  • Capacità: regola funzionale espressa in termini di prodotto.
  • Limite: soglia quantificabile associata a una capacità o risorsa.
  • Permesso: autorizzazione di un attore a eseguire un'azione.
  • Configurazione: parametro di comportamento disponibile entro le regole già concesse.

Una decisione può richiedere tutti i livelli. Per creare un'automazione, l'azienda necessita della capacità corrispondente, deve essere al di sotto del limite di automazioni attive e l'utente deve avere il permesso di amministrazione. Successivamente, il flusso può validare la configurazione di destinazione.

Modellare regole di dominio, non nomi di piani

Mantenga un catalogo stabile di capacità con identificatori tecnici indipendenti dal marketing: automation.create, data.export o api.webhooks. Il catalogo può includere il tipo di valore atteso: booleano, intero, insieme di opzioni o policy strutturata. L'identificatore esprime un'esigenza di prodotto; non deve incorporare il nome di un piano né una campagna.

L'assegnazione commerciale può essere risolta in un livello separato. Un piano attivo fornisce un insieme di concessioni, ma possono esistere anche componenti aggiuntivi, migrazioni legacy ed eccezioni esplicite. Il risultato per ogni azienda è una risoluzione dei diritti effettivi con provenienza.

capacità: automation.create
valore effettivo: true
provenienza: componente aggiuntivo per automazioni
validità: fino alla cancellazione

Questa provenienza è essenziale. Se una capacità è attiva, prodotto, supporto e fatturazione devono sapere se deriva dal piano attuale, da una clausola legacy o da un'eccezione con data di scadenza. Eviti di memorizzare soltanto un campo plan nell'azienda e di dedurre tutto il resto in ogni punto di utilizzo.

Un unico servizio decisionale

In PHP, esponga un servizio di dominio, per esempio EntitlementResolver o CapabilityGate, che riceva l'azienda, la capacità e il contesto necessario. Deve restituire una decisione spiegabile, non soltanto un booleano: consentito o rifiutato, valore risolto, motivo, regola sorgente e data di valutazione. Questa data rappresenta l'istante in cui il resolver ha determinato la decisione e consente di interpretare correttamente validità, scadenze e successive modifiche del piano. Controller, comandi, listener e worker asincroni consultano questo servizio; non ricostruiscono le proprie query di sottoscrizione.

Definire limiti misurabili prima di programmarli

Un limite ambiguo genera conflitti ed errori di implementazione. “Fino a 100 utenti” richiede di rispondere a cosa conta come utente: invito in sospeso, utente sospeso, membro eliminato durante il ciclo, account di servizio? “Mille esportazioni” richiede di definire periodo, fuso orario, tentativi e se un'esportazione non riuscita consuma quota.

Per ogni limite, documenti almeno:

  • La risorsa, l'evento o il consumo conteggiato.
  • L'ambito: azienda, progetto, utente o integrazione.
  • La finestra: totale attivo, giorno solare, mese di fatturazione o finestra mobile.
  • Il momento del controllo: prima della creazione, all'attivazione, all'invio o dopo il consolidamento.
  • La reazione: bloccare, consentire con avviso, mettere in coda, degradare o richiedere approvazione.
  • La gestione di concorrenza, tentativi, annullamenti e rollback.

I limiti di oggetti attivi vengono solitamente validati con un'operazione transazionale o una riserva che eviti di superare la soglia in condizioni di concorrenza. I limiti di consumo necessitano di un contatore con semantica chiara e idempotenza tramite una chiave di evento. Non si affidi soltanto a un contatore mostrato nell'interfaccia: due richieste simultanee possono superare un controllo preventivo e oltrepassare il massimo.

Distingua inoltre tra avviso e blocco. Un avviso all'80% migliora la prevedibilità, ma non sostituisce una protezione effettiva nel punto in cui la risorsa viene creata o eseguita.

Applicare le regole in tutti i percorsi di esecuzione

Nascondere un pulsante migliora l'esperienza, ma non è un controllo di accesso. La validazione deve esistere nel caso d'uso del server che esegue l'azione. In questo modo copre l'interfaccia web, l'API pubblica, le integrazioni e le chiamate interne.

I processi asincroni richiedono una decisione aggiuntiva: verificare al momento dell'accodamento e verificare nuovamente all'esecuzione quando il job può subire ritardi. Se un'azienda perde una capacità tra questi due momenti, la policy deve definire se il job viene annullato, completato perché accettato in precedenza oppure richiede una revisione. La scelta dipende dal tipo di operazione, ma deve essere coerente e registrata.

Gli strumenti di supporto e amministrazione non dovrebbero aggirare silenziosamente le regole. Possono operare con una diversa autorizzazione amministrativa, ma devono lasciare tracciabilità e indicare se generano una concessione formale, una correzione dei dati o un'azione eccezionale.

Gestire cambiamenti, diritti legacy ed eccezioni senza biforcare il prodotto

Un cambio di piano non consiste soltanto nell'aggiornare un'etichetta. Può ridurre un limite al di sotto dell'utilizzo attuale o rimuovere una capacità che sostiene processi attivi. Definisca policy per tipo di risorsa: impedire nuove creazioni e conservare l'esistente, disattivare esplicitamente gli elementi eccedenti, concedere un periodo di transizione o richiedere una scelta all'amministratore dell'azienda.

Le eccezioni temporanee devono essere concessioni di prima classe con ambito, valore, motivo, emittente e scadenza. Un campo manuale come is_vip è difficile da interpretare e tende a sopravvivere alla causa originaria. Per i clienti legacy, modelli un'assegnazione di migrazione con regole precise e data di revisione, invece di creare rami di codice permanenti.

Un'eccezione sostenibile è un dato verificabile che lo stesso resolver interpreta; un'eccezione pericolosa è un condizionale speciale aggiunto a un flusso specifico.

Combinare capacità, ruoli e isolamento multi-tenant

In una piattaforma multi-tenant, ogni query relativa a diritti, consumo e configurazione deve essere delimitata dall'azienda corretta. Non derivi il contesto soltanto da valori inviati dal client. Lo risolva dall'autenticazione, dal dominio richiesto o dal contesto interno validato, e lo propaghi ai job in coda e agli eventi.

La decisione finale è solitamente un'intersezione: l'azienda dispone della capacità, il limite non è stato esaurito e l'attore possiede il permesso richiesto. Centralizzare le capacità non sostituisce un modello di ruoli; evita che ruoli e piani si mescolino. Un ruolo può concedere chi amministra le automazioni, mentre la capacità determina se l'azienda può usare le automazioni.

Dati, audit e test che consentono di spiegare le decisioni

Conservi assegnazioni di diritti con validità e precedenza, insieme agli eventi di consumo quando un aggregato non è sufficiente. Registri le decisioni rilevanti: azienda, attore o processo, capacità, valore valutato, risultato, fonte e correlazione della richiesta. Non memorizzi dati personali non necessari in questi registri e stabilisca la conservazione in conformità ai propri obblighi.

L'audit deve rispondere al motivo per cui un'azione è stata rifiutata senza obbligare a leggere codice storico. È particolarmente utile in caso di modifiche commerciali, incidenti di fatturazione e operazioni di supporto.

I test devono includere una matrice di capacità e valori, limiti sulla soglia esatta, concorrenza, cambi di piano, scadenza delle eccezioni e tentativi degli eventi. Esegua gli stessi casi tramite HTTP, API e worker in coda quando condividono il caso d'uso. Aggiunga test di isolamento per confermare che un'azienda non possa consultare né consumare diritti di un'altra.

Piano graduale per centralizzare una piattaforma PHP esistente

  1. Inventari nomi dei piani, condizioni, contatori ed eccezioni manuali nel codice e nelle operazioni.
  2. Scelga una capacità o un limite ad alto impatto e ne definisca la semantica completa prima di migrarlo.
  3. Introduca il resolver come facciata, inizialmente compatibile con le fonti attuali.
  4. Sposti i punti di applicazione nel caso d'uso centrale, non soltanto nell'interfaccia.
  5. Registri le decisioni e confronti il nuovo comportamento con quello precedente prima di rimuovere i rami legacy.
  6. Migri piano per piano verso assegnazioni esplicite ed elimini i riferimenti commerciali dal dominio.

Checklist prima di pubblicare una modifica

Checklist prima di pubblicare una modifica — guía visual de DedicatedPHP
  • La capacità ha un identificatore stabile e una definizione di business inequivocabile?
  • Il limite specifica unità, ambito, periodo, concorrenza e reazione al superamento?
  • La regola viene applicata su server, API e processi asincroni?
  • Ruoli, capacità e contesto aziendale vengono validati separatamente?
  • I cambi di piano e le eccezioni hanno validità, provenienza e audit?
  • Esistono test per la soglia del limite, la revoca e l'isolamento multi-tenant?

Con questo modello, il catalogo commerciale può evolvere senza trasformare ogni modifica in una ricerca di condizionali. La piattaforma conserva regole comprensibili, misurabili e difendibili sia per il prodotto sia per l'ingegneria.

Vuoi applicare queste idee al tuo progetto?Parliamo della tua piattaforma PHP.
Visualizza il servizio correlato