Seed, inspect, observe, and roll back the provider-neutral workspace billing status page.
Workspace billing status runbook
Section titled “Workspace billing status runbook”This runbook covers the dashboard Billing page (/{-$locale}/billing) and its
provider-neutral status read model. It is status metadata only: it does not collect payment
details, run checkout, enforce seats, or replace a future provider integration.
Data model and access semantics
Section titled “Data model and access semantics”workspace_billing_statusis a dedicated globalDB_0table. Commercial metadata is kept separate from workspace identity inentities;entities.statusandentities.termination_atremain the operational lifecycle source of truth.- Statuses are
unconfigured,trialing,active,grace_period,past_due,scheduled_cancel, andcanceled. - The page derives an effective state of
active,trial,ending,ended, orattention_required. An unconfigured record is shown as Misconfigured; a read failure is shown as Unknown with retry. - Archived workspaces or workspaces whose termination date has passed are ended, regardless of billing status. A future termination date makes access ending and is called out beside the billing state. Billing data is retained for reference.
- Workspace members may read the current workspace status. Workspace admins/owners may use the controlled bootstrap form on the current workspace. Superadmins may inspect and update a selected workspace from Dashboard → Admin → Workspace Settings → Billing status.
- The server functions authorize against the authenticated workspace context. Clients cannot select another workspace through the current-workspace read function.
Seed or update a status
Section titled “Seed or update a status”- Apply migration
0047_workspace_billing_statustoDB_0using the managed migration runner. - Open the admin workspace management page, select Billing status, and load the selected workspace.
- Enter the provider/source label (
manualis the default), plan key and name, subscription status, interval, relevant dates, cancellation intent, and optional seat counts. - Save, then open the workspace Billing page and confirm the displayed derived state. Use
unconfiguredwith blank plan fields for an intentionally unconfigured workspace. - Do not put card numbers, provider secrets, or the raw provider snapshot into this form. A future provider-sync path must write the same read model through a separately reviewed server path.
Configured statuses require a plan key and plan name. Period dates are optional, but an end date before a start date is rejected. The initial feature does not change entitlements or block product operations based on seats.
Observability and troubleshooting
Section titled “Observability and troubleshooting”Billing reads and updates use the dashboard server-function telemetry seam. Structured route
metrics include the workspace ID, subscription status, effective access state, provider/source,
configuration flag, and duration. Update activity is emitted as
workspace.billing.status.updated with workspace_id, old_status, new_status, plan_key,
effective_at, and source: "manual_admin".
- Unknown / unavailable: check the dashboard Worker logs for
source=workspace-billingand operationreadorupdate. Confirm migration0047exists onpublications-db-0(DB_0). GlitchTip captures the underlying exception; retry after the binding or database issue is fixed. - Misconfigured: this is a valid empty state, not a database failure. Seed the status through the admin path after confirming the workspace and plan identity with the owner.
- Past due, grace period, canceled, or ending: compare the recorded status and dates with the authoritative commercial record. The page intentionally reports the stored status and workspace lifecycle; it does not reconcile or change access policy.
- Missing activity event: the status write remains successful, but the event failure is captured in GlitchTip and the warning is visible in Worker logs. Re-run the save after fixing the activity/AOA dependency and verify the activity trail.
Rollout and rollback
Section titled “Rollout and rollback”Roll out additively: apply the DB_0 migration, deploy the dashboard, seed one configured and one intentionally unconfigured workspace, and verify both page states plus the route/activity logs. Keep the billing navigation entry enabled only after the migration and the read path are healthy.
To roll back the application without deleting data, deploy the previous dashboard or hide the
Billing route/nav entry and disable bootstrap writes. Keep workspace_billing_status in place so
stored status is available when the corrected route returns.
Only remove the table after the dashboard read/write path is disabled and any required status
snapshot has been exported. Execute migrations/rollback/0047_workspace_billing_status.sql on
DB_0; it drops the billing indexes/table and does not alter entities or workspace lifecycle
records. Re-apply the additive migration before re-enabling the feature.
Provider webhooks, reconciliation jobs, checkout, invoices, and a dedicated billing Worker are future work. If signed callbacks or reconciliation are introduced, add a billing-ingress Worker that writes this same read model and preserves the event contract before changing the dashboard DTO.