Make reminder schedules additive across frequency tiers

Each frequency tier now inherits all reminder days from smaller tiers:
- Monthly: 3d, 1d, day-of (was: 3d, day-of)
- Quarterly: 7d, 3d, 1d, day-of (was: 7d, 3d, day-of)
- Semi-Annual: 14d, 7d, 3d, 1d, day-of (was: 14d, 7d, day-of)
- Annual: 30d, 14d, 7d, 3d, 1d, day-of (was: 30d, 14d, 7d, day-of)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-19 23:24:21 -06:00
parent 69206c6930
commit 51afa0837d

View File

@@ -20,17 +20,17 @@ var OverdueConfig = struct {
// Key: interval days (matches TaskFrequency.days in DB, 0 = Once/null)
// Value: array of days before due date to send reminders (0 = day-of)
//
// To add a reminder: append the number of days before to the slice
// Example: FrequencySchedules[30] = []int{7, 3, 0} adds 7-day warning to Monthly
// Schedules are ADDITIVE - each tier inherits all reminders from smaller tiers
// Example: Monthly (30) gets 3d + 1d + day-of because it includes Bi-Weekly's 1d
var FrequencySchedules = map[int][]int{
0: {0}, // 1. Once (null/0): day-of only
1: {0}, // 2. Daily: day-of only
7: {0}, // 3. Weekly: day-of only
14: {1, 0}, // 4. Bi-Weekly: 1 day before, day-of
30: {3, 0}, // 5. Monthly: 3 days before, day-of
90: {7, 3, 0}, // 6. Quarterly: 7d, 3d, day-of
180: {14, 7, 0}, // 7. Semi-Annually: 14d, 7d, day-of
365: {30, 14, 7, 0}, // 8. Annually: 30d, 14d, 7d, day-of
0: {0}, // 1. Once (null/0): day-of only
1: {0}, // 2. Daily: day-of only
7: {0}, // 3. Weekly: day-of only
14: {1, 0}, // 4. Bi-Weekly: 1d, day-of
30: {3, 1, 0}, // 5. Monthly: 3d, 1d, day-of
90: {7, 3, 1, 0}, // 6. Quarterly: 7d, 3d, 1d, day-of
180: {14, 7, 3, 1, 0}, // 7. Semi-Annually: 14d, 7d, 3d, 1d, day-of
365: {30, 14, 7, 3, 1, 0}, // 8. Annually: 30d, 14d, 7d, 3d, 1d, day-of
}
// HumanReadableSchedule returns admin-friendly description for each frequency
@@ -40,11 +40,11 @@ var HumanReadableSchedule = map[int]string{
0: "Day-of → Overdue (tapering)",
1: "Day-of → Overdue (tapering)",
7: "Day-of → Overdue (tapering)",
14: "1 day before → Day-of → Overdue",
30: "3 days before → Day-of → Overdue",
90: "7d → 3d → Day-of → Overdue",
180: "14d → 7d → Day-of → Overdue",
365: "30d → 14d → 7d → Day-of → Overdue",
14: "1d → Day-of → Overdue",
30: "3d → 1d → Day-of → Overdue",
90: "7d → 3d → 1d → Day-of → Overdue",
180: "14d → 7d → 3d → 1d → Day-of → Overdue",
365: "30d → 14d → 7d → 3d → 1d → Day-of → Overdue",
}
// FrequencyNames maps interval days to frequency names for display