Don't ping owners on rank-only standings changes in Discord
All checks were successful
🚀 Deploy / 🧪 Test (pull_request) Successful in 3m24s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Successful in 1m23s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
🚀 Deploy / 🧪 Test (push) Successful in 3m17s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m28s
🚀 Deploy / 🐳 Build (push) Successful in 1m11s
🚀 Deploy / 🚀 Deploy (push) Successful in 11s
All checks were successful
🚀 Deploy / 🧪 Test (pull_request) Successful in 3m24s
🚀 Deploy / ʦ🔍 Typecheck & Lint (pull_request) Successful in 1m23s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
🚀 Deploy / 🧪 Test (push) Successful in 3m17s
🚀 Deploy / ʦ🔍 Typecheck & Lint (push) Successful in 1m28s
🚀 Deploy / 🐳 Build (push) Successful in 1m11s
🚀 Deploy / 🚀 Deploy (push) Successful in 11s
The first score of a season displaces every other team's rank (e.g. everyone becomes T2), which fired a mass @-ping of the whole league even though only one owner actually scored. The Standings Changes section pinged every team whose rank *or* points changed. Now the section pings an owner only when that team's points genuinely changed this event; rank-only shufflers are still displayed with their rank delta, but by name and without a mention. Mirrors the existing "display but don't ping" behaviour in the Scored Matches section and preserves pings for pure season-standings sports (F1, IndyCar), where a real scorer's points always change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
91227b2cb3
commit
3f6af2665e
2 changed files with 48 additions and 5 deletions
|
|
@ -277,6 +277,43 @@ describe("sendStandingsUpdateNotification", () => {
|
|||
expect(desc).not.toContain("Gamma");
|
||||
});
|
||||
|
||||
it("pings scorers but not rank-only shufflers", async () => {
|
||||
await sendStandingsUpdateNotification({
|
||||
webhookUrl: WEBHOOK_URL,
|
||||
seasonName: "My League 2025",
|
||||
standings: [
|
||||
// Alpha scored — points changed, moved up.
|
||||
{ teamId: "a", teamName: "Alpha", totalPoints: 150, rank: 1, discordUserId: "111" },
|
||||
// Beta was displaced down without scoring — rank changed only.
|
||||
{ teamId: "b", teamName: "Beta", totalPoints: 125, rank: 2, username: "beta_owner", discordUserId: "222" },
|
||||
],
|
||||
previousStandings: new Map([
|
||||
["a", 125],
|
||||
["b", 125],
|
||||
]),
|
||||
previousRanks: new Map([
|
||||
["a", 2],
|
||||
["b", 1],
|
||||
]),
|
||||
});
|
||||
|
||||
const desc = getDescription();
|
||||
// Beta is still displayed with its rank movement…
|
||||
expect(desc).toContain("Beta");
|
||||
expect(desc).toContain("↓1");
|
||||
// …but by name, not as an @-mention.
|
||||
expect(desc).not.toContain("<@222>");
|
||||
// Alpha scored, so it keeps its mention.
|
||||
expect(desc).toContain("<@111>");
|
||||
|
||||
const payload = getPayload();
|
||||
// Only the scorer is pinged.
|
||||
expect(payload.content).toContain("111");
|
||||
expect(payload.content).not.toContain("222");
|
||||
expect(payload.allowed_mentions.users).toContain("111");
|
||||
expect(payload.allowed_mentions.users).not.toContain("222");
|
||||
});
|
||||
|
||||
it("omits rank delta when no previousRanks provided", async () => {
|
||||
await sendStandingsUpdateNotification({
|
||||
webhookUrl: WEBHOOK_URL,
|
||||
|
|
|
|||
|
|
@ -175,13 +175,19 @@ export async function sendStandingsUpdateNotification({
|
|||
const isTied = buildTiedRankChecker(standings.map((s) => s.rank));
|
||||
const rankLabel = (rank: number) => (isTied(rank) ? `T${rank}` : `${rank}`);
|
||||
|
||||
// A team's points genuinely changed this event (vs. merely being displaced in
|
||||
// rank because someone else scored). Only real scorers are pinged; rank-only
|
||||
// shufflers are still displayed, but by name and without an @-mention.
|
||||
const pointsChanged = (s: StandingEntry) => {
|
||||
const prevPoints = previousStandings.get(s.teamId);
|
||||
return prevPoints !== undefined && prevPoints !== s.totalPoints;
|
||||
};
|
||||
|
||||
// Standings changes section — show teams whose points or rank changed.
|
||||
const changedTeams = standings.filter((s) => {
|
||||
const prevPoints = previousStandings.get(s.teamId);
|
||||
const pointsChanged = prevPoints !== undefined && prevPoints !== s.totalPoints;
|
||||
const prevRank = previousRanks?.get(s.teamId);
|
||||
const rankChanged = prevRank !== undefined && prevRank !== s.rank;
|
||||
return pointsChanged || rankChanged;
|
||||
return pointsChanged(s) || rankChanged;
|
||||
});
|
||||
|
||||
if (changedTeams.length > 0) {
|
||||
|
|
@ -206,7 +212,7 @@ export async function sendStandingsUpdateNotification({
|
|||
}
|
||||
|
||||
const escapedName = escapeMarkdown(s.teamName);
|
||||
const managerLabel = s.discordUserId
|
||||
const managerLabel = s.discordUserId && pointsChanged(s)
|
||||
? `<@${s.discordUserId}>`
|
||||
: s.username
|
||||
? escapeMarkdown(s.username)
|
||||
|
|
@ -225,7 +231,7 @@ export async function sendStandingsUpdateNotification({
|
|||
// Collect Discord user IDs of all opted-in managers appearing in this notification.
|
||||
const pingUserIds = new Set<string>();
|
||||
for (const s of changedTeams) {
|
||||
if (s.discordUserId) pingUserIds.add(s.discordUserId);
|
||||
if (s.discordUserId && pointsChanged(s)) pingUserIds.add(s.discordUserId);
|
||||
}
|
||||
for (const m of relevantMatches ?? []) {
|
||||
if (m.winnerDiscordUserId) pingUserIds.add(m.winnerDiscordUserId);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue