fix(teams): say "game server", not "shard", on the never-synced Teams panel #221

Merged
whitlocktech merged 1 commits from fix/teams-panel-neutral-wording into main 2026-10-22 14:59:40 -05:00
6 changed files with 9 additions and 9 deletions

View File

@@ -41,7 +41,7 @@ export function relativeTime(when, now = Date.now()) {
* Distinct from `teamAdmin.freshnessOf`, which is worded for an operator
* debugging a sync. A visitor needs one sentence about whether what they are
* looking at is current, and specifically must never be shown an unconfirmed
* empty projection as though it were a confirmed empty shard.
* empty projection as though it were a confirmed empty one.
*/
export function freshnessNote(sync = {}, now = Date.now()) {
// Nothing supplies Teams here, so there is nothing to be stale ABOUT. A
@@ -57,7 +57,7 @@ export function freshnessNote(sync = {}, now = Date.now()) {
* Group feed items into days, newest first, preserving order within a day (§4.3).
*
* Keyed by local calendar date rather than by a UTC slice: "yesterday" is a
* property of where the reader is sitting, and a shard's evening raid landing at
* property of where the reader is sitting, and a game server's evening raid landing at
* 00:30 UTC belongs on the day the players experienced it.
*/
export function groupByDay(items = [], locale = undefined) {

View File

@@ -3,7 +3,7 @@
//
// Plain JS with tests, following lib/moduleAdmin.js. The reason it is worth
// splitting here specifically: this screen's job is to tell an operator the
// difference between "the shard has no Teams" and "core has not been able to ask
// difference between "the game server has no Teams" and "core has not been able to ask
// for two hours", and those two produce almost the same page. Getting that
// wording right is logic, not markup.
@@ -31,7 +31,7 @@ export function freshnessOf(sync = {}) {
return {
tone: TONE.bad,
label: 'Never synced',
detail: 'Core has never had an answer it could trust. What is shown below is not a confirmed empty shard.',
detail: 'Core has never had an answer it could trust. What is shown below does not confirm that the game server has no Teams.',
}
}
if (sync.stale) {

View File

@@ -14,7 +14,7 @@ import TeamVoice from './TeamVoice.jsx'
// Three panels, in the order an operator needs them:
//
// 1. **Sync state**, verbatim, including the last error. The screen's first job
// is to make "the shard has no Teams" and "core has not been able to ask for
// is to make "the game server has no Teams" and "core has not been able to ask for
// two hours" impossible to confuse — they render almost identically
// otherwise, and one is fine while the other is an outage.
// 2. **The review queue** — Teams auto-hidden because their name matched the

View File

@@ -19,7 +19,7 @@ test('a deployment with no provider is not stale, it is uninvolved', () => {
assert.equal(freshnessNote({ configured: false }, NOW), null)
})
test('never synced is a warning, and never reads as a confirmed empty shard', () => {
test('never synced is a warning, and never reads as a confirmed empty roster', () => {
const note = freshnessNote({ configured: true, lastSyncAt: null }, NOW)
assert.equal(note.tone, 'warn')
assert.match(note.text, /Not yet confirmed/)

View File

@@ -21,13 +21,13 @@ test('no provider is idle, not a fault', () => {
assert.match(f.label, /No Team provider/)
})
test('never synced is reported as never synced, not as an empty shard', () => {
test('never synced is reported as never synced, not as a game server with no Teams', () => {
// The failure this prevents: an empty projection core has never confirmed,
// rendered as though the game genuinely has no Teams.
const f = freshnessOf({ configured: true, lastSyncAt: null })
assert.equal(f.tone, TONE.bad)
assert.equal(f.label, 'Never synced')
assert.match(f.detail, /not a confirmed empty shard/)
assert.match(f.detail, /does not confirm that the game server has no Teams/)
})
test('stale says how old it is', () => {

View File

@@ -135,7 +135,7 @@ async function syncStatus() {
configured: true,
lastSyncAt,
// Never synced at all is stale: a page must not present an empty projection
// as a confirmed empty shard.
// as a confirmed empty one.
stale: ageS > intervalS * STALE_INTERVALS,
consecutiveFailures: state ? state.consecutive_failures : 0,
}