fix(rust): answer refusals in the field core reads, and show the name the game last saw
The two defects the phase 6 browser walk found and #6 described but did not carry. They were written, walked and left uncommitted; `edge` still has the shapes the walk condemned. **Every refusal sentence was invisible.** Core's request primitive reads one field — `(data && data.message) || res.statusText` — and this module has answered `{ error: … }` since phase 1. It got away with it because every failure until phase 6 landed in `ErrorState` on a page whose whole content was missing, where a generic sentence is honest. A form is different: the sentence IS the outcome, and the link page showed *Service Unavailable* for all four of the refusals phase 6 exists to write. All 23 bodies now answer in `message` — core's `Error` schema, which these routes' own `#swagger.responses` already referenced, so the annotations stop being a claim the handlers contradict. `test/errorShape.test.js` drives each outcome rather than grepping for the field, and asserts the half that is easy to leave behind: a body carrying BOTH fields renders correctly in a browser and keeps the wrong shape alive for the next route that copies it. **The player saw a stale name.** `/player/rust` showed the name recorded at link time while the admin panel showed the one the game last saw — the same person labelled two ways on one site, because a Rust name changes on a whim and only the admin read joined `rust_players`. A LEFT JOIN, because an account can be linked and never played on. 123 server tests, 39 client tests, `check:imports`, `check:bundle`, `check:swagger`, `check:externals` — all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM
This commit is contained in:
@@ -28,14 +28,26 @@ async function getBySteamId(steamId) {
|
||||
return rows[0]
|
||||
}
|
||||
|
||||
/** Every Steam account one website user holds, newest first. */
|
||||
/**
|
||||
* Every Steam account one website user holds, newest first.
|
||||
*
|
||||
* **It joins `rust_players` for the name the game last saw**, and that is not a
|
||||
* convenience. The name on the LINK is what the player was called at the moment
|
||||
* they linked, which is a Rust name and changes on a whim — so a player who has
|
||||
* renamed since sees a name they no longer use, on the one page of the site that
|
||||
* is about who they are. The admin panel already preferred the newer one; this
|
||||
* is the same rule applied where the person themselves is reading.
|
||||
*
|
||||
* A LEFT JOIN, because a player can link an account and never play on it.
|
||||
*/
|
||||
async function listForUser(userId) {
|
||||
return core.query(
|
||||
`SELECT steam_id AS steamId, user_id AS userId, name, server_id AS serverId,
|
||||
linked_at AS linkedAt
|
||||
FROM ${LINKS}
|
||||
WHERE user_id = ?
|
||||
ORDER BY linked_at DESC`,
|
||||
`SELECT l.steam_id AS steamId, l.user_id AS userId, l.name, l.server_id AS serverId,
|
||||
l.linked_at AS linkedAt, p.name AS playerName
|
||||
FROM ${LINKS} l
|
||||
LEFT JOIN ${PLAYERS} p ON p.steam_id = l.steam_id
|
||||
WHERE l.user_id = ?
|
||||
ORDER BY l.linked_at DESC`,
|
||||
[userId],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,9 +34,20 @@ function shape(row) {
|
||||
}
|
||||
}
|
||||
|
||||
/** The Steam accounts one website user holds. */
|
||||
/**
|
||||
* The Steam accounts one website user holds.
|
||||
*
|
||||
* The name is the one the GAME last saw, falling back to the one recorded when
|
||||
* they linked — the rule the admin panel already used, applied on the page the
|
||||
* player themselves reads. A browser walk found the two disagreeing: staff saw
|
||||
* `Wanderer` and the player saw `Wanderer-old`, for the same person on the same
|
||||
* site.
|
||||
*/
|
||||
async function listForUser(userId) {
|
||||
return (await db.listForUser(userId)).map(shape)
|
||||
return (await db.listForUser(userId)).map((row) => ({
|
||||
...shape(row),
|
||||
name: row.playerName || row.name || null,
|
||||
}))
|
||||
}
|
||||
|
||||
/** True when this user holds this Steam id. The ownership gate every player read uses. */
|
||||
|
||||
Reference in New Issue
Block a user