From 6da385425e4cd3c8f9699b5fd10d4803204fffff Mon Sep 17 00:00:00 2001 From: wtclaude Date: Mon, 24 Aug 2026 11:22:45 -0500 Subject: [PATCH] fix(handoff): print the shard screen's real path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The end-of-run block told operators to paste the four values at `/admin/shard`. That page moved when the shard screens became part of the `uo` module: a module owns one path segment wherever it appears (website `MODULE_SYSTEM.md` §2.8), so it is `/admin/uo/link`, labelled "Shard (uo-link)". The old path is worse than a 404. The SPA has no route for it, so it sends the operator to the dashboard — the link looks like it worked, and the values they were told to paste have nowhere to go. - The path is now a named constant, `ADMIN_SHARD_PATH`, carrying why it is not the obvious string and the fact that API routes are NOT affected by the module namespacing rule (they keep `/api/v1/admin/shard/*`). - Both handoff tests assert the new path, so this cannot regress quietly. - The two user-facing labels that name the screen — the `--site-url` help text and `update`'s protocol-change instruction — say "Admin → Shard (uo-link)", matching what the sidebar actually reads. Found while writing the runicgateway.com installation journey, by pasting the printed link into a real deployment and landing on the dashboard. Co-Authored-By: Claude --- src/cli.rs | 4 ++-- src/sidecar.rs | 24 ++++++++++++++++++++---- src/update.rs | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 518e39c..7e9cc48 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -77,7 +77,7 @@ pub struct Cli { pub patches_unsupported_servuo: bool, /// `--host `: the hostname to print in the website URLs. pub host: Option, - /// `--site-url `: the site's base URL, for the Admin → Shard link. + /// `--site-url `: the site's base URL, for the Admin → Shard (uo-link) link. pub site_url: Option, /// `--yes`: assume the default answer to every prompt. pub assume_yes: bool, @@ -137,7 +137,7 @@ Options: --host install. The hostname to print in the website URLs. --site-url install. Your site's base URL, for the - Admin → Shard link. + Admin → Shard (uo-link) link. --yes Assume the default answer to every prompt. On uninstall it means yes: that prompt defaults to no, and typing `uninstall diff --git a/src/sidecar.rs b/src/sidecar.rs index 61b5831..afa0151 100644 --- a/src/sidecar.rs +++ b/src/sidecar.rs @@ -294,6 +294,18 @@ fn port_of(bind: &str) -> &str { } } +/// Where the shard settings live in the website's admin panel. +/// +/// NOT `/admin/shard`, which is what this printed until 2026-08-24 and what an operator who ran +/// an older build still has in their scrollback. Those screens belong to the `uo` MODULE now, and +/// a module owns one path segment wherever it appears (website `MODULE_SYSTEM.md` §2.8), so the +/// page moved. The old path does not 404 — the SPA sends it to the dashboard, which is the worst +/// way for a link in a handoff to be wrong, because it looks like it worked. +/// +/// API routes are NOT affected by that rule and keep `/api/v1/admin/shard/*`. This is the SPA URL +/// a person types. +const ADMIN_SHARD_PATH: &str = "/admin/uo/link"; + /// The end-of-run block from PLAN.md §6 — the one manual step the installer cannot do. /// /// Returned as a string rather than printed so it can be tested, and so the caller decides where it @@ -312,12 +324,13 @@ pub fn handoff(doc: &ConfigDoc, host: &str, site_url: Option<&str>) -> String { Protocol version {protocol}\n \ Auth token {token}\n \ (also in {config})\n\n\ - Paste these into Admin → Shard on your Runic Gateway site:\n \ - {site}/admin/shard\n\n\ + Paste these into Admin → Shard (uo-link) on your Runic Gateway site:\n \ + {site}{admin_path}\n\n\ The token is write-only once saved — the site will never show it back to you.\n", protocol = doc.protocol, token = doc.web.auth_token, config = doc.config_path, + admin_path = ADMIN_SHARD_PATH, ) } @@ -401,7 +414,7 @@ mod tests { assert!(block.contains(&doc.web.auth_token), "{block}"); // The trailing slash on the site URL must not produce a double slash in the link. assert!( - block.contains("https://my-site.example/admin/shard"), + block.contains("https://my-site.example/admin/uo/link"), "{block}" ); assert!(block.contains("/etc/runicgateway/sidecar.toml"), "{block}"); @@ -412,7 +425,10 @@ mod tests { // An unattended run has nobody to ask, and the token is far too useful to withhold over a // link the operator does not need. let block = handoff(&doc(), "shard", None); - assert!(block.contains("https:///admin/shard"), "{block}"); + assert!( + block.contains("https:///admin/uo/link"), + "{block}" + ); assert!(block.contains("4f9c"), "{block}"); } diff --git a/src/update.rs b/src/update.rs index 3394604..c494701 100644 --- a/src/update.rs +++ b/src/update.rs @@ -81,7 +81,7 @@ pub fn closing(prior: Option<&InstallRecord>, bundle: &Bundle, now: &InstallReco println!(); ui::warn(&format!( "The protocol version changed: {} → {}.\n \ - Update the Protocol version field in Admin → Shard on your website. Nothing else \ + Update the Protocol version field in Admin → Shard (uo-link) on your website. Nothing else \ changed —\n the URLs and the auth token are the same, and the sidecar answers a \ website still set to\n {} with 409 rather than mis-parsing it.", previous_protocol.unwrap_or(bundle.protocol), -- 2.49.1