feat(plan): per-account limit overrides#33
Open
t03i wants to merge 1 commit into
Open
Conversation
Split the `plan` enum into a scheduling class (priority + SLO bucket)
and per-account numeric quota. `PlanResolver.resolve` now returns
`ResolvedAccount { plan, limits }`, merging a sparse `user.limits jsonb`
override over plan-class defaults composed from existing config sources.
- shared: `EffectiveLimits`/`ResolvedAccount`, `OverrideLimitsSchema`
(strict, capped positive ints), `mergeLimits`, `MAX_SEQUENCE_LENGTH_CAP`
- gateway: `DbPlanResolver` reads `plan, limits` and parses defensively
(parse failure → class defaults); `AuthContext` carries `limits`
- consumers read `auth.limits.*`: submissions/min, concurrency,
per-request maxSequenceLength, and shedding's per-account sloSeconds
- additive nullable `user.limits` migration + dev seed example
- admin-only `PUT/DELETE /admin/accounts/{userId}/limits` (full-replace /
clear), audit-logged, behind the existing admin gate
- backend E2E proving an override enforces limits differing from the plan
Archive the completed change; create the canonical `plan-limits` spec.
Fold the prod shedding-validation details (enforce toggle, configurability
round-trip, per-account sloSeconds knob) into `simplify-load-testing`.
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.
Summary
Splits the
planenum into a scheduling class (queue priority + SLO bucket) and per-account numeric quota, so two accounts on the same class can enforce different limits — the original intent behind "enterprise".PlanResolver.resolvenow returnsResolvedAccount { plan, limits }, merging a sparseuser.limits jsonboverride over plan-class defaults composed from the existing config sources (PLAN_LIMITS,RATE_LIMIT_SUBMISSIONS_*, sheddingsloSeconds). Consumers readauth.limits.*off the auth context instead of indexingPLAN_LIMITS[plan]at the call site.Changes
EffectiveLimits/ResolvedAccount,OverrideLimitsSchema(.strict(), capped positive ints),mergeLimits,MAX_SEQUENCE_LENGTH_CAP.DbPlanResolverreadsplan, limitsand parses the override defensively (parse failure → logs + class defaults);AuthContextcarrieslimits.submissionsPerMinute),withinConcurrentJobLimit(maxConcurrentJobs), per-requestmaxSequenceLengthcheck in both submit routes, and shedding'sdecideAdmission(per-accountsloSeconds, falling back to config).user.limitsmigration (no backfill) + dev seed example.PUT/DELETE /admin/accounts/{userId}/limits(full-replace / clear-to-NULL), audit-logged, behind the existing admin gate.per-account-limit-overrideschange → canonicalplan-limitsspec; folded prod shedding-validation details (enforce toggle, configurability round-trip, per-accountsloSecondsknob) intosimplify-load-testing.Behaviour
Defaults equal current behaviour — deploying with zero overrides is a no-op. The static submit schema
.maxwas raised toMAX_SEQUENCE_LENGTH_CAPso an override can actually raise the length ceiling; the resolved per-account limit is enforced in the handler.openapi.v1.jsonreflects the newmaxLength.Testing
bun run typecheck/lint/test(598 unit + component) /build— all green.limits-override.test.tsproving an override enforces a limit differing from the plan default; migration applied the column live.🤖 Generated with Claude Code