mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-04 01:52:18 +08:00
Adds four tiered badges to discourse-topic-voting so topic authors are recognized when their ideas get traction: - Daydreamer (Bronze, 1 vote) - Brainstormer (Silver, 5 votes) - Innovator (Silver, 15 votes) - Visionary (Gold, 25 votes) Badges are multi-grant and tied to the qualifying topic's first post, so a user earns each tier once per topic that reaches the threshold. Self-votes (voting on your own topic) are excluded. All badges are disabled by default; the Silver and Gold tiers (Brainstormer, Innovator, Visionary) allow the badge to be used as a title when enabled. <img width="287" height="216" alt="image" src="https://github.com/user-attachments/assets/3a84c2b2-6157-4504-b5a5-45e7c660e90c" /> ### How it is wired - `Votes::Cast` enqueues a `BackfillBadges` job after a vote is cast. - `TopicMerger.merge` and `VoteReclaim` also enqueue the job so merged or reclaimed topics are re-evaluated immediately rather than having to wait for the daily consistency pass. - The job calls `BadgeGranter.backfill` scoped to the topic's first post. Queries join `badge_posts`, which already filters out deleted and unlisted topics, read-restricted categories, and categories with `allow_badges` disabled. - Each query returns `granted_at` as the timestamp of the Nth qualifying vote (via `ROW_NUMBER()`), so every tier reflects when that threshold was actually crossed rather than when the most recent vote landed. - Revocation (vote removed, topic deleted, category changed) runs on the daily full backfill via `auto_revoke`, consistent with how discourse-solved handles the same pattern. ### Notification handling To avoid "granted badge" notification avalanches when the feature is first enabled on a community with years of existing votes, core now exposes a `:badge_granter_suppress_notification` modifier. The plugin registers it and suppresses notifications for its four badges when the qualifying vote is older than 2 weeks. Combined with the per-tier `granted_at`, this means only the tier the author just crossed produces a notification; lower tiers whose threshold was reached long ago stay silent. Ref - t/182304 |
||
|---|---|---|
| .. | ||
| admin/search | ||
| admin_notices | ||
| categories | ||
| category | ||
| discourse_id | ||
| flags | ||
| groups | ||
| nested_topic | ||
| notification/action | ||
| notifications | ||
| problem_check | ||
| site_setting | ||
| tags | ||
| themes | ||
| upcoming_changes | ||
| user | ||
| video_conversion | ||
| anonymous_shadow_creator_spec.rb | ||
| auto_silence_spec.rb | ||
| badge_granter_spec.rb | ||
| base_bookmarkable_spec.rb | ||
| category_hashtag_data_source_spec.rb | ||
| color_scheme_revisor_spec.rb | ||
| destroy_task_spec.rb | ||
| email_settings_exception_handler_spec.rb | ||
| email_settings_validator_spec.rb | ||
| email_style_updater_spec.rb | ||
| external_upload_manager_spec.rb | ||
| flag_sockpuppets_spec.rb | ||
| group_action_logger_spec.rb | ||
| group_mentions_updater_spec.rb | ||
| group_message_spec.rb | ||
| hashtag_autocomplete_service_spec.rb | ||
| heat_settings_updater_spec.rb | ||
| hub_push_notification_pusher_spec.rb | ||
| inline_uploads_multisite_spec.rb | ||
| inline_uploads_spec.rb | ||
| locale_normalizer_spec.rb | ||
| notification_emailer_spec.rb | ||
| post_action_notifier_spec.rb | ||
| post_alerter_spec.rb | ||
| post_bookmarkable_spec.rb | ||
| post_owner_changer_spec.rb | ||
| problem_check_spec.rb | ||
| push_notification_pusher_spec.rb | ||
| random_topic_selector_spec.rb | ||
| search_indexer_spec.rb | ||
| sidebar_site_settings_backfiller_spec.rb | ||
| site_settings_spec.rb | ||
| staff_action_logger_spec.rb | ||
| tag_hashtag_data_source_spec.rb | ||
| tag_settings_updater_spec.rb | ||
| theme_settings_migrations_runner_spec.rb | ||
| themes_spec.rb | ||
| topic_bookmarkable_spec.rb | ||
| topic_status_updater_spec.rb | ||
| topic_timestamp_changer_spec.rb | ||
| trust_level_granter_spec.rb | ||
| user_activator_spec.rb | ||
| user_anonymizer_spec.rb | ||
| user_authenticator_spec.rb | ||
| user_destroyer_spec.rb | ||
| user_merger_spec.rb | ||
| user_notification_schedule_processor_spec.rb | ||
| user_password_expirer_spec.rb | ||
| user_silencer_spec.rb | ||
| user_stat_count_updater_spec.rb | ||
| user_suspender_spec.rb | ||
| user_updater_spec.rb | ||
| username_changer_spec.rb | ||
| username_checker_service_spec.rb | ||
| wildcard_domain_checker_spec.rb | ||
| wildcard_url_checker_spec.rb | ||
| word_watcher_spec.rb | ||