Fix issues with critical alerts breaking the simulation
This commit is contained in:
@@ -6,9 +6,9 @@ import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const alert = {
|
||||
id: 'alert-1',
|
||||
alertType: 'SofaSepsis',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'SOFA_SEPSIS',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
details: 'SOFA delta >= 2',
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ import AlertCard from '@/components/alerts/AlertCard.vue'
|
||||
|
||||
const openAlert = {
|
||||
id: 'alert-1',
|
||||
alertType: 'SepsisWarning',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'SEPSIS_WARNING',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
details: 'SIRS criteria met',
|
||||
triggeredAt: '2026-06-19T12:00:00Z',
|
||||
}
|
||||
@@ -15,7 +15,7 @@ const openAlert = {
|
||||
const resolvedAlert = {
|
||||
...openAlert,
|
||||
id: 'alert-2',
|
||||
status: 'Resolved',
|
||||
status: 'RESOLVED',
|
||||
}
|
||||
|
||||
describe('AlertCard', () => {
|
||||
@@ -25,7 +25,7 @@ describe('AlertCard', () => {
|
||||
|
||||
it('showsAlertTypeAndSeverity', () => {
|
||||
const wrapper = mount(AlertCard, { props: { alert: openAlert } })
|
||||
expect(wrapper.text()).toContain('Critical')
|
||||
expect(wrapper.text()).toContain('CRITICAL')
|
||||
expect(wrapper.text()).toContain('Sepsis Warning (SIRS — Legacy)')
|
||||
})
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('AlertCard', () => {
|
||||
props: {
|
||||
alert: {
|
||||
...openAlert,
|
||||
status: 'Acknowledged',
|
||||
status: 'ACKNOWLEDGED',
|
||||
acknowledgedBy: 'Demo Nurse (NURSE)',
|
||||
acknowledgedAt: '2026-06-19T12:30:00Z',
|
||||
},
|
||||
|
||||
@@ -3,19 +3,19 @@ import { alertTypeLabel, bundleTriggerLabel } from '@/api/normalize'
|
||||
|
||||
describe('AlertLabels', () => {
|
||||
it('sofaSepsisLabel', () => {
|
||||
expect(alertTypeLabel('SofaSepsis')).toBe('Sepsis Alert (SOFA)')
|
||||
expect(alertTypeLabel('SOFA_SEPSIS')).toBe('Sepsis Alert (SOFA)')
|
||||
})
|
||||
|
||||
it('legacySepsisLabel', () => {
|
||||
expect(alertTypeLabel('SepsisWarning')).toBe('Sepsis Warning (SIRS — Legacy)')
|
||||
expect(alertTypeLabel('SEPSIS_WARNING')).toBe('Sepsis Warning (SIRS — Legacy)')
|
||||
})
|
||||
|
||||
it('qsofaScreenLabel', () => {
|
||||
expect(alertTypeLabel('QsofaScreen')).toBe('qSOFA Screen')
|
||||
expect(alertTypeLabel('QSOFA_SCREEN')).toBe('qSOFA Screen')
|
||||
})
|
||||
|
||||
it('gcsCriticalLabel', () => {
|
||||
expect(alertTypeLabel('GcsCritical')).toBe('GCS Critical (≤ 8)')
|
||||
expect(alertTypeLabel('GCS_CRITICAL')).toBe('GCS Critical (≤ 8)')
|
||||
})
|
||||
|
||||
it('bundleTriggerSofa', () => {
|
||||
|
||||
@@ -5,16 +5,16 @@ import AlertReasoning from '@/components/alerts/AlertReasoning.vue'
|
||||
|
||||
const sepsisAlert = {
|
||||
id: 'alert-1',
|
||||
alertType: 'SepsisWarning',
|
||||
severity: 'Critical',
|
||||
alertType: 'SEPSIS_WARNING',
|
||||
severity: 'CRITICAL',
|
||||
details: 'SIRS criteria met',
|
||||
triggeredAt: '2026-06-19T12:00:00Z',
|
||||
}
|
||||
|
||||
const qsofaScreenAlert = {
|
||||
id: 'alert-2',
|
||||
alertType: 'QsofaScreen',
|
||||
severity: 'Warning',
|
||||
alertType: 'QSOFA_SCREEN',
|
||||
severity: 'WARNING',
|
||||
details: 'qSOFA screen positive',
|
||||
triggeredAt: '2026-06-19T12:30:00Z',
|
||||
}
|
||||
@@ -42,7 +42,7 @@ describe('AlertReasoning', () => {
|
||||
const unknown = {
|
||||
id: 'alert-3',
|
||||
alertType: 'CustomUnknown',
|
||||
severity: 'Warning',
|
||||
severity: 'WARNING',
|
||||
details: 'Something unusual happened',
|
||||
triggeredAt: '2026-06-19T13:00:00Z',
|
||||
}
|
||||
@@ -54,8 +54,8 @@ describe('AlertReasoning', () => {
|
||||
it('showsStructuredExplanationWhenPresent', () => {
|
||||
const news2Alert = {
|
||||
id: 'alert-4',
|
||||
alertType: 'News2Emergency',
|
||||
severity: 'Critical',
|
||||
alertType: 'NEWS2_EMERGENCY',
|
||||
severity: 'CRITICAL',
|
||||
details: 'NEWS2 score 8 (HIGH): RESP_RATE=3, SPO2=2',
|
||||
triggeredAt: '2026-06-19T14:00:00Z',
|
||||
explanation: {
|
||||
|
||||
@@ -18,9 +18,9 @@ describe('CriticalAlertBanner', () => {
|
||||
const alertStore = useAlertStore()
|
||||
alertStore.bannerAlerts = [{
|
||||
id: 'alert-1',
|
||||
alertType: 'SofaSepsis',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'SOFA_SEPSIS',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
details: 'SOFA delta >= 2',
|
||||
explanation: {
|
||||
narrativeSummary: 'SOFA 6 — respiratory (+2), renal (+2).',
|
||||
|
||||
@@ -13,9 +13,9 @@ const events = [
|
||||
{
|
||||
type: 'alert',
|
||||
timestamp: '2026-06-23T11:00:00Z',
|
||||
alertType: 'QsofaScreen',
|
||||
severity: 'Warning',
|
||||
status: 'Open',
|
||||
alertType: 'QSOFA_SCREEN',
|
||||
severity: 'WARNING',
|
||||
status: 'OPEN',
|
||||
},
|
||||
{
|
||||
type: 'medication',
|
||||
|
||||
@@ -23,8 +23,8 @@ vi.mock('@/stores/alertQuality', () => ({
|
||||
|
||||
const defaultProps = {
|
||||
alertId: 'alert-1',
|
||||
alertType: 'SepsisWarning',
|
||||
severity: 'Critical',
|
||||
alertType: 'SEPSIS_WARNING',
|
||||
severity: 'CRITICAL',
|
||||
}
|
||||
|
||||
function ratingButtons(wrapper) {
|
||||
|
||||
@@ -10,8 +10,8 @@ const { mockSummaryStats, mockByAlertType } = vi.hoisted(() => ({
|
||||
falsePositiveRate: 33,
|
||||
},
|
||||
mockByAlertType: {
|
||||
SepsisWarning: [{ rating: 'useful' }, { rating: 'would-act' }],
|
||||
WarningHeartRate: [{ rating: 'false-positive' }],
|
||||
SEPSIS_WARNING: [{ rating: 'useful' }, { rating: 'would-act' }],
|
||||
WARNING_HEART_RATE: [{ rating: 'false-positive' }],
|
||||
},
|
||||
}))
|
||||
|
||||
|
||||
@@ -3,23 +3,23 @@ import { detectNewCriticalAlerts, isNotifiableCriticalAlert } from '@/composable
|
||||
|
||||
const criticalOpen = {
|
||||
id: 'a1',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'SofaSepsis',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
alertType: 'SOFA_SEPSIS',
|
||||
}
|
||||
|
||||
const criticalAcknowledged = {
|
||||
id: 'a2',
|
||||
severity: 'Critical',
|
||||
status: 'Acknowledged',
|
||||
alertType: 'News2Emergency',
|
||||
severity: 'CRITICAL',
|
||||
status: 'ACKNOWLEDGED',
|
||||
alertType: 'NEWS2_EMERGENCY',
|
||||
}
|
||||
|
||||
const warningOpen = {
|
||||
id: 'a3',
|
||||
severity: 'Warning',
|
||||
status: 'Open',
|
||||
alertType: 'News2Warning',
|
||||
severity: 'WARNING',
|
||||
status: 'OPEN',
|
||||
alertType: 'NEWS2_WARNING',
|
||||
}
|
||||
|
||||
describe('criticalAlertDetect', () => {
|
||||
@@ -39,7 +39,7 @@ describe('criticalAlertDetect', () => {
|
||||
it('detectsNewCriticalAlertsAfterSeed', () => {
|
||||
const seeded = detectNewCriticalAlerts([criticalOpen], [], false)
|
||||
const next = detectNewCriticalAlerts(
|
||||
[criticalOpen, { ...criticalOpen, id: 'a4', alertType: 'GcsCritical' }],
|
||||
[criticalOpen, { ...criticalOpen, id: 'a4', alertType: 'GCS_CRITICAL' }],
|
||||
seeded.nextSeenIds,
|
||||
seeded.seeded,
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ const enrichment = {
|
||||
admissionReason: 'Sepsis workup',
|
||||
patient: { allergies: 'Penicillin' },
|
||||
},
|
||||
openAlerts: [{ alertType: 'News2Emergency' }],
|
||||
openAlerts: [{ alertType: 'NEWS2_EMERGENCY' }],
|
||||
pendingOrders: [{ description: 'Blood cultures', status: 'Pending' }],
|
||||
vitals: extractLatestVitals([
|
||||
{ observationCode: 'HEART_RATE', value: 110, unit: 'bpm', recordedAt: '2026-06-23T10:00:00Z' },
|
||||
|
||||
@@ -11,9 +11,9 @@ describe('alert store notifications', () => {
|
||||
const store = useAlertStore()
|
||||
const critical = {
|
||||
id: 'alert-1',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'SofaSepsis',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
alertType: 'SOFA_SEPSIS',
|
||||
}
|
||||
|
||||
expect(store.applyPollResults([critical])).toEqual([])
|
||||
@@ -21,9 +21,9 @@ describe('alert store notifications', () => {
|
||||
|
||||
const next = {
|
||||
id: 'alert-2',
|
||||
severity: 'Critical',
|
||||
status: 'Open',
|
||||
alertType: 'GcsCritical',
|
||||
severity: 'CRITICAL',
|
||||
status: 'OPEN',
|
||||
alertType: 'GCS_CRITICAL',
|
||||
}
|
||||
const newAlerts = store.applyPollResults([critical, next])
|
||||
expect(newAlerts.map(alert => alert.id)).toEqual(['alert-2'])
|
||||
|
||||
@@ -14,7 +14,7 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('addFeedback_createsEntry', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
|
||||
expect(store.entries).toHaveLength(1)
|
||||
expect(store.entries[0].alertId).toBe('a1')
|
||||
@@ -23,8 +23,8 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('addFeedback_updatesExisting', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'false-positive')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'false-positive')
|
||||
|
||||
expect(store.entries).toHaveLength(1)
|
||||
expect(store.entries[0].rating).toBe('false-positive')
|
||||
@@ -32,10 +32,10 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('stats_computesCorrectly', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a2', 'SepsisWarning', 'Critical', 'would-act')
|
||||
store.addFeedback('a3', 'WarningHeartRate', 'Warning', 'false-positive')
|
||||
store.addFeedback('a4', 'WarningHeartRate', 'Warning', 'too-early')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
store.addFeedback('a2', 'SEPSIS_WARNING', 'CRITICAL', 'would-act')
|
||||
store.addFeedback('a3', 'WARNING_HEART_RATE', 'WARNING', 'false-positive')
|
||||
store.addFeedback('a4', 'WARNING_HEART_RATE', 'WARNING', 'too-early')
|
||||
|
||||
expect(store.stats.total).toBe(4)
|
||||
expect(store.stats.useful).toBe(2)
|
||||
@@ -46,18 +46,18 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('byAlertType_groupsCorrectly', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a2', 'WarningHeartRate', 'Warning', 'false-positive')
|
||||
store.addFeedback('a3', 'SepsisWarning', 'Critical', 'too-early')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
store.addFeedback('a2', 'WARNING_HEART_RATE', 'WARNING', 'false-positive')
|
||||
store.addFeedback('a3', 'SEPSIS_WARNING', 'CRITICAL', 'too-early')
|
||||
|
||||
expect(Object.keys(store.byAlertType)).toHaveLength(2)
|
||||
expect(store.byAlertType.SepsisWarning).toHaveLength(2)
|
||||
expect(store.byAlertType.WarningHeartRate).toHaveLength(1)
|
||||
expect(store.byAlertType.SEPSIS_WARNING).toHaveLength(2)
|
||||
expect(store.byAlertType.WARNING_HEART_RATE).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('exportAsJson_generatesValidJson', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
|
||||
let capturedBlob = null
|
||||
const click = vi.fn()
|
||||
@@ -81,7 +81,7 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('clearAll_emptiesEntries', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
store.clearAll()
|
||||
|
||||
expect(store.entries).toHaveLength(0)
|
||||
@@ -89,7 +89,7 @@ describe('useFeedbackStore', () => {
|
||||
|
||||
it('persistsToLocalStorage', () => {
|
||||
const store = useFeedbackStore()
|
||||
store.addFeedback('a1', 'SepsisWarning', 'Critical', 'useful')
|
||||
store.addFeedback('a1', 'SEPSIS_WARNING', 'CRITICAL', 'useful')
|
||||
|
||||
const stored = JSON.parse(localStorage.getItem('vigilcare-feedback'))
|
||||
expect(stored).toHaveLength(1)
|
||||
|
||||
Reference in New Issue
Block a user