Web App (Future)¶
This document also describes a planned, not-yet-built capability - see decisions/0006-optional-web-architecture.md for why no Gradle module exists for it today.
Core Requirement: the Core Runs Fully Without the Web¶
The web app is optional and additive, not a prerequisite. A server operator
who only uses the in-game GUI/commands never installs a web-server part.
That's already structurally enforced: nothing in dev.universaladmin.core,
.module, .action, .storage, etc. has a dependency pointing toward
"web" - the dependency only points the other way (a future web layer
depends on the core, not the reverse).
Same Services, Same Actions¶
The web app is meant to call the same application services and Actions as
the GUI and commands - no separate "web business logic" path. That's why
Actor/ActorType already has a WEB case (see actions.md)
and why GUI click handlers may not contain logic (see gui.md):
any logic stuck only in a click handler would have to be rewritten for the
web app.
Planned Building Blocks (Not Built)¶
universaladmin-webGradle module - separate process or embedded server (decision open), depends onuniversaladmin-api(see extensions.md), not directly on core internals.- REST API over the same actions/services.
- WebSockets/live updates for dashboard widgets and live views (e.g. online players, performance graphs).
- Web authentication, separate from the Minecraft account (a server admin doesn't necessarily have a Minecraft account for web access) - mechanism open.
- Dashboard widgets as their own extension point (see extensions.md), so extensions can contribute their own web views without changing the core web code.
What This Means for Today's Code¶
- No service/action may accept anything that only exists in an in-game
context (e.g. requiring an
org.bukkit.entity.Playerdirectly as a parameter where aUUID/anActorwould do) - that would later force the web app to build a fakePlayer. SeeAction/Actorin actions.md for the existing pattern. MessageService/MessageKeyalready exist separate from the GUI, so the same translations can later be reused by a web view. Concretely:MessageService.get(key, args...)returns a plain, parameter-substitutedString(may still contain MiniMessage markup like<red>, but never an AdventureComponentinstance). The in-game layer converts that into aComponentviadev.universaladmin.localization.ComponentMessages; a web view would instead translate the same string into HTML/CSS (MiniMessage tags → CSS classes or similar) - its own, not-yet-existing renderer, not part ofMessageServiceitself. See docs/development/settings.md.