feat(subscription): plan, trial, subscribe, and on-demand billing#28
Open
abhisek wants to merge 4 commits into
Open
feat(subscription): plan, trial, subscribe, and on-demand billing#28abhisek wants to merge 4 commits into
abhisek wants to merge 4 commits into
Conversation
…mands Add the `safedep subscription` domain over the control-plane SubscriptionService and BillingService: subscription status subscription trial enable subscription create [--seats N] subscription ondemand enable --accept-terms | disable | status subscription customer create | show subscription portal open - Named for user intent (plan/access), not billing mechanism: low-level billing (invoices, payment methods) is delegated to the hosted portal. - create targets the Professional plan (only self-serve tier; Enterprise is custom), takes --seats (default 5, min 1), opens checkout in the browser, and polls status until active. Return URLs match the web app's billing flow. - trial and create share an ensureCustomer step: interactive billing-profile prompts for humans, flags for agents, keyed off GetBillingCustomer NOT_FOUND. - ondemand enable requires --accept-terms (records terms version 2026-07-23) and routes the typed ErrorReason to the next action: ENTITLEMENT_NOT_AVAILABLE -> subscribe, PAYMENT_METHOD_REQUIRED -> portal. - Bumps the safedep/api bindings to pick up on-demand billing. Adds the `open` verb to the allow-list for browser/portal session commands. Docs: one page per leaf under docs/cmd, linked from README. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SafeDep Report SummaryPackage Details
This report is generated by SafeDep Github App |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 264a55d4cd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The entitlements table added noise to the common `subscription status` view. Hide it by default and surface it only when --entitlements is passed, consistently across table, plain, and json output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Trial enable no longer claims activation before it completes: runTrialEnable reports whether a trial/active status was actually observed, and the command prints a "still syncing" warning otherwise (covers --wait=false and timeout). - openInBrowser surfaces a browser-launch failure via dry/log plus a manual-open hint instead of discarding the error. - Billing remediation and status hints now point to `subscription portal open` (the actionable leaf) instead of the `portal` parent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ctivity Address review on the wait/poll and interactivity behavior: - pollUntilStatus derives a timeout-bounded context so each status RPC is capped by --timeout (a stalled control-plane call can no longer outlast the flag), and a timeout now returns an error instead of (acct,false): waited trial-enable and create fail non-zero instead of exiting 0 on an unconfirmed wait, so automation does not treat it as success. - interactive() keys off real terminal state (stdin is a TTY), excluding agent mode, instead of the user-overridable --output/SAFEDEP_OUTPUT presentation mode. Prompts and browser launch no longer break under SAFEDEP_OUTPUT=plain in a terminal, nor block on stdin under forced rich in CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




What
Adds the
safedep subscriptiondomain — the tenant's plan and access lifecycle — over the control-planeSubscriptionServiceandBillingService.Design
subscription, notbilling.createtargets the Professional plan (the only self-serve tier; Enterprise is custom → contact sales), takes--seats(default 5, min 1), opens the provider checkout in the browser, and pollsGetSubscriptionAccountStatusuntil active (completion is webhook-gated). Checkout/portal return URLs match the web app's billing flow (app.safedep.io/settings/billing[...]).ensureCustomerruns before trial and subscribe: interactive billing-profile prompts for humans, flags for agents, keyed offGetBillingCustomerreturningNOT_FOUND.ondemand enablerequires--accept-terms(records terms version2026-07-23, printssafedep.io/terms/) and maps the typedErrorReasonto the next action:ENTITLEMENT_NOT_AVAILABLE→ subscribe,PAYMENT_METHOD_REQUIRED→ portal.statusis the hub — status, tier, trial days, on-demand summary, entitlements — and every dead-end ends with the exact next command.Renderablecontract (table/plain/json); browser is opened for humans, only printed for agents.Verbs
Adds
opento the allow-list (internal/cmd/verbs.go) for browser/portal session commands (subscription portal open). Justification: opening a provider-hosted browser session is a distinct action not covered by existing verbs. All other leaves use existing verbs.API bump
Bumps the
safedep/apigenerated bindings to...20260723065119to pick up the on-demand billing messages/RPCs (GetOnDemandBillingState,EnableOnDemandBilling,DisableOnDemandBilling,TenantOnDemandBillingState).Follow-ups (noted in the design spec)
terms_versionfor now).--tierselection when more self-serve tiers exist.Testing
make build,make test,golangci-lint run ./..., and the convention tests all pass locally. Table-driven unit tests cover enum mapping,ErrorReasonrouting,ensureCustomer(exists / missing-flags / creates-from-flags), trial enable, thecreatebranches (already-active / checkout-error / needs-checkout), seat min-1 validation, and the renderers.🤖 Generated with Claude Code