docs(openspec): add SDD artifact trail for recent alarm and EQ changes
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m30s

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.
This commit is contained in:
2026-07-04 12:42:11 +02:00
parent e5b6d8acb3
commit bccc5c48b8
64 changed files with 6020 additions and 0 deletions
@@ -0,0 +1,66 @@
# Proposal: Alarm Live Countdown
## Intent
Pre-notice notifications show hardcoded Spanish text ("Empieza en 30 minutos") regardless of locale or actual remaining time. Additionally, snooze dismissal silently fails when the alarm screen launches from a dead-app state via full-screen intent, leaving the modal visible after the user taps snooze.
These are user-facing quality issues: incorrect language breaks trust for non-Spanish users, and a stuck alarm screen is a blocking UX defect.
## Scope
### In Scope
- Compute actual remaining minutes at pre-notice fire time and display in notification
- Use existing translated `durationMinutesOnly` ARB key pattern for l10n-ready text
- Add a new ARB key for the pre-notice message with minute placeholder
- Fix snooze dismissal on cold-start (dead-app) Navigator edge case
### Out of Scope
- Per-minute live-updating notifications (AlarmManager chain, foreground service, WorkManager)
- iOS notification changes (pre-notice is Android-only)
- Snooze duration configuration
## Capabilities
### New Capabilities
- `alarm-pre-notice-l10n`: Localized pre-notice notification text with computed remaining minutes
### Modified Capabilities
- `alarm-snooze-dismiss`: Fix Navigator.pop() no-op on dead-app launch path
## Approach
**Feature 1 (Countdown text):** In `PluriWaveAlarmReceiver.showPreNoticeNotification()`, compute `(triggerAtMillis - System.currentTimeMillis()) / 60_000` to get remaining minutes. Replace the hardcoded string with a new ARB key (`preNoticeCountdown`) that accepts a `{minutes}` placeholder. Reuse the existing `durationMinutesOnly` pattern already translated across all 13 locales. Single notification, no update chain, no new services.
**Feature 2 (Snooze dismiss):** In `_posponer()`, replace `navigator.pop()` with `if (navigator.canPop()) navigator.pop() else SystemNavigator.pop()`. Two-line fix.
## Affected Areas
| Area | Impact | Description |
|------|--------|-------------|
| `android/.../PluriWaveAlarmReceiver.kt` | Modified | Compute remaining minutes, use l10n string |
| `lib/pantallas/pantalla_alarma_sonando.dart` | Modified | canPop guard in `_posponer()` |
| `lib/l10n/app_*.arb` (13 files) | Modified | New `preNoticeCountdown` key |
## Risks
| Risk | Likelihood | Mitigation |
|------|------------|------------|
| Kotlin code cannot access Flutter ARB strings directly | Med | Use Android string resources or pass formatted string via MethodChannel |
| `SystemNavigator.pop()` closes entire app unexpectedly | Low | Only used when canPop is false (dead-app launch); app was not user-opened |
| Negative remaining minutes if system clock drifts | Low | Clamp to minimum 1 minute |
## Rollback Plan
Both changes are isolated. Revert the two commits (one per feature). Pre-notice reverts to hardcoded string; snooze reverts to current `pop()` behavior. No data migration, no schema changes.
## Dependencies
- None. All affected APIs and keys already exist in the codebase.
## Success Criteria
- [ ] Pre-notice notification displays remaining minutes in the device locale
- [ ] No hardcoded Spanish text in notification path
- [ ] Snooze dismisses the alarm screen when launched from dead-app state
- [ ] All 13 locale ARB files contain the new key
- [ ] Existing tests pass; new tests cover both features