fix(alarmas): heal alarms already poisoned by the old Detener anchor
The anchor fix stops NEW damage, but devices that ran the buggy build still carry a future occurrence in ultimaEjecucionGestionada in SharedPreferences. _esValida rejects any candidate matching it, so the affected alarm would keep skipping that day with nothing in the UI to explain it -- which reads as "still broken" rather than "fixed". _recalcular now drops an ultimaEjecucionGestionada that is meaningfully in the future. An occurrence cannot have been handled before it happens, so such a value is corrupt by definition, and dropping it can only ever restore a real future ring: the double-fire guard it also feeds needs a PAST occurrence to do its job, and those are untouched. Placed in the recalculation that every load and every mutation already funnels through, so an affected alarm heals on the next app open with no user action -- no delete-and-recreate. Tests: 1122 -> 1124, including one proving a genuine past occurrence is still preserved.
This commit is contained in:
@@ -568,13 +568,34 @@ class ServicioAlarmas {
|
||||
alarma.activa &&
|
||||
alarma.snoozeHasta != null &&
|
||||
alarma.snoozeHasta!.isAfter(ahora);
|
||||
// Self-heal for state poisoned before the Detener anchor fix: a stop
|
||||
// that closed a FUTURE occurrence wrote it into
|
||||
// ultimaEjecucionGestionada, and _esValida rejects any candidate
|
||||
// matching it -- so the alarm silently skips that day forever after,
|
||||
// with nothing in the UI to explain it. An occurrence cannot have been
|
||||
// handled before it happens, so a value meaningfully in the future is
|
||||
// corrupt by definition and safe to drop: it can only ever suppress a
|
||||
// real future ring, never prevent a double-fire (which needs a PAST
|
||||
// occurrence to guard). Placed here, in the recalculation every load and
|
||||
// every mutation already funnels through, so an affected alarm heals on
|
||||
// the next app open with no user action.
|
||||
final gestionada = alarma.ultimaEjecucionGestionada;
|
||||
final gestionadaCorrupta =
|
||||
gestionada != null &&
|
||||
gestionada.isAfter(
|
||||
ahora.add(ServicioProgramacionAlarmas.toleranciaDisparoInminente),
|
||||
);
|
||||
final saneada =
|
||||
gestionadaCorrupta
|
||||
? alarma.copyWith(limpiarUltimaEjecucionGestionada: true)
|
||||
: alarma;
|
||||
final proxima = _programacion.calcularProxima(
|
||||
alarma: alarma,
|
||||
alarma: saneada,
|
||||
desde: ahora,
|
||||
vacaciones: vacaciones,
|
||||
excepciones: excepciones,
|
||||
);
|
||||
return alarma.copyWith(
|
||||
return saneada.copyWith(
|
||||
proximaEjecucion: proxima,
|
||||
limpiarProximaEjecucion: true,
|
||||
limpiarSnooze: !snoozeActivo,
|
||||
|
||||
Reference in New Issue
Block a user