feat(rust): what the site has given a player, as the player reads it
Phase 8's website half. Phase 7 made the site the author of in-game
privilege and gave an operator every view of it; this is the other side,
and it is the first time a player can see what they hold without asking
one.
`GET /player/rust/permissions` is self-scoped in SQL and read-only by
construction — a grant a player could change would not be a grant. Three
things make it a different shape from the admin read rather than a
filtered one:
* the scope arithmetic is answered on the server. A client handed `*`
would have to know what the fleet is to say anything, and then
`inScope` exists twice. Each entry carries the servers it reaches,
already resolved and already marked.
* `live` is the pushed ledger, never the authored row. A grant is not a
privilege in a game until a sync confirmed it, and phase 7 is careful
never to record a push that silently did nothing — so "waiting" is
honest, and the alternative is the site claiming to have given
something it has not.
* nothing says WHY it is waiting. An offline server, a permission no
loaded plugin registered and a store that has never seen the account
all look the same from here; telling them apart is an operator's
diagnosis and an inventory of what is installed.
An entitlement that reaches nobody still lists, and the page says so —
authored against the website account, it exists before a Steam id does,
and hiding it until one turns up is the defect the admin user page
shipped in phase 7 (PLAN.md §20.5).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMH6bw1jXMgbyF3ZWGEzSM
This commit is contained in:
@@ -127,6 +127,58 @@ module.exports = {
|
||||
links: { type: 'array', items: { $ref: '#/components/schemas/RustLink' } },
|
||||
},
|
||||
},
|
||||
RustPlayerReach: {
|
||||
type: 'object',
|
||||
description: 'One server an entitlement’s scope reaches, and whether it is there yet.',
|
||||
properties: {
|
||||
id: { type: 'string', example: 'main' },
|
||||
name: { type: 'string', example: 'Main · Vanilla+' },
|
||||
live: {
|
||||
type: 'boolean',
|
||||
description: 'True only when a sync confirmed this into that server’s own store. False covers every way it has not arrived — the server is offline, no loaded plugin registered the name, or its store has never seen the account — and the difference between those is an operator’s diagnosis, not a player’s.',
|
||||
example: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
RustPlayerPermissions: {
|
||||
type: 'object',
|
||||
description: 'What the site has given the signed-in player in game (GET /player/rust/permissions).',
|
||||
properties: {
|
||||
accounts: {
|
||||
type: 'integer',
|
||||
description: 'How many Steam accounts the caller has linked. Zero is why an entitlement can be authored and reach nobody.',
|
||||
example: 1,
|
||||
},
|
||||
groups: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string', example: 'vip' },
|
||||
title: { type: 'string', example: 'VIP' },
|
||||
scope: { type: 'string', description: 'A server id, or `*` for the whole fleet.', example: '*' },
|
||||
since: { type: 'string', format: 'date-time' },
|
||||
permissions: { type: 'array', items: { type: 'string' }, example: ['kits.vip'] },
|
||||
reach: { type: 'array', items: { $ref: '#/components/schemas/RustPlayerReach' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
grants: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
permission: { type: 'string', example: 'kits.vip' },
|
||||
scope: { type: 'string', example: '*' },
|
||||
source: { type: 'string', description: 'Who authored it — `admin` now, an event action later.', example: 'admin' },
|
||||
note: { type: 'string', nullable: true },
|
||||
since: { type: 'string', format: 'date-time' },
|
||||
reach: { type: 'array', items: { $ref: '#/components/schemas/RustPlayerReach' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RustLinkRequest: {
|
||||
type: 'object',
|
||||
required: ['code'],
|
||||
|
||||
Reference in New Issue
Block a user