# Cameleer Web UI - UX Audit Findings

**Date:** 2026-04-09
**URL:** https://desktop-fb5vgj9.siegeln.internal/server/
**Build:** 69dcce2
**Auditor:** Claude (automated browser audit)

---

## 1. Exchange Detail (Split View)

**Screenshots:** `04-exchange-detail-ok.png`, `05-exchange-detail-err.png`, `27-exchange-err-error-tab.png`

### What Works Well
- Split view layout (50/50) is clean and efficient -- table on left, detail on right
- Processor timeline visualization is excellent -- clear step sequence with color-coded status (green OK, red/amber error)
- Exchange detail tabs (Info, Headers, Input, Output, Error, Config, Timeline, Log) are comprehensive
- Error tab shows full Java stack trace with Copy button and exception message prominently displayed
- ERR rows in table have clear red status badge with icon
- Correlated exchanges section present (even when none found)
- JSON download button available on the detail view

### Issues Found

**Important:**
- **Exchange ID is raw hex, hard to scan.** The IDs like `96E395B0088AA6D-000000000001ED46` are 33+ characters wide. They push the table columns apart and are hard for humans to parse. Consider truncating with copy-on-click or showing a short hash.
- **Attributes column always shows "--".** Every single exchange row displays "--" in the Attributes column. If no attributes are captured, this column wastes horizontal space. Consider hiding it when empty or showing it only when relevant data exists.
- **Status shows "OK" but detail shows "COMPLETED".** The table status column shows "OK" / "ERR" but the detail panel shows "COMPLETED" / "FAILED". This terminology mismatch is confusing -- pick one convention.

**Nice-to-have:**
- **No breadcrumb update when exchange selected.** The breadcrumb still shows "All Applications" even when viewing a specific exchange detail. Should show: All Applications > sample-app > Exchange 96E39...
- **No action buttons on exchange detail.** No "Replay", "Trace", or "View Route" buttons in the detail view. Users would benefit from contextual actions.
- **Back navigation relies on de-selecting the row.** There is no explicit "Close" or "Back" button on the detail panel.

---

## 2. Dashboard Tab

**Screenshots:** `07-dashboard-full.png`, `08-dashboard-drilldown.png`

### What Works Well
- KPI strip is clean and scannable: Throughput (7/s), Success Rate (98.0%), P99 Latency (6695ms), SLA Compliance (38.0%), Active Errors (3)
- L1 (applications) -> L2 (routes) drill-down works via table row click
- L2 view shows comprehensive route performance table with throughput, success %, avg/P99, SLA %, sparkline
- Top Errors table with error velocity and "last seen" is very useful
- Charts: Throughput by Application, Error Rate, Volume vs SLA Compliance, 7-Day Pattern heatmap
- Color coding is consistent (amber for primary metrics, red for errors)
- Auto-refresh indicator shows "Auto-refresh: 30s"

### Issues Found

**Important:**
- **Application Health table row click is blocked by overlapping elements.** Playwright detected `_tableSection` and `_chartGrid` divs intercepting pointer events on the table row. While JavaScript `.click()` works, this means CSS `pointer-events` or `z-index` is wrong -- real mouse clicks may be unreliable depending on scroll position.
- **SLA Compliance 0.0% shows "BREACH" label** in L2 view but no explanation of what the SLA threshold is until you look closely at the latency chart. The SLA threshold (300ms) should be shown next to the KPI, not just in the chart.
- **7-Day Pattern heatmap is flat/empty.** The heatmap shows data only for the current day, making it look broken for a fresh deployment. Consider showing "Insufficient data" when less than 2 days of data exist.
- **"Application Volume vs SLA Compliance" bubble chart** truncates long application names (e.g., "complex-fulfil..." in L2). The chart has limited space for labels.

**Nice-to-have:**
- **No trend arrows on KPI values in L2.** The L1 dashboard shows up/down arrows (all "up"), but L2 KPIs show percentage change text instead. The two levels should be consistent.
- **P99 latency 6695ms is not formatted as seconds.** Values over 1000ms should display as "6.7s" for readability. The L2 view uses raw milliseconds (1345ms) which is also inconsistent with the L1 (6695ms) and the exchange list which does format durations.
- **Throughput numbers use locale-specific formatting.** In the route table: `1.050` (German locale?) vs `14.377` -- these look like decimal numbers rather than thousands. Consider using explicit thousands separator or always using K suffix.

---

## 3. Runtime Tab

**Screenshots:** `09-runtime-tab.png`, `09-runtime-full.png`, `10-runtime-agent-detail.png`, `24-runtime-agent-detail-full.png`

### What Works Well
- KPI strip: Total Agents (3), Applications (1), Active Routes (30/0), Total TPS (4.8), Dead (0) -- clear at a glance
- Agent state indicators are clear: green "LIVE" badges, "3/3 LIVE" summary
- Instance table shows key metrics: State, Uptime, TPS, Errors, Heartbeat
- Clicking an agent row navigates to a rich detail view with 6 charts (CPU, Memory, Throughput, Error Rate, Thread Count, GC Pauses)
- Agent capabilities displayed as badges (LOGFORWARDING, DIAGRAMS, TRACING, METRICS)
- Application Log viewer with level filtering (Error/Warn/Info/Debug/Trace) and auto-scroll
- Timeline shows agent events (CONFIG_APPLIED, COMMAND_SUCCESS) with relative timestamps

### Issues Found

**Critical:**
- **GC Pauses chart X-axis is unreadable.** The chart renders ~60 full ISO-8601 timestamps (`2026-04-09T14:16:00Z` through `2026-04-09T15:15:00Z`) as X-axis labels. These overlap completely and form an unreadable block of text. All other charts use concise numeric labels (e.g., "12", "24"). The GC Pauses chart should use the same time formatting.

**Important:**
- **Agent state shows "UNKNOWN" alongside "LIVE".** The detail view shows both "LIVE" and "UNKNOWN" state indicators. The "UNKNOWN" appears to be a secondary state field (perhaps container state?) but it is confusing to show two conflicting states without explanation.
- **Memory chart shows absolute MB values but no percentage on Y-axis.** The KPI shows "46% / 57 MB / 124 MB" which is great, but the chart Y-axis goes from 0-68 MB which doesn't match the 124 MB limit. The max heap should be indicated on the chart (e.g., as a reference line).
- **Throughput chart Y-axis scale is wildly mismatched.** The KPI shows 2.0 msg/s but the Y-axis goes to 1.2k msg/s, making the actual data appear as a flat line near zero. The Y-axis should auto-scale to the actual data range.
- **Error Rate chart Y-axis shows "err/h"** but the unit inconsistency with the KPI (which shows percentage "1.7%") is confusing.

**Nice-to-have:**
- **"DEAD 0" KPI in the overview is redundant** when "all healthy" text is already shown below it. Consider combining or removing the redundant label.
- **Application Log shows "0 entries"** in the overview but "100 entries" in the agent detail. The overview log may not aggregate across agents, which is misleading.

---

## 4. Deployments Tab

**Screenshots:** `12-deployments-list.png`, `25-app-detail.png`, `11-deployments-tab.png`

### What Works Well
- App list is clean: Name, Environment (with colored badges DEFAULT/DEVELOPMENT), Updated, Created columns
- App detail page shows configuration tabs: Monitoring, Resources, Variables, Traces & Taps, Route Recording
- Read-only mode with explicit "Edit" button prevents accidental changes
- "Upload JAR" and "Delete App" action buttons are visible
- Create Application form (`/apps/new`) is comprehensive with Identity & Artifact section, deploy toggle, and monitoring sub-tabs

### Issues Found

**Important:**
- **Navigating to `/server/apps` redirected to `/server/apps/new`** on the initial visit, bypassing the apps list. This happened once but not consistently. The default route for the Deployments tab should always be the list view, not the create form.
- **No deployment status/progress visible in the list.** The apps list shows "RUNNING" status only in the detail view. The list should show the deployment status directly (RUNNING/STOPPED/FAILED badge per row).
- **"Updated: 59m ago" is relative time** which becomes stale if the page is left open. Consider showing absolute timestamp on hover.

**Nice-to-have:**
- **Configuration form select dropdowns** (Engine Level, Payload Capture, App Log Level, etc.) all use native HTML selects with a custom `"triangle"` indicator -- this is inconsistent with the design system's `Select` component used elsewhere.
- **"External URL" field shows `/default/.../`** placeholder which is cryptic. Should show the full resolved URL or explain the pattern.

---

## 5. Command Palette (Ctrl+K)

**Screenshots:** `14-command-palette.png`, `15-command-palette-search.png`, `16-command-palette-keyboard.png`

### What Works Well
- Opens instantly with Ctrl+K
- Shows categorized results: All (24), Applications (1), Exchanges (10), Routes (10), Agents (3)
- Search is fast and filters results in real-time (typed "error" -> filtered to 11 results)
- Search term highlighting (yellow background on matched text)
- Keyboard navigation works (ArrowDown moves selection)
- Rich result items: exchange IDs with status, routes with app name and exchange count, applications with agent count
- Escape closes the palette
- Category tabs allow filtering by type

### Issues Found

**Nice-to-have:**
- **Exchange IDs in search results are full hex strings.** The same issue as the exchanges table -- `5EF55FC31352A9A-000000000001F07C` is hard to scan. Show a shorter preview.
- **No keyboard shortcut hints in results.** Results don't show "Enter to open" or "Tab to switch category" -- users must discover these by trial.
- **Category counts don't update when filtering.** When I typed "error", the category tabs still show the original counts (Applications, Exchanges 10, Routes 1, Agents) but some categories become empty. The empty categories should hide or dim.

---

## 6. Dark Mode

**Screenshots:** `17-dark-mode-exchanges.png`, `18-dark-mode-dashboard.png`, `19-dark-mode-runtime.png`

### What Works Well
- Dark mode applies cleanly across all pages
- Table rows have good contrast (light text on dark background)
- Status badges (OK green, ERR red) remain clearly visible
- Chart lines and data points are visible against dark backgrounds
- KPI cards have distinct dark card backgrounds with readable text
- The dark mode toggle is easy to find (moon icon in header)
- Theme preference persists in localStorage (`cameleer-theme`)

### Issues Found

**Important:**
- **Chart backgrounds appear as opaque dark cards but chart lines may be harder to see.** The throughput and error rate charts use amber/orange lines on dark gray backgrounds -- this is acceptable but not ideal. Consider slightly brighter chart colors in dark mode.
- **Application Volume vs SLA chart** in dashboard: the bubble/bar labels may have low contrast in dark mode (hard to verify at screenshot resolution).

**Nice-to-have:**
- **Sidebar border/separator** between the sidebar and main content area is very subtle in dark mode. A slightly more visible divider would help.
- **Environment badges** (DEFAULT in gold, DEVELOPMENT in orange) are designed for light mode and may look less distinct against the dark background.

---

## 7. Cross-Cutting Interaction Issues

### Status Filter Buttons (OK/Warn/Error/Running)

**Screenshots:** `03-exchanges-error-filtered.png`

**Important:**
- **Error filter works correctly** -- clicking the Error button filters to show only ERR exchanges (447 in the test). The button shows active/pressed state.
- **Filter state is not preserved in URL.** Navigating away and back loses the filter. Consider encoding active filters in the URL query string.
- **KPI strip does not update when filter is active.** When Error filter is active, the KPI strip still shows overall stats (Total 23.4K, Err% 1.9%). It should either update to show filtered stats or clearly indicate it shows overall stats.

### Column Sorting

**Screenshot:** `23-sorting-route.png`

- Sorting works correctly (Route column sorted alphabetically, "audit-log" rows grouped)
- Sort indicator arrow is visible on the column header
- **Sorting is client-side only (within the 50-row page).** With 23K+ exchanges, sorting only the visible page is misleading. Consider either fetching sorted data from the server or clearly labeling "sorted within current page."

### Pagination

- Pagination works: "1-25 of 50", page 1/2, rows per page selector (10/25/50/100)
- Next/Previous page buttons work
- **"50 of 23,485 exchanges" label is confusing.** The "50" refers to the server-side limit (max fetched), not the page size (25). This should read "Showing 1-25 of 23,485" or similar.

### Sidebar App Tree

**Screenshot:** `20-sidebar-expanded.png`

- Expand/collapse works for "sample app"
- Shows all 10 routes with exchange counts (audit-log 5.3k, file-processing 114.2k, etc.)
- Exchange counts use K-suffix formatting which is good
- **Add to starred button is present** (star icon on the app)

### Environment Selector

- Dropdown works: All Envs / default / development
- Switching environment correctly filters data (65K -> 3.5K exchanges)
- Selection persists in localStorage

### Time Range Pills

**Screenshot:** `21-time-range-3h.png`

- Time range pills work (1h, 3h, 6h, Today, 24h, 7d)
- Switching updates data and KPI strip correctly
- Custom date range is shown: "9. Apr. 16:14 -- now" with clickable start/end timestamps
- **Date formatting uses European style** ("9. Apr. 16:14") which is fine but inconsistent with ISO timestamps elsewhere.

---

## 8. Systematic Navigation Bug

**Critical:**

During the audit, the browser consistently auto-redirected from any page to `/server/admin/rbac` (Users & Roles) after interactions involving the Playwright accessibility snapshot tool. This happened:
- After taking snapshots of the exchanges page
- After clicking exchange detail rows
- After interacting with filter buttons
- After attempting to click table rows

The redirect does **not** happen when using only JavaScript-based interactions (`page.evaluate`) without the Playwright snapshot/click methods. The root cause appears to be that the Playwright MCP accessibility snapshot tool triggers focus/click events on sidebar items (specifically "Users & Roles"), causing unintended navigation.

**While this is likely a tool interaction artifact rather than a real user-facing bug**, it reveals that:
1. The sidebar tree items may have overly aggressive focus/activation behavior (activating on focus rather than explicit click)
2. There may be no route guard preventing unexpected navigation when the user hasn't explicitly clicked a sidebar item

Recommend investigating whether keyboard focus on sidebar tree items triggers navigation (it should require Enter/click, not just focus).

---

## Summary of Issues by Severity

### Critical (1)
1. **GC Pauses chart X-axis renders ~60 full ISO timestamps** -- completely unreadable (Runtime > Agent Detail)

### Important (10)
1. **Exchange ID columns are too wide** -- 33-char hex strings push table layout (Exchanges)
2. **Attributes column always shows "--"** -- wastes space (Exchanges)
3. **Status terminology mismatch** -- "OK/ERR" in table vs "COMPLETED/FAILED" in detail (Exchange Detail)
4. **Dashboard table row clicks intercepted by overlapping divs** -- z-index/pointer-events issue (Dashboard)
5. **SLA threshold not shown on KPI** -- have to find it in the chart (Dashboard L2)
6. **Agent state shows "UNKNOWN" alongside "LIVE"** -- confusing dual state (Runtime Agent Detail)
7. **Throughput chart Y-axis scale mismatch** -- 2 msg/s data on 1.2k scale, appears flat (Runtime Agent Detail)
8. **Error Rate chart unit mismatch** -- "err/h" on chart vs "%" on KPI (Runtime Agent Detail)
9. **Filter state not preserved in URL** (Exchanges)
10. **"50 of 23,485 exchanges" pagination label is confusing** (Exchanges)

### Nice-to-have (12)
1. No breadcrumb update when exchange selected
2. No action buttons (Replay/Trace) on exchange detail
3. No explicit Close/Back button on detail panel
4. P99 latency not formatted as seconds when >1000ms
5. Throughput numbers use locale-specific decimal formatting
6. 7-Day Pattern heatmap appears empty with limited data
7. Exchange IDs in command palette are full hex strings
8. No keyboard shortcut hints in command palette results
9. Sidebar border subtle in dark mode
10. Deployment list doesn't show status badges
11. "Updated: 59m ago" relative time goes stale
12. Category counts in command palette don't update when filtering
