Skip to content

Commit dabe8eb

Browse files
Render scheduler-role health on the Waterline dashboard
Adds a Scheduler-role health section to the Operator metrics panel on `resources/js/screens/dashboard.vue`. The section reads the frozen `operator_metrics.schedules.*` namespace exposed by the workflow v2 package — `active`, `paused`, `missed`, `oldest_overdue_at`, `max_overdue_ms`, `fires_total`, `failures_total` — so operators can read namespace-wide scheduler lag and failure trends on the dashboard without cross-referencing the schedules registry. Graceful degradation: the section renders a short 'no scheduler-role metrics exposed' note when the `operator_metrics.schedules` key is absent (pre-alpha workflow builds that predate the schedule metrics surface). The rest of the panel renders unchanged. Assets: `public/app.js` + `public/mix-manifest.json` rebuilt with `npm run production`. Tests: V2DashboardStatsControllerTest 4/125 green under phpunit-sqlite.xml in php:8.4-cli-alpine. Public Boundary scan exit 0. No feature assertion is added for the `operator_metrics.schedules` keys yet because the vendored workflow alpha predates the schedule metrics contract; once a new alpha lands, a follow-up slice can pin the key shape in V2DashboardStatsControllerTest.
1 parent a84cec2 commit dabe8eb

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

public/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/mix-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"/app.js": "/app.js?id=9ffaca09c5284fe2234d8db01eaa8be7",
2+
"/app.js": "/app.js?id=bd13ae38fe059a9a27f896bb0d995078",
33
"/app-dark.css": "/app-dark.css?id=8b1b08a71c8e9860d0a9030d902c30d0",
44
"/app.css": "/app.css?id=4d346e04fa466f5227cee3c313fbea25",
55
"/img/favicon.png": "/img/favicon.png?id=7c006241b093796d6abfa3049df93a59",

resources/js/screens/dashboard.vue

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,28 @@
411411
</p>
412412
</section>
413413

414+
<section class="wl-operator-section">
415+
<div class="wl-panel-subtitle">Scheduler-role health</div>
416+
<p v-if="!operatorSchedulesAvailable()" class="text-muted">
417+
No scheduler-role metrics exposed by the current workflow engine.
418+
</p>
419+
<template v-else>
420+
<p>
421+
{{ operatorMetricLabel('schedules', 'active') }} active schedules,
422+
{{ operatorMetricLabel('schedules', 'paused') }} paused,
423+
{{ operatorMetricLabel('schedules', 'missed') }} overdue this tick,
424+
oldest {{ operatorDurationMetricLabel('schedules', 'max_overdue_ms') }} behind.
425+
</p>
426+
<p v-if="operatorScheduleOldestOverdueAt()">
427+
Oldest overdue fire due at {{ operatorScheduleOldestOverdueAt() }}.
428+
</p>
429+
<p>
430+
{{ operatorMetricLabel('schedules', 'fires_total') }} fires recorded against active schedules,
431+
{{ operatorMetricLabel('schedules', 'failures_total') }} failures.
432+
</p>
433+
</template>
434+
</section>
435+
414436
<section class="wl-operator-section">
415437
<div class="wl-panel-subtitle">Worker compatibility fleet</div>
416438
<p v-if="!operatorWorkerFleet().length" class="text-muted">
@@ -1070,6 +1092,18 @@ export default {
10701092
return repair.oldest_missing_run_started_at || null;
10711093
},
10721094
1095+
operatorSchedulesAvailable() {
1096+
const schedules = this.operatorMetrics && this.operatorMetrics.schedules;
1097+
1098+
return schedules !== undefined && schedules !== null;
1099+
},
1100+
1101+
operatorScheduleOldestOverdueAt() {
1102+
const schedules = (this.operatorMetrics && this.operatorMetrics.schedules) || {};
1103+
1104+
return schedules.oldest_overdue_at || null;
1105+
},
1106+
10731107
operatorWorkerFleet() {
10741108
const workers = (this.operatorMetrics && this.operatorMetrics.workers) || {};
10751109
const fleet = Array.isArray(workers.fleet) ? workers.fleet : [];

0 commit comments

Comments
 (0)