2026-03-18 10:06:38 +01:00
|
|
|
export interface KpiMetric {
|
|
|
|
|
label: string
|
|
|
|
|
value: string | number
|
|
|
|
|
unit?: string
|
|
|
|
|
trend: 'up' | 'down' | 'neutral'
|
|
|
|
|
trendValue: string
|
|
|
|
|
trendSentiment: 'good' | 'bad' | 'neutral'
|
|
|
|
|
detail: string
|
|
|
|
|
accent: 'amber' | 'success' | 'error' | 'running' | 'warning'
|
|
|
|
|
sparkline: number[]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TimeSeriesPoint {
|
|
|
|
|
timestamp: Date
|
|
|
|
|
value: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MetricSeries {
|
|
|
|
|
label: string
|
|
|
|
|
data: TimeSeriesPoint[]
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-19 16:33:34 +01:00
|
|
|
// Generate a realistic time series for the past hours (06:00 - now ~09:15)
|
2026-03-18 10:06:38 +01:00
|
|
|
function generateTimeSeries(
|
|
|
|
|
baseValue: number,
|
|
|
|
|
variance: number,
|
|
|
|
|
points: number,
|
|
|
|
|
): TimeSeriesPoint[] {
|
|
|
|
|
const result: TimeSeriesPoint[] = []
|
|
|
|
|
const now = new Date('2026-03-18T09:15:00')
|
|
|
|
|
const start = new Date('2026-03-18T06:00:00')
|
|
|
|
|
const totalMs = now.getTime() - start.getTime()
|
|
|
|
|
const interval = totalMs / points
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i <= points; i++) {
|
|
|
|
|
const ts = new Date(start.getTime() + i * interval)
|
|
|
|
|
const noise = (Math.random() - 0.5) * 2 * variance
|
|
|
|
|
const trend = (i / points) * (baseValue * 0.1) // slight upward trend
|
|
|
|
|
result.push({ timestamp: ts, value: Math.max(0, baseValue + noise + trend) })
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// KPI stat cards data
|
|
|
|
|
export const kpiMetrics: KpiMetric[] = [
|
|
|
|
|
{
|
2026-03-19 16:33:34 +01:00
|
|
|
label: 'Exchanges',
|
2026-03-18 10:06:38 +01:00
|
|
|
value: '3,241',
|
|
|
|
|
trend: 'up',
|
|
|
|
|
trendValue: '+12%',
|
|
|
|
|
trendSentiment: 'good',
|
2026-03-19 16:33:34 +01:00
|
|
|
detail: '97.1% success rate',
|
2026-03-18 10:06:38 +01:00
|
|
|
accent: 'amber',
|
|
|
|
|
sparkline: [28, 32, 29, 35, 38, 41, 37, 44, 42, 47, 45, 51, 48, 52],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Success Rate',
|
|
|
|
|
value: '97.1%',
|
|
|
|
|
trend: 'down',
|
|
|
|
|
trendValue: '-0.4%',
|
|
|
|
|
trendSentiment: 'bad',
|
|
|
|
|
detail: '3,147 ok / 56 warn / 38 error',
|
|
|
|
|
accent: 'success',
|
|
|
|
|
sparkline: [98.2, 97.9, 98.1, 97.8, 97.5, 97.6, 97.4, 97.2, 97.3, 97.1, 97.0, 97.1, 97.2, 97.1],
|
|
|
|
|
},
|
|
|
|
|
{
|
2026-03-19 16:33:34 +01:00
|
|
|
label: 'Errors',
|
2026-03-18 10:06:38 +01:00
|
|
|
value: 38,
|
|
|
|
|
trend: 'up',
|
|
|
|
|
trendValue: '+5',
|
|
|
|
|
trendSentiment: 'bad',
|
2026-03-19 16:33:34 +01:00
|
|
|
detail: '38 errors in selected period',
|
2026-03-18 10:06:38 +01:00
|
|
|
accent: 'error',
|
|
|
|
|
sparkline: [1, 2, 1, 3, 2, 4, 3, 5, 4, 6, 5, 7, 6, 8],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Throughput',
|
|
|
|
|
value: '47.2',
|
|
|
|
|
unit: 'msg/s',
|
|
|
|
|
trend: 'neutral',
|
|
|
|
|
trendValue: '→',
|
|
|
|
|
trendSentiment: 'neutral',
|
|
|
|
|
detail: 'Capacity: 120 msg/s · 39%',
|
|
|
|
|
accent: 'running',
|
|
|
|
|
sparkline: [44, 46, 45, 47, 48, 46, 47, 48, 46, 47, 48, 47, 46, 47],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Latency p99',
|
|
|
|
|
value: 287,
|
|
|
|
|
unit: 'ms',
|
|
|
|
|
trend: 'up',
|
|
|
|
|
trendValue: '+23ms',
|
|
|
|
|
trendSentiment: 'bad',
|
|
|
|
|
detail: 'SLA: <300ms · CLOSE',
|
|
|
|
|
accent: 'warning',
|
|
|
|
|
sparkline: [198, 212, 205, 218, 224, 231, 238, 245, 252, 261, 268, 275, 281, 287],
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
// Time series chart data
|
|
|
|
|
export const throughputSeries: MetricSeries[] = [
|
|
|
|
|
{
|
|
|
|
|
label: 'order-service',
|
|
|
|
|
data: generateTimeSeries(47, 8, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'payment-svc',
|
|
|
|
|
data: generateTimeSeries(28, 5, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'shipment-svc',
|
|
|
|
|
data: generateTimeSeries(19, 4, 40),
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
export const latencySeries: MetricSeries[] = [
|
|
|
|
|
{
|
|
|
|
|
label: 'p50',
|
|
|
|
|
data: generateTimeSeries(98, 15, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'p95',
|
|
|
|
|
data: generateTimeSeries(187, 25, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'p99',
|
|
|
|
|
data: generateTimeSeries(258, 35, 40),
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
export const errorCountSeries: MetricSeries[] = [
|
|
|
|
|
{
|
|
|
|
|
label: 'payment-flow',
|
|
|
|
|
data: generateTimeSeries(12, 4, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'order-flow',
|
|
|
|
|
data: generateTimeSeries(8, 3, 40),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'shipment-flow',
|
|
|
|
|
data: generateTimeSeries(4, 2, 40),
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
// Route-level metrics summary
|
|
|
|
|
export interface RouteMetricRow {
|
|
|
|
|
routeId: string
|
|
|
|
|
routeName: string
|
2026-03-19 15:29:27 +01:00
|
|
|
appId: string
|
2026-03-18 15:54:27 +01:00
|
|
|
exchangeCount: number
|
2026-03-18 10:06:38 +01:00
|
|
|
successRate: number
|
|
|
|
|
avgDurationMs: number
|
|
|
|
|
p99DurationMs: number
|
|
|
|
|
errorCount: number
|
|
|
|
|
sparkline: number[]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const routeMetrics: RouteMetricRow[] = [
|
|
|
|
|
{
|
|
|
|
|
routeId: 'order-intake',
|
|
|
|
|
routeName: 'order-intake',
|
2026-03-19 15:29:27 +01:00
|
|
|
appId: 'order-service',
|
2026-03-18 15:54:27 +01:00
|
|
|
exchangeCount: 892,
|
2026-03-18 10:06:38 +01:00
|
|
|
successRate: 99.2,
|
|
|
|
|
avgDurationMs: 88,
|
|
|
|
|
p99DurationMs: 142,
|
|
|
|
|
errorCount: 7,
|
|
|
|
|
sparkline: [82, 86, 84, 88, 91, 87, 90, 88, 85, 89, 88, 86, 89, 88],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
routeId: 'order-enrichment',
|
|
|
|
|
routeName: 'order-enrichment',
|
2026-03-19 15:29:27 +01:00
|
|
|
appId: 'order-service',
|
2026-03-18 15:54:27 +01:00
|
|
|
exchangeCount: 541,
|
2026-03-18 10:06:38 +01:00
|
|
|
successRate: 97.6,
|
|
|
|
|
avgDurationMs: 156,
|
|
|
|
|
p99DurationMs: 287,
|
|
|
|
|
errorCount: 13,
|
|
|
|
|
sparkline: [142, 148, 152, 158, 162, 155, 159, 164, 156, 160, 154, 158, 156, 156],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
routeId: 'payment-process',
|
|
|
|
|
routeName: 'payment-process',
|
2026-03-19 15:29:27 +01:00
|
|
|
appId: 'payment-svc',
|
2026-03-18 15:54:27 +01:00
|
|
|
exchangeCount: 414,
|
2026-03-18 10:06:38 +01:00
|
|
|
successRate: 96.1,
|
|
|
|
|
avgDurationMs: 234,
|
|
|
|
|
p99DurationMs: 412,
|
|
|
|
|
errorCount: 16,
|
|
|
|
|
sparkline: [210, 225, 232, 218, 241, 235, 228, 242, 238, 231, 244, 237, 233, 234],
|
|
|
|
|
},
|
2026-03-19 15:29:27 +01:00
|
|
|
{
|
|
|
|
|
routeId: 'payment-validate',
|
|
|
|
|
routeName: 'payment-validate',
|
|
|
|
|
appId: 'payment-svc',
|
|
|
|
|
exchangeCount: 498,
|
|
|
|
|
successRate: 99.8,
|
|
|
|
|
avgDurationMs: 142,
|
|
|
|
|
p99DurationMs: 198,
|
|
|
|
|
errorCount: 1,
|
|
|
|
|
sparkline: [138, 141, 140, 143, 145, 142, 144, 141, 139, 143, 142, 140, 141, 142],
|
|
|
|
|
},
|
2026-03-18 10:06:38 +01:00
|
|
|
{
|
|
|
|
|
routeId: 'shipment-dispatch',
|
|
|
|
|
routeName: 'shipment-dispatch',
|
2026-03-19 15:29:27 +01:00
|
|
|
appId: 'shipment-tracker',
|
2026-03-18 15:54:27 +01:00
|
|
|
exchangeCount: 387,
|
2026-03-18 10:06:38 +01:00
|
|
|
successRate: 98.4,
|
|
|
|
|
avgDurationMs: 118,
|
|
|
|
|
p99DurationMs: 248,
|
|
|
|
|
errorCount: 6,
|
|
|
|
|
sparkline: [112, 115, 118, 114, 120, 116, 119, 117, 118, 121, 116, 118, 119, 118],
|
|
|
|
|
},
|
2026-03-19 15:29:27 +01:00
|
|
|
{
|
|
|
|
|
routeId: 'shipment-track',
|
|
|
|
|
routeName: 'shipment-track',
|
|
|
|
|
appId: 'shipment-tracker',
|
|
|
|
|
exchangeCount: 923,
|
|
|
|
|
successRate: 99.5,
|
|
|
|
|
avgDurationMs: 94,
|
|
|
|
|
p99DurationMs: 167,
|
|
|
|
|
errorCount: 5,
|
|
|
|
|
sparkline: [88, 91, 93, 95, 92, 94, 96, 93, 91, 95, 94, 92, 93, 94],
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
routeId: 'notification-dispatch',
|
|
|
|
|
routeName: 'notification-dispatch',
|
|
|
|
|
appId: 'notification-hub',
|
|
|
|
|
exchangeCount: 471,
|
|
|
|
|
successRate: 98.9,
|
|
|
|
|
avgDurationMs: 62,
|
|
|
|
|
p99DurationMs: 124,
|
|
|
|
|
errorCount: 5,
|
|
|
|
|
sparkline: [58, 60, 63, 61, 64, 62, 60, 63, 65, 62, 61, 63, 62, 62],
|
|
|
|
|
},
|
2026-03-18 10:06:38 +01:00
|
|
|
]
|