Skip to content

QuotaWallBanner on top-level pages reads /api/v1/usage/wall (U1)#41

Merged
mastermanas805 merged 2 commits into
mainfrom
pricing/u1-quota-banner-fresh
May 12, 2026
Merged

QuotaWallBanner on top-level pages reads /api/v1/usage/wall (U1)#41
mastermanas805 merged 2 commits into
mainfrom
pricing/u1-quota-banner-fresh

Conversation

@mastermanas805
Copy link
Copy Markdown
Member

Summary

Track U1 — usage-based upgrade banner on the dashboard.

  • New <QuotaWallBanner /> component (src/components/QuotaWallBanner.tsx). Polls GET /api/v1/usage/wall on mount and every 5 minutes; when near_wall=true renders an axis-aware banner with an Upgrade CTA pointing at /app/billing.
  • Mounted on OverviewPage, ResourcesPage, DeploymentsPage — the three surfaces where seeing the wall is most actionable.
  • New fetchQuotaWall() API client in src/api/index.ts with typed QuotaWallResponse.

Dismissibility

  • localStorage key instanode.quotaWallDismiss.<team_id> stores {percent, at} so dismiss state is per-team (two teams sharing a browser don't share dismisses).
  • Reappear rule: when percent_used climbs ≥ 5pp above the dismissed value, the banner shows again. Encodes "I saw it at X%" instead of "ignore forever."

Design

  • shouldRender(wall, dismiss) exported as a pure function — the unit tests exercise the decision matrix directly without mounting a tree.
  • Banner is unconditionally hidden when near_wall=false, when the API errors, or before the team id is known (loading state) so we never leak across teams.

Test plan

  • 11 new tests in QuotaWallBanner.test.tsx cover all shouldRender branches and the rendering / dismiss / reappear flows
  • Full dashboard suite green — 220 passed | 3 skipped (223)
  • tsc --noEmit clean

🤖 Generated with Claude Code

New component QuotaWallBanner — yellow banner above page content that
appears when the caller's team is at ≥80% of any tier-limit axis
(storage / connections / provisions). Reads GET /api/v1/usage/wall on
mount and every 5 minutes; renders the metadata fields the worker
attached to the audit row.

Mounted on OverviewPage, ResourcesPage, and DeploymentsPage — the three
surfaces where seeing the wall is most actionable for an upgrade
decision.

Dismiss state persists per-team in localStorage. Reappear rule: if
percent_used climbs >= 5pp above the dismissed value, the banner
shows again. Per-team key prevents one team's dismiss bleeding into
another's view when two teams share a browser profile.

shouldRender is exported as a pure function so the unit tests can
exercise the decision logic directly without mounting a tree. 11
new tests; the full dashboard suite passes (220/220).

api: new fetchQuotaWall() in src/api/index.ts. Types are explicit
on the response shape so consumers don't drift if the backend adds
fields.
…er-fresh

# Conflicts:
#	src/pages/OverviewPage.tsx
#	src/pages/ResourcesPage.tsx
@mastermanas805 mastermanas805 merged commit ca7f979 into main May 12, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant