Files
FreeTLab bccc5c48b8
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s
docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Persist the exploration, proposal, spec, design, tasks, and
verify/archive reports produced during the multi-device EQ,
alarm-countdown, and notification-visual-polish SDD cycles.
2026-07-04 12:42:11 +02:00

66 lines
4.2 KiB
Markdown

# Proposal: Pre-notice Live Countdown
## Intent
The 30-minute alarm pre-notice posts a single static notification at T-30min and never updates — it shows "30 min" frozen until the alarm fires. Users expect the same live, decrementing behavior the snooze countdown already ships (29, 28, ... 1 min). This change makes the pre-notice a TRUE per-minute live countdown, reusing the proven snooze-chain pattern already in production in this exact codebase.
## Scope
### In Scope
- Re-arm the pre-notice as a repeating per-minute chain (first post at T-30min unchanged; ticks at T-29 ... T-1).
- New `AlarmScheduler.armNextPreNoticeCountdownTick(id, remaining)` mirroring `armNextSnoozeCountdownTick`.
- Self-healing ticks: each recomputes remaining minutes from wall clock (`ceilMinutes()`), not a decrementing counter.
- Self-stop at `remaining <= 1` (final minute handled by the real fire alarm, same as snooze).
- Extend cancellation to tear down the new tick chain at all 5 sites (see Risks).
### Out of Scope
- Refactoring snooze + pre-notice into one shared countdown engine (Approach 1 — rejected; risks shipped snooze code).
- Any l10n / ARB / Dart / `MainActivity` work (`preNoticeCountdown` key already wired in all 13 locales).
- iOS pre-notice behavior.
## Capabilities
> No `openspec/specs/` exists yet. These are NEW capabilities.
### New Capabilities
- `alarm-pre-notice-countdown`: per-minute live countdown for the 30-min pre-notice notification, including arm/tick/cancel lifecycle and self-healing minute computation.
### Modified Capabilities
- None.
## Approach
Reuse `ACTION_PRE_NOTICE` for both first-post and tick (no new action constant). Keep `schedulePreNotice()` arming the first exact alarm at T-30min. After the receiver posts the pre-notice notification (skip/postpone actions stay in `PluriWaveAlarmReceiver`), it calls `AlarmScheduler.armNextPreNoticeCountdownTick(id, remaining)` to re-arm at the next minute boundary — keeping notification-building in the receiver and AlarmManager primitives in the scheduler, consistent with current separation of concerns. Switch pre-notice to `ceilMinutes()` for consistency with snooze. Use requestCode slot 9.
## Affected Areas
| Area | Impact | Description |
|------|--------|-------------|
| `android/.../AlarmScheduler.kt` | Modified | Add `armNextPreNoticeCountdownTick` + `cancelPreNoticeCountdown`; extend `cancelAlarm()` and `scheduleSpec` teardown; use `ceilMinutes()`. |
| `android/.../PluriWaveAlarmReceiver.kt` | Modified | `ACTION_PRE_NOTICE` re-arms next tick after posting; `ACTION_SKIP_NEXT`/`ACTION_POSTPONE_NEXT` now cancel the tick chain. |
## Risks
| Risk | Likelihood | Mitigation |
|------|------------|------------|
| Doze 9-min quota delays ticks over the longer 30-min window | Med | Each tick computes from wall clock → countdown "jumps" not breaks; parallel `setAlarmClock()` exits Doze near fire. |
| Missing a cancellation site leaks a repeating chain | Med | Explicit 5-site checklist: `cancelAlarm`, `scheduleSpec` no-trigger branch, snooze-transition branch, `ACTION_SKIP_NEXT`, `ACTION_POSTPONE_NEXT`. |
| Notification ID overlap with snooze countdown | Low | Invariant already holds (`scheduleSpec` branches on `snoozeUntilMillis != null`); preserve it. |
| OEM aggressive battery killers | Low | Pre-existing, already accepted for snooze; not unique to this change. |
## Rollback Plan
Revert the two Kotlin files (`AlarmScheduler.kt`, `PluriWaveAlarmReceiver.kt`) to prior commit. No schema, l10n, Dart, or config changes accompany this change, so rollback is a clean single-commit revert with zero migration. Pre-notice falls back to the existing single-shot behavior.
## Dependencies
- None. Prior `alarm-live-countdown` change already shipped the l10n template, `setNotificationStrings` plumbing, and the snooze-chain reference implementation.
## Success Criteria
- [ ] Pre-notice notification updates each minute from 29 down to 1 with the device idle/screen-off.
- [ ] Chain self-stops at the final minute; the real fire alarm takes over.
- [ ] Skip-next and postpone-next from the pre-notice cancel the tick chain (no orphaned repeating alarm).
- [ ] Snooze transition cancels the pre-notice tick chain; no double-notification.
- [ ] Snooze countdown behavior is unchanged (no regression).