feat: CAPA overdue escalation cron — 4 thresholds, once-per-threshold via notifications_log

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
This commit is contained in:
2026-07-11 15:20:15 +08:00
co-authored by Claude Opus 4.8
parent 804b1fbf33
commit 75fa2605bf
5 changed files with 179 additions and 0 deletions
@@ -0,0 +1,34 @@
import { describe, it, expect } from 'vitest'
import { getEscalationThreshold } from '@/lib/notifications/capa-escalation'
describe('getEscalationThreshold', () => {
function daysFromNow(n: number): string {
const d = new Date()
d.setDate(d.getDate() + n)
return d.toISOString().split('T')[0]
}
it('returns warning_3d when due in 3 days', () => {
expect(getEscalationThreshold(daysFromNow(3))).toBe('warning_3d')
})
it('returns due_today when due today', () => {
expect(getEscalationThreshold(daysFromNow(0))).toBe('due_today')
})
it('returns overdue_3d when 3 days past due', () => {
expect(getEscalationThreshold(daysFromNow(-3))).toBe('overdue_3d')
})
it('returns overdue_7d when 7 days past due', () => {
expect(getEscalationThreshold(daysFromNow(-7))).toBe('overdue_7d')
})
it('returns null for 2 days before due (no threshold)', () => {
expect(getEscalationThreshold(daysFromNow(2))).toBeNull()
})
it('returns null for 4 days before due', () => {
expect(getEscalationThreshold(daysFromNow(4))).toBeNull()
})
})