Skip to content

feat(accounts): name the instance an account belongs to - #158

Merged
kipavy merged 1 commit into
devfrom
feat/account-instance-marker
Aug 20, 2026
Merged

feat(accounts): name the instance an account belongs to#158
kipavy merged 1 commit into
devfrom
feat/account-instance-marker

Conversation

@kipavy

@kipavy kipavy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Every switch-target row read "Cloud", so an account on the official cloud and one on a self-hosted instance were indistinguishable — same email, same icon, same sublabel. SavedAccount already carried server_url; only the design was missing.

The rule

Mark only what is not the default, in slots that already exist. No new row, no new line, no extra width. An official-cloud account is byte-for-byte unchanged.

Surface Official cloud Self-hosted
Switch row circle-user + "Cloud" lucide:server + stackdome.example.tld, full URL in the hover title
Account header circle-user + "Cloud account" lucide:server + the host
Auth server field collapsed, "Custom server URL" open, "Server: <host>"

Considered and rejected: the hostname on every row (pushes a URL at people who only ever use one instance), an icon swap with no text (two self-hosted instances stay ambiguous), and user-assigned nicknames (a whole editing surface; deliberately deferred).

How the label is derived

src/utils/serverInstance.ts — hostname, a leading api./www. dropped only when the rest still contains a dot, a non-default port kept because it is what distinguishes two instances on one host. Anything absent or unparseable counts as the default: better unmarked than mislabelled.

server_url Label
https://api.voltius.app "Cloud" — never marked
https://stackdome.example.tld stackdome.example.tld
https://api.stackdome.example.tld stackdome.example.tld
http://192.168.1.40:8443 192.168.1.40:8443
https://api.local api.local — stripping would leave a bare name
null / unparseable "Cloud"

The auth screen, and why it needed a device-scoped record

"Add another account…" landed on the auth screen with the server field collapsed and reset to https://api.voltius.app, so aiming at a self-hosted instance was one un-clicked disclosure away from silently registering on the official cloud.

Auto-expanding on a non-default value is not reachable on its own: adding an account clears server_url along with every other ACCOUNT_CACHE_KEYS entry, so the screen has nothing non-default to open on. The field now seeds from voltius.last-server-url — device-scoped localStorage, written on a successful sign-in, surviving teardown because clearPersistedAccountUiState removes only its explicit key list.

Duplications collapsed on the way

  • DEFAULT_SERVER lived in both AuthPage.tsx and CloudAuthModal.tsx, as did the disclosure block. Both now use ServerUrlField; the screens disagreed only about input styling, which is one inputClassName prop.
  • Four routes into a server session — register, login re-auth, signInToCloud, linkToCloud — each wrote the same keychain list by hand. persistServerSession is now the single place that writes it, and the single place that records the instance, which a fifth route would otherwise forget.

Testing

Suite 3758/3758 across 483 files; tsc --noEmit exit 0. New: 14 tests for the label rules and the remembered instance, 3 for ServerUrlField, 4 in SidebarAccountButton.switcher.test.tsx (two accounts sharing an email on different instances, the server icon and title, and both header cases), 2 in account.serverAuth.test.ts (a successful registration remembers the instance, a failed one leaves it alone).

⚠️ Not live-clicked. Unit tests only — proving the two-instance case end to end needs a real self-hosted server.

Every switch-target row read "Cloud", so an account on the official
cloud and one on a self-hosted instance were indistinguishable — same
email, same icon, same sublabel. The data was already there:
SavedAccount carries server_url.

Only a non-default instance is marked, in slots that already exist: the
row's icon becomes lucide:server and its sublabel the host, with the
full URL in the hover title. An official-cloud row is unchanged. The
account header does the same for the account you are on.

The auth screen collapsed its server field and reset it to the official
cloud, so "Add another account…" aimed a self-hosted user back at
api.voltius.app without ever showing which instance they were on. The
field now seeds from the instance this machine last signed in to — kept
device-scoped, because adding an account clears server_url along with
every other account-scoped key — and opens, naming the host, whenever
that is not the official cloud.

Two duplications collapsed on the way: DEFAULT_SERVER lived in both
auth screens, and four routes into a server session each wrote the same
keychain list by hand. persistServerSession is now the single place
that records the instance, which a fifth route would have forgotten.
@kipavy
kipavy merged commit 4d4e1d0 into dev Aug 20, 2026
4 checks passed
@kipavy
kipavy deleted the feat/account-instance-marker branch August 20, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant