Skip to content

Backend: Hide moderator badge behind a feature flag#8757

Merged
aapeliv merged 5 commits into
developfrom
backend/feature/hide-moderator-badge
May 23, 2026
Merged

Backend: Hide moderator badge behind a feature flag#8757
aapeliv merged 5 commits into
developfrom
backend/feature/hide-moderator-badge

Conversation

@aapeliv

@aapeliv aapeliv commented May 23, 2026

Copy link
Copy Markdown
Member

Hides the moderator profile badge from the UI, gated behind a GrowthBook feature flag so it can be rolled out and rolled back without a deploy.

This adds a generic hidden flag to badge definitions. A hidden badge is still awarded to users and stored in user_badges (no data churn), but is:

  • excluded from the GetBadges catalog (so it disappears from the /badges page),
  • stripped from every user's badges list on GetUser, public profiles, and admin user-details, and
  • not announced via add/remove notifications.

The moderator badge is marked hidden. Whether the flag is honored is controlled by a new global gate hide_moderator_badge (via check_global_gate, which evaluates against a stable synthetic identity so it works in anonymous/AUTH_LEVEL_OPEN and background-job contexts where there is no user). The gate is off by default, so behavior is unchanged in production until the flag is turned on; turning it off again is an instant rollback.

To roll out: create a boolean feature/gate named hide_moderator_badge in GrowthBook (default off) and turn it on when ready.

Testing

  • Added test_hidden_badge_is_awarded_but_not_shown (gate on, the default in tests): the badge row is created but absent from GetUser and no notification fires.
  • Added test_hidden_badge_is_shown_when_rollout_gate_off (disables experimentation via monkeypatch): the badge is shown on the profile and the add is notified — verifying the pre-rollout/rollback path.
  • Updated test_GetBadges to reflect the moderator badge being excluded from the catalog when the gate is on.
  • Ran the badge-touching suites (test_api, test_resources, test_bg_jobs, test_donations, test_public, test_admin) — all pass. make format clean; make mypy has only 2 pre-existing errors in untouched files.

Backend checklist

  • Added tests for any new code or added a regression test if fixing a bug
  • Run the backend locally and it works
  • Added migrations if there are any database changes, rebased onto develop if necessary for linear migration history (no DB changes)

Web frontend checklist

  • There are no console warnings when running the app
  • Added tests where relevant (defensive guard only — skips badge ids not in the catalog so a hidden id can't crash the profile)
  • Clicked around my changes running locally and it works
  • Checked Desktop, Mobile and Tablet screen sizes

For maintainers

  • Maintainers can push commits to my branch
  • Maintainers can merge this PR for me

This PR was created with the Couchers PR skill.

@aapeliv
aapeliv requested a review from nabramow as a code owner May 23, 2026 02:01
@vercel

vercel Bot commented May 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
couchers Ready Ready Preview May 23, 2026 3:58pm

Request Review

@nabramow

nabramow commented May 23, 2026

Copy link
Copy Markdown
Member

I might be misunderstanding, but it looks like you're using this in the badges update query but not the get query?

aapeliv and others added 5 commits May 23, 2026 11:50
…rd time

Add an optional `flag` to badge definitions: a flagged badge is only
awarded (and listed in the GetBadges catalog) while its feature flag is
on. The flag defaults on, so the moderator badge stays visible until
show_moderator_badge is turned off in GrowthBook.

The update_badges job converges membership, so flipping the flag off
removes the moderator badge from all superusers on the next run; the
catalog filter and a profile-side guard hide it from the web UI
immediately. This keeps the badge's existence the single source of
truth - no per-read-site filtering or notification special-casing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…tend

Drop the per-read GetBadges catalog filter so the badge catalog always
returns the full list (badge name/color/description always resolve). The
show_moderator_badge flag now only controls membership via update_badges.

Hide the moderator badge from the /badges explorer with a frontend guard
that mirrors the backend default-on flag, using useFeatureValue(..., true)
so the badge shows unless the flag is explicitly off.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The badge-explorer hide and profile guard now live in #8766; this branch
keeps only the backend gating.
…dges

Add module-level get_boolean_value / get_string_value / ... to experimentation
for evaluating flags with no user/request context (anonymous, like a logged-out
user). The enabled / pass-all-gates gating moves into shared helpers that both
the new global functions and CouchersContext use - the context keeps its cached
per-request evaluator by passing it in.

update_badges now calls experimentation.get_boolean_value directly instead of
constructing a throwaway logged-out CouchersContext just to read a flag.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Name the no-user functions get_global_boolean_value / get_global_string_value
/ ... so call sites read as explicitly global, and spell out in the comments
that they're only for flags that genuinely can't be per-user (a toggle that
behaves the same for everyone) - anything per-user must go through the context
so rollouts and experiments can bucket by user.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@aapeliv
aapeliv force-pushed the backend/feature/hide-moderator-badge branch from 551071c to 185934e Compare May 23, 2026 15:55
@aapeliv
aapeliv merged commit c803f4a into develop May 23, 2026
5 checks passed
@aapeliv
aapeliv deleted the backend/feature/hide-moderator-badge branch May 23, 2026 16:10
@github-actions

Copy link
Copy Markdown
Contributor

📝 Release Notes

This PR does not need to be included in release notes.

Reason: This change mainly adds backend feature-flag control to hide or show the moderator badge, with no user-visible effect until a separate flag is enabled. As submitted, production behavior is unchanged by default, and it is mostly internal rollout infrastructure rather than a clear end-user feature release.

🤖 Bot Debug Information

Model: couchers.openai.gpt-5.4
Decision: exclude
Reasoning: This change mainly adds backend feature-flag control to hide or show the moderator badge, with no user-visible effect until a separate flag is enabled. As submitted, production behavior is unchanged by default, and it is mostly internal rollout infrastructure rather than a clear end-user feature release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants