Repository navigation
feat: detect the API version of the server and what the API key may do - #343
Merged
2 commits merged intoNov 13, 2026
Merged
2 commits merged into
2 commits merged into
Conversation
Two small queries (GetApiVersion, GetKeyAccess) tell NOVA which Unraid API version the active server runs and which roles and permissions its API key holds. The result is kept in memory as ServerCapabilities and exposed as MainViewModel.capabilities; nothing reads it yet, so there is no visible change. Detection runs when the server, its address or the key changes, on pull-to-refresh, and when the app returns to the foreground. There is no timer, no retry loop and no polling. Unknown is never denied: a failed detection, a refused `me` and a role NOVA does not know leave the access unknown, so controls stay as they are today. Only a successful answer can say "denied". The model, the role table, the classification of server answers and the repository wiring have unit tests built on the real response bodies of an Unraid 7.4.0 server. ADR-0047 records the decision. Refs #315, #247, #317, #316 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Refresh the capabilities on every ON_START so a fresh MainViewModel after a finished activity re-detects (the repository joins a running detection, so the first start does not probe twice). Correct the schema comment about unknown enum values (UNKNOWN__, no raw name) and the CapabilityProbeTest KDoc about which bodies are recorded and which are constructed. ADR-0047 follows. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
nofuturekid
force-pushed
the
feat/server-capabilities-foundation
branch
from
November 13, 2026 17:36
4a368b8 to
6aec2a0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
NOVA now knows which Unraid API version the active server runs and which roles and permissions its API key holds. This is the foundation for hiding controls a read-only key cannot use (#315), the "API too old" hint (#247), the one-step container restart (#317) and the key-permission documentation (#316). Nothing reads it yet, so there is no visible change.
ServerCapabilitiesand its small types (ApiVersion,ApiFeature,KeyAction,Access,Support,KeyAccess,Detection) indata/model/ServerCapabilities.kt, pure Kotlin.access(KeyAction)uses the static role table of the Unraid API plus the key's explicit permissions;supports(ApiFeature)compares against the floors 4.30.0, 4.35.0 and 4.36.0 (a build suffix such as+8e587fe2is ignored).queries.graphql,GetApiVersionandGetKeyAccess, and the matching additions to the clientschema.graphqls. They are separate becausemeis non-null: aFORBIDDENon it would otherwise lose the version too.CapabilityProbe.ktsends them and classifies the answers byextensions.code:UNAUTHENTICATEDis a rejected key, a validation failure on the version means an API older than 4.15.0,FORBIDDENleaves the access unknown, transport and other errors are a failed detection. The mapping lives in its own file;GraphQlMapper.ktis untouched.CapabilityRepository(a singleton built likeUpdateTracker) holds the result in memory andMainViewModel.capabilitiesexposes it. Detection runs only when the server, its address or the key changes, on pull-to-refresh, and when the app returns to the foreground. No timer, no retry loop, no polling.Unknown is never denied: a failed detection, a refused
meand a role NOVA does not know leave the access unknown, so controls behave as today. A failed re-detection keeps the last good result for the same target, a new target starts unknown, and a late answer for an old target is dropped.Tests
Unit tests encode why: a read-only key is denied every control, ADMIN is allowed everything, explicit permissions add to a role,
*_OWNdoes not count, an unknown role stays unknown, every mutation inmutations.graphqlbelongs to exactly oneKeyAction, version parsing and the floors, each server answer class (bodies taken from a real Unraid 7.4.0 server), and in the repository: no re-probe for a rename, joining a running detection, no probe without a trigger after an hour of virtual time, no retry after a failure.Smoke check (read-only, VIEWER key, real server on Unraid 7.4.0): both operations answer HTTP 200 with the shapes the tests use (
info.versions.core.{unraid,api}andme.{roles,permissions}), noerrors.Deliberately left out
Hiding controls and the "View only" note, per-tab error reasons, the restart mutation, the Add server Test, documentation of key permissions, version bump and CHANGELOG (nothing user-visible changes). DockerTab, VmsTab, ArrayTab, the Overview, the update code,
GraphQlMapper.kt,SettingsStore.ktand.github/are not touched.Two small deviations from the written design (see ADR-0047)
setAppVisible(true)); it joins a detection that is already running, so the first start does not probe twice.Refs #315
Refs #247
Refs #317
Refs #316
🤖 Generated with Claude Code