diff --git a/cmd/server/openapi.go b/cmd/server/openapi.go index f4fcbdc9..cf89ca16 100644 --- a/cmd/server/openapi.go +++ b/cmd/server/openapi.go @@ -447,7 +447,7 @@ func componentSchemas() map[string]interface{} { "mostEfficientPing": schemaRef("PingScore"), "relayLeaderboard": map[string]interface{}{"type": "array", "items": schemaRef("PingLeaderboardEntry"), "description": "Top nodes ranked by number of distinct pings they appeared as a relay hop in (deduped per ping first, so one busy ping's many branches can't over-credit a relay)."}, "observerLeaderboard": map[string]interface{}{"type": "array", "items": schemaRef("PingLeaderboardEntry"), "description": "Top observers ranked by number of pings they were the first station to hear."}, - "senderLeaderboard": map[string]interface{}{"type": "array", "items": schemaRef("PingLeaderboardEntry"), "description": "Top senders ranked by number of pings sent. Keyed by the sender display name from the channel message itself -- no resolved pubkey, so entries never carry one."}, + "senderLeaderboard": map[string]interface{}{"type": "array", "items": schemaRef("PingLeaderboardEntry"), "description": "Top senders ranked by number of pings sent in the last 30 days (unlike the other leaderboards and records, which are all-time). Keyed by the sender display name from the channel message itself -- no resolved pubkey, so entries never carry one."}, }, }, "AreaDensity": map[string]interface{}{ diff --git a/public/ping-scores.js b/public/ping-scores.js index 341d77d2..ef777ada 100644 --- a/public/ping-scores.js +++ b/public/ping-scores.js @@ -125,7 +125,7 @@ '

Global records and leaderboards from every "ping" sent in any channel (' + data.totalPings + ' total). Not scoped by region. Updated ' + escapeHtml(formatAgo(data.generatedAt)) + '.

' + '
' + recordsHtml + '
' + '
' + - leaderboardTableHtml('Top Senders', phIcon('megaphone'), data.senderLeaderboard, 'Sender') + + leaderboardTableHtml('Top Senders (30 days)', phIcon('megaphone'), data.senderLeaderboard, 'Sender') + leaderboardTableHtml('Top Relays', phIcon('repeat'), data.relayLeaderboard) + leaderboardTableHtml('Top First-Hearers', phIcon('eye'), data.observerLeaderboard) + '
' + diff --git a/test-ping-scores.js b/test-ping-scores.js index 22ed9b21..096f29b9 100644 --- a/test-ping-scores.js +++ b/test-ping-scores.js @@ -136,7 +136,7 @@ function makeSandbox(apiImpl) { assert.ok(container.innerHTML.includes('RelayOne'), 'should show the relay leaderboard entry, got: ' + container.innerHTML); assert.ok(container.innerHTML.includes('ObsOne'), 'should show the observer leaderboard entry, got: ' + container.innerHTML); assert.ok(container.innerHTML.includes('PingMaster'), 'should show the sender leaderboard entry, got: ' + container.innerHTML); - assert.ok(container.innerHTML.includes('Top Senders'), 'should show the Top Senders leaderboard heading, got: ' + container.innerHTML); + assert.ok(container.innerHTML.includes('Top Senders (30 days)'), 'should show the Top Senders leaderboard heading with the 30-day window noted, got: ' + container.innerHTML); passed++; console.log(' ✅ renders all 5 records and all three leaderboards (including Top Senders) from a populated response'); } catch (e) { failed++; console.log(' ❌ renders all 5 records and all three leaderboards (including Top Senders) from a populated response: ' + e.message); }