Tell administrators about a location without a schedule

A notification when a schedule is turned off, then a reminder: once a week while another
location is backed up, every day when none is. The round trip now also checks the text of
these notifications and of the one about names, and that one location never gets two runs.
This commit is contained in:
2026-11-07 00:23:28 +01:00
parent e58b86fc48
commit 36f2427e9a
8 changed files with 97 additions and 12 deletions
+24
View File
@@ -101,6 +101,30 @@ final class AlertService {
return $v === '' ? null : (int)$v;
}
/**
* Whether it is time to remind administrators of a location without a schedule: once a week
* while another location is still backed up, every day when none is. An hour of margin, so
* that the moment of the cron run does not push a reminder to the next day.
*/
public static function offReminderDue(int $last, int $now, bool $othersActive): bool {
return $now - $last >= ($othersActive ? 7 * 86400 : 86400) - 3600;
}
public function checkOff(Target $target, bool $othersActive): void {
if ((string)$target->getSchedule() !== '') {
return;
}
$key = 'off_notified_' . $target->getId();
$now = time();
$last = max((int)$target->getScheduleSince(), $this->appConfig->getValueInt(Application::APP_ID, $key, 0));
if (!self::offReminderDue($last, $now, $othersActive)) {
return;
}
$this->appConfig->setValueInt(Application::APP_ID, $key, $now);
$this->notifyAdmins('schedule_off', 'off-' . $target->getId() . '-' . date('Y-m-d', $now),
['target' => $target->getName(), 'others' => $othersActive ? '1' : '0']);
}
/** At most one notification per location per day. */
public function checkStale(Target $target): void {
if ((string)$target->getSchedule() === '') {