mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-27 02:05:26 +08:00
## Summary - Moves scorable weight configuration and category filtering from global site settings to individual leaderboards - Each leaderboard can override any of the 15 score weight values and specify its own scorable categories - Score calculation now runs per leaderboard into a new `gamification_leaderboard_scores` table - Admin UI gains a "Scoring configuration" section on the leaderboard edit form ## Details Previously all leaderboards shared the same pre-calculated scores from global site settings. This made it impossible to have e.g. a "posts-only" leaderboard alongside a "likes-focused" one. Now each leaderboard can optionally override: - **Score weights**: Set per-action point values (empty = inherit global default, 0 = disabled) - **Scorable categories**: Restrict which categories count toward scoring (empty = inherit global setting) The old `gamification_scores` table is no longer written to — a post-deploy migration to drop it will follow separately. ## Test plan - [ ] Create a leaderboard with default scoring — scores match current behavior - [ ] Create a leaderboard with custom weights (e.g. `post_created` = 10, all others empty) — only overridden weights differ - [ ] Set a weight to 0 — that scorable is disabled for the leaderboard - [ ] Set per-leaderboard categories — only those categories count - [ ] Clear categories — inherits global `scorable_categories` setting - [ ] Existing leaderboards with no overrides behave identically after upgrade - [ ] Directory scores and user card scores work correctly (read from default leaderboard) - [ ] `bin/rspec plugins/discourse-gamification/spec/` — 120 examples, 0 failures
67 lines
1.7 KiB
Ruby
Vendored
67 lines
1.7 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
module DiscourseGamification
|
|
class DirectoryIntegration
|
|
def self.query
|
|
<<~SQL
|
|
WITH default_leaderboard AS (
|
|
SELECT
|
|
id,
|
|
from_date,
|
|
to_date
|
|
FROM
|
|
gamification_leaderboards
|
|
ORDER BY
|
|
id ASC
|
|
LIMIT 1
|
|
), total_score AS (
|
|
SELECT
|
|
gls.user_id,
|
|
SUM(gls.score) AS score
|
|
FROM
|
|
gamification_leaderboard_scores gls
|
|
INNER JOIN
|
|
default_leaderboard lb ON gls.leaderboard_id = lb.id
|
|
WHERE
|
|
gls.date >= :since
|
|
AND
|
|
(
|
|
(
|
|
lb.from_date IS NULL
|
|
OR
|
|
gls.date >= lb.from_date
|
|
)
|
|
AND
|
|
(
|
|
lb.to_date IS NULL
|
|
OR
|
|
gls.date <= lb.to_date
|
|
)
|
|
)
|
|
GROUP BY
|
|
1
|
|
), scored_directory AS (
|
|
SELECT
|
|
directory_items.user_id,
|
|
COALESCE(total_score.score, 0) AS score
|
|
FROM
|
|
directory_items
|
|
LEFT JOIN
|
|
total_score ON total_score.user_id = directory_items.user_id
|
|
WHERE
|
|
directory_items.period_type = :period_type
|
|
)
|
|
UPDATE
|
|
directory_items
|
|
SET
|
|
gamification_score = scored_directory.score
|
|
FROM
|
|
scored_directory
|
|
WHERE
|
|
scored_directory.user_id = directory_items.user_id AND
|
|
directory_items.period_type = :period_type AND
|
|
scored_directory.score != directory_items.gamification_score
|
|
SQL
|
|
end
|
|
end
|
|
end
|