Merge pull request 'docs(link): the shard-name fallback, the atlas places shape, and two traps' (#76) from docs/protocol-3-smoke-findings into edge
Reviewed-on: #76
This commit is contained in:
@@ -970,14 +970,22 @@ push, and Play (M6–M8) follow the designed app.
|
||||
(`atlas`). Note the path: `/public/atlas`, **not** `/public/shard` — the atlas is static shard
|
||||
*content*, not live shard *state*, and unlike `/shard/*` it **is** `siteMode`-gated like
|
||||
`/posts` and `/wiki`, so a site in maintenance mode withholds it independently of the sidecar.
|
||||
Two units/naming traps from `v3.md` §6.3: respawn delays are **seconds** throughout, and
|
||||
`points` is a *count* on the search route while `spawners` is the *list* on the detail route.
|
||||
Three traps. Two are units/naming, from `v3.md` §6.3: respawn delays are **seconds**
|
||||
throughout, and `points` is a *count* on the search route while `spawners` is the *list* on
|
||||
the detail route. The third is a **shape**: `places` is a list of
|
||||
`{facet, label, spawners, maxAlive}` **objects**, not of place-name strings — it is the
|
||||
aggregate the screen exists to show ("Shrines, Isamu-Jima, Yew"), it arrives only on the
|
||||
detail route, and typing it `List<String>` makes that whole route fail to decode while the
|
||||
request itself returns `200`.
|
||||
- **Verification** — the five-rung walk (`anonymous`, `logged_in`, `player`, `staff`, `admin`)
|
||||
against a local website on the cutover branch, per
|
||||
[`../link/v3.md`](../link/v3.md) §11 and the shard-visibility smoke harness; plus one pass with
|
||||
**every feature disabled** in Admin → Shard Visibility, confirming the app *hides* each surface
|
||||
instead of erroring on it. Unit tests cover the menu filter (role × feature set), the
|
||||
`404`/`403`/`503` mapping, and DTO decode for each new shape.
|
||||
`404`/`403`/`503` mapping, and DTO decode for each new shape. **Decode tests must feed real
|
||||
captured JSON**, not DTOs built in Kotlin: the fakes under `data/api/fake/` construct objects
|
||||
directly, so they can never catch a wire/type mismatch — which is how the `places` shape above
|
||||
shipped past a green suite.
|
||||
- **Excluded**, in the same class as M10's exclusions: the admin *configuration* panels — Shard
|
||||
Visibility, Spawn Atlas and Cliloc import — alongside the hero/CMS block editor, Discord-bot
|
||||
config, uo-link config and OAuth-provider setup.
|
||||
|
||||
27
link/v3.md
27
link/v3.md
@@ -350,8 +350,11 @@ Sidecar — `store.rs`: singleton `ruleset(id CHECK(id=1), rev, json, updated_t)
|
||||
`main.rs`: new arm in the board-projection match; `web.rs`: `GET /ruleset` served from the store, so
|
||||
it answers during a shard outage (`PROTOCOL_2.md` §12.2).
|
||||
|
||||
Website — `uoLinkClient.getRuleset()`; `uoLinkSocket.backfill()` (object-shaped, so follow the
|
||||
`getPresence()` block's explicit form, not the array-only `snapshot()` helper); `shardIngest.js` →
|
||||
Website — `uoLinkClient.getRuleset()`; `uoLinkSocket.backfill()` (object-shaped, so it cannot use the
|
||||
array-only `snapshot()` helper — but it **must still go through `shardIngest.ingest()`**, as
|
||||
`ingestEach` does, rather than calling `shardState.setRuleset` directly: the two arrival orders have
|
||||
to produce the same stored frame, and a direct call quietly made backfill a second writer that
|
||||
skipped the normalization below); `shardIngest.js` →
|
||||
`shardState.setRuleset`, **not** in `LOGGED_KINDS` (it re-arrives every reconnect and `server.hello`
|
||||
already marks those); `KIND_FEATURE['world.ruleset'] = 'ruleset'`; `shard_ruleset` singleton table
|
||||
(`rev`, `expansion`, `payload JSON`, `t`); `GET /public/shard/ruleset` behind
|
||||
@@ -360,6 +363,17 @@ already marks those); `KIND_FEATURE['world.ruleset'] = 'ruleset'`; `shard_rulese
|
||||
Client — NEW `routes/public/Rules.jsx` at `/site/rules`, alongside
|
||||
`/site/champs|guilds|governors|houses`; live via `useShardFeed({ filter: new Set(['world.ruleset']) })`.
|
||||
|
||||
**The `shard` field falls back to the instance's own name.** ServUO ships `Server.cfg` with
|
||||
`Name=My Shard`, so an operator who never edited it publishes that verbatim — which is the shard
|
||||
saying *unnamed*, not naming anything, and the rules page then reads "My Shard" under a header
|
||||
carrying the real one. `shardIngest` substitutes `settings.getInstanceName()` (the admin-editable
|
||||
site title, else `BRAND_NAME` — the same resolution `getPublic().brand.name` uses, so one install
|
||||
never shows two names) when `shard` is absent, blank, or exactly the stock default, matched
|
||||
case-insensitively and trim-tolerantly but only as a **whole** value: a shard genuinely called
|
||||
*"My Shard Reborn"* has named itself and keeps it. Applied at **ingest**, not on read, because the
|
||||
ruleset is also broadcast live — the same object goes to the SSE fan-out, so a read-time
|
||||
substitution would be undone by the next reconnect's frame.
|
||||
|
||||
### 5.4 Risk
|
||||
|
||||
Perf is nil (~3 KB per connect). The only real risk is publishing a secret, mitigated by the explicit
|
||||
@@ -638,6 +652,15 @@ Client — NEW `routes/public/Leaderboards.jsx` at `/site/leaderboards`; a "Loya
|
||||
added to `components/CharacterSheet.jsx`, one edit serving both `PlayerCharacter.jsx` and
|
||||
`AdminCharacter.jsx`.
|
||||
|
||||
**An unscored board still renders a row.** Most systems on a young shard have `top: []`, and a page
|
||||
of blank cards reads as broken rather than as new — so a board with no entries shows a single
|
||||
placeholder bearing the **instance's own name** with an em dash where a score goes, above the
|
||||
existing "nobody has earned points here yet" line. It is deliberately **not** shaped like an entry —
|
||||
no rank, no medal, no bar, muted — because a placeholder that looked like a real standing would be a
|
||||
fabricated one; the first real entry replaces it outright. Purely presentational: the API keeps
|
||||
sending an empty `top`, so no consumer ever receives an invented row. Web and app render it the same
|
||||
way (`Leaderboards.jsx`, `LeaderboardsScreen.kt`).
|
||||
|
||||
### 7.5 What the run against a real shard changed
|
||||
|
||||
The plan above was written from reading `PointsSystem.cs`. Booting the actual shard (ServUO 57.4, a
|
||||
|
||||
Reference in New Issue
Block a user