Skip to content

fix(platform): show NO_TIER in admin rate-limit display + aggregate reconciliation alerting into one Discord alert - #13291

Merged
majdyz merged 6 commits into
devfrom
fix/admin-rate-limit-no-tier-display
Jun 4, 2026
Merged

fix(platform): show NO_TIER in admin rate-limit display + aggregate reconciliation alerting into one Discord alert#13291
majdyz merged 6 commits into
devfrom
fix/admin-rate-limit-no-tier-display

Conversation

@majdyz

@majdyz majdyz commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Why / What / How

Why: The admin "User Rate Limits" page rendered NO_TIER users as BASIC. NO_TIER was not part of the component's known tier list, so the unknown-tier fallback masked it as BASIC. During the payments launch this is actively misleading — a paywalled / no-access user appears to have BASIC access. Concretely, a NO_TIER tester showed up in the admin UI as BASIC, hiding the fact that they had no access.

What: Handle NO_TIER as a first-class tier in RateLimitDisplay (badge, dropdown option, label, color) and make it the safe fallback for unknown/missing tiers instead of BASIC.

How:

  • Added NO_TIER as the first entry of the TIERS tuple.
  • Added NO_TIER: "no access (paywalled)" to TIER_MULTIPLIERS and NO_TIER: "bg-red-100 text-red-700" to TIER_COLORS.
  • Changed the unknown-tier fallback from "BASIC" to "NO_TIER" — an unknown/missing tier is effectively no-tier, not BASIC.

NO_TIER is a valid SubscriptionTier enum value in the OpenAPI spec, and SetUserTierRequest.tier accepts it, so the dropdown can now also SET NO_TIER to revoke access (the backend set_user_rate_limit_tier / set_user_tier already accepts it). No other spot in the admin/rate-limits feature hardcodes the tier list or assumes BASIC as default — useRateLimitManager.ts passes the tier through as a string.

Changes 🏗️

  • RateLimitDisplay.tsx: add NO_TIER to TIERS, TIER_MULTIPLIERS, TIER_COLORS; fall back to NO_TIER (not BASIC) for unknown tiers.
  • RateLimitDisplay.test.tsx: assert NO_TIER renders as its own badge + "no access (paywalled)" label + selected dropdown value (not BASIC); update unknown-tier fallback test to expect NO_TIER; bump dropdown option count to 6.

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • pnpm format, pnpm lint, pnpm types pass
    • pnpm test:unit RateLimitDisplay — 21 tests pass (including new NO_TIER cases)
    • pnpm test:unit RateLimitManager — 19 tests pass (no regression)

@majdyz
majdyz requested a review from a team as a code owner June 4, 2026 11:34
@majdyz
majdyz requested review from Bentlybro and Pwuts and removed request for a team June 4, 2026 11:34
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Jun 4, 2026
@github-actions github-actions Bot added the platform/frontend AutoGPT Platform - Front end label Jun 4, 2026
@github-actions github-actions Bot added the size/m label Jun 4, 2026
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a NO_TIER subscription state and multiplier-driven labels to the rate-limit admin UI (wired from subscription status and covered by tests). Backend Stripe reconciliation stops per-user Discord alerts for lazy reconciles, logs discrepancies at INFO, reformats sweep alerts into untruncated per-user bullets at WARNING, and updates tests.

Changes

NO_TIER tier state support

Layer / File(s) Summary
Tier label logic, colors, and multiplier wiring
autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/RateLimitDisplay.tsx, .../useRateLimitManager.ts, RateLimitManager.tsx
Introduce NO_TIER, add tierLabel that interprets an optional tierMultipliers map, extend TIER_COLORS, import useGetSubscriptionStatus to expose tierMultipliers, and pass tierMultipliers through to RateLimitDisplay.
RateLimitDisplay select labels and toast
autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/RateLimitDisplay.tsx
Fallback unknown tiers to NO_TIER, change toast/select labels to use tierLabel(newTier, tierMultipliers) instead of a removed static mapping.
NO_TIER tests and multiplier coverage
autogpt_platform/frontend/src/app/(platform)/admin/rate-limits/components/__tests__/RateLimitDisplay.test.tsx
Update tests to assert unknown tiers map to NO_TIER, verify paywalled badge text/color, expect six select options, and add coverage for integer, fractional, missing-tier, and absent tierMultipliers behaviors.

Stripe reconciliation alerting and logging

Layer / File(s) Summary
Suppress per-user Ops alerts in lazy reconcile
autogpt_platform/backend/backend/data/credit.py, autogpt_platform/backend/backend/api/features/v1_stripe_webhook_test.py
reconcile_stripe_tier_for_user no longer awaits per-user Discord alerts on lazy-reconcile paths; discrepancies are recorded via log_tier_reconciliation_discrepancy(..., via="lazy-reconcile"). log_tier_reconciliation_discrepancy now records INFO-level events and alert_tier_reconciliation_discrepancy logs full payload on delivery errors.
Sweep alert formatting and per-user bullets
autogpt_platform/backend/backend/data/stripe_reconciliation.py, autogpt_platform/backend/backend/data/stripe_reconciliation_test.py
Remove truncation cap; _alert_sweep_discrepancies now emits a WARNING-level header and an untruncated affected-user bullet list containing user_id, previous_tier → new_tier, and direction, delegating message splitting to SendDiscordMessageBlock.
Reconciliation webhook tests
autogpt_platform/backend/backend/api/features/v1_stripe_webhook_test.py
Update tests to expect no per-user alert on lazy reconcile and to validate the new sweep alert content format and counts.

Sequence Diagram(s)

sequenceDiagram
  participant Reconcile as reconcile_stripe_tier_for_user
  participant Logger as log_tier_reconciliation_discrepancy
  participant Sweep as _alert_sweep_discrepancies
  participant Chunker as SendDiscordMessageBlock
  participant Alert as alert_tier_reconciliation_discrepancy

  Reconcile->>Logger: record discrepancy (INFO, via="lazy-reconcile")
  Note right of Reconcile: lazy reconcile paths do not await per-user Alert
  Reconcile--xAlert: no per-user alert for lazy reconcile
  Sweep->>Chunker: build header + bullets (user_id, previous→new, direction)
  Chunker->>Alert: send WARNING message part i/N
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • kcze
  • Bentlybro
  • Pwuts
  • ntindle

Poem

🐰 I hopped through tiers both new and old,
NO_TIER now stands quiet, paywalled and bold,
Logs now whisper where loud pings once cried,
Sweep lists the users, no truncation to hide,
A rabbit taps keys—changes tidy and right.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the two main changes: NO_TIER handling in the admin rate-limit display and aggregated reconciliation alerting into a single Discord alert.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the motivation, approach, and implementation details for both frontend NO_TIER display fixes and backend reconciliation alerting changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/admin-rate-limit-no-tier-display

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.77419% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 72.71%. Comparing base (3620990) to head (d06c840).
⚠️ Report is 6 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13291      +/-   ##
==========================================
+ Coverage   72.69%   72.71%   +0.01%     
==========================================
  Files        2355     2358       +3     
  Lines      175563   175736     +173     
  Branches    17760    17779      +19     
==========================================
+ Hits       127624   127778     +154     
- Misses      44166    44180      +14     
- Partials     3773     3778       +5     
Flag Coverage Δ
platform-backend 80.58% <95.65%> (+<0.01%) ⬆️
platform-frontend 40.40% <100.00%> (+0.16%) ⬆️
platform-frontend-e2e 31.05% <ø> (-0.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 80.58% <95.65%> (+<0.01%) ⬆️
Platform Frontend 44.86% <100.00%> (+0.07%) ⬆️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

… system alert

Replace per-user Sentry events with a single Discord (PLATFORM) system alert
per sweep that lists the affected user IDs and a 'reconciled N accounts
(X upgraded, Y downgraded)' summary. Per-discrepancy logging drops from ERROR
(one Sentry event per user) to INFO + PostHog metric; the lazy on-access path
no longer pings ops per-user. Steady state stays silent.
@github-actions github-actions Bot added platform/backend AutoGPT Platform - Back end size/l and removed size/m labels Jun 4, 2026
@majdyz majdyz changed the title fix(frontend): show NO_TIER in admin rate-limit display instead of masking as BASIC fix(platform): show NO_TIER in admin rate-limit display + aggregate reconciliation alerting into one Discord alert Jun 4, 2026
@majdyz

majdyz commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Added a second commit (per request, consolidating from the now-closed #13292):

refactor(backend): aggregate reconciliation alerting into one Discord system alert

Follow-up to the merged reconciliation work (#13284). The sweep previously emitted a per-user ERROR log → one Sentry event per reconciled account (noisy — a single reconciled tester produced its own alert). This replaces that with one Discord PLATFORM system alert per sweep listing the affected user IDs and a "reconciled N account(s) (X upgraded, Y downgraded)" summary; per-discrepancy logging drops to INFO + PostHog metric, and the lazy on-access path no longer pings ops per-user. Steady-state sweeps stay silent.

Tests: sweep asserts the aggregate message + user-id list; lazy/steady-state assert no per-user ping. 329 backend tests green; black/ruff clean.

Note: this PR now spans two concerns (frontend admin display + backend alerting) — bundled here at the author's request.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🟢 Low Risk — File Overlap Only

These PRs touch the same files but different sections (click to expand)

Summary: 0 conflict(s), 0 medium risk, 5 low risk (out of 5 PRs with file overlap)


Auto-generated on push. Ignores: openapi.json, lock files.

…lert

Discord-only system alert (WARNING log, no Sentry): count header up front
(reconciled N: X upgraded, Y downgraded), then the FULL affected-user list at
the end — each line 'user_id  from_tier -> to_tier (direction)' — chunked across
messages to respect Discord's 2000-char limit instead of truncating at 25.
ntindle
ntindle previously approved these changes Jun 4, 2026
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 👍🏼 Mergeable in AutoGPT development kanban Jun 4, 2026
…t failures

- Admin rate-limit page shows live LD/config-driven multipliers (e.g. MAX 42.66x)
  read from /credits/subscription tier_multipliers, instead of hardcoded numbers;
  NO_TIER shows 'no access (paywalled)', missing tiers fall back gracefully.
- Reconciliation Discord-alert failures now log at ERROR (-> Sentry) with the FULL
  alert content (count + user list + tier changes), so a broken bot token / gateway
  timeout surfaces loudly with the payload instead of failing silently.
…Block splits

SendDiscordMessageBlock.chunk_message already splits any >2000-char message, so
the custom _chunk_alert was redundant — and worse: looping the alert helper per
chunk opened a new bot login/gateway connection per chunk. Send one full message
(header + complete affected-user list) and let the block split it once.
… map (incl ENTERPRISE)

The admin User Rate Limits page showed the generic "tier limits" label for
ENTERPRISE (and any tier without a Stripe price) because the multiplier data
came from /credits/subscription tier_multipliers, which the backend filters to
priceable/priced tiers only.

Surface the full per-tier multiplier map on the admin /rate_limit response via
get_tier_multipliers() and read it on the admin page instead of the
subscription endpoint, so admin-managed tiers (ENTERPRISE, etc.) render their
real multiplier.
@majdyz
majdyz merged commit 2675d26 into dev Jun 4, 2026
43 checks passed
@majdyz
majdyz deleted the fix/admin-rate-limit-no-tier-display branch June 4, 2026 14:02
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Jun 4, 2026
@github-project-automation github-project-automation Bot moved this to Done in Frontend Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform/backend AutoGPT Platform - Back end platform/frontend AutoGPT Platform - Front end size/l

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants