fix(backoffice): merchant-friendly wording in Monitoring
Analytics, Reports, and Diagnostics were already clean (no raw
HTTP/queue-worker strings found on audit). Monitoring had three spots
speaking developer language by default:
- Background queue names ("order-notifications") -> friendly labels
("Order notifications").
- Webhook event keys ("order.created") -> friendly labels ("New order
placed").
- Activity log's "api" category showed the raw HTTP line
("GET /api/products responded 200 in 84ms") as the primary message.
Now shows a plain-language summary by default ("Product data
refreshed successfully"), with the raw string moved to a collapsed
"Technical details" <details> per event (api/error/warning rows).
This commit is contained in:
@@ -8,6 +8,8 @@ export interface AdminMonitoringEvent {
|
||||
category: AdminMonitoringCategory;
|
||||
level: AdminMonitoringLevel;
|
||||
message: string;
|
||||
/** Raw technical detail (endpoint, status code, latency, etc.), shown only behind "Technical details". */
|
||||
technicalDetail?: string;
|
||||
actor: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="queue-grid">
|
||||
@for (queue of facade.queues(); track queue.name) {
|
||||
<div class="queue-item">
|
||||
<strong>{{ queue.name }}</strong>
|
||||
<strong>{{ queueLabel(queue.name) }}</strong>
|
||||
<span>{{ 'adminMonitoring.depth' | translate }}: {{ queue.depth }}</span>
|
||||
<app-badge [variant]="queue.status === 'healthy' ? 'success' : queue.status === 'degraded' ? 'warning' : 'danger'">{{ ('adminMonitoring.queueStatus.' + queue.status) | translate }}</app-badge>
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@
|
||||
@for (delivery of facade.webhooks(); track delivery.id) {
|
||||
<tr>
|
||||
<th scope="row">{{ delivery.endpoint }}</th>
|
||||
<td>{{ delivery.event }}</td>
|
||||
<td>{{ webhookEventLabel(delivery.event) }}</td>
|
||||
<td><app-badge [variant]="delivery.status === 'delivered' ? 'success' : delivery.status === 'failed' ? 'danger' : 'neutral'">{{ ('adminMonitoring.webhookStatus.' + delivery.status) | translate }}</app-badge></td>
|
||||
<td>{{ delivery.timestamp | date:'short' }}</td>
|
||||
</tr>
|
||||
@@ -97,7 +97,15 @@
|
||||
<tr>
|
||||
<td>{{ ('adminMonitoring.categoryValue.' + event.category) | translate }}</td>
|
||||
<td><app-badge [variant]="event.level === 'error' ? 'danger' : event.level === 'warning' ? 'warning' : 'neutral'">{{ ('adminMonitoring.levelValue.' + event.level) | translate }}</app-badge></td>
|
||||
<td>{{ event.message }}</td>
|
||||
<td>
|
||||
{{ event.message }}
|
||||
@if (event.technicalDetail) {
|
||||
<details class="monitoring-technical-detail">
|
||||
<summary>{{ 'adminMonitoring.technicalDetails' | translate }}</summary>
|
||||
<code>{{ event.technicalDetail }}</code>
|
||||
</details>
|
||||
}
|
||||
</td>
|
||||
<td>{{ event.actor }}</td>
|
||||
<td>{{ event.timestamp | date:'short' }}</td>
|
||||
</tr>
|
||||
|
||||
@@ -13,3 +13,12 @@ select { min-height: 40px; padding: 0 10px; border: 1px solid var(--border-color
|
||||
// to a plain <td> - only the semantics change, not the visuals.
|
||||
tbody th[scope='row'] { font-weight: inherit; color: inherit; text-align: left; vertical-align: middle; }
|
||||
tbody tr:last-child th[scope='row'] { border-bottom: none; }
|
||||
|
||||
.monitoring-technical-detail {
|
||||
margin-top: 4px;
|
||||
font-size: var(--font-size-sm, 0.8125rem);
|
||||
color: var(--text-secondary);
|
||||
|
||||
summary { cursor: pointer; color: var(--text-secondary); }
|
||||
code { display: block; margin-top: 4px; word-break: break-all; }
|
||||
}
|
||||
|
||||
@@ -25,7 +25,26 @@ export class AdminMonitoringPageComponent {
|
||||
|
||||
readonly categories = ['all', 'audit', 'security', 'login', 'failed_login', 'api', 'error', 'warning'] as const;
|
||||
|
||||
private readonly queueLabels: Record<string, string> = {
|
||||
'order-notifications': 'Order notifications',
|
||||
'media-processing': 'Media processing',
|
||||
'webhook-delivery': 'Webhook delivery',
|
||||
};
|
||||
|
||||
private readonly webhookEventLabels: Record<string, string> = {
|
||||
'order.created': 'New order placed',
|
||||
'inventory.updated': 'Inventory updated',
|
||||
};
|
||||
|
||||
constructor() {
|
||||
this.facade.loadAll();
|
||||
}
|
||||
|
||||
queueLabel(name: string): string {
|
||||
return this.queueLabels[name] ?? name;
|
||||
}
|
||||
|
||||
webhookEventLabel(event: string): string {
|
||||
return this.webhookEventLabels[event] ?? event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ export class AdminMonitoringLocalGateway implements AdminMonitoringGateway {
|
||||
category,
|
||||
level,
|
||||
message: this.messageFor(category, index),
|
||||
technicalDetail: this.technicalDetailFor(category, index),
|
||||
actor: ACTORS[index % ACTORS.length],
|
||||
timestamp: new Date(Date.now() - index * 45 * 60 * 1000).toISOString(),
|
||||
};
|
||||
@@ -73,10 +74,19 @@ export class AdminMonitoringLocalGateway implements AdminMonitoringGateway {
|
||||
case 'security': return `Security policy check passed (#${index})`;
|
||||
case 'login': return `Successful admin login (#${index})`;
|
||||
case 'failed_login': return `Failed login attempt (#${index})`;
|
||||
case 'api': return `GET /api/products responded 200 in ${80 + index}ms`;
|
||||
case 'error': return `Unhandled exception in checkout flow (#${index})`;
|
||||
case 'warning': return `Slow query detected (#${index})`;
|
||||
case 'api': return `Product data refreshed successfully`;
|
||||
case 'error': return `A background task failed unexpectedly`;
|
||||
case 'warning': return `A data lookup took longer than usual`;
|
||||
default: return `Event #${index}`;
|
||||
}
|
||||
}
|
||||
|
||||
private technicalDetailFor(category: AdminMonitoringCategory, index: number): string | undefined {
|
||||
switch (category) {
|
||||
case 'api': return `GET /api/products responded 200 in ${80 + index}ms`;
|
||||
case 'error': return `Unhandled exception in checkout flow (#${index})`;
|
||||
case 'warning': return `Slow query detected (#${index})`;
|
||||
default: return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user