feat: Operations Passwords tab and Service Health (#1635, layer 1 of 3) - #1636
Merged
Conversation
…ns service health (#1635) Implementation plan for three stacked layers (Operations and service health; a Password Delivery Service off the worker task queue; convergence of Set Password and Synchronise Password), and the PRD amendment recording the decisions that change requirements 21, 25 and 31. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rations (#1635) The standalone /admin/password-synchronisation page (unreleased) is dropped per decision D9. Its body moves to OperationsPasswordsTab, hosted as a fourth tab on Operations with a key icon and an amber badge of parked plus expired changes. The metaverseObjectId and connectedSystemId deep links keep working on the Operations route, and clearing a deep-linked filter also drops it from the URL so it does not return when the tab is re-created on a switch back. Deep links and wording updated: the Metaverse Object panel's queue link, the Connected Systems list indicator tooltip, the Administration index (tile removed; Operations tile mentions password delivery), the concepts doc and the unreleased changelog entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each background service now writes a ServiceHeartbeat row every 5 seconds from the same place it touches its container health-check file: the Worker's synchronisation loop (with its in-flight tasks as CurrentWork) and the Scheduler (both while waiting for readiness and, in heartbeat-sized slices of its 30-second wait, in its main loop). SystemHealthServer (JimApplication.SystemHealth) derives Running / Stale / NoProgress / NotSeen per service from the newest row, with the worst state as the report's Overall, for the Operations page, REST API and PowerShell to read. - JIM.Models.Operations: JimService, ServiceHeartbeat, ServiceHealthState, ServiceHealth, ServiceHealthReport - ISystemRepository: single-statement ON CONFLICT upsert, newest-per-service read, per-service prune - Migration AddServiceHeartbeats (unique index on Service, InstanceId) - ServiceHeartbeatWriter: throttled, prunes its service's day-old rows on first write, never throws a database failure into the host loop (first failure at Warning, repeats at Debug, recovery at Information) - JimVersion.Current shared by Web, Worker and Scheduler; HealthController uses it - TaskTask carries a dispatch-time description and start so the heartbeat costs no extra reads Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…1635) GET /api/v1/system/health (Administrator) returns the ServiceHealthReport the Operations page reads: overall state, web version, generated-at and one entry per service with state, reason, current work and instance detail, enums as string names, Cache-Control: no-store. Get-JIMServiceHealth emits one JIM.ServiceHealth object per service, or a single JIM.ServiceHealthSummary with -Summary whose Overall is the worst state present, for monitoring scripts. Docs: new configuration/operations.md describing the Operations page and its Service Health strip (states, thresholds, banner, version skew, REST and PowerShell equivalents), the cmdlet reference, and the endpoint noted in the API overview and deployment health table. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Password delivery has no heartbeat writer until the Password Delivery Service lands in the next layer, so listing it as expected put a permanent "never reported" card and a permanent administrator banner on every deployment. The report now covers the expected services (Worker sync loop, Scheduler) plus any service that has actually reported, in enum order; the next layer adds password delivery to the expected list. Docs describe three cards accordingly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
One card per background service at the top of Operations (Worker · Sync, Worker · Passwords, Scheduler) plus a Live updates card for the notification relay, polled by the page every ten seconds alongside the Passwords badge; a banner above every page for administrators when a service is not seen or a task has stalled, hidden on Operations itself; a red dot on the Operations tile of the Administration index under the same verdict. MainLayout's footer version now comes from JimVersion.Current so it matches what the strip compares service versions against. A password delivery service that has never reported beside a reporting Worker is treated as a version gap rather than an outage: the card says so, the banner stays quiet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The read model now decides which services are expected, so the banner's special case for a never-reported password delivery loop is redundant. Until a delivery loop is in the report, the synchronisation loop down is the whole Worker down, and the banner says so in those words. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…form cards (#1635) Replace ServiceHealthState with two enums: ServiceHealthStatus (Healthy, Degraded, Unhealthy; ordered by severity, Overall is the max) and ServiceHealthCondition (Heartbeating, HeartbeatOverdue, Stalled, NoHeartbeat, NeverStarted), with the thresholds unchanged and StatusOf as the single condition-to-status mapping. Reason sentences become plain words ("Heartbeat 3 seconds ago", "No heartbeat for 4 minutes", "Never started"). The REST DTO carries status and condition, the cmdlet Status and Condition, and the docs, Pester and API tests follow. Rebuild ServiceHealthStrip as a panel: a header with the title, a worst-first summary ("1 service unhealthy, 1 degraded") and the Live updates indicator (no longer a card), over a CSS grid of identical four-slot cards (name and status pill; activity; condition; host, version, uptime). The pill is the only coloured element; version skew is a "differs from portal" chip rather than amber text. The banner sentences and the Administration index red dot (Unhealthy, or Degraded by Stalled) are unchanged in behaviour. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
JayVDZ
enabled auto-merge (squash)
September 6, 2026 17:18
JayVDZ
pushed a commit
that referenced
this pull request
Sep 6, 2026
…ivery-service Three-way merge using the layer 1 tip (63bbbfe) as the base, because #1636 squash-merged and git's default merge-base predates it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mw5XPncvpoN78zeazx5jgi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Layer 1 of #1635 (plan:
engineering/plans/doing/PASSWORD_PIPELINE_CONVERGENCE.md). Bottom of a three-layer stack; layers 2 (Password Delivery Service) and 3 (one password operation) follow on top./admin/password-synchronisationpage moves under Administration > Operations as a fourth tab beside Queue, History and Schedules, badged with parked plus expired changes. Deep links carrymetaverseObjectIdandconnectedSystemIdon the Operations route.jim.workerandjim.schedulerwrite aServiceHeartbeatsrow every 5 s (instance, host, version, started, last seen, current work) alongside the file touch the container health check already uses. New migrationAddServiceHeartbeats.GET /api/v1/system/health(Administrator,Cache-Control: no-store) andGet-JIMServiceHealth(per-service objects, or-Summary). Docs: newdocs/configuration/operations.md,docs/powershell/system.md, API index, deployment health section. Changelog entries under Unreleased.Verification
dotnet build JIM.sln: 0 warnings, 0 errors.dotnet test JIM.sln: green (see checks).System.Tests.ps1and module tests: green.Lint-Changelog.ps1: passes.ServiceHeartbeatsrows for WorkerSync and Scheduler present with ages of 1 to 7 s over a 20 s sample; migration applied cleanly; web container healthy with the new components in the image. No signed-in screenshot: the review browser cannot reach the devcontainer's ports.Closes nothing on its own; #1635 closes when the stack lands.
🤖 Generated with Claude Code