feat(admin): deployment-admin billing page with per-org task quota overrides - #5863
Open
viktormarinho wants to merge 1 commit into
Open
feat(admin): deployment-admin billing page with per-org task quota overrides#5863viktormarinho wants to merge 1 commit into
viktormarinho wants to merge 1 commit into
Conversation
…errides Adds a Billing tab to the deployment-admin dashboard, shown only when the deployment enforces the task quota (GET /api/_admin/me now exposes taskQuotaEnforced for the gate). - GET /api/_admin/billing/orgs: per-org quota consumption, ordered by all-time live claims; the current bucket and effective limit are computed with the same taskQuotaState + LIVE_CLAIM_FILTER the enforcement path uses, so the view cannot disagree with what a dispatch would allow. - PATCH /api/_admin/billing/orgs/:orgId: sets/clears the per-org override columns from migration 164 (previously writer-less), via a new OrganizationBillingStorage.setQuotaOverrides. Validates positive int4, audits with previous values like the other privileged admin actions. - Web: admin billing page mirroring the orgs tab (search, usage, edit-quota dialog with blank-means-default), i18n en + pt-BR. - E2E: override round-trip, insert-branch self-heal, omitted-field semantics, trial and sub:<periodEnd>/sub:pending buckets, released-claim refunds, validation 400s (incl. int4 overflow and JSON null body), and Billing-tab absence when the quota gate is off.
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.
Summary
Adds a Billing tab to the deployment-admin dashboard (
/_admin/billing), visible only when the deployment enforces the task quota (STUDIO_TASK_QUOTA_ENFORCED). Operators can see how much quota each org has consumed/claimed and set per-org free/monthly allowances — the operator action migration 164's override columns were designed for (they had no writer until now).API (
apps/api/src/api/routes/admin.ts)GET /api/_admin/menow returnstaskQuotaEnforced— the flag the UI tab gates on.GET /api/_admin/billing/orgs?search&limit— org listing ordered by all-time live claims (top consumers first), with subscription status, current bucket (trial /sub:<periodEnd>/sub:pending),used/limitfor that bucket, and the per-org overrides. The bucket and effective limit are computed with the sametaskQuotaStatethe enforcement path uses, and every count shares the newLIVE_CLAIM_FILTERfromOrganizationBillingStorage, so this view cannot disagree with what a dispatch would allow.PATCH /api/_admin/billing/orgs/:orgId— sets/clears overrides via a newOrganizationBillingStorage.setQuotaOverrides(keeps all writers oforganization_billingin the storage class).nullresets to the deployment default; omitted fields are untouched. Validates positive int4 (0/negatives/overflow → 400, never a constraint 500). Audited like/impersonate/member-add: durable stdout line + PostHog, real-actor attribution under impersonation, and previous values included so a lowered quota is reconstructable.Both endpoints sit behind the existing
requireDeploymentAdmin+ untrusted-Origin middlewares. No Stripe ids are exposed in the listing. The PATCH deliberately works while the gate is off (columns are dormant; overrides set ahead of enabling stick).Web (
apps/web)routes/admin/billing.tsxmirroring the orgs tab: search, usage per current period (with renewal date), all-time claims, quota columns showingdefault (N)when unset, and an edit dialog where blank = deployment default. Tab hidden unless/mereportstaskQuotaEnforced.Tests
New e2e coverage in
packages/e2e/tests/deployment-admin.spec.ts:sub:<ISO>key round-trip a timestamptz serialization drift would break, plussub:pending.used/totalClaims.nullbody) and unknown-org 404.Testing notes
bun run fmt,bun run check(all workspaces),bun run lint, andbun run knippass.bun test apps/api/src/billing apps/api/src/settings: pure unit tests pass (the 2 pre-existing integration tests in that dir require a local Postgres and are unrelated).packages/e2e); it follows the spec's serial-mode + fresh-org-per-test doctrine.Scale note: the listing's ordering subquery is an index probe per org pre-LIMIT (same ~10^5-org ceiling as
/orgs); the doc comment records why the/orgsLATERAL upgrade path does not apply here and what does.Summary by cubic
Adds a Billing tab to the deployment-admin dashboard to view per‑org task‑quota usage and set free/monthly quota overrides. The tab appears only when task quota is enforced, and usage/limits match the enforcement logic.
/_admin/billingwith search, current-period usage (with renew date), all‑time claims, and an edit dialog where blank = deployment default. Tab is gated bytaskQuotaEnforcedfrom/api/_admin/me. i18n added (en, pt‑BR).GET /api/_admin/menow returnstaskQuotaEnforced.GET /api/_admin/billing/orgs?search&limitlists orgs ordered by all‑time live claims, with status, bucket key (trial/sub:<periodEnd>/sub:pending),used/limit, and overrides; counts use the sametaskQuotaStateandLIVE_CLAIM_FILTERas enforcement.PATCH /api/_admin/billing/orgs/:orgIdsets per‑org overrides;nullresets to defaults, omitted fields are untouched. Validates positive int4, audits with previous values, and works even if the gate is off.OrganizationBillingStorage.setQuotaOverrides,liveClaimCountsByPeriod, and sharedLIVE_CLAIM_FILTERfor consistent counting.Written for commit 164c4b7. Summary will update on new commits.