Live subscriptions and lifecycle – system description
The subscription table and its relations, saving, state changes, writing item limits onto users, credit and cancellation, and the overnight lifecycle run.
Overview
Management of live subscriptions belonging to users and clients. Table names carry the installation's own prefix in the database.
Data model
| Table | Role |
|---|---|
subscription | subscription: user, client, plan, state (trial, active, past_due, suspended, canceled, expired), cycle, seats, trial end, period end, cancel at period end |
subscription_item | individual items of the subscription with limits |
subscription_account | the user's credit account and home client |
subscription_event | state log |
payment_transaction | payment transactions |
subscription_credit | credit ledger |
Saving and state changes
- Form:
canAction(edit); save:canSave. Plan required; for a new subscription an existing user and an active plan; the client only within content permission; the billing company only fromgetBillableCompanies()(otherwise silently left out). - New subscription: ensure the user's account row (
ensureAccount), billing company, thenDlbtpayment::startTrial()(7 days). - Existing:
saveSubscription(), billing company, cache flush. - Items:
saveItems()by delete and rewrite, thenmaterialiseLimits()– writes the item limit onto the owner user's EXISTING assignment row. setstate:Dlbtpayment::setState()(+ state log +syncGrants()); fortrial,active,past_duesyncClientPlan()for every user of the client.
Item choice (item, SYSTEM): the function list offers only active functions classified SUBSCRIPTION; plantemplate returns a plan's legacy content items. The item and limit blocks appear with item or edit, and limit or edit; as these are SYSTEM keys, the real restriction is edit.
Credit, cancellation, deletion
credit:Dlbtcredit::grant(), returns the new balance;account_id > 0,amount > 0.cancel:Dlbtpayment::requestCancel(), at period end or immediately; errorsnot_found,already_ended.delete: blocked by a payment transaction (error_in_use); otherwise physical deletion with the state log.autocomplete:findUsers(), at most 8 hits, empty withoutedit.
Background job: subscription_lifecycle
Global seed job in the catalog-side cron queue processor. Steps: Dlbtpayment::runLifecycle() (expired trial with cancellation → expired; expired trial or period → charge, success active, failure past_due; lasting non-payment → suspended; cancelled with expired period → closed), then Dlbtbilling::applyPendingPlans() (due downgrades) and Dlbtbilling::invoiceMonthlyUsage() (monthly overage invoice). Log prefix: subscription_lifecycle.
Permissions and limitations
list:UNMAPPED;item,limit:SYSTEM;edit,add,credit,cancel,delete,debug: not classified.- The list shows every subscription without content scope.
creditdoes not check the account's content scope.