refactor(client): delete the UO client half (phase 3, slice 3) #139
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/module-extract-client"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 3, slice 3 of
docs/website/MODULE_SYSTEM.md§2.7.1 — core's half. Pairs with Module-uo#4, which must merge first, and docs#138.35 files / 5,332 lines out, plus the three additions core owed before they could leave.
MODULE_API_VERSION1.2.0 → 1.3.0.The three additions (commit 1)
player.invite.accepted, a third extension slot. Core's invite page owned a UO game-account step — it read agameAccountSignupflag out of core's own settings and posted to a shard route — and an invite is a core concept staff receive too, so the page stays and its optional next step becomes a slot. Whether there is a step at all is the module's call; core keeps the shell, the skip control and the destination.iconon a nav item. Without it the six extracted rows would have been the only text-only entries in a sidebar where every other row has a glyph. Core supplies no fallback — an invented one is core making a presentation choice for content it knows nothing about.iconwas already among the fields an override may not touch, so the concept predates a module being able to send one.api.BASE, which §3.5 specified from the first draft andshared.jsnever published.requestis fetch-only, so an EventSource builds its own URL, and the shard's live feed is two of them; the alternative is a module hardcoding/api/v1.AcceptInviteis the only core caller ofextensionForoutsideSlot.jsx, and legitimately: the answer decides a navigation, not a decoration. Decoration goes inside<Slot wrap>— that is the footer-separator bug from slice 2, andhasExtensionstays deleted.The deletion (commit 2)
Nine rows leave the public header and six leave the admin sidebar; both lists are now free of
featuregates and ofIconShard.moduleTitlealready handled a module page's heading, so the TITLES entries and thesectionTitlebranch simply go./playerhadPlayerCharactersas its index — a UO page. Rather than name a replacement or invent a landing screen, it resolves to the first row of the base player nav this viewer can reach (firstDestinationFor, besideallowedPathsFor). With the module installed that is still Characters, so a player's first screen after signing in does not change. From the BASE nav, never the override-merged one: an override is presentation, and where everybody lands is behaviour.It is deliberately generic and deliberately not in the portal layout. The admin index is the same question with a hardcoded answer, and the direction of travel is one logged-in area that shows the right things for the viewer's permissions — this is the function that serves both, ready when that happens and nothing to unwind if it does.
game_account_signupgoes with the rest of core's UO prose: the mode list, the derived public flag, the validation, and a Site Settings field whose help text named Bridge.cfg. The row itself is untouched and module-uo reads it throughctx.settings— the data stays, the semantics move.Two fixes the browser smoke produced (commit 3)
PlayerPortalLayoutrendered<n.icon />unguarded whereAdminLayoutguarded its equivalent. Correct for as long as every row there was core's own and had an icon; React error #130 and a blank player portal the moment a module registered one without.MODULES_DIRis resolved absolute.resolveClientchecks containment by comparing an absolutepath.resolve(dir, entry)against the module directory, so a relativeMODULES_DIR— which §7.7's own recipe produces when run fromserver/— failed every module with "client.entry escapes the module directory", pointing at the module for core's problem.Verification
firstDestinationFor, +2 nav icon)routes.manifest.json158 public + 2 internal, unchanged;routes.guards.jsonunchangedswagger-output.jsonloses exactly one property, and only because it was hand-written inswagger.js— regeneration alone would have left the spec documenting a field core no longer returns/uo/*, the interleaved nav in all three areas, all three slots filled,/player→/player/uo/characters, the invite flow end to end, and the SSE feed connected (which isapi.BASEworking)One thing the smoke made concrete, worth reading before merge: decision 9 (clean break, no nav-override migration) costs more than "a hidden row may reappear". The review instance had the nine UO rows gathered into a dropdown section; those override keys now match nothing, the section is empty, and the rows render flat across two lines of the header. An operator's ordering, labels, hidden state and grouping of the UO rows are lost and must be redone.
AI disclosure
Written with Claude Code.
Co-Authored-By: Claude noreply@anthropic.com