Skip to content

Commit ea57872

Browse files
committed
Update summarize.ts
1 parent d5a5d89 commit ea57872

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

packages/shared/src/lib/health-check/summarize.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import type { HealthCheckSnapshot } from './state/HealthCheckState';
22

3-
export type OverallStatus = 'healthy' | 'unhealthy' | 'unknown';
3+
export type OverallStatus = 'healthy' | 'partial' | 'unhealthy' | 'unknown';
4+
5+
// Provider checks registered as 'OAuth2: <provider>' form one login group:
6+
// users need only one working provider, so a broken provider alongside a
7+
// healthy one degrades the system to 'partial' rather than 'unhealthy'.
8+
const OAUTH2_GROUP_PREFIX = 'OAuth2: ';
49

510
export interface ServiceHealthView extends HealthCheckSnapshot {
611
/** True when the last result is too old to say anything about the present. */
@@ -30,6 +35,9 @@ const DEFAULT_STALE_AFTER_MS = 3 * 60_000;
3035
* - A result older than two check intervals proves nothing about the present;
3136
* it is flagged stale and counted as 'unknown'.
3237
* - 'healthy' requires every service to have a fresh, healthy result.
38+
* - OAuth2 provider checks are one group: as long as one provider is healthy,
39+
* failed providers yield 'partial' instead of 'unhealthy'. With no healthy
40+
* provider left (or a non-OAuth service down), the status is 'unhealthy'.
3341
*/
3442
export function summarizeHealth(
3543
snapshots: Record<string, HealthCheckSnapshot>,
@@ -49,11 +57,20 @@ export function summarizeHealth(
4957
const unhealthy = list.filter((s) => effectiveStatus(s) === 'unhealthy').length;
5058
const unknown = list.filter((s) => effectiveStatus(s) === 'unknown').length;
5159

60+
const entries = Object.entries(services);
61+
const isOAuth2 = ([name]: [string, ServiceHealthView]) => name.startsWith(OAUTH2_GROUP_PREFIX);
62+
const coreStatuses = entries.filter((e) => !isOAuth2(e)).map(([, s]) => effectiveStatus(s));
63+
const oauthStatuses = entries.filter(isOAuth2).map(([, s]) => effectiveStatus(s));
64+
const oauthHealthy = oauthStatuses.filter((s) => s === 'healthy').length;
65+
const oauthUnhealthy = oauthStatuses.filter((s) => s === 'unhealthy').length;
66+
5267
let overallStatus: OverallStatus;
5368
if (list.length === 0) {
5469
overallStatus = 'unknown';
55-
} else if (unhealthy > 0) {
70+
} else if (coreStatuses.includes('unhealthy') || (oauthUnhealthy > 0 && oauthHealthy === 0)) {
5671
overallStatus = 'unhealthy';
72+
} else if (oauthUnhealthy > 0) {
73+
overallStatus = 'partial';
5774
} else if (unknown > 0) {
5875
overallStatus = 'unknown';
5976
} else {

0 commit comments

Comments
 (0)