fix(web): make plural /automations/:id the canonical detail route

The list card linked to the singular /automation/:id, which mismatched
the rest of the new automations CRUD surface (/automations,
/automations/new, /automations/:id/edit). Switch the card link and the
slug-preview text on the create form to the plural form, and mount
/automations/:id in the router alongside the existing singular route
(kept as a back-compat alias for any older bookmarks).

Drive-by: fold two adjacent `use super::*` imports into one and reflow
a long `if let` line in the automations handler (linter cleanup; no
behavior change).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-05-29 08:47:31 -04:00
parent 737dd75149
commit fee245d788
No known key found for this signature in database
4 changed files with 6 additions and 7 deletions

View file

@ -161,7 +161,7 @@ export function AutomationFormFields({
) : (
<>
Identifier used in the URL:{" "}
<span className="font-mono text-fg-2">/automation/{values.id || "<slug>"}</span>
<span className="font-mono text-fg-2">/automations/{values.id || "<slug>"}</span>
</>
)
}

View file

@ -113,6 +113,8 @@ export const routes: RouteObject[] = [
route("automations", Automations),
route("automations/new", AutomationsNew),
route("automations/:id/edit", AutomationsEdit),
route("automations/:id", AutomationDetail),
// Backwards-compatible singular automation route used by older links.
route("automation/:id", AutomationDetail),
route("runs", Runs),
route("runs/:id", RunDetail, {

View file

@ -119,7 +119,7 @@ function AutomationCard({
const Icon = automation.icon;
return (
<div className="group flex items-center gap-4 rounded-md border border-line bg-panel/80 p-4 transition-all duration-200 hover:border-line-strong hover:bg-panel hover:shadow-lg hover:shadow-black/20">
<Link to={`/automation/${automation.id}`} className="flex min-w-0 flex-1 items-center gap-4">
<Link to={`/automations/${automation.id}`} className="flex min-w-0 flex-1 items-center gap-4">
<div
className="flex size-9 shrink-0 items-center justify-center rounded-md border bg-panel-alt/60"
style={{ borderColor: `color-mix(in srgb, ${automation.color} 20%, transparent)`, color: automation.color }}

View file

@ -15,8 +15,7 @@ use super::super::{
ApiError, AppState, IntoResponse, Json, PaginationParams, Path, RequiredUser, Response, Router,
State, StatusCode, get, paginate_items,
};
use super::lifecycle;
use super::runs;
use super::{lifecycle, runs};
use crate::automation_materializer::AutomationRunMaterializeInput;
use crate::principal_middleware::RequiredRunToolActor;
@ -186,9 +185,7 @@ async fn create_automation_run(
// the run sits in `Submitted` forever because the scheduler only claims
// `Runnable`. Mirror what the UI does for a manual create-then-start flow.
if response.status().is_success() {
if let Err(err) =
lifecycle::queue_run_start(state.as_ref(), run_id, false, actor).await
{
if let Err(err) = lifecycle::queue_run_start(state.as_ref(), run_id, false, actor).await {
tracing::warn!(
%run_id,
automation_id = %automation.id,