function initialState() { return { consecutiveFailures: 0, alerted: false, lastAlertAt: null }; } // Keycloakのtoken発行チェック結果からアラート状態を遷移させる純粋関数。 // alertThreshold回連続失敗するまでは通知しない(単発の揺らぎで騒がない)。 // 通知後もダウンが続く場合はrealertIntervalMsごとに再通知、復旧したら1回だけ復旧通知する。 function evaluate(state, checkOk, now, { alertThreshold, realertIntervalMs }) { if (checkOk) { if (state.alerted) { return { newState: initialState(), action: 'alert-recovered' }; } return { newState: initialState(), action: 'none' }; } const consecutiveFailures = state.consecutiveFailures + 1; if (consecutiveFailures < alertThreshold) { return { newState: { ...state, consecutiveFailures }, action: 'none' }; } if (!state.alerted) { return { newState: { consecutiveFailures, alerted: true, lastAlertAt: now }, action: 'alert-down' }; } if (now - state.lastAlertAt >= realertIntervalMs) { return { newState: { consecutiveFailures, alerted: true, lastAlertAt: now }, action: 'alert-still-down' }; } return { newState: { consecutiveFailures, alerted: true, lastAlertAt: state.lastAlertAt }, action: 'none' }; } module.exports = { initialState, evaluate };