From fbf3570812058961220f686d65802e300a163b06 Mon Sep 17 00:00:00 2001 From: phil-accelbyte <225106921+phil-accelbyte@users.noreply.github.com> Date: Tue, 23 Jun 2026 20:35:36 +0800 Subject: [PATCH] fix(shape): promote appName to priority-1 field in list tables appName is the primary identifier for CSM app operations (get, delete, start, stop, etc.) but fell through to the default priority-8 bucket, so it was excluded from the 4-column list view in favour of createdAt/updatedAt/description. Promote it to priority 1, add an explicit "App Name" label, and use it as the entity heading for single-app views. --- src/runtime/dispatch/shape.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/runtime/dispatch/shape.rs b/src/runtime/dispatch/shape.rs index 74b71cb..754b89e 100644 --- a/src/runtime/dispatch/shape.rs +++ b/src/runtime/dispatch/shape.rs @@ -33,6 +33,7 @@ pub(crate) fn normalize_label(key: &str) -> String { "emailAddress" => return "Email".to_string(), "displayName" => return "Display Name".to_string(), "userName" => return "Username".to_string(), + "appName" => return "App Name".to_string(), "namespace" => return "Namespace".to_string(), "enable" => return "Enabled".to_string(), _ => {} @@ -80,7 +81,7 @@ pub(crate) fn normalize_value(value: &Value) -> Option { fn field_priority(key: &str) -> u8 { match key { "id" | "userId" | "clientId" | "roleId" | "namespaceId" => 0, - "name" | "displayName" | "userName" | "emailAddress" => 1, + "name" | "displayName" | "userName" | "emailAddress" | "appName" => 1, "status" | "enabled" | "active" | "verified" | "emailVerified" | "banned" => 2, "namespace" | "platform" | "platformId" => 3, "createdBy" | "updatedBy" | "deletedBy" => 4, @@ -383,6 +384,7 @@ pub(crate) fn dedupe_heading_field( const HEADING_NAME_KEYS: &[&str] = &[ "displayName", "name", + "appName", "clientName", "userName", "emailAddress", @@ -764,6 +766,32 @@ mod tests { assert_eq!(table.rows[1], vec!["user-2", "—", "bob@example.com"]); } + #[test] + fn test_build_list_table_app_name_precedes_status_and_timestamps() { + let items = vec![json!({ + "appId": "app-001", + "appName": "my-service", + "appStatus": "running", + "createdAt": "2026-01-01T00:00:00Z", + "namespace": "my-game" + })]; + let table = build_list_table(&items, "App", &CommandIntent::List, false); + let app_name_pos = table + .headers + .iter() + .position(|h| h == "App Name") + .expect("App Name header present"); + let created_pos = table + .headers + .iter() + .position(|h| h == "Created") + .expect("Created header present"); + assert!( + app_name_pos < created_pos, + "appName should sort before createdAt" + ); + } + /// An array of bare scalars (the `{"regions": [...]}` shape, unwrapped) is /// rendered as a single column named after the source key, not dropped. #[test]