refactor: rename group/groupName to application/applicationName
The execution-related "group" concept actually represents the
application name. Rename all Java fields, API parameters, and frontend
types from groupName→applicationName and group→application for clarity.
- Java records: ExecutionSummary, ExecutionDetail, ExecutionDocument,
ExecutionRecord, ProcessorRecord
- API params: SearchRequest.group→application, SearchController
@RequestParam group→application
- Services: IngestionService, DetailService, SearchIndexer, StatsStore
- Frontend: schema.d.ts, Dashboard, ExchangeDetail, RouteDetail,
executions query hooks
Database column names (group_name) and OpenSearch field names are
unchanged — only the API-facing Java/TS field names are renamed.
RBAC group references (groups table, GroupRepository, GroupsTab) are
a separate domain concept and are NOT affected by this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:21:38 +01:00
<!--
============================================================================
2026-04-15 15:28:42 +02:00
CAMELEER v2 — Operations Dashboard (Dark Theme)
refactor: rename group/groupName to application/applicationName
The execution-related "group" concept actually represents the
application name. Rename all Java fields, API parameters, and frontend
types from groupName→applicationName and group→application for clarity.
- Java records: ExecutionSummary, ExecutionDetail, ExecutionDocument,
ExecutionRecord, ProcessorRecord
- API params: SearchRequest.group→application, SearchController
@RequestParam group→application
- Services: IngestionService, DetailService, SearchIndexer, StatsStore
- Frontend: schema.d.ts, Dashboard, ExchangeDetail, RouteDetail,
executions query hooks
Database column names (group_name) and OpenSearch field names are
unchanged — only the API-facing Java/TS field names are renamed.
RBAC group references (groups table, GroupRepository, GroupsTab) are
a separate domain concept and are NOT affected by this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:21:38 +01:00
============================================================================
DESIGN NOTES — SYNTHESIS RATIONALE
===================================
What was taken from each expert:
FROM DESIGN EXPERT:
- Amber-gold accent (#D4940F) as the primary brand color, maintaining the
"Desert Dusk" identity even in dark mode. The camel silhouette SVG logo.
- Typography system: DM Sans + JetBrains Mono, four-level hierarchy.
- Card-based layouts with subtle borders and layered surfaces.
- Duration bar sparklines for quick visual comparison.
- Warm sidebar tone (not pure black, but warm obsidian).
FROM USABILITY EXPERT:
- Full information hierarchy: health strip -> filter bar -> results -> detail.
- Master-detail pattern with slide-in panel (45% width on row select).
- Status pills with live counts, time preset chips, removable filter tags.
- Relative timestamps ("2m ago") with absolute fallback.
- Keyboard shortcut hints bar.
- Failed/running row border accents for scan-ability.
- Processor Gantt timeline in detail panel.
- Tab-based progressive disclosure in detail (Overview/Processors/Exchange/Error).
FROM OPERATOR EXPERT:
- Business IDs (Order ID, Customer, Source) as first-class table columns.
- Inline error previews directly below failed rows — no click needed.
- SLA threshold indicators on metric charts and duration cells.
- Agent health panel (integrated into sidebar).
- Trend arrows on all metric cards (directional context).
- Top error pattern grouping with occurrence counts.
- Shift-aware labeling ("since 06:00", overnight vs. today split).
KEY DESIGN DECISIONS:
1. Dark palette uses refined obsidian (#0B0F18) not generic navy. Surfaces
layer from #0B0F18 -> #111827 -> #1A2332 -> #212D3F for depth.
2. Status colors are tuned for dark contrast: emerald (#10B981), amber
(#F0B429), rose (#F43F5E), sky blue (#3B82F6) with subtle glow effects.
3. The warm amber accent (#D4940F) provides brand continuity with the light
theme — both mocks are clearly the same product.
4. Glow effects on status indicators (box-shadow with colored alpha) give
the dark theme a polished, premium feel without being garish.
5. Chart palettes use semi-transparent fills that work on dark backgrounds,
with SLA threshold lines clearly visible.
WHAT MAKES THIS BETTER THAN EACH INDIVIDUAL:
- Design expert had the warm brand but was light-only. This proves the amber
brand works equally well on dark backgrounds.
- Usability expert had a dark theme but with generic navy colors and no
business context. This uses refined obsidian + business data.
- Operator expert had excellent data but a flat single-page layout with no
sidebar or detail panel. This adds proper navigation + drill-down.
- The synthesis creates a cohesive dark monitoring experience: professional
enough for a NOC wall display, detailed enough for incident response.
============================================================================
-->
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=1920" >
2026-04-15 15:28:42 +02:00
< title > Cameleer — Operations Dashboard (Dark)< / title >
refactor: rename group/groupName to application/applicationName
The execution-related "group" concept actually represents the
application name. Rename all Java fields, API parameters, and frontend
types from groupName→applicationName and group→application for clarity.
- Java records: ExecutionSummary, ExecutionDetail, ExecutionDocument,
ExecutionRecord, ProcessorRecord
- API params: SearchRequest.group→application, SearchController
@RequestParam group→application
- Services: IngestionService, DetailService, SearchIndexer, StatsStore
- Frontend: schema.d.ts, Dashboard, ExchangeDetail, RouteDetail,
executions query hooks
Database column names (group_name) and OpenSearch field names are
unchanged — only the API-facing Java/TS field names are renamed.
RBAC group references (groups table, GroupRepository, GroupsTab) are
a separate domain concept and are NOT affected by this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:21:38 +01:00
< link href = "https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel = "stylesheet" >
< style >
/* ==========================================================================
RESET & FOUNDATIONS
========================================================================== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
/* Surface palette (obsidian layers) */
--bg-deep: #0B0F18;
--bg-base: #0E1220;
--bg-surface: #141B2A;
--bg-raised: #1A2332;
--bg-hover: #212D3F;
/* Sidebar (warm obsidian) */
--sidebar-bg: #0E1118;
--sidebar-hover: #171D28;
--sidebar-active: #1D2636;
--sidebar-text: #94A3B8;
--sidebar-muted: #475569;
/* Text */
--text-primary: #E8ECF4;
--text-secondary: #94A3B8;
--text-muted: #5A6B83;
--text-faint: #3A4A5E;
/* Borders */
--border: #1E2D3D;
--border-subtle: #172030;
/* Brand accent (amber-gold) */
--amber: #D4940F;
--amber-light: #F0C060;
--amber-bg: rgba(212, 148, 15, 0.12);
--amber-deep: #A67200;
--amber-glow: rgba(212, 148, 15, 0.15);
/* Status colors (dark-optimized, brighter for contrast) */
--success: #10B981;
--success-bg: rgba(16, 185, 129, 0.10);
--success-border: rgba(16, 185, 129, 0.25);
--success-glow: rgba(16, 185, 129, 0.15);
--warning: #F0B429;
--warning-bg: rgba(240, 180, 41, 0.10);
--warning-border: rgba(240, 180, 41, 0.25);
--error: #F43F5E;
--error-bg: rgba(244, 63, 94, 0.08);
--error-border: rgba(244, 63, 94, 0.20);
--error-glow: rgba(244, 63, 94, 0.12);
--running: #3B82F6;
--running-bg: rgba(59, 130, 246, 0.10);
--running-border: rgba(59, 130, 246, 0.25);
--cyan: #22D3EE;
--cyan-bg: rgba(34, 211, 238, 0.10);
/* Typography */
--font-body: 'DM Sans', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
/* Spacing & Radii */
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
/* Shadows (dark-optimized: deeper, colored) */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3);
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.4);
--shadow-card: 0 1px 3px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--border-subtle);
}
html { font-size: 14px; }
body {
font-family: var(--font-body);
background: var(--bg-deep);
color: var(--text-primary);
line-height: 1.5;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
/* Subtle gradient background */
body::before {
content: '';
position: fixed;
inset: 0;
background:
radial-gradient(ellipse 900px 450px at 15% 10%, rgba(212, 148, 15, 0.03), transparent),
radial-gradient(ellipse 700px 700px at 85% 85%, rgba(34, 211, 238, 0.015), transparent);
pointer-events: none;
z-index: 0;
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
/* ==========================================================================
ANIMATIONS
========================================================================== */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
50% { box-shadow: 0 0 0 5px rgba(16, 185, 129, 0); }
}
@keyframes errorPulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(244, 63, 94, 0.2); }
50% { box-shadow: 0 0 0 4px rgba(244, 63, 94, 0); }
}
@keyframes slideIn {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes glowPulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
.animate-in { animation: fadeIn 0.3s ease-out both; }
.delay-1 { animation-delay: 0.04s; }
.delay-2 { animation-delay: 0.08s; }
.delay-3 { animation-delay: 0.12s; }
.delay-4 { animation-delay: 0.16s; }
/* ==========================================================================
LAYOUT: 3-column
========================================================================== */
.app {
display: flex;
height: 100vh;
overflow: hidden;
position: relative;
z-index: 1;
}
/* ==========================================================================
SIDEBAR (warm obsidian)
========================================================================== */
.sidebar {
width: 220px;
flex-shrink: 0;
background: var(--sidebar-bg);
border-right: 1px solid var(--border-subtle);
display: flex;
flex-direction: column;
overflow: hidden;
}
.sidebar-logo {
padding: 16px 18px;
display: flex;
align-items: center;
gap: 10px;
border-bottom: 1px solid var(--border-subtle);
}
.sidebar-logo .brand {
font-family: var(--font-mono);
font-weight: 600;
font-size: 15px;
color: var(--amber-light);
letter-spacing: -0.3px;
}
.sidebar-logo .version {
font-family: var(--font-mono);
font-size: 10px;
color: var(--sidebar-muted);
margin-left: 2px;
}
.sidebar-search { padding: 10px 12px; }
.sidebar-search input {
width: 100%;
background: var(--bg-raised);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 6px 10px 6px 28px;
color: var(--sidebar-text);
font-family: var(--font-body);
font-size: 12px;
outline: none;
transition: border-color 0.15s;
}
.sidebar-search input::placeholder { color: var(--sidebar-muted); }
.sidebar-search input:focus { border-color: var(--amber); }
.sidebar-search-wrap { position: relative; }
.sidebar-search-wrap .search-icon {
position: absolute;
left: 9px;
top: 50%;
transform: translateY(-50%);
color: var(--sidebar-muted);
font-size: 12px;
}
.sidebar-section {
padding: 14px 12px 5px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--sidebar-muted);
}
.sidebar-items {
flex: 1;
overflow-y: auto;
padding: 0 6px;
}
.sidebar-item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 12px;
border-radius: var(--radius-sm);
color: var(--sidebar-text);
font-size: 13px;
cursor: pointer;
transition: all 0.12s;
text-decoration: none;
border-left: 3px solid transparent;
margin-bottom: 1px;
}
.sidebar-item:hover { background: var(--sidebar-hover); color: var(--text-primary); }
.sidebar-item.active { background: var(--sidebar-active); color: var(--amber-light); border-left-color: var(--amber); }
.sidebar-item .health {
width: 7px;
height: 7px;
border-radius: 50%;
flex-shrink: 0;
}
.health-live { background: var(--success); box-shadow: 0 0 6px var(--success-glow); }
.health-stale { background: var(--warning); box-shadow: 0 0 6px rgba(240, 180, 41, 0.3); }
.health-dead { background: var(--sidebar-muted); }
.sidebar-item .item-info { flex: 1; min-width: 0; }
.sidebar-item .item-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-item .item-meta { font-size: 11px; color: var(--sidebar-muted); font-family: var(--font-mono); }
.sidebar-item .item-count {
font-family: var(--font-mono);
font-size: 11px;
color: var(--sidebar-muted);
background: var(--bg-raised);
padding: 1px 6px;
border-radius: 10px;
}
.sidebar-item.active .item-count { background: var(--amber-bg); color: var(--amber-light); }
.sidebar-divider {
height: 1px;
background: var(--border-subtle);
margin: 6px 12px;
}
/* Agent health in sidebar */
.sidebar-agents-header {
padding: 14px 12px 6px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--sidebar-muted);
display: flex;
align-items: center;
justify-content: space-between;
}
.sidebar-agent-badge {
font-family: var(--font-mono);
font-size: 10px;
padding: 1px 6px;
border-radius: 10px;
background: var(--success-bg);
color: var(--success);
border: 1px solid var(--success-border);
}
.agent-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
margin: 0 6px 2px;
border-radius: var(--radius-sm);
font-size: 11px;
color: var(--sidebar-text);
transition: background 0.1s;
}
.agent-item:hover { background: var(--sidebar-hover); }
.agent-dot {
width: 6px;
height: 6px;
border-radius: 50%;
flex-shrink: 0;
}
.agent-info { flex: 1; min-width: 0; }
.agent-name { font-family: var(--font-mono); font-size: 11px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-secondary); }
.agent-detail { font-size: 10px; color: var(--sidebar-muted); }
.agent-stats-col {
text-align: right;
font-family: var(--font-mono);
font-size: 10px;
color: var(--sidebar-muted);
}
.agent-tps { color: var(--sidebar-text); }
.sidebar-bottom {
border-top: 1px solid var(--border-subtle);
padding: 6px;
}
.sidebar-bottom .sidebar-item {
font-size: 12px;
color: var(--sidebar-muted);
border-left: 3px solid transparent;
}
.sidebar-bottom .sidebar-item:hover { color: var(--sidebar-text); }
/* ==========================================================================
MAIN CONTENT AREA
========================================================================== */
.main {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
min-width: 0;
}
/* Top bar */
.topbar {
display: flex;
align-items: center;
gap: 12px;
padding: 0 24px;
height: 48px;
flex-shrink: 0;
background: rgba(14, 18, 32, 0.85);
backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border-subtle);
}
.topbar-breadcrumb {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--text-muted);
}
.topbar-breadcrumb .crumb-active { color: var(--text-primary); font-weight: 600; }
.topbar-breadcrumb .crumb-sep { color: var(--text-faint); font-size: 11px; }
.topbar-search {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-raised);
color: var(--text-muted);
font-size: 12px;
cursor: pointer;
transition: border-color 0.15s;
min-width: 280px;
}
.topbar-search:hover { border-color: var(--text-muted); }
.topbar-kbd {
font-family: var(--font-mono);
font-size: 10px;
background: var(--bg-surface);
border: 1px solid var(--border);
padding: 0 4px;
border-radius: 3px;
color: var(--text-muted);
margin-left: auto;
}
.topbar-right {
margin-left: auto;
display: flex;
align-items: center;
gap: 12px;
}
.topbar-env {
font-family: var(--font-mono);
font-size: 10px;
font-weight: 600;
padding: 3px 10px;
border-radius: 10px;
background: var(--success-bg);
color: var(--success);
border: 1px solid var(--success-border);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.topbar-shift {
font-family: var(--font-mono);
font-size: 10px;
padding: 3px 10px;
border-radius: 10px;
background: var(--cyan-bg);
color: var(--cyan);
border: 1px solid rgba(34, 211, 238, 0.2);
}
.topbar-user {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--text-secondary);
}
.topbar-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--amber-bg);
color: var(--amber);
font-weight: 600;
font-size: 11px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(212, 148, 15, 0.3);
}
/* Content scroll container */
.content-wrap {
flex: 1;
display: flex;
overflow: hidden;
}
.content {
flex: 1;
overflow-y: auto;
padding: 20px 24px 40px;
min-width: 0;
}
/* ==========================================================================
HEALTH STATUS BAR
========================================================================== */
.health-strip {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
margin-bottom: 16px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
padding: 12px 16px;
position: relative;
overflow: hidden;
transition: border-color 0.2s;
cursor: pointer;
}
.stat-card:hover { border-color: var(--border); }
.stat-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
}
.stat-card.card-amber::before { background: linear-gradient(90deg, var(--amber), transparent); }
.stat-card.card-green::before { background: linear-gradient(90deg, var(--success), transparent); }
.stat-card.card-error::before { background: linear-gradient(90deg, var(--error), transparent); }
.stat-card.card-teal::before { background: linear-gradient(90deg, var(--cyan), transparent); }
.stat-card.card-warn::before { background: linear-gradient(90deg, var(--warning), transparent); }
.stat-card.has-errors { animation: errorPulse 2.5s ease-in-out infinite; }
.stat-label {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.6px;
color: var(--text-muted);
margin-bottom: 3px;
}
.stat-value-row {
display: flex;
align-items: baseline;
gap: 6px;
}
.stat-value {
font-family: var(--font-mono);
font-size: 20px;
font-weight: 600;
line-height: 1.2;
color: var(--text-primary);
}
.stat-value.val-amber { color: var(--amber); }
.stat-value.val-green { color: var(--success); }
.stat-value.val-error { color: var(--error); }
.stat-value.val-teal { color: var(--cyan); }
.stat-value.val-warn { color: var(--warning); }
.stat-unit { font-size: 12px; color: var(--text-muted); }
.stat-trend {
font-family: var(--font-mono);
font-size: 11px;
display: inline-flex;
align-items: center;
gap: 2px;
margin-left: auto;
}
.trend-up-good { color: var(--success); }
.trend-up-bad { color: var(--error); }
.trend-down-good { color: var(--success); }
.trend-down-bad { color: var(--error); }
.trend-flat { color: var(--text-muted); }
.stat-detail { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.stat-detail strong { color: var(--text-secondary); }
/* ==========================================================================
FILTER BAR
========================================================================== */
.filter-section {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
padding: 12px 16px;
margin-bottom: 16px;
}
.filter-row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.filter-group {
display: flex;
align-items: center;
gap: 5px;
}
.filter-label {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-muted);
white-space: nowrap;
margin-right: 2px;
}
.filter-sep {
width: 1px;
height: 22px;
background: var(--border);
margin: 0 6px;
}
.filter-pill {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 12px;
border: 1px solid var(--border);
border-radius: 20px;
background: transparent;
color: var(--text-secondary);
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.12s;
white-space: nowrap;
}
.filter-pill:hover { border-color: var(--text-muted); background: var(--bg-raised); }
.filter-pill.active {
background: var(--amber-bg);
border-color: rgba(212, 148, 15, 0.35);
color: var(--amber-light);
font-weight: 600;
}
.pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill-count { font-family: var(--font-mono); font-size: 10px; opacity: 0.7; }
.filter-input-wrap { position: relative; flex: 1; max-width: 360px; }
.filter-input-wrap .fi-icon {
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
font-size: 13px;
}
.filter-input {
width: 100%;
padding: 6px 12px 6px 30px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-raised);
color: var(--text-primary);
font-family: var(--font-body);
font-size: 12px;
outline: none;
transition: border-color 0.15s;
}
.filter-input::placeholder { color: var(--text-muted); }
.filter-input:focus { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-bg); }
.active-filters {
display: flex;
gap: 6px;
flex-wrap: wrap;
align-items: center;
margin-top: 8px;
}
.filter-tag {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 3px 10px;
background: var(--amber-bg);
border: 1px solid rgba(212, 148, 15, 0.25);
border-radius: 20px;
font-size: 11px;
color: var(--amber-light);
font-family: var(--font-mono);
}
.filter-tag-remove { cursor: pointer; opacity: 0.5; font-size: 13px; line-height: 1; background: none; border: none; color: inherit; }
.filter-tag-remove:hover { opacity: 1; }
.clear-all { font-size: 11px; color: var(--text-muted); cursor: pointer; padding: 3px 6px; background: none; border: none; }
.clear-all:hover { color: var(--error); }
/* ==========================================================================
EXECUTION TABLE
========================================================================== */
.table-section {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
overflow: hidden;
margin-bottom: 20px;
}
.table-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border-bottom: 1px solid var(--border-subtle);
}
.table-title { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.table-right { display: flex; align-items: center; gap: 12px; }
.table-meta { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.live-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 5px 12px;
border: 1px solid var(--success-border);
border-radius: var(--radius-sm);
background: var(--success-bg);
color: var(--success);
font-family: var(--font-mono);
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
}
.live-btn:hover { background: rgba(16, 185, 129, 0.15); }
.live-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--success);
animation: pulse 2s ease-in-out infinite;
}
.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead {
background: var(--bg-raised);
border-bottom: 1px solid var(--border);
}
th {
padding: 9px 14px;
text-align: left;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.8px;
color: var(--text-muted);
white-space: nowrap;
user-select: none;
cursor: pointer;
transition: color 0.12s;
}
th:hover { color: var(--text-secondary); }
th.sorted { color: var(--amber); }
.sort-arrow { font-size: 8px; margin-left: 3px; opacity: 0.4; }
th.sorted .sort-arrow { opacity: 1; }
tbody tr {
border-bottom: 1px solid var(--border-subtle);
border-left: 3px solid transparent;
transition: background 0.08s;
cursor: pointer;
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--bg-hover); }
tbody tr.selected { background: var(--amber-bg); }
tbody tr.row-error { border-left-color: var(--error); }
tbody tr.row-warning { border-left-color: var(--warning); }
tbody tr.row-running { border-left-color: var(--running); }
td {
padding: 9px 14px;
font-size: 13px;
vertical-align: top;
white-space: nowrap;
}
/* Status badge with glow */
.status-badge {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 2px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.2px;
}
.status-success { background: var(--success-bg); color: var(--success); border: 1px solid var(--success-border); }
.status-warning { background: var(--warning-bg); color: var(--warning); border: 1px solid var(--warning-border); }
.status-error { background: var(--error-bg); color: var(--error); border: 1px solid var(--error-border); }
.status-running { background: var(--running-bg); color: var(--running); border: 1px solid var(--running-border); }
.status-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
/* Glow on status indicators */
.status-success .status-dot { box-shadow: 0 0 4px var(--success-glow); }
.status-error .status-dot { box-shadow: 0 0 4px var(--error-glow); }
.route-name { font-weight: 500; color: var(--text-primary); }
.route-name:hover { color: var(--amber); }
.route-group { font-size: 11px; color: var(--text-muted); }
.biz-id { font-family: var(--font-mono); font-weight: 500; color: var(--cyan); font-size: 12px; }
.biz-id-secondary { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.time-relative { color: var(--text-secondary); font-size: 13px; }
.time-absolute { font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); display: block; }
.duration { font-family: var(--font-mono); font-size: 12px; }
.dur-fast { color: var(--success); }
.dur-normal { color: var(--text-primary); }
.dur-slow { color: var(--warning); }
.dur-breach { color: var(--error); font-weight: 600; }
.sla-tag {
display: inline-flex;
align-items: center;
gap: 2px;
color: var(--error);
font-size: 10px;
font-family: var(--font-mono);
font-weight: 600;
margin-left: 4px;
animation: glowPulse 2s ease-in-out infinite;
}
.agent-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-muted);
}
.agent-badge-dot { width: 5px; height: 5px; border-radius: 50%; }
/* Error preview row */
.error-preview-row td {
padding: 0 14px 8px 20px !important;
border-bottom: 1px solid var(--border-subtle);
}
.error-preview {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 8px 12px;
background: rgba(244, 63, 94, 0.05);
border: 1px solid var(--error-border);
border-left: 3px solid var(--error);
border-radius: var(--radius-sm);
font-family: var(--font-mono);
font-size: 11px;
color: var(--error);
line-height: 1.6;
}
.error-preview-icon { flex-shrink: 0; margin-top: 1px; }
.error-preview-text { white-space: normal; word-break: break-word; }
.error-expand-hint { color: var(--text-muted); font-size: 10px; margin-top: 4px; font-family: var(--font-body); }
/* Pagination */
.table-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 16px;
border-top: 1px solid var(--border-subtle);
font-size: 12px;
color: var(--text-muted);
background: var(--bg-raised);
}
.pagination { display: flex; align-items: center; gap: 4px; }
.page-btn {
padding: 4px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: transparent;
color: var(--text-secondary);
font-size: 12px;
font-family: var(--font-mono);
cursor: pointer;
transition: all 0.12s;
}
.page-btn:hover { background: var(--bg-hover); border-color: var(--text-muted); }
.page-btn.active { background: var(--amber-bg); border-color: rgba(212, 148, 15, 0.35); color: var(--amber-light); font-weight: 600; }
/* ==========================================================================
METRICS ROW
========================================================================== */
.metrics-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 14px;
margin-bottom: 20px;
}
.metric-card {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
overflow: hidden;
}
.metric-card-header {
padding: 12px 16px 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.metric-card-title { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.metric-card-value { font-family: var(--font-mono); font-size: 14px; font-weight: 600; color: var(--text-primary); }
.metric-chart { padding: 10px 16px 12px; height: 90px; position: relative; }
.chart-line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.chart-area { opacity: 0.15; }
.chart-grid-line { stroke: var(--border-subtle); stroke-width: 0.5; }
.chart-label { font-family: var(--font-mono); font-size: 9px; fill: var(--text-muted); }
.sla-line { stroke: var(--error); stroke-width: 1; stroke-dasharray: 4 3; opacity: 0.6; }
.sla-label-text { fill: var(--error); font-size: 8px; font-family: var(--font-mono); opacity: 0.7; }
/* ==========================================================================
DETAIL PANEL
========================================================================== */
.detail-panel {
width: 0;
overflow: hidden;
transition: width 0.25s ease, opacity 0.2s ease;
opacity: 0;
border-left: 1px solid transparent;
display: flex;
flex-direction: column;
background: var(--bg-surface);
flex-shrink: 0;
}
.detail-panel.open {
width: 400px;
opacity: 1;
border-left-color: var(--border);
animation: slideIn 0.25s ease-out both;
}
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.detail-breadcrumb { font-size: 11px; color: var(--text-muted); display: flex; align-items: center; gap: 5px; }
.detail-breadcrumb .bc-sep { color: var(--text-faint); font-size: 9px; }
.detail-breadcrumb .bc-current { color: var(--amber); font-weight: 500; }
.detail-close {
width: 26px;
height: 26px;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text-muted);
cursor: pointer;
font-size: 13px;
transition: all 0.15s;
}
.detail-close:hover { color: var(--text-primary); border-color: var(--text-muted); }
.detail-tabs { display: flex; border-bottom: 1px solid var(--border-subtle); flex-shrink: 0; }
.detail-tab {
padding: 9px 16px;
font-size: 12px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.15s;
background: none;
border-top: none; border-left: none; border-right: none;
font-family: var(--font-body);
}
.detail-tab:hover { color: var(--text-secondary); }
.detail-tab.active { color: var(--amber); border-bottom-color: var(--amber); }
.detail-body {
flex: 1;
overflow-y: auto;
padding: 16px;
background: var(--bg-deep);
}
.detail-section { margin-bottom: 18px; }
.detail-section-title {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.8px;
color: var(--text-muted);
margin-bottom: 8px;
}
.detail-grid {
display: grid;
grid-template-columns: 100px 1fr;
gap: 6px 10px;
font-size: 12px;
}
.detail-key { color: var(--text-muted); font-size: 11px; }
.detail-val { color: var(--text-primary); font-family: var(--font-mono); font-size: 11px; word-break: break-all; }
.detail-val.error-text { color: var(--error); }
.detail-val.link { color: var(--amber); cursor: pointer; }
/* Processor timeline */
.processor-timeline { display: flex; flex-direction: column; gap: 5px; }
.proc-row { display: flex; align-items: center; gap: 8px; font-size: 11px; }
.proc-name {
width: 100px;
text-align: right;
color: var(--text-secondary);
font-family: var(--font-mono);
font-size: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 0;
}
.proc-bar-bg {
flex: 1;
height: 16px;
background: var(--bg-raised);
border-radius: 3px;
position: relative;
overflow: hidden;
}
.proc-bar-fill {
position: absolute;
top: 0;
height: 100%;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 5px;
font-family: var(--font-mono);
font-size: 8px;
color: rgba(255,255,255,0.8);
min-width: 20px;
}
.proc-ok { background: rgba(16, 185, 129, 0.45); }
.proc-slow { background: rgba(240, 180, 41, 0.45); }
.proc-fail { background: rgba(244, 63, 94, 0.45); }
.proc-dur { width: 42px; font-family: var(--font-mono); font-size: 10px; color: var(--text-muted); flex-shrink: 0; }
/* Error block */
.error-block {
background: rgba(244, 63, 94, 0.05);
border: 1px solid var(--error-border);
border-left: 3px solid var(--error);
border-radius: var(--radius-sm);
padding: 12px 14px;
}
.error-class { font-family: var(--font-mono); font-size: 11px; color: var(--error); font-weight: 600; margin-bottom: 4px; }
.error-message-detail { font-family: var(--font-mono); font-size: 10px; color: var(--text-secondary); line-height: 1.6; }
.error-expand { margin-top: 6px; font-size: 10px; color: var(--text-muted); cursor: pointer; background: none; border: none; font-family: var(--font-mono); }
.error-expand:hover { color: var(--amber); }
/* Detail actions */
.detail-actions {
display: flex;
gap: 6px;
padding: 10px 16px;
border-top: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.action-btn { padding: 6px 14px; border-radius: var(--radius-sm); font-size: 11px; font-weight: 500; cursor: pointer; transition: all 0.15s; font-family: var(--font-body); }
.action-btn.primary { background: var(--amber); color: var(--bg-deep); border: none; }
.action-btn.primary:hover { background: var(--amber-light); }
.action-btn.secondary { background: none; border: 1px solid var(--border); color: var(--text-secondary); }
.action-btn.secondary:hover { border-color: var(--text-muted); color: var(--text-primary); }
/* ==========================================================================
KEYBOARD SHORTCUTS BAR
========================================================================== */
.shortcuts-bar {
position: fixed;
bottom: 12px;
right: 12px;
display: flex;
gap: 10px;
z-index: 50;
animation: fadeIn 0.5s ease-out 0.5s both;
}
.shortcut-hint {
display: flex;
align-items: center;
gap: 5px;
font-size: 10px;
color: var(--text-muted);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: 4px 8px;
}
.shortcut-hint kbd {
font-family: var(--font-mono);
font-size: 9px;
background: var(--bg-raised);
border: 1px solid var(--border);
border-radius: 3px;
padding: 0 4px;
color: var(--text-secondary);
}
.mono { font-family: var(--font-mono); }
< / style >
< / head >
< body >
< div class = "app" >
<!-- SIDEBAR -->
< aside class = "sidebar" >
< div class = "sidebar-logo" >
< svg width = "24" height = "26" viewBox = "940 300 900 1000" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
< path style = "fill:#D4940F" d = "M 1385 . 2768 , 1205 . 0273 c -1 . 7727 , -1 . 0809 -3 . 4419 , -2 . 9917 -3 . 7093 , -4 . 2463 -0 . 2674 , -1 . 2545 -0 . 6851 , -23 . 881 -0 . 9282 , -50 . 281 -0 . 4544 , -49 . 3389 -1 . 4003 , -65 . 7355 -5 . 6645 , -98 . 1921 -10 . 4552 , -79 . 57719 -28 . 3441 , -125 . 96796 -62 . 5438 , -162 . 19311 -9 . 2529 , -9 . 80096 -19 . 9748 , -18 . 38696 -33 . 931 , -27 . 17162 -12 . 6119 , -7 . 93853 -24 . 8581 , -13 . 73088 -49 . 5 , -23 . 41316 -41 . 7081 , -16 . 38789 -67 . 8677 , -32 . 29827 -89 . 0588 , -54 . 16599 -34 . 7586 , -35 . 86827 -54 . 3653 , -83 . 30392 -59 . 0504 , -142 . 86402 -0 . 8357 , -10 . 6245 -0 . 92 , -22 . 5842 -0 . 2891 , -41 0 . 4899 , -14 . 3 0 . 8164 , -35 . 225 0 . 7255 , -46 . 5 -0 . 1983 , -24 . 59199 -2 . 0251 , -34 . 76973 -8 . 4617 , -47 . 14159 -6 . 2021 , -11 . 92135 -10 . 364 , -15 . 10789 -36 . 2345 , -27 . 74305 -25 . 4032 , -12 . 40694 -27 . 7701 , -13 . 30168 -35 . 4717 , -13 . 40961 -4 . 63013 , -0 . 0649 -7 . 47783 , 0 . 72754 -15 . 6593 , 4 . 35747 -9 . 86218 , 4 . 37563 -10 . 15161 , 4 . 43672 -21 , 4 . 43267 -10 . 86566 , -0 . 004 -11 . 08917 , -0 . 0517 -18 . 30169 , -3 . 90103 -17 . 43524 , -9 . 3052 -21 . 50075 , -23 . 5772 -13 . 55784 , -47 . 59486 2 . 73631 , -8 . 27402 10 . 00732 , -22 . 43593 14 . 69263 , -28 . 61719 5 . 4984 , -7 . 25394 10 . 89014 , -11 . 83885 20 . 83968 , -17 . 72117 15 . 06768 , -8 . 90827 29 . 60254 , -11 . 98884 63 . 90372 , -13 . 54403 l 16 . 5765 , -0 . 75156 14 . 9235 , -7 . 05735 c 8 . 2079 , -3 . 88154 17 . 1735 , -7 . 76831 19 . 9235 , -8 . 63727 7 . 7052 , -2 . 43474 21 . 059 , -4 . 67186 27 . 8605 , -4 . 66741 8 . 0518 , 0 . 005 22 . 643 , 2 . 41202 30 . 0139 , 4 . 95066 l 5 . 8744 , 2 . 02321 4 . 8856 , -4 . 09041 c 10 . 341 , -8 . 65797 18 . 6496 , -12 . 95738 28 . 96 , -14 . 98583 6 . 9966 , -1 . 37649 26 . 3532 , -0 . 64631 32 . 1116 , 1 . 21134 4 . 5531 , 1 . 46885 5 . 4951 , 3 . 7902 6 . 3689 , 15 . 69592 1 . 5167 , 20 . 66426 -5 . 0112 , 40 . 44987 -18 . 1772 , 55 . 09363 -4 . 3065 , 4 . 78983 -4 . 5016 , 5 . 25488 -3 . 4977 , 8 . 33516 4 . 5184 , 13 . 86447 5 . 3154 , 38 . 07517 2 . 1537 , 65 . 42564 -5 . 169 , 44 . 71349 -5 . 0411 , 70 . 7797 0 . 5404 , 110 . 15637 6 . 8135 , 48 . 06863 22 . 3335 , 73 . 51874 48 . 2051 , 79 . 04779 24 . 1748 , 5 . 16643 45 . 2921 , -5 . 78181 66 . 8353 , -34 . 65077 4 . 809 , -6 . 4442 11 . 1363 , -14 . 93006 14 . 0608 , -18 . 85747 7 . 3865 , -9 . 91943 25 . 6102 , -27 . 11708 35 . 952 , -33 . 92766 12 . 5235 , -8 . 24739 26 . 8808 , -14 . 74833 42 . 8527 , -19 . 40354 15 . 4108 , -4 . 49168 26 . 7091 , -9 . 74984 36 . 2432 , -16 . 86731 3 . 4338 , -2 . 56341 13 . 3338 , -12 . 03104 22 , -21 . 03916 26 . 2356 , -27 . 27067 44 . 5755 , -40 . 32368 66 . 9928 , -47 . 68062 19 . 1052 , -6 . 26998 35 . 4927 , -7 . 73718 50 . 8681 , -4 . 55427 37 . 0856 , 7 . 67726 63 . 5507 , 26 . 77589 100 . 2888 , 72 . 37362 16 . 6011 , 20 . 60463 29 . 9711 , 32 . 07977 51 . 6071 , 44 . 29313 39 . 3131 , 22 . 19195 50 . 1228 , 30 . 50985 68 . 8076 , 52 . 94655 5 . 4963 , 6 . 6 12 . 9187 , 14 . 91604 16 . 4941 , 18 . 4801 33 . 6796 , 33 . 57259 54 . 1965 , 72 . 51092 61 . 6587 , 117 . 0199 2 . 7315 , 16 . 29242 3 . 3374 , 26 . 62538 3 . 1861 , 54 . 33713 l -0 . 1465 , 26 . 83714 -2 . 7975 , 2 . 40572 c -3 . 9132 , 3 . 36522 -7 . 2806 , 3 . 99163 -11 . 2591 , 2 . 09442 -6 . 4731 , -3 . 08682 -6 . 5715 , -3 . 57833 -6 . 878 , -34 . 36929 -0 . 2908 , -29 . 2175 -2 . 0265 , -46 . 13705 -6 . 6479 , -64 . 80512 -3 . 2997 , -13 . 32891 -12 . 2529 , -34 . 61943 -17 . 0313 , -40 . 5 l -2 . 0314 , -2 . 5 0 . 5698 , 3 . 5 c 5 . 8574 , 35 . 97875 4 . 2855 , 72 . 40287 -5 . 3946 , 125 -8 . 4016 , 45 . 65054 -4 . 3665 , 69 . 39588 20 . 7318 , 122 11 . 4175 , 23 . 93009 12 . 5452 , 27 . 25907 12 . 4212 , 36 . 6684 -0 . 1018 , 7 . 7227 -2 . 5346 , 19 . 5162 -13 . 1674 , 63 . 8316 -1 . 0558 , 4 . 4 -3 . 5336 , 14 . 975 -5 . 5063 , 23 . 5 -1 . 9727 , 8 . 525 -4 . 2259 , 18 . 2 -5 . 0072 , 21 . 5 -0 . 7812 , 3 . 3 -3 . 4495 , 15 . 225 -5 . 9296 , 26 . 5 -9 . 1636 , 41 . 6596 -13 . 4372 , 59 . 8787 -14 . 5204 , 61 . 9027 -2 . 4994 , 4 . 6702 -5 . 2312 , 5 . 0973 -32 . 6024 , 5 . 0973 H 1765 . 8 l -3 . 4 , -3 . 4 c -2 . 3518 , -2 . 3518 -3 . 4 , -4 . 3226 -3 . 4 , -6 . 3925 0 , -1 . 6458 2 . 2347 , -12 . 1533 4 . 966 , -23 . 35 8 . 6906 , -35 . 6259 11 . 6969 , -54 . 778 12 . 6921 , -80 . 8575 1 . 3475 , -35 . 3073 -4 . 6406 , -62 . 7687 -18 . 7825 , -86 . 137 -7 . 6672 , -12 . 66954 -11 . 9163 , -17 . 84148 -29 . 8756 , -36 . 36415 -22 . 9362 , -23 . 65574 -34 . 6222 , -39 . 72583 -47 . 9268 , -65 . 90697 -5 . 7294 , -11 . 27448 -13 . 6061 , -31 . 99995 -15 . 5051 , -40 . 79778 -0 . 3212 , -1 . 48824 -1 . 0176 , -3 . 84619 -1 . 5475 , -5 . 2399 l -0 . 9634 , -2 . 534 -11 . 7786 , 7 . 15145 c -38 . 634 , 23 . 45687 -74 . 5513 , 34 . 71091 -124 . 1895 , 38 . 91257 -14 . 5402 , 1 . 23075 -58 . 2359 , 0 . 66344 -71 . 9142 , -0 . 93369 -5 . 4419 , -0 . 63542 -6 . 4542 , -0 . 49723 -7 . 25 , 0 . 98972 -0 . 5545 , 1 . 03621 -0 . 9249 , 60 . 63835 -0 . 9249 , 148 . 84365 0 , 161 . 6262 0 . 4025 , 151 . 2052 -5 . 9673 , 154 . 4992 -2 . 3865 , 1 . 2341 -7 . 4633 , 1 . 5162 -27 . 233 , 1 . 5132 -22 . 3926 , -0 -24 . 5527 , -0 . 158 -27 . 5229 , -1 . 969 z M 1424 , 1045 . 6452 c 0 , -87 . 21053 0 . 3878 , -144 . 17994 1 . 0365 , -152 . 24998 1 . 8115 , -22 . 53829 7 . 2373 , -44 . 8067 16 . 1142 , -66 . 13567 20 . 7842 , -49 . 93942 66 . 8961 , -95 . 01414 129 . 8493 , -126 . 92865 14 . 9469 , -7 . 57742 29 . 283
< / svg >
< div >
< span class = "brand" > cameleer< / span > < span class = "version" > v3< / span >
< / div >
< / div >
< div class = "sidebar-search" >
< div class = "sidebar-search-wrap" >
< span class = "search-icon" > ◇ < / span >
< input type = "text" placeholder = "Filter applications..." >
< / div >
< / div >
< div class = "sidebar-section" > Applications< / div >
< div class = "sidebar-items" >
< div class = "sidebar-item" >
< span class = "health health-live" > < / span >
< div class = "item-info" > < div class = "item-name" > All Applications< / div > < / div >
< span class = "item-count" > 4< / span >
< / div >
< div class = "sidebar-divider" > < / div >
< div class = "sidebar-item active" >
< span class = "health health-live" > < / span >
< div class = "item-info" > < div class = "item-name" > order-service< / div > < div class = "item-meta" > 2 agents< / div > < / div >
< span class = "item-count" > 1,847< / span >
< / div >
< div class = "sidebar-item" >
< span class = "health health-live" > < / span >
< div class = "item-info" > < div class = "item-name" > payment-gateway< / div > < div class = "item-meta" > 2 agents< / div > < / div >
< span class = "item-count" > 923< / span >
< / div >
< div class = "sidebar-item" >
< span class = "health health-live" > < / span >
< div class = "item-info" > < div class = "item-name" > shipment-tracker< / div > < div class = "item-meta" > 2 agents< / div > < / div >
< span class = "item-count" > 471< / span >
< / div >
< div class = "sidebar-item" >
< span class = "health health-stale" > < / span >
< div class = "item-info" > < div class = "item-name" > notification-hub< / div > < div class = "item-meta" > 1 agent< / div > < / div >
< span class = "item-count" > 128< / span >
< / div >
< div class = "sidebar-divider" > < / div >
< div class = "sidebar-section" > Routes< / div >
< div class = "sidebar-item" style = "padding-left: 22px;" >
< span style = "color: var(--sidebar-muted); font-size: 10px;" > ▸ < / span >
< div class = "item-info" > < div class = "item-name" > order-intake< / div > < / div >
< span class = "item-count" > 892< / span >
< / div >
< div class = "sidebar-item" style = "padding-left: 22px;" >
< span style = "color: var(--sidebar-muted); font-size: 10px;" > ▸ < / span >
< div class = "item-info" > < div class = "item-name" > order-enrichment< / div > < / div >
< span class = "item-count" > 541< / span >
< / div >
< div class = "sidebar-item" style = "padding-left: 22px;" >
< span style = "color: var(--sidebar-muted); font-size: 10px;" > ▸ < / span >
< div class = "item-info" > < div class = "item-name" > payment-process< / div > < / div >
< span class = "item-count" > 414< / span >
< / div >
< / div >
<!-- Agent health -->
< div class = "sidebar-agents-header" >
< span > Agents< / span >
< span class = "sidebar-agent-badge" > 4/4 live< / span >
< / div >
< div style = "padding: 0 0 6px; overflow-y: auto; max-height: 180px;" >
< div class = "agent-item" >
< span class = "agent-dot health-live" > < / span >
< div class = "agent-info" > < div class = "agent-name" > prod-1< / div > < div class = "agent-detail" > order-service v3.2.1< / div > < / div >
< div class = "agent-stats-col" > < div class = "agent-tps" > 14.2/s< / div > < div > 12s ago< / div > < / div >
< / div >
< div class = "agent-item" >
< span class = "agent-dot health-live" > < / span >
< div class = "agent-info" > < div class = "agent-name" > prod-2< / div > < div class = "agent-detail" > payment-svc v3.2.1< / div > < / div >
< div class = "agent-stats-col" > < div class = "agent-tps" > 11.8/s< / div > < div style = "color: var(--error);" > 3 err/h< / div > < / div >
< / div >
< div class = "agent-item" >
< span class = "agent-dot health-live" > < / span >
< div class = "agent-info" > < div class = "agent-name" > prod-3< / div > < div class = "agent-detail" > shipment-svc v3.2.0< / div > < / div >
< div class = "agent-stats-col" > < div class = "agent-tps" > 12.1/s< / div > < div > 5s ago< / div > < / div >
< / div >
< div class = "agent-item" >
< span class = "agent-dot health-live" > < / span >
< div class = "agent-info" > < div class = "agent-name" > prod-4< / div > < div class = "agent-detail" > shipment-svc v3.2.0< / div > < / div >
< div class = "agent-stats-col" > < div class = "agent-tps" > 9.1/s< / div > < div > 3s ago< / div > < / div >
< / div >
< / div >
< div class = "sidebar-bottom" >
< div class = "sidebar-item" > < span style = "font-size: 13px; width: 18px; text-align: center;" > ⚙ < / span > < div class = "item-info" > < div class = "item-name" > Admin< / div > < / div > < / div >
< div class = "sidebar-item" > < span style = "font-size: 13px; width: 18px; text-align: center;" > ☰ < / span > < div class = "item-info" > < div class = "item-name" > API Docs< / div > < / div > < / div >
< / div >
< / aside >
<!-- MAIN CONTENT -->
< div class = "main" >
< div class = "topbar" >
< div class = "topbar-breadcrumb" >
< span > Applications< / span >
< span class = "crumb-sep" > /< / span >
< span class = "crumb-active" > order-service< / span >
< / div >
< div class = "topbar-search" >
< span style = "font-size: 12px; color: var(--text-muted);" > 🔎 < / span >
< span > Search by Order ID, route, error...< / span >
< span class = "topbar-kbd" > Ctrl+K< / span >
< / div >
< div class = "topbar-right" >
< span class = "topbar-env" > PRODUCTION< / span >
< span class = "topbar-shift" > Shift: Day (06:00-18:00)< / span >
< div class = "topbar-user" >
< span > hendrik< / span >
< div class = "topbar-avatar" > H< / div >
< / div >
< / div >
< / div >
< div class = "content-wrap" >
< div class = "content" >
<!-- Health strip -->
< div class = "health-strip animate-in" >
< div class = "stat-card card-amber" >
< div class = "stat-label" > Executions (shift)< / div >
< div class = "stat-value-row" > < span class = "stat-value" > 3,241< / span > < span class = "stat-trend trend-up-good" > +12%< / span > < / div >
< div class = "stat-detail" > < strong > 97.1%< / strong > success since 06:00< / div >
< / div >
< div class = "stat-card card-green" >
< div class = "stat-label" > Success Rate< / div >
< div class = "stat-value-row" > < span class = "stat-value val-green" > 97.1%< / span > < span class = "stat-trend trend-down-bad" > -0.4%< / span > < / div >
< div class = "stat-detail" > 3,147 ok / 56 warn / 38 error< / div >
< / div >
< div class = "stat-card card-error has-errors" >
< div class = "stat-label" > Errors (shift)< / div >
< div class = "stat-value-row" > < span class = "stat-value val-error" > 38< / span > < span class = "stat-trend trend-up-bad" > +5< / span > < / div >
< div class = "stat-detail" > < strong > 23< / strong > overnight · < strong > 15< / strong > since 06:00< / div >
< / div >
< div class = "stat-card card-teal" >
< div class = "stat-label" > Throughput< / div >
< div class = "stat-value-row" > < span class = "stat-value" > 47.2< / span > < span class = "stat-unit" > msg/s< / span > < span class = "stat-trend trend-flat" > ↔ < / span > < / div >
< div class = "stat-detail" > Capacity: 120 msg/s · < strong > 39%< / strong > < / div >
< / div >
< div class = "stat-card card-warn" >
< div class = "stat-label" > Latency p99< / div >
< div class = "stat-value-row" > < span class = "stat-value val-warn" > 287< / span > < span class = "stat-unit" > ms< / span > < span class = "stat-trend trend-up-bad" > +23ms< / span > < / div >
< div class = "stat-detail" > SLA: < 300ms · < strong style = "color: var(--warning);" > CLOSE< / strong > < / div >
< / div >
< / div >
<!-- Filter bar -->
< div class = "filter-section animate-in delay-1" >
< div class = "filter-row" >
< div class = "filter-input-wrap" >
< span class = "fi-icon" > 🔎 < / span >
< input class = "filter-input" type = "text" placeholder = "Search by Order ID, correlation ID, error message..." >
< / div >
< div class = "filter-sep" > < / div >
< div class = "filter-group" >
< span class = "filter-label" > Status< / span >
< span class = "filter-pill active" > All < span class = "pill-count" > 3,241< / span > < / span >
< span class = "filter-pill" > < span class = "pill-dot" style = "background: var(--success);" > < / span > OK < span class = "pill-count" > 3,147< / span > < / span >
< span class = "filter-pill" > < span class = "pill-dot" style = "background: var(--warning);" > < / span > Warn < span class = "pill-count" > 56< / span > < / span >
< span class = "filter-pill" > < span class = "pill-dot" style = "background: var(--error);" > < / span > Error < span class = "pill-count" > 38< / span > < / span >
< span class = "filter-pill" > < span class = "pill-dot" style = "background: var(--running);" > < / span > Running < span class = "pill-count" > 9< / span > < / span >
< / div >
< div class = "filter-sep" > < / div >
< div class = "filter-group" >
< span class = "filter-label" > Time< / span >
< span class = "filter-pill" > 15m< / span >
< span class = "filter-pill" > 1h< / span >
< span class = "filter-pill active" > Shift< / span >
< span class = "filter-pill" > 24h< / span >
< span class = "filter-pill" > 7d< / span >
< / div >
< / div >
< div class = "active-filters" >
< span class = "filter-tag" > time: since 06:00 (shift) < button class = "filter-tag-remove" > × < / button > < / span >
< span class = "filter-tag" > app: order-service < button class = "filter-tag-remove" > × < / button > < / span >
< span class = "filter-tag" > sort: newest first < button class = "filter-tag-remove" > × < / button > < / span >
< button class = "clear-all" > Clear all< / button >
< / div >
< / div >
<!-- Execution table -->
< div class = "table-section animate-in delay-2" >
< div class = "table-header" >
< span class = "table-title" > Recent Executions< / span >
< div class = "table-right" >
< span class = "table-meta" > Showing 1-20 of 3,241< / span >
< button class = "live-btn" > < span class = "live-dot" > < / span > LIVE< / button >
< / div >
< / div >
< div class = "table-scroll" >
< table >
< thead >
< tr >
< th style = "width: 85px" > Status< / th >
< th > Route< / th >
< th > Order ID< / th >
< th > Customer< / th >
< th class = "sorted" > Started < span class = "sort-arrow" > ▼ < / span > < / th >
< th > Duration< / th >
< th > Agent< / th >
< / tr >
< / thead >
< tbody >
< tr class = "row-success" >
< td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td >
< td > < div class = "route-name" > order-intake< / div > < div class = "route-group" > order-flow< / div > < / td >
< td > < div class = "biz-id" > OP-92184< / div > < div class = "biz-id-secondary" > SAP-DE< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-44210< / span > < / td >
< td > < span class = "time-relative" > 2 min ago< / span > < span class = "time-absolute" > 09:12:04< / span > < / td >
< td > < span class = "duration dur-fast" > 87ms< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td >
< / tr >
< tr class = "row-success" >
< td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td >
< td > < div class = "route-name" > payment-validate< / div > < div class = "route-group" > payment-flow< / div > < / td >
< td > < div class = "biz-id" > OP-92183< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-18773< / span > < / td >
< td > < span class = "time-relative" > 3 min ago< / span > < span class = "time-absolute" > 09:11:22< / span > < / td >
< td > < span class = "duration dur-normal" > 164ms< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-2< / span > < / td >
< / tr >
< tr class = "row-running" >
< td > < span class = "status-badge status-running" > < span class = "status-dot" style = "animation: pulse 1.5s ease-in-out infinite;" > < / span > RUN< / span > < / td >
< td > < div class = "route-name" > order-enrichment< / div > < div class = "route-group" > order-flow< / div > < / td >
< td > < div class = "biz-id" > OP-92185< / div > < div class = "biz-id-secondary" > EDI-US< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-67501< / span > < / td >
< td > < span class = "time-relative" > 30s ago< / span > < span class = "time-absolute" > 09:13:44< / span > < / td >
< td > < span class = "duration" style = "color: var(--running);" > ~30s< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td >
< / tr >
< tr class = "row-warning" >
< td > < span class = "status-badge status-warning" > < span class = "status-dot" > < / span > WARN< / span > < / td >
< td > < div class = "route-name" > shipment-dispatch< / div > < div class = "route-group" > shipment-flow< / div > < / td >
< td > < div class = "biz-id" > OP-92180< / div > < div class = "biz-id-secondary" > SAP-DE< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-55019< / span > < / td >
< td > < span class = "time-relative" > 5 min ago< / span > < span class = "time-absolute" > 09:09:47< / span > < / td >
< td > < span class = "duration dur-slow" > 248ms< / span > < span class = "sla-tag" > SLA< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-3< / span > < / td >
< / tr >
<!-- ERROR with inline preview -->
< tr class = "row-error selected" >
< td > < span class = "status-badge status-error" > < span class = "status-dot" > < / span > ERR< / span > < / td >
< td > < div class = "route-name" > payment-process< / div > < div class = "route-group" > payment-flow< / div > < / td >
< td > < div class = "biz-id" > OP-88421< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-31094< / span > < / td >
< td > < span class = "time-relative" > 8 min ago< / span > < span class = "time-absolute" > 09:06:11< / span > < / td >
< td > < span class = "duration dur-breach" > 412ms< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-2< / span > < / td >
< / tr >
< tr class = "error-preview-row" >
< td colspan = "7" >
< div class = "error-preview" >
< span class = "error-preview-icon" > ⚠ < / span >
< div >
< div class = "error-preview-text" > org.apache.camel.CamelExecutionException: Payment gateway timeout after 5000ms — POST https://pay.provider.com/v2/charge returned HTTP 504. Retry exhausted (3/3).< / div >
< div class = "error-expand-hint" > Click to view full stack trace and exchange snapshot< / div >
< / div >
< / div >
< / td >
< / tr >
<!-- ERROR 2 -->
< tr class = "row-error" >
< td > < span class = "status-badge status-error" > < span class = "status-dot" > < / span > ERR< / span > < / td >
< td > < div class = "route-name" > order-enrichment< / div > < div class = "route-group" > order-flow< / div > < / td >
< td > < div class = "biz-id" > OP-88419< / div > < div class = "biz-id-secondary" > EDI-US< / div > < / td >
< td > < span class = "biz-id-secondary" > CUST-72841< / span > < / td >
< td > < span class = "time-relative" > 12 min ago< / span > < span class = "time-absolute" > 09:02:38< / span > < / td >
< td > < span class = "duration dur-breach" > 1,247ms< / span > < / td >
< td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td >
< / tr >
< tr class = "error-preview-row" >
< td colspan = "7" >
< div class = "error-preview" >
< span class = "error-preview-icon" > ⚠ < / span >
< div >
< div class = "error-preview-text" > java.sql.SQLTransientConnectionException: HikariPool-1 - Connection not available, request timed out after 1000ms. (pool: 10, active: 10, idle: 0, waiting: 3)< / div >
< div class = "error-expand-hint" > Click to view full stack trace and exchange snapshot< / div >
< / div >
< / div >
< / td >
< / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > order-intake< / div > < div class = "route-group" > order-flow< / div > < / td > < td > < div class = "biz-id" > OP-92179< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-90123< / span > < / td > < td > < span class = "time-relative" > 14 min ago< / span > < span class = "time-absolute" > 09:00:15< / span > < / td > < td > < span class = "duration dur-fast" > 62ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-3< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > payment-validate< / div > < div class = "route-group" > payment-flow< / div > < / td > < td > < div class = "biz-id" > OP-92178< / div > < div class = "biz-id-secondary" > SAP-DE< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-44210< / span > < / td > < td > < span class = "time-relative" > 16 min ago< / span > < span class = "time-absolute" > 08:58:33< / span > < / td > < td > < span class = "duration dur-normal" > 131ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > shipment-track< / div > < div class = "route-group" > shipment-flow< / div > < / td > < td > < div class = "biz-id" > OP-92175< / div > < div class = "biz-id-secondary" > EDI-US< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-67892< / span > < / td > < td > < span class = "time-relative" > 21 min ago< / span > < span class = "time-absolute" > 08:53:07< / span > < / td > < td > < span class = "duration dur-fast" > 94ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-4< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > order-intake< / div > < div class = "route-group" > order-flow< / div > < / td > < td > < div class = "biz-id" > OP-92174< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-15293< / span > < / td > < td > < span class = "time-relative" > 24 min ago< / span > < span class = "time-absolute" > 08:50:41< / span > < / td > < td > < span class = "duration dur-fast" > 73ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > payment-process< / div > < div class = "route-group" > payment-flow< / div > < / td > < td > < div class = "biz-id" > OP-92173< / div > < div class = "biz-id-secondary" > SAP-DE< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-88104< / span > < / td > < td > < span class = "time-relative" > 28 min ago< / span > < span class = "time-absolute" > 08:46:19< / span > < / td > < td > < span class = "duration dur-normal" > 198ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-2< / span > < / td > < / tr >
< tr class = "row-warning" > < td > < span class = "status-badge status-warning" > < span class = "status-dot" > < / span > WARN< / span > < / td > < td > < div class = "route-name" > order-enrichment< / div > < div class = "route-group" > order-flow< / div > < / td > < td > < div class = "biz-id" > OP-92170< / div > < div class = "biz-id-secondary" > EDI-US< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-50321< / span > < / td > < td > < span class = "time-relative" > 35 min ago< / span > < span class = "time-absolute" > 08:39:52< / span > < / td > < td > < span class = "duration dur-slow" > 267ms< / span > < span class = "sla-tag" > SLA< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > shipment-dispatch< / div > < div class = "route-group" > shipment-flow< / div > < / td > < td > < div class = "biz-id" > OP-92168< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-29104< / span > < / td > < td > < span class = "time-relative" > 42 min ago< / span > < span class = "time-absolute" > 08:32:28< / span > < / td > < td > < span class = "duration dur-fast" > 55ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-3< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > order-intake< / div > < div class = "route-group" > order-flow< / div > < / td > < td > < div class = "biz-id" > OP-92165< / div > < div class = "biz-id-secondary" > SAP-DE< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-77618< / span > < / td > < td > < span class = "time-relative" > 51 min ago< / span > < span class = "time-absolute" > 08:23:14< / span > < / td > < td > < span class = "duration dur-fast" > 81ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-4< / span > < / td > < / tr >
< tr class = "row-error" > < td > < span class = "status-badge status-error" > < span class = "status-dot" > < / span > ERR< / span > < / td > < td > < div class = "route-name" > payment-process< / div > < div class = "route-group" > payment-flow< / div > < / td > < td > < div class = "biz-id" > OP-91844< / div > < div class = "biz-id-secondary" > WEB-EU< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-10082< / span > < / td > < td > < span class = "time-relative" > 5 hours ago< / span > < span class = "time-absolute" > 04:12:55< / span > < / td > < td > < span class = "duration dur-breach" > timeout< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-2< / span > < / td > < / tr >
< tr class = "row-success" > < td > < span class = "status-badge status-success" > < span class = "status-dot" > < / span > OK< / span > < / td > < td > < div class = "route-name" > order-intake< / div > < div class = "route-group" > order-flow< / div > < / td > < td > < div class = "biz-id" > OP-91840< / div > < div class = "biz-id-secondary" > EDI-US< / div > < / td > < td > < span class = "biz-id-secondary" > CUST-38291< / span > < / td > < td > < span class = "time-relative" > 5 hours ago< / span > < span class = "time-absolute" > 04:10:22< / span > < / td > < td > < span class = "duration dur-fast" > 78ms< / span > < / td > < td > < span class = "agent-badge" > < span class = "agent-badge-dot health-live" > < / span > prod-1< / span > < / td > < / tr >
< / tbody >
< / table >
< / div >
< div class = "table-footer" >
< span class = "mono" style = "font-size: 11px;" > 20 rows per page< / span >
< div class = "pagination" >
< button class = "page-btn active" > 1< / button >
< button class = "page-btn" > 2< / button >
< button class = "page-btn" > 3< / button >
< button class = "page-btn" > ...< / button >
< button class = "page-btn" > 162< / button >
< / div >
< / div >
< / div >
<!-- Metrics panel -->
< div class = "metrics-row animate-in delay-3" >
< div class = "metric-card" >
< div class = "metric-card-header" >
< span class = "metric-card-title" > Throughput (1h)< / span >
< span class = "metric-card-value" > 47.2< span style = "font-size:11px; font-weight:400; color: var(--text-muted)" > msg/s< / span > < / span >
< / div >
< div class = "metric-chart" >
< svg width = "100%" height = "100%" viewBox = "0 0 300 65" preserveAspectRatio = "none" >
< line x1 = "0" y1 = "16" x2 = "300" y2 = "16" class = "chart-grid-line" / >
< line x1 = "0" y1 = "32" x2 = "300" y2 = "32" class = "chart-grid-line" / >
< line x1 = "0" y1 = "48" x2 = "300" y2 = "48" class = "chart-grid-line" / >
< path d = "M0,50 L25,47 50,43 75,45 100,40 125,37 150,39 175,35 200,33 225,35 250,37 275,34 300,33 L300,65 L0,65 Z" fill = "#22D3EE" class = "chart-area" / >
< path d = "M0,50 L25,47 50,43 75,45 100,40 125,37 150,39 175,35 200,33 225,35 250,37 275,34 300,33" stroke = "#22D3EE" class = "chart-line" / >
< text x = "0" y = "63" class = "chart-label" > 08:15< / text >
< text x = "145" y = "63" class = "chart-label" > 08:45< / text >
< text x = "282" y = "63" class = "chart-label" > 09:14< / text >
< / svg >
< / div >
< / div >
< div class = "metric-card" >
< div class = "metric-card-header" >
< span class = "metric-card-title" > Latency p99 (1h)< / span >
< span class = "metric-card-value" style = "color: var(--warning);" > 287< span style = "font-size:11px; font-weight:400; color: var(--text-muted)" > ms< / span > < span style = "font-size:12px; color: var(--error);" > ↗ < / span > < / span >
< / div >
< div class = "metric-chart" >
< svg width = "100%" height = "100%" viewBox = "0 0 300 65" preserveAspectRatio = "none" >
< line x1 = "0" y1 = "16" x2 = "300" y2 = "16" class = "chart-grid-line" / >
< line x1 = "0" y1 = "32" x2 = "300" y2 = "32" class = "chart-grid-line" / >
< line x1 = "0" y1 = "48" x2 = "300" y2 = "48" class = "chart-grid-line" / >
< line x1 = "0" y1 = "10" x2 = "300" y2 = "10" class = "sla-line" / >
< text x = "4" y = "8" class = "sla-label-text" > SLA 300ms< / text >
< rect x = "0" y = "0" width = "300" height = "10" fill = "rgba(244, 63, 94, 0.04)" / >
< path d = "M0,42 L25,40 50,37 75,35 100,33 125,30 150,27 175,23 200,20 225,18 250,16 275,14 300,13 L300,65 L0,65 Z" fill = "#F0B429" class = "chart-area" / >
< path d = "M0,42 L25,40 50,37 75,35 100,33 125,30 150,27 175,23 200,20 225,18 250,16 275,14 300,13" stroke = "#F0B429" class = "chart-line" / >
< path d = "M0,52 L25,53 50,52 75,50 100,52 125,51 150,50 175,52 200,50 225,49 250,50 275,48 300,47" stroke = "#22D3EE" stroke-width = "1" opacity = "0.4" fill = "none" stroke-dasharray = "4 3" / >
< text x = "0" y = "63" class = "chart-label" > 08:15< / text >
< text x = "145" y = "63" class = "chart-label" > 08:45< / text >
< text x = "282" y = "63" class = "chart-label" > 09:14< / text >
< / svg >
< / div >
< / div >
< div class = "metric-card" >
< div class = "metric-card-header" >
< span class = "metric-card-title" > Error Rate (1h)< / span >
< span class = "metric-card-value" style = "color: var(--error);" > 2.9< span style = "font-size:11px; font-weight:400; color: var(--text-muted)" > %< / span > < span style = "font-size:12px;" > ↗ < / span > < / span >
< / div >
< div class = "metric-chart" >
< svg width = "100%" height = "100%" viewBox = "0 0 300 65" preserveAspectRatio = "none" >
< line x1 = "0" y1 = "16" x2 = "300" y2 = "16" class = "chart-grid-line" / >
< line x1 = "0" y1 = "32" x2 = "300" y2 = "32" class = "chart-grid-line" / >
< line x1 = "0" y1 = "48" x2 = "300" y2 = "48" class = "chart-grid-line" / >
< line x1 = "0" y1 = "16" x2 = "300" y2 = "16" class = "sla-line" / >
< text x = "4" y = "14" class = "sla-label-text" > SLA 5%< / text >
< rect x = "2" y = "54" width = "18" height = "11" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "24" y = "56" width = "18" height = "9" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "46" y = "58" width = "18" height = "7" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "68" y = "55" width = "18" height = "10" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "90" y = "52" width = "18" height = "13" rx = "2" fill = "rgba(244, 63, 94, 0.3)" / >
< rect x = "112" y = "56" width = "18" height = "9" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "134" y = "59" width = "18" height = "6" rx = "2" fill = "rgba(244, 63, 94, 0.25)" / >
< rect x = "156" y = "50" width = "18" height = "15" rx = "2" fill = "rgba(244, 63, 94, 0.35)" / >
< rect x = "178" y = "45" width = "18" height = "20" rx = "2" fill = "rgba(244, 63, 94, 0.5)" / >
< rect x = "200" y = "42" width = "18" height = "23" rx = "2" fill = "rgba(244, 63, 94, 0.55)" / >
< rect x = "222" y = "38" width = "18" height = "27" rx = "2" fill = "rgba(244, 63, 94, 0.6)" / >
< rect x = "244" y = "36" width = "18" height = "29" rx = "2" fill = "rgba(244, 63, 94, 0.65)" / >
< rect x = "266" y = "34" width = "18" height = "31" rx = "2" fill = "rgba(244, 63, 94, 0.75)" / >
< text x = "0" y = "63" class = "chart-label" > 08:15< / text >
< text x = "145" y = "63" class = "chart-label" > 08:45< / text >
< text x = "282" y = "63" class = "chart-label" > 09:14< / text >
< / svg >
< / div >
< / div >
< / div >
< / div > <!-- /content -->
<!-- DETAIL PANEL -->
< div class = "detail-panel open" >
< div class = "detail-header" >
< div class = "detail-breadcrumb" >
< span > order-service< / span >
< span class = "bc-sep" > ▸ < / span >
< span > payment-process< / span >
< span class = "bc-sep" > ▸ < / span >
< span class = "bc-current" > OP-88421< / span >
< / div >
< button class = "detail-close" title = "Close (Esc)" > × < / button >
< / div >
< div class = "detail-tabs" >
< button class = "detail-tab active" > Overview< / button >
< button class = "detail-tab" > Processors< / button >
< button class = "detail-tab" > Exchange< / button >
< button class = "detail-tab" > Error< / button >
< / div >
< div class = "detail-body" >
< div class = "detail-section" >
< div class = "detail-section-title" > Execution Details< / div >
< div class = "detail-grid" >
< span class = "detail-key" > Status< / span >
< span class = "detail-val" > < span class = "status-badge status-error" style = "font-size:10px" > < span class = "status-dot" > < / span > FAILED< / span > < / span >
< span class = "detail-key" > Order ID< / span >
< span class = "detail-val" style = "color: var(--cyan);" > OP-88421< / span >
< span class = "detail-key" > Customer< / span >
< span class = "detail-val" > CUST-31094< / span >
< span class = "detail-key" > Source< / span >
< span class = "detail-val" > WEB-EU< / span >
< span class = "detail-key" > Correlation ID< / span >
< span class = "detail-val" > c7e2a1f0-9b3d-4e1a-8f2c-5d6e7f8a9b0c< / span >
< span class = "detail-key" > Application< / span >
< span class = "detail-val" > order-service< / span >
< span class = "detail-key" > Route< / span >
< span class = "detail-val link" > payment-process< / span >
< span class = "detail-key" > Agent< / span >
< span class = "detail-val" > prod-2< / span >
< span class = "detail-key" > Started< / span >
< span class = "detail-val" > 2026-03-17T09:06:11.341Z< / span >
< span class = "detail-key" > Duration< / span >
< span class = "detail-val error-text" > 412ms< / span >
< span class = "detail-key" > Processors< / span >
< span class = "detail-val" > 7 (5 ok, 1 failed, 1 skipped)< / span >
< / div >
< / div >
< div class = "detail-section" >
< div class = "detail-section-title" > Processor Timeline< / div >
< div class = "processor-timeline" >
< div class = "proc-row" > < span class = "proc-name" > unmarshal< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-ok" style = "left:0;width:8%" > 12ms< / div > < / div > < span class = "proc-dur" > 12ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" > validate< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-ok" style = "left:8%;width:5%" > 8ms< / div > < / div > < span class = "proc-dur" > 8ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" > enrich(inventory)< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-slow" style = "left:13%;width:20%" > 85ms< / div > < / div > < span class = "proc-dur" > 85ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" > transform< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-ok" style = "left:33%;width:3%" > 5ms< / div > < / div > < span class = "proc-dur" > 5ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" > to(payment-api)< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-fail" style = "left:36%;width:58%" > 280ms< / div > < / div > < span class = "proc-dur" > 280ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" > log< / span > < div class = "proc-bar-bg" > < div class = "proc-bar-fill proc-ok" style = "left:94%;width:2%" > 2ms< / div > < / div > < span class = "proc-dur" > 2ms< / span > < / div >
< div class = "proc-row" > < span class = "proc-name" style = "color: var(--text-faint);" > marshal< / span > < div class = "proc-bar-bg" style = "opacity:0.3" > < / div > < span class = "proc-dur" style = "color: var(--text-faint);" > skip< / span > < / div >
< / div >
< / div >
< div class = "detail-section" >
< div class = "detail-section-title" > Error< / div >
< div class = "error-block" >
< div class = "error-class" > org.apache.camel.http.base.HttpOperationFailedException< / div >
< div class = "error-message-detail" >
HTTP operation failed invoking https://pay.provider.com/v2/charge< br >
with statusCode: 504 Gateway Timeout< br >
Retry exhausted (3/3 attempts)< br >
at processor: to(payment-api) [step 5/7]
< / div >
< button class = "error-expand" > ▸ Show full stack trace< / button >
< / div >
< / div >
< / div >
< div class = "detail-actions" >
< button class = "action-btn primary" > View Route Diagram< / button >
< button class = "action-btn secondary" > Copy ID< / button >
< button class = "action-btn secondary" > Re-process< / button >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "shortcuts-bar" >
< div class = "shortcut-hint" > < kbd > Ctrl< / kbd > +< kbd > K< / kbd > Search< / div >
< div class = "shortcut-hint" > < kbd > ↑ < / kbd > < kbd > ↓ < / kbd > Navigate< / div >
< div class = "shortcut-hint" > < kbd > Enter< / kbd > Detail< / div >
< div class = "shortcut-hint" > < kbd > Esc< / kbd > Close< / div >
< div class = "shortcut-hint" > < kbd > ?< / kbd > Shortcuts< / div >
< / div >
< / body >
< / html >